]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ide/ide-probe.c
ide: set IDE_AFLAG_DRQ_INTERRUPT in do_identify()
[linux-2.6-omap-h63xx.git] / drivers / ide / ide-probe.c
index 06575a12b63518d01f2de299be39fb97f814afbe..bce427ee08aa3286301ae8342e7a32b09abf5337 100644 (file)
@@ -121,7 +121,8 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
        /* read 512 bytes of id info */
        hwif->tp_ops->input_data(drive, NULL, id, SECTOR_SIZE);
 
-       drive->id_read = 1;
+       drive->dev_flags |= IDE_DFLAG_ID_READ;
+
        local_irq_enable();
 #ifdef DEBUG
        printk(KERN_INFO "%s: dumping identify data\n", drive->name);
@@ -153,8 +154,8 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
 
        printk(KERN_INFO "%s: %s, ", drive->name, m);
 
-       drive->present = 1;
-       drive->dead = 0;
+       drive->dev_flags |= IDE_DFLAG_PRESENT;
+       drive->dev_flags &= ~IDE_DFLAG_DEAD;
 
        /*
         * Check for an ATAPI device
@@ -172,14 +173,14 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
                                                printk(KERN_CONT "cdrom or floppy?, assuming ");
                                        if (drive->media != ide_cdrom) {
                                                printk(KERN_CONT "FLOPPY");
-                                               drive->removable = 1;
+                                               drive->dev_flags |= IDE_DFLAG_REMOVABLE;
                                                break;
                                        }
                                }
                                /* Early cdrom models used zero */
                                type = ide_cdrom;
                        case ide_cdrom:
-                               drive->removable = 1;
+                               drive->dev_flags |= IDE_DFLAG_REMOVABLE;
 #ifdef CONFIG_PPC
                                /* kludge for Apple PowerBook internal zip */
                                if (!strstr(m, "CD-ROM") && strstr(m, "ZIP")) {
@@ -195,7 +196,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
                                break;
                        case ide_optical:
                                printk(KERN_CONT "OPTICAL");
-                               drive->removable = 1;
+                               drive->dev_flags |= IDE_DFLAG_REMOVABLE;
                                break;
                        default:
                                printk(KERN_CONT "UNKNOWN (type %d)", type);
@@ -205,6 +206,8 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
                drive->media = type;
                /* an ATAPI device ignores DRDY */
                drive->ready_stat = 0;
+               if (ata_id_cdb_intr(id))
+                       drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT;
                return;
        }
 
@@ -216,7 +219,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
 
        /* CF devices are *not* removable in Linux definition of the term */
        if (is_cfa == 0 && (id[ATA_ID_CONFIG] & (1 << 7)))
-               drive->removable = 1;
+               drive->dev_flags |= IDE_DFLAG_REMOVABLE;
 
        drive->media = ide_disk;
 
@@ -226,7 +229,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
 
 err_misc:
        kfree(id);
-       drive->present = 0;
+       drive->dev_flags &= ~IDE_DFLAG_PRESENT;
        return;
 }
 
@@ -426,16 +429,15 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
        ide_hwif_t *hwif = HWIF(drive);
        const struct ide_tp_ops *tp_ops = hwif->tp_ops;
        int rc;
-       u8 stat;
+       u8 present = !!(drive->dev_flags & IDE_DFLAG_PRESENT), stat;
+
+       /* avoid waiting for inappropriate probes */
+       if (present && drive->media != ide_disk && cmd == ATA_CMD_ID_ATA)
+               return 4;
 
-       if (drive->present) {
-               /* avoid waiting for inappropriate probes */
-               if (drive->media != ide_disk && cmd == ATA_CMD_ID_ATA)
-                       return 4;
-       }
 #ifdef DEBUG
        printk(KERN_INFO "probing for %s: present=%d, media=%d, probetype=%s\n",
-               drive->name, drive->present, drive->media,
+               drive->name, present, drive->media,
                (cmd == ATA_CMD_ID_ATA) ? "ATA" : "ATAPI");
 #endif
 
@@ -446,8 +448,8 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
        SELECT_DRIVE(drive);
        msleep(50);
 
-       if (ide_read_device(drive) != drive->select.all && !drive->present) {
-               if (drive->select.b.unit != 0) {
+       if (ide_read_device(drive) != drive->select && present == 0) {
+               if (drive->dn & 1) {
                        /* exit with drive0 selected */
                        SELECT_DRIVE(&hwif->drives[0]);
                        /* allow ATA_BUSY to assert & clear */
@@ -460,7 +462,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
        stat = tp_ops->read_status(hwif);
 
        if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) ||
-           drive->present || cmd == ATA_CMD_ID_ATAPI) {
+           present || cmd == ATA_CMD_ID_ATAPI) {
                /* send cmd and wait */
                if ((rc = try_to_identify(drive, cmd))) {
                        /* failed: try again */
@@ -493,7 +495,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
                /* not present or maybe ATAPI */
                rc = 3;
        }
-       if (drive->select.b.unit != 0) {
+       if (drive->dn & 1) {
                /* exit with drive0 selected */
                SELECT_DRIVE(&hwif->drives[0]);
                msleep(50);
@@ -542,8 +544,8 @@ static void enable_nest (ide_drive_t *drive)
  *     and presents things to the user as needed.
  *
  *     Returns:        0  no device was found
- *                     1  device was found (note: drive->present might
- *                        still be 0)
+ *                     1  device was found
+ *                        (note: IDE_DFLAG_PRESENT might still be not set)
  */
  
 static inline u8 probe_for_drive (ide_drive_t *drive)
@@ -559,10 +561,10 @@ static inline u8 probe_for_drive (ide_drive_t *drive)
         *      Also note that 0 everywhere means "can't do X"
         */
  
+       drive->dev_flags &= ~IDE_DFLAG_ID_READ;
+
        drive->id = kzalloc(SECTOR_SIZE, GFP_KERNEL);
-       drive->id_read = 0;
-       if(drive->id == NULL)
-       {
+       if (drive->id == NULL) {
                printk(KERN_ERR "ide: out of memory for id data.\n");
                return 0;
        }
@@ -571,14 +573,14 @@ static inline u8 probe_for_drive (ide_drive_t *drive)
        strcpy(m, "UNKNOWN");
 
        /* skip probing? */
-       if (!drive->noprobe) {
+       if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0) {
 retry:
                /* if !(success||timed-out) */
                if (do_probe(drive, ATA_CMD_ID_ATA) >= 2)
                        /* look for ATAPI device */
                        (void)do_probe(drive, ATA_CMD_ID_ATAPI);
 
-               if (!drive->present)
+               if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
                        /* drive not found */
                        return 0;
 
@@ -588,7 +590,7 @@ retry:
                }
 
                /* identification failed? */
-               if (!drive->id_read) {
+               if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) {
                        if (drive->media == ide_disk) {
                                printk(KERN_INFO "%s: non-IDE drive, CHS=%d/%d/%d\n",
                                        drive->name, drive->cyl,
@@ -598,15 +600,17 @@ retry:
                        } else {
                                /* nuke it */
                                printk(KERN_WARNING "%s: Unknown device on bus refused identification. Ignoring.\n", drive->name);
-                               drive->present = 0;
+                               drive->dev_flags &= ~IDE_DFLAG_PRESENT;
                        }
                }
                /* drive was found */
        }
-       if(!drive->present)
+
+       if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
                return 0;
+
        /* The drive wasn't being helpful. Add generic info only */
-       if (drive->id_read == 0) {
+       if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) {
                generic_id(drive);
                return 1;
        }
@@ -616,7 +620,7 @@ retry:
                ide_disk_init_mult_count(drive);
        }
 
-       return drive->present;
+       return !!(drive->dev_flags & IDE_DFLAG_PRESENT);
 }
 
 static void hwif_release_dev(struct device *dev)
@@ -707,7 +711,8 @@ static int ide_port_wait_ready(ide_hwif_t *hwif)
                ide_drive_t *drive = &hwif->drives[unit];
 
                /* Ignore disks that we will not probe for later. */
-               if (!drive->noprobe || drive->present) {
+               if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0 ||
+                   (drive->dev_flags & IDE_DFLAG_PRESENT)) {
                        SELECT_DRIVE(drive);
                        hwif->tp_ops->set_irq(hwif, 1);
                        mdelay(2);
@@ -739,7 +744,7 @@ void ide_undecoded_slave(ide_drive_t *dev1)
 {
        ide_drive_t *dev0 = &dev1->hwif->drives[0];
 
-       if ((dev1->dn & 1) == 0 || dev0->present == 0)
+       if ((dev1->dn & 1) == 0 || (dev0->dev_flags & IDE_DFLAG_PRESENT) == 0)
                return;
 
        /* If the models don't match they are not the same product */
@@ -759,7 +764,7 @@ void ide_undecoded_slave(ide_drive_t *dev1)
        /* Appears to be an IDE flash adapter with decode bugs */
        printk(KERN_WARNING "ide-probe: ignoring undecoded slave\n");
 
-       dev1->present = 0;
+       dev1->dev_flags &= ~IDE_DFLAG_PRESENT;
 }
 
 EXPORT_SYMBOL_GPL(ide_undecoded_slave);
@@ -772,7 +777,8 @@ static int ide_probe_port(ide_hwif_t *hwif)
 
        BUG_ON(hwif->present);
 
-       if (hwif->drives[0].noprobe && hwif->drives[1].noprobe)
+       if ((hwif->drives[0].dev_flags & IDE_DFLAG_NOPROBE) &&
+           (hwif->drives[1].dev_flags & IDE_DFLAG_NOPROBE))
                return -EACCES;
 
        /*
@@ -794,9 +800,9 @@ static int ide_probe_port(ide_hwif_t *hwif)
         */
        for (unit = 0; unit < MAX_DRIVES; ++unit) {
                ide_drive_t *drive = &hwif->drives[unit];
-               drive->dn = (hwif->channel ? 2 : 0) + unit;
+
                (void) probe_for_drive(drive);
-               if (drive->present)
+               if (drive->dev_flags & IDE_DFLAG_PRESENT)
                        rc = 0;
        }
 
@@ -820,17 +826,19 @@ static void ide_port_tune_devices(ide_hwif_t *hwif)
        for (unit = 0; unit < MAX_DRIVES; unit++) {
                ide_drive_t *drive = &hwif->drives[unit];
 
-               if (drive->present && port_ops && port_ops->quirkproc)
-                       port_ops->quirkproc(drive);
+               if (drive->dev_flags & IDE_DFLAG_PRESENT) {
+                       if (port_ops && port_ops->quirkproc)
+                               port_ops->quirkproc(drive);
+               }
        }
 
        for (unit = 0; unit < MAX_DRIVES; ++unit) {
                ide_drive_t *drive = &hwif->drives[unit];
 
-               if (drive->present) {
+               if (drive->dev_flags & IDE_DFLAG_PRESENT) {
                        ide_set_max_pio(drive);
 
-                       drive->nice1 = 1;
+                       drive->dev_flags |= IDE_DFLAG_NICE1;
 
                        if (hwif->dma_ops)
                                ide_set_dma(drive);
@@ -840,14 +848,14 @@ static void ide_port_tune_devices(ide_hwif_t *hwif)
        for (unit = 0; unit < MAX_DRIVES; ++unit) {
                ide_drive_t *drive = &hwif->drives[unit];
 
-               if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT)
-                       drive->no_io_32bit = 1;
+               if ((hwif->host_flags & IDE_HFLAG_NO_IO_32BIT) ||
+                   drive->id[ATA_ID_DWORD_IO])
+                       drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT;
                else
-                       drive->no_io_32bit = drive->id[ATA_ID_DWORD_IO] ? 1 : 0;
+                       drive->dev_flags &= ~IDE_DFLAG_NO_IO_32BIT;
        }
 }
 
-#if MAX_HWIFS > 1
 /*
  * save_match() is used to simplify logic in init_irq() below.
  *
@@ -872,7 +880,6 @@ static void save_match(ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match)
        if (!m || m->irq != hwif->irq) /* don't undo a prior perfect match */
                *match = new;
 }
-#endif /* MAX_HWIFS > 1 */
 
 /*
  * init request queue
@@ -959,7 +966,7 @@ static void ide_port_setup_devices(ide_hwif_t *hwif)
        for (i = 0; i < MAX_DRIVES; i++) {
                ide_drive_t *drive = &hwif->drives[i];
 
-               if (!drive->present)
+               if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
                        continue;
 
                if (ide_init_queue(drive)) {
@@ -1029,7 +1036,7 @@ static int init_irq (ide_hwif_t *hwif)
 
        mutex_lock(&ide_cfg_mtx);
        hwif->hwgroup = NULL;
-#if MAX_HWIFS > 1
+
        /*
         * Group up with any other hwifs that share our irq(s).
         */
@@ -1054,7 +1061,7 @@ static int init_irq (ide_hwif_t *hwif)
                        }
                }
        }
-#endif /* MAX_HWIFS > 1 */
+
        /*
         * If we are still without a hwgroup, then form a new one
         */
@@ -1153,12 +1160,13 @@ static struct kobject *ata_probe(dev_t dev, int *part, void *data)
        ide_hwif_t *hwif = data;
        int unit = *part >> PARTN_BITS;
        ide_drive_t *drive = &hwif->drives[unit];
-       if (!drive->present)
+
+       if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
                return NULL;
 
        if (drive->media == ide_disk)
                request_module("ide-disk");
-       if (drive->scsi)
+       if (drive->dev_flags & IDE_DFLAG_SCSI)
                request_module("ide-scsi");
        if (drive->media == ide_cdrom || drive->media == ide_optical)
                request_module("ide-cd");
@@ -1205,7 +1213,7 @@ EXPORT_SYMBOL_GPL(ide_unregister_region);
 void ide_init_disk(struct gendisk *disk, ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
-       unsigned int unit = (drive->select.all >> 4) & 1;
+       unsigned int unit = drive->dn & 1;
 
        disk->major = hwif->major;
        disk->first_minor = unit << PARTN_BITS;
@@ -1248,7 +1256,7 @@ static void drive_release_dev (struct device *dev)
        ide_remove_drive_from_hwgroup(drive);
        kfree(drive->id);
        drive->id = NULL;
-       drive->present = 0;
+       drive->dev_flags &= ~IDE_DFLAG_PRESENT;
        /* Messed up locking ... */
        spin_unlock_irq(&ide_lock);
        blk_cleanup_queue(drive->queue);
@@ -1327,7 +1335,7 @@ static void hwif_register_devices(ide_hwif_t *hwif)
                struct device *dev = &drive->gendev;
                int ret;
 
-               if (!drive->present)
+               if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
                        continue;
 
                snprintf(dev->bus_id, BUS_ID_SIZE, "%u.%u", hwif->index, i);
@@ -1351,12 +1359,14 @@ static void ide_port_init_devices(ide_hwif_t *hwif)
        for (i = 0; i < MAX_DRIVES; i++) {
                ide_drive_t *drive = &hwif->drives[i];
 
+               drive->dn = i + hwif->channel * 2;
+
                if (hwif->host_flags & IDE_HFLAG_IO_32BIT)
                        drive->io_32bit = 1;
                if (hwif->host_flags & IDE_HFLAG_UNMASK_IRQS)
-                       drive->unmask = 1;
+                       drive->dev_flags |= IDE_DFLAG_UNMASK;
                if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS)
-                       drive->no_unmask = 1;
+                       drive->dev_flags |= IDE_DFLAG_NO_UNMASK;
 
                if (port_ops && port_ops->init_dev)
                        port_ops->init_dev(drive);
@@ -1513,19 +1523,14 @@ static int ide_find_port_slot(const struct ide_port_info *d)
         * ports 0x1f0/0x170 (the ide0/ide1 defaults).
         */
        mutex_lock(&ide_cfg_mtx);
-       if (MAX_HWIFS == 1) {
-               if (ide_indexes == 0 && i == 0)
-                       idx = 1;
+       if (bootable) {
+               if ((ide_indexes | i) != (1 << MAX_HWIFS) - 1)
+                       idx = ffz(ide_indexes | i);
        } else {
-               if (bootable) {
-                       if ((ide_indexes | i) != (1 << MAX_HWIFS) - 1)
-                               idx = ffz(ide_indexes | i);
-               } else {
-                       if ((ide_indexes | 3) != (1 << MAX_HWIFS) - 1)
-                               idx = ffz(ide_indexes | 3);
-                       else if ((ide_indexes & 3) != 3)
-                               idx = ffz(ide_indexes);
-               }
+               if ((ide_indexes | 3) != (1 << MAX_HWIFS) - 1)
+                       idx = ffz(ide_indexes | 3);
+               else if ((ide_indexes & 3) != 3)
+                       idx = ffz(ide_indexes);
        }
        if (idx >= 0)
                ide_indexes |= (1 << idx);
@@ -1541,8 +1546,7 @@ static void ide_free_port_slot(int idx)
        mutex_unlock(&ide_cfg_mtx);
 }
 
-struct ide_host *ide_host_alloc_all(const struct ide_port_info *d,
-                                   hw_regs_t **hws)
+struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws)
 {
        struct ide_host *host;
        int i;
@@ -1551,7 +1555,7 @@ struct ide_host *ide_host_alloc_all(const struct ide_port_info *d,
        if (host == NULL)
                return NULL;
 
-       for (i = 0; i < MAX_HWIFS; i++) {
+       for (i = 0; i < MAX_HOST_PORTS; i++) {
                ide_hwif_t *hwif;
                int idx;
 
@@ -1593,18 +1597,6 @@ struct ide_host *ide_host_alloc_all(const struct ide_port_info *d,
 
        return host;
 }
-EXPORT_SYMBOL_GPL(ide_host_alloc_all);
-
-struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws)
-{
-       hw_regs_t *hws_all[MAX_HWIFS];
-       int i;
-
-       for (i = 0; i < MAX_HWIFS; i++)
-               hws_all[i] = (i < 4) ? hws[i] : NULL;
-
-       return ide_host_alloc_all(d, hws_all);
-}
 EXPORT_SYMBOL_GPL(ide_host_alloc);
 
 int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
@@ -1613,7 +1605,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
        ide_hwif_t *hwif, *mate = NULL;
        int i, j = 0;
 
-       for (i = 0; i < MAX_HWIFS; i++) {
+       for (i = 0; i < MAX_HOST_PORTS; i++) {
                hwif = host->ports[i];
 
                if (hwif == NULL) {
@@ -1626,22 +1618,22 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
 
                if (d == NULL) {
                        mate = NULL;
-                       continue;
-               }
+               } else {
+                       if ((i & 1) && mate) {
+                               hwif->mate = mate;
+                               mate->mate = hwif;
+                       }
 
-               if ((i & 1) && mate) {
-                       hwif->mate = mate;
-                       mate->mate = hwif;
-               }
+                       mate = (i & 1) ? NULL : hwif;
 
-               mate = (i & 1) ? NULL : hwif;
+                       ide_init_port(hwif, i & 1, d);
+                       ide_port_cable_detect(hwif);
+               }
 
-               ide_init_port(hwif, i & 1, d);
-               ide_port_cable_detect(hwif);
                ide_port_init_devices(hwif);
        }
 
-       for (i = 0; i < MAX_HWIFS; i++) {
+       for (i = 0; i < MAX_HOST_PORTS; i++) {
                hwif = host->ports[i];
 
                if (hwif == NULL)
@@ -1658,7 +1650,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
                        ide_port_tune_devices(hwif);
        }
 
-       for (i = 0; i < MAX_HWIFS; i++) {
+       for (i = 0; i < MAX_HOST_PORTS; i++) {
                hwif = host->ports[i];
 
                if (hwif == NULL)
@@ -1682,7 +1674,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
                        ide_acpi_port_init_devices(hwif);
        }
 
-       for (i = 0; i < MAX_HWIFS; i++) {
+       for (i = 0; i < MAX_HOST_PORTS; i++) {
                hwif = host->ports[i];
 
                if (hwif == NULL)
@@ -1695,7 +1687,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
                        hwif_register_devices(hwif);
        }
 
-       for (i = 0; i < MAX_HWIFS; i++) {
+       for (i = 0; i < MAX_HOST_PORTS; i++) {
                hwif = host->ports[i];
 
                if (hwif == NULL)
@@ -1740,7 +1732,7 @@ void ide_host_free(struct ide_host *host)
        ide_hwif_t *hwif;
        int i;
 
-       for (i = 0; i < MAX_HWIFS; i++) {
+       for (i = 0; i < MAX_HOST_PORTS; i++) {
                hwif = host->ports[i];
 
                if (hwif == NULL)
@@ -1758,7 +1750,7 @@ void ide_host_remove(struct ide_host *host)
 {
        int i;
 
-       for (i = 0; i < MAX_HWIFS; i++) {
+       for (i = 0; i < MAX_HOST_PORTS; i++) {
                if (host->ports[i])
                        ide_unregister(host->ports[i]);
        }