ide: move read_sff_dma_status() method to 'struct ide_dma_ops'
[safe/jmp/linux-2.6] / drivers / ide / ide-probe.c
index 9dfa99f..0ccbb44 100644 (file)
@@ -463,7 +463,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
        if (ide_read_device(drive) != drive->select && present == 0) {
                if (drive->dn & 1) {
                        /* exit with drive0 selected */
-                       SELECT_DRIVE(&hwif->drives[0]);
+                       SELECT_DRIVE(hwif->devices[0]);
                        /* allow ATA_BUSY to assert & clear */
                        msleep(50);
                }
@@ -509,7 +509,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
        }
        if (drive->dn & 1) {
                /* exit with drive0 selected */
-               SELECT_DRIVE(&hwif->drives[0]);
+               SELECT_DRIVE(hwif->devices[0]);
                msleep(50);
                /* ensure drive irq is clear */
                (void)tp_ops->read_status(hwif);
@@ -697,7 +697,8 @@ out:
 
 static int ide_port_wait_ready(ide_hwif_t *hwif)
 {
-       int unit, rc;
+       ide_drive_t *drive;
+       int i, rc;
 
        printk(KERN_DEBUG "Probing IDE interface %s...\n", hwif->name);
 
@@ -714,9 +715,7 @@ static int ide_port_wait_ready(ide_hwif_t *hwif)
                return rc;
 
        /* Now make sure both master & slave are ready */
-       for (unit = 0; unit < MAX_DRIVES; unit++) {
-               ide_drive_t *drive = &hwif->drives[unit];
-
+       ide_port_for_each_dev(i, drive, hwif) {
                /* Ignore disks that we will not probe for later. */
                if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0 ||
                    (drive->dev_flags & IDE_DFLAG_PRESENT)) {
@@ -732,8 +731,8 @@ static int ide_port_wait_ready(ide_hwif_t *hwif)
        }
 out:
        /* Exit function with master reselected (let's be sane) */
-       if (unit)
-               SELECT_DRIVE(&hwif->drives[0]);
+       if (i)
+               SELECT_DRIVE(hwif->devices[0]);
 
        return rc;
 }
@@ -749,7 +748,7 @@ out:
 
 void ide_undecoded_slave(ide_drive_t *dev1)
 {
-       ide_drive_t *dev0 = &dev1->hwif->drives[0];
+       ide_drive_t *dev0 = dev1->hwif->devices[0];
 
        if ((dev1->dn & 1) == 0 || (dev0->dev_flags & IDE_DFLAG_PRESENT) == 0)
                return;
@@ -778,14 +777,15 @@ EXPORT_SYMBOL_GPL(ide_undecoded_slave);
 
 static int ide_probe_port(ide_hwif_t *hwif)
 {
+       ide_drive_t *drive;
        unsigned long flags;
        unsigned int irqd;
-       int unit, rc = -ENODEV;
+       int i, rc = -ENODEV;
 
        BUG_ON(hwif->present);
 
-       if ((hwif->drives[0].dev_flags & IDE_DFLAG_NOPROBE) &&
-           (hwif->drives[1].dev_flags & IDE_DFLAG_NOPROBE))
+       if ((hwif->devices[0]->dev_flags & IDE_DFLAG_NOPROBE) &&
+           (hwif->devices[1]->dev_flags & IDE_DFLAG_NOPROBE))
                return -EACCES;
 
        /*
@@ -796,7 +796,8 @@ static int ide_probe_port(ide_hwif_t *hwif)
        if (irqd)
                disable_irq(hwif->irq);
 
-       local_irq_set(flags);
+       local_irq_save(flags);
+       local_irq_enable_in_hardirq();
 
        if (ide_port_wait_ready(hwif) == -EBUSY)
                printk(KERN_DEBUG "%s: Wait for ready failed before probe !\n", hwif->name);
@@ -805,9 +806,7 @@ static int ide_probe_port(ide_hwif_t *hwif)
         * Second drive should only exist if first drive was found,
         * but a lot of cdrom drives are configured as single slaves.
         */
-       for (unit = 0; unit < MAX_DRIVES; ++unit) {
-               ide_drive_t *drive = &hwif->drives[unit];
-
+       ide_port_for_each_dev(i, drive, hwif) {
                (void) probe_for_drive(drive);
                if (drive->dev_flags & IDE_DFLAG_PRESENT)
                        rc = 0;
@@ -828,20 +827,17 @@ static int ide_probe_port(ide_hwif_t *hwif)
 static void ide_port_tune_devices(ide_hwif_t *hwif)
 {
        const struct ide_port_ops *port_ops = hwif->port_ops;
-       int unit;
-
-       for (unit = 0; unit < MAX_DRIVES; unit++) {
-               ide_drive_t *drive = &hwif->drives[unit];
+       ide_drive_t *drive;
+       int i;
 
+       ide_port_for_each_dev(i, drive, hwif) {
                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];
-
+       ide_port_for_each_dev(i, drive, hwif) {
                if (drive->dev_flags & IDE_DFLAG_PRESENT) {
                        ide_set_max_pio(drive);
 
@@ -852,11 +848,8 @@ 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->id[ATA_ID_DWORD_IO])
+       ide_port_for_each_dev(i, drive, hwif) {
+               if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT)
                        drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT;
                else
                        drive->dev_flags &= ~IDE_DFLAG_NO_IO_32BIT;
@@ -926,12 +919,11 @@ static DEFINE_MUTEX(ide_cfg_mtx);
  */
 static int ide_port_setup_devices(ide_hwif_t *hwif)
 {
+       ide_drive_t *drive;
        int i, j = 0;
 
        mutex_lock(&ide_cfg_mtx);
-       for (i = 0; i < MAX_DRIVES; i++) {
-               ide_drive_t *drive = &hwif->drives[i];
-
+       ide_port_for_each_dev(i, drive, hwif) {
                if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
                        continue;
 
@@ -1016,7 +1008,7 @@ 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];
+       ide_drive_t *drive = hwif->devices[unit];
 
        if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
                return NULL;
@@ -1160,10 +1152,10 @@ out:
 
 static void hwif_register_devices(ide_hwif_t *hwif)
 {
+       ide_drive_t *drive;
        unsigned int i;
 
-       for (i = 0; i < MAX_DRIVES; i++) {
-               ide_drive_t *drive = &hwif->drives[i];
+       ide_port_for_each_dev(i, drive, hwif) {
                struct device *dev = &drive->gendev;
                int ret;
 
@@ -1186,11 +1178,10 @@ static void hwif_register_devices(ide_hwif_t *hwif)
 static void ide_port_init_devices(ide_hwif_t *hwif)
 {
        const struct ide_port_ops *port_ops = hwif->port_ops;
+       ide_drive_t *drive;
        int i;
 
-       for (i = 0; i < MAX_DRIVES; i++) {
-               ide_drive_t *drive = &hwif->drives[i];
-
+       ide_port_for_each_dev(i, drive, hwif) {
                drive->dn = i + hwif->channel * 2;
 
                if (hwif->host_flags & IDE_HFLAG_IO_32BIT)
@@ -1238,6 +1229,8 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
        if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) {
                int rc;
 
+               hwif->dma_ops = d->dma_ops;
+
                if (d->init_dma)
                        rc = d->init_dma(hwif, d);
                else
@@ -1245,12 +1238,13 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
 
                if (rc < 0) {
                        printk(KERN_INFO "%s: DMA disabled\n", hwif->name);
+
+                       hwif->dma_ops = NULL;
                        hwif->dma_base = 0;
                        hwif->swdma_mask = 0;
                        hwif->mwdma_mask = 0;
                        hwif->ultra_mask = 0;
-               } else if (d->dma_ops)
-                       hwif->dma_ops = d->dma_ops;
+               }
        }
 
        if ((d->host_flags & IDE_HFLAG_SERIALIZE) ||
@@ -1281,16 +1275,16 @@ static const u8 ide_hwif_to_major[] =
 
 static void ide_port_init_devices_data(ide_hwif_t *hwif)
 {
-       int unit;
+       ide_drive_t *drive;
+       int i;
 
-       for (unit = 0; unit < MAX_DRIVES; ++unit) {
-               ide_drive_t *drive = &hwif->drives[unit];
-               u8 j = (hwif->index * MAX_DRIVES) + unit;
+       ide_port_for_each_dev(i, drive, hwif) {
+               u8 j = (hwif->index * MAX_DRIVES) + i;
 
                memset(drive, 0, sizeof(*drive));
 
                drive->media                    = ide_disk;
-               drive->select                   = (unit << 4) | ATA_DEVICE_OBS;
+               drive->select                   = (i << 4) | ATA_DEVICE_OBS;
                drive->hwif                     = hwif;
                drive->ready_stat               = ATA_DRDY;
                drive->bad_wstat                = BAD_W_STAT;
@@ -1308,9 +1302,6 @@ static void ide_port_init_devices_data(ide_hwif_t *hwif)
 
 static void ide_init_port_data(ide_hwif_t *hwif, unsigned int index)
 {
-       /* bulk initialize hwif & drive info with zeros */
-       memset(hwif, 0, sizeof(ide_hwif_t));
-
        /* fill in any non-zero initial values */
        hwif->index     = index;
        hwif->major     = ide_hwif_to_major[index];
@@ -1387,12 +1378,43 @@ static void ide_free_port_slot(int idx)
        mutex_unlock(&ide_cfg_mtx);
 }
 
+static void ide_port_free_devices(ide_hwif_t *hwif)
+{
+       ide_drive_t *drive;
+       int i;
+
+       ide_port_for_each_dev(i, drive, hwif)
+               kfree(drive);
+}
+
+static int ide_port_alloc_devices(ide_hwif_t *hwif, int node)
+{
+       int i;
+
+       for (i = 0; i < MAX_DRIVES; i++) {
+               ide_drive_t *drive;
+
+               drive = kzalloc_node(sizeof(*drive), GFP_KERNEL, node);
+               if (drive == NULL)
+                       goto out_nomem;
+
+               hwif->devices[i] = drive;
+       }
+       return 0;
+
+out_nomem:
+       ide_port_free_devices(hwif);
+       return -ENOMEM;
+}
+
 struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws)
 {
        struct ide_host *host;
+       struct device *dev = hws[0] ? hws[0]->dev : NULL;
+       int node = dev ? dev_to_node(dev) : -1;
        int i;
 
-       host = kzalloc(sizeof(*host), GFP_KERNEL);
+       host = kzalloc_node(sizeof(*host), GFP_KERNEL, node);
        if (host == NULL)
                return NULL;
 
@@ -1403,10 +1425,15 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws)
                if (hws[i] == NULL)
                        continue;
 
-               hwif = kzalloc(sizeof(*hwif), GFP_KERNEL);
+               hwif = kzalloc_node(sizeof(*hwif), GFP_KERNEL, node);
                if (hwif == NULL)
                        continue;
 
+               if (ide_port_alloc_devices(hwif, node) < 0) {
+                       kfree(hwif);
+                       continue;
+               }
+
                idx = ide_find_port_slot(d);
                if (idx < 0) {
                        printk(KERN_ERR "%s: no free slot for interface\n",
@@ -1428,8 +1455,7 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws)
                return NULL;
        }
 
-       if (hws[0])
-               host->dev[0] = hws[0]->dev;
+       host->dev[0] = dev;
 
        if (d) {
                host->init_chipset = d->init_chipset;
@@ -1446,9 +1472,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_HOST_PORTS; i++) {
-               hwif = host->ports[i];
-
+       ide_host_for_each_port(i, hwif, host) {
                if (hwif == NULL) {
                        mate = NULL;
                        continue;
@@ -1474,9 +1498,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
                ide_port_init_devices(hwif);
        }
 
-       for (i = 0; i < MAX_HOST_PORTS; i++) {
-               hwif = host->ports[i];
-
+       ide_host_for_each_port(i, hwif, host) {
                if (hwif == NULL)
                        continue;
 
@@ -1491,9 +1513,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_HOST_PORTS; i++) {
-               hwif = host->ports[i];
-
+       ide_host_for_each_port(i, hwif, host) {
                if (hwif == NULL)
                        continue;
 
@@ -1518,9 +1538,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_HOST_PORTS; i++) {
-               hwif = host->ports[i];
-
+       ide_host_for_each_port(i, hwif, host) {
                if (hwif == NULL)
                        continue;
 
@@ -1528,9 +1546,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
                        hwif_register_devices(hwif);
        }
 
-       for (i = 0; i < MAX_HOST_PORTS; i++) {
-               hwif = host->ports[i];
-
+       ide_host_for_each_port(i, hwif, host) {
                if (hwif == NULL)
                        continue;
 
@@ -1570,11 +1586,10 @@ EXPORT_SYMBOL_GPL(ide_host_add);
 
 static void __ide_port_unregister_devices(ide_hwif_t *hwif)
 {
+       ide_drive_t *drive;
        int i;
 
-       for (i = 0; i < MAX_DRIVES; i++) {
-               ide_drive_t *drive = &hwif->drives[i];
-
+       ide_port_for_each_dev(i, drive, hwif) {
                if (drive->dev_flags & IDE_DFLAG_PRESENT) {
                        device_unregister(&drive->gendev);
                        wait_for_completion(&drive->gendev_rel_comp);
@@ -1643,12 +1658,11 @@ void ide_host_free(struct ide_host *host)
        ide_hwif_t *hwif;
        int i;
 
-       for (i = 0; i < MAX_HOST_PORTS; i++) {
-               hwif = host->ports[i];
-
+       ide_host_for_each_port(i, hwif, host) {
                if (hwif == NULL)
                        continue;
 
+               ide_port_free_devices(hwif);
                ide_free_port_slot(hwif->index);
                kfree(hwif);
        }
@@ -1659,11 +1673,12 @@ EXPORT_SYMBOL_GPL(ide_host_free);
 
 void ide_host_remove(struct ide_host *host)
 {
+       ide_hwif_t *hwif;
        int i;
 
-       for (i = 0; i < MAX_HOST_PORTS; i++) {
-               if (host->ports[i])
-                       ide_unregister(host->ports[i]);
+       ide_host_for_each_port(i, hwif, host) {
+               if (hwif)
+                       ide_unregister(hwif);
        }
 
        ide_host_free(host);
@@ -1682,8 +1697,8 @@ void ide_port_scan(ide_hwif_t *hwif)
        hwif->present = 1;
 
        ide_port_tune_devices(hwif);
-       ide_acpi_port_init_devices(hwif);
        ide_port_setup_devices(hwif);
+       ide_acpi_port_init_devices(hwif);
        hwif_register_devices(hwif);
        ide_proc_port_register_devices(hwif);
 }