ide-disk: use to_ide_drv() and ide_drv_g()
[safe/jmp/linux-2.6] / drivers / ide / ide-probe.c
index 57c7418..19f8c77 100644 (file)
@@ -206,6 +206,10 @@ 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;
+               /* we don't do head unloading on ATAPI devices */
+               drive->dev_flags |= IDE_DFLAG_NO_UNLOAD;
                return;
        }
 
@@ -221,6 +225,9 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
 
        drive->media = ide_disk;
 
+       if (!ata_id_has_unload(drive->id))
+               drive->dev_flags |= IDE_DFLAG_NO_UNLOAD;
+
        printk(KERN_CONT "%s DISK drive\n", is_cfa ? "CFA" : "ATA");
 
        return;
@@ -446,8 +453,8 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
        SELECT_DRIVE(drive);
        msleep(50);
 
-       if (ide_read_device(drive) != drive->select.all && present == 0) {
-               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 */
@@ -493,7 +500,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);
@@ -650,8 +657,8 @@ static int ide_register_port(ide_hwif_t *hwif)
                goto out;
        }
 
-       hwif->portdev = device_create_drvdata(ide_port_class, &hwif->gendev,
-                                             MKDEV(0, 0), hwif, hwif->name);
+       hwif->portdev = device_create(ide_port_class, &hwif->gendev,
+                                     MKDEV(0, 0), hwif, hwif->name);
        if (IS_ERR(hwif->portdev)) {
                ret = PTR_ERR(hwif->portdev);
                device_unregister(&hwif->gendev);
@@ -798,7 +805,7 @@ 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->dev_flags & IDE_DFLAG_PRESENT)
                        rc = 0;
@@ -956,9 +963,9 @@ static void ide_add_drive_to_hwgroup(ide_drive_t *drive)
  * - allocate the block device queue
  * - link drive into the hwgroup
  */
-static void ide_port_setup_devices(ide_hwif_t *hwif)
+static int ide_port_setup_devices(ide_hwif_t *hwif)
 {
-       int i;
+       int i, j = 0;
 
        mutex_lock(&ide_cfg_mtx);
        for (i = 0; i < MAX_DRIVES; i++) {
@@ -970,12 +977,19 @@ static void ide_port_setup_devices(ide_hwif_t *hwif)
                if (ide_init_queue(drive)) {
                        printk(KERN_ERR "ide: failed to init %s\n",
                                        drive->name);
+                       kfree(drive->id);
+                       drive->id = NULL;
+                       drive->dev_flags &= ~IDE_DFLAG_PRESENT;
                        continue;
                }
 
+               j++;
+
                ide_add_drive_to_hwgroup(drive);
        }
        mutex_unlock(&ide_cfg_mtx);
+
+       return j;
 }
 
 static ide_hwif_t *ide_ports[MAX_HWIFS];
@@ -1211,7 +1225,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;
@@ -1357,6 +1371,8 @@ 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)
@@ -1542,8 +1558,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;
@@ -1552,7 +1567,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;
 
@@ -1594,18 +1609,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,
@@ -1614,7 +1617,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) {
@@ -1627,22 +1630,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)
@@ -1659,7 +1662,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)
@@ -1672,10 +1675,13 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
                        continue;
                }
 
-               j++;
-
                if (hwif->present)
-                       ide_port_setup_devices(hwif);
+                       if (ide_port_setup_devices(hwif) == 0) {
+                               hwif->present = 0;
+                               continue;
+                       }
+
+               j++;
 
                ide_acpi_init(hwif);
 
@@ -1683,7 +1689,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)
@@ -1696,7 +1702,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)
@@ -1741,7 +1747,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)
@@ -1759,7 +1765,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]);
        }