diff options
author | Tejun Heo <htejun@gmail.com> | 2007-08-06 11:36:23 +0200 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-10-12 20:55:30 +0200 |
commit | f58229f8060055b08b34008ea08f31de1e2f003c (patch) | |
tree | 6ca5ef546671cb975ef3632fb032c238eaf1bb4c | |
parent | libata-link: introduce ata_link (diff) | |
download | linux-f58229f8060055b08b34008ea08f31de1e2f003c.tar.xz linux-f58229f8060055b08b34008ea08f31de1e2f003c.zip |
libata-link: implement and use link/device iterators
Multiple links and different number of devices per link should be
considered to iterate over links and devices. This patch implements
and uses link and device iterators - ata_port_for_each_link() and
ata_link_for_each_dev() - and ata_link_max_devices().
This change makes a lot of functions iterate over only possible
devices instead of from dev 0 to dev ATA_MAX_DEVICES. All such
changes have been examined and nothing should be broken.
While at it, add a separating comment before device helpers to
distinguish them better from link helpers and others.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r-- | drivers/ata/ata_generic.c | 7 | ||||
-rw-r--r-- | drivers/ata/libata-acpi.c | 6 | ||||
-rw-r--r-- | drivers/ata/libata-core.c | 58 | ||||
-rw-r--r-- | drivers/ata/libata-eh.c | 117 | ||||
-rw-r--r-- | drivers/ata/libata-scsi.c | 26 | ||||
-rw-r--r-- | drivers/ata/pata_it821x.c | 5 | ||||
-rw-r--r-- | drivers/ata/pata_ixp4xx_cf.c | 5 | ||||
-rw-r--r-- | drivers/ata/pata_legacy.c | 5 | ||||
-rw-r--r-- | drivers/ata/pata_pdc2027x.c | 13 | ||||
-rw-r--r-- | drivers/ata/pata_platform.c | 6 | ||||
-rw-r--r-- | drivers/ata/pata_rz1000.c | 5 | ||||
-rw-r--r-- | drivers/ata/sata_sil.c | 12 | ||||
-rw-r--r-- | include/linux/libata.h | 17 |
13 files changed, 134 insertions, 148 deletions
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index b5e390ff5bd8..44328a16075c 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c @@ -46,21 +46,20 @@ static int generic_set_mode(struct ata_port *ap, struct ata_device **unused) { int dma_enabled = 0; - int i; + struct ata_device *dev; /* Bits 5 and 6 indicate if DMA is active on master/slave */ if (ap->ioaddr.bmdma_addr) dma_enabled = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); - for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *dev = &ap->link.device[i]; + ata_link_for_each_dev(dev, &ap->link) { if (ata_dev_enabled(dev)) { /* We don't really care */ dev->pio_mode = XFER_PIO_0; dev->dma_mode = XFER_MW_DMA_0; /* We do need the right mode information for DMA or PIO and this comes from the current configuration flags */ - if (dma_enabled & (1 << (5 + i))) { + if (dma_enabled & (1 << (5 + dev->devno))) { ata_id_to_dma_mode(dev, XFER_MW_DMA_0); dev->flags &= ~ATA_DFLAG_PIO; } else { diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 0023ac4ff496..43af2e06d446 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -509,7 +509,7 @@ int ata_acpi_on_suspend(struct ata_port *ap) */ void ata_acpi_on_resume(struct ata_port *ap) { - int i; + struct ata_device *dev; if (ap->acpi_handle && (ap->pflags & ATA_PFLAG_GTM_VALID)) { BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA); @@ -519,8 +519,8 @@ void ata_acpi_on_resume(struct ata_port *ap) } /* schedule _GTF */ - for (i = 0; i < ATA_MAX_DEVICES; i++) - ap->link.device[i].flags |= ATA_DFLAG_ACPI_PENDING; + ata_link_for_each_dev(dev, &ap->link) + dev->flags |= ATA_DFLAG_ACPI_PENDING; } /** diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index dd2de485124a..f30c4771b3af 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2105,21 +2105,19 @@ int ata_bus_probe(struct ata_port *ap) { unsigned int classes[ATA_MAX_DEVICES]; int tries[ATA_MAX_DEVICES]; - int i, rc; + int rc; struct ata_device *dev; ata_port_probe(ap); - for (i = 0; i < ATA_MAX_DEVICES; i++) - tries[i] = ATA_PROBE_MAX_TRIES; + ata_link_for_each_dev(dev, &ap->link) + tries[dev->devno] = ATA_PROBE_MAX_TRIES; retry: /* reset and determine device classes */ ap->ops->phy_reset(ap); - for (i = 0; i < ATA_MAX_DEVICES; i++) { - dev = &ap->link.device[i]; - + ata_link_for_each_dev(dev, &ap->link) { if (!(ap->flags & ATA_FLAG_DISABLED) && dev->class != ATA_DEV_UNKNOWN) classes[dev->devno] = dev->class; @@ -2134,18 +2132,16 @@ int ata_bus_probe(struct ata_port *ap) /* after the reset the device state is PIO 0 and the controller state is undefined. Record the mode */ - for (i = 0; i < ATA_MAX_DEVICES; i++) - ap->link.device[i].pio_mode = XFER_PIO_0; + ata_link_for_each_dev(dev, &ap->link) + dev->pio_mode = XFER_PIO_0; /* read IDENTIFY page and configure devices. We have to do the identify specific sequence bass-ackwards so that PDIAG- is released by the slave device */ - for (i = ATA_MAX_DEVICES - 1; i >= 0; i--) { - dev = &ap->link.device[i]; - - if (tries[i]) - dev->class = classes[i]; + ata_link_for_each_dev(dev, &ap->link) { + if (tries[dev->devno]) + dev->class = classes[dev->devno]; if (!ata_dev_enabled(dev)) continue; @@ -2163,8 +2159,7 @@ int ata_bus_probe(struct ata_port *ap) /* After the identify sequence we can now set up the devices. We do this in the normal order so that the user doesn't get confused */ - for(i = 0; i < ATA_MAX_DEVICES; i++) { - dev = &ap->link.device[i]; + ata_link_for_each_dev(dev, &ap->link) { if (!ata_dev_enabled(dev)) continue; @@ -2180,8 +2175,8 @@ int ata_bus_probe(struct ata_port *ap) if (rc) goto fail; - for (i = 0; i < ATA_MAX_DEVICES; i++) - if (ata_dev_enabled(&ap->link.device[i])) + ata_link_for_each_dev(dev, &ap->link) + if (ata_dev_enabled(dev)) return 0; /* no device present, disable port */ @@ -2803,16 +2798,14 @@ static int ata_dev_set_mode(struct ata_device *dev) int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev) { + struct ata_link *link = &ap->link; struct ata_device *dev; - int i, rc = 0, used_dma = 0, found = 0; - + int rc = 0, used_dma = 0, found = 0; /* step 1: calculate xfer_mask */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { + ata_link_for_each_dev(dev, link) { unsigned int pio_mask, dma_mask; - dev = &ap->link.device[i]; - if (!ata_dev_enabled(dev)) continue; @@ -2831,8 +2824,7 @@ int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev) goto out; /* step 2: always set host PIO timings */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - dev = &ap->link.device[i]; + ata_link_for_each_dev(dev, link) { if (!ata_dev_enabled(dev)) continue; @@ -2849,9 +2841,7 @@ int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev) } /* step 3: set host DMA timings */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - dev = &ap->link.device[i]; - + ata_link_for_each_dev(dev, link) { if (!ata_dev_enabled(dev) || !dev->dma_mode) continue; @@ -2862,9 +2852,7 @@ int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev) } /* step 4: update devices' xfer mode */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - dev = &ap->link.device[i]; - + ata_link_for_each_dev(dev, link) { /* don't update suspended devices' xfer mode */ if (!ata_dev_enabled(dev)) continue; @@ -6113,6 +6101,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host) ap->link.ap = ap; + /* can't use iterator, ap isn't initialized yet */ for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->link.device[i]; dev->link = &ap->link; @@ -6453,7 +6442,8 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) /* kick EH for boot probing */ spin_lock_irqsave(ap->lock, flags); - ehi->probe_mask = (1 << ATA_MAX_DEVICES) - 1; + ehi->probe_mask = + (1 << ata_link_max_devices(&ap->link)) - 1; ehi->action |= ATA_EH_SOFTRESET; ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET; @@ -6551,7 +6541,7 @@ int ata_host_activate(struct ata_host *host, int irq, void ata_port_detach(struct ata_port *ap) { unsigned long flags; - int i; + struct ata_device *dev; if (!ap->ops->error_handler) goto skip_eh; @@ -6568,8 +6558,8 @@ void ata_port_detach(struct ata_port *ap) */ spin_lock_irqsave(ap->lock, flags); - for (i = 0; i < ATA_MAX_DEVICES; i++) - ata_dev_disable(&ap->link.device[i]); + ata_link_for_each_dev(dev, &ap->link) + ata_dev_disable(dev); spin_unlock_irqrestore(ap->lock, flags); diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index e2681f56ed44..8c37ec0bbf6c 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -200,23 +200,24 @@ static unsigned int ata_eh_dev_action(struct ata_device *dev) return ehc->i.action | ehc->i.dev_action[dev->devno]; } -static void ata_eh_clear_action(struct ata_device *dev, +static void ata_eh_clear_action(struct ata_link *link, struct ata_device *dev, struct ata_eh_info *ehi, unsigned int action) { - int i; + struct ata_device *tdev; if (!dev) { ehi->action &= ~action; - for (i = 0; i < ATA_MAX_DEVICES; i++) - ehi->dev_action[i] &= ~action; + ata_link_for_each_dev(tdev, link) + ehi->dev_action[tdev->devno] &= ~action; } else { /* doesn't make sense for port-wide EH actions */ WARN_ON(!(action & ATA_EH_PERDEV_MASK)); /* break ehi->action into ehi->dev_action */ if (ehi->action & action) { - for (i = 0; i < ATA_MAX_DEVICES; i++) - ehi->dev_action[i] |= ehi->action & action; + ata_link_for_each_dev(tdev, link) + ehi->dev_action[tdev->devno] |= + ehi->action & action; ehi->action &= ~action; } @@ -922,7 +923,8 @@ void ata_eh_qc_retry(struct ata_queued_cmd *qc) */ static void ata_eh_detach_dev(struct ata_device *dev) { - struct ata_port *ap = dev->link->ap; + struct ata_link *link = dev->link; + struct ata_port *ap = link->ap; unsigned long flags; ata_dev_disable(dev); @@ -937,8 +939,8 @@ static void ata_eh_detach_dev(struct ata_device *dev) } /* clear per-dev EH actions */ - ata_eh_clear_action(dev, &dev->link->eh_info, ATA_EH_PERDEV_MASK); - ata_eh_clear_action(dev, &dev->link->eh_context.i, ATA_EH_PERDEV_MASK); + ata_eh_clear_action(link, dev, &link->eh_info, ATA_EH_PERDEV_MASK); + ata_eh_clear_action(link, dev, &link->eh_context.i, ATA_EH_PERDEV_MASK); spin_unlock_irqrestore(ap->lock, flags); } @@ -978,7 +980,7 @@ static void ata_eh_about_to_do(struct ata_port *ap, struct ata_device *dev, ehi->flags &= ~ATA_EHI_RESET_MODIFIER_MASK; } - ata_eh_clear_action(dev, ehi, action); + ata_eh_clear_action(&ap->link, dev, ehi, action); if (!(ehc->i.flags & ATA_EHI_QUIET)) ap->pflags |= ATA_PFLAG_RECOVERED; @@ -1009,7 +1011,7 @@ static void ata_eh_done(struct ata_port *ap, struct ata_device *dev, ehc->i.flags &= ~ATA_EHI_RESET_MODIFIER_MASK; } - ata_eh_clear_action(dev, &ehc->i, action); + ata_eh_clear_action(&ap->link, dev, &ehc->i, action); } /** @@ -1736,10 +1738,11 @@ static void ata_eh_report(struct ata_port *ap) static int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset, unsigned int *classes, unsigned long deadline) { - int i, rc; + struct ata_device *dev; + int rc; - for (i = 0; i < ATA_MAX_DEVICES; i++) - classes[i] = ATA_DEV_UNKNOWN; + ata_link_for_each_dev(dev, &ap->link) + classes[dev->devno] = ATA_DEV_UNKNOWN; rc = reset(ap, classes, deadline); if (rc) @@ -1749,14 +1752,16 @@ static int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset, * is complete and convert all ATA_DEV_UNKNOWN to * ATA_DEV_NONE. */ - for (i = 0; i < ATA_MAX_DEVICES; i++) - if (classes[i] != ATA_DEV_UNKNOWN) + ata_link_for_each_dev(dev, &ap->link) + if (classes[dev->devno] != ATA_DEV_UNKNOWN) break; - if (i < ATA_MAX_DEVICES) - for (i = 0; i < ATA_MAX_DEVICES; i++) - if (classes[i] == ATA_DEV_UNKNOWN) - classes[i] = ATA_DEV_NONE; + if (dev) { + ata_link_for_each_dev(dev, &ap->link) { + if (classes[dev->devno] == ATA_DEV_UNKNOWN) + classes[dev->devno] = ATA_DEV_NONE; + } + } return 0; } @@ -1781,10 +1786,11 @@ static int ata_eh_reset(struct ata_port *ap, int classify, unsigned int *classes = ehc->classes; int verbose = !(ehc->i.flags & ATA_EHI_QUIET); int try = 0; + struct ata_device *dev; unsigned long deadline; unsigned int action; ata_reset_fn_t reset; - int i, rc; + int rc; /* about to reset */ ata_eh_about_to_do(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK); @@ -1808,8 +1814,8 @@ static int ata_eh_reset(struct ata_port *ap, int classify, "port disabled. ignoring.\n"); ehc->i.action &= ~ATA_EH_RESET_MASK; - for (i = 0; i < ATA_MAX_DEVICES; i++) - classes[i] = ATA_DEV_NONE; + ata_link_for_each_dev(dev, &ap->link) + classes[dev->devno] = ATA_DEV_NONE; rc = 0; } else @@ -1826,8 +1832,8 @@ static int ata_eh_reset(struct ata_port *ap, int classify, reset = softreset; else { /* prereset told us not to reset, bang classes and return */ - for (i = 0; i < ATA_MAX_DEVICES; i++) - classes[i] = ATA_DEV_NONE; + ata_link_for_each_dev(dev, &ap->link) + classes[dev->devno] = ATA_DEV_NONE; rc = 0; goto out; } @@ -1908,8 +1914,8 @@ static int ata_eh_reset(struct ata_port *ap, int classify, /* After the reset, the device state is PIO 0 and the * controller state is undefined. Record the mode. */ - for (i = 0; i < ATA_MAX_DEVICES; i++) - ap->link.device[i].pio_mode = XFER_PIO_0; + ata_link_for_each_dev(dev, &ap->link) + dev->pio_mode = XFER_PIO_0; /* record current link speed */ if (sata_scr_read(ap, SCR_STATUS, &sstatus) == 0) @@ -1935,7 +1941,7 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, struct ata_device *dev; unsigned int new_mask = 0; unsigned long flags; - int i, rc = 0; + int rc = 0; DPRINTK("ENTER\n"); @@ -1943,11 +1949,9 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, * be done backwards such that PDIAG- is released by the slave * device before the master device is identified. */ - for (i = ATA_MAX_DEVICES - 1; i >= 0; i--) { - unsigned int action, readid_flags = 0; - - dev = &ap->link.device[i]; - action = ata_eh_dev_action(dev); + ata_link_for_each_dev_reverse(dev, &ap->link) { + unsigned int action = ata_eh_dev_action(dev); + unsigned int readid_flags = 0; if (ehc->i.flags & ATA_EHI_DID_RESET) readid_flags |= ATA_READID_POSTRESET; @@ -1981,7 +1985,7 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, dev->id); switch (rc) { case 0: - new_mask |= 1 << i; + new_mask |= 1 << dev->devno; break; case -ENOENT: /* IDENTIFY was issued to non-existent @@ -2005,10 +2009,8 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, /* Configure new devices forward such that user doesn't see * device detection messages backwards. */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - dev = &ap->link.device[i]; - - if (!(new_mask & (1 << i))) + ata_link_for_each_dev(dev, &ap->link) { + if (!(new_mask & (1 << dev->devno))) continue; ehc->i.flags |= ATA_EHI_PRINTINFO; @@ -2035,20 +2037,22 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, static int ata_port_nr_enabled(struct ata_port *ap) { - int i, cnt = 0; + struct ata_device *dev; + int cnt = 0; - for (i = 0; i < ATA_MAX_DEVICES; i++) - if (ata_dev_enabled(&ap->link.device[i])) + ata_link_for_each_dev(dev, &ap->link) + if (ata_dev_enabled(dev)) cnt++; return cnt; } static int ata_port_nr_vacant(struct ata_port *ap) { - int i, cnt = 0; + struct ata_device *dev; + int cnt = 0; - for (i = 0; i < ATA_MAX_DEVICES; i++) - if (ap->link.device[i].class == ATA_DEV_UNKNOWN) + ata_link_for_each_dev(dev, &ap->link) + if (dev->class == ATA_DEV_UNKNOWN) cnt++; return cnt; } @@ -2056,7 +2060,7 @@ static int ata_port_nr_vacant(struct ata_port *ap) static int ata_eh_skip_recovery(struct ata_port *ap) { struct ata_eh_context *ehc = &ap->link.eh_context; - int i; + struct ata_device *dev; /* thaw frozen port, resume link and recover failed devices */ if ((ap->pflags & ATA_PFLAG_FROZEN) || @@ -2064,9 +2068,7 @@ static int ata_eh_skip_recovery(struct ata_port *ap) return 0; /* skip if class codes for all vacant slots are ATA_DEV_NONE */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *dev = &ap->link.device[i]; - + ata_link_for_each_dev(dev, &ap->link) { if (dev->class == ATA_DEV_UNKNOWN && ehc->classes[dev->devno] != ATA_DEV_NONE) return 0; @@ -2153,19 +2155,18 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, { struct ata_eh_context *ehc = &ap->link.eh_context; struct ata_device *dev; - int i, rc; + int rc; DPRINTK("ENTER\n"); /* prep for recovery */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - dev = &ap->link.device[i]; - + ata_link_for_each_dev(dev, &ap->link) { ehc->tries[dev->devno] = ATA_EH_DEV_TRIES; /* collect port action mask recorded in dev actions */ - ehc->i.action |= ehc->i.dev_action[i] & ~ATA_EH_PERDEV_MASK; - ehc->i.dev_action[i] &= ATA_EH_PERDEV_MASK; + ehc->i.action |= + ehc->i.dev_action[dev->devno] & ~ATA_EH_PERDEV_MASK; + ehc->i.dev_action[dev->devno] &= ATA_EH_PERDEV_MASK; /* process hotplug request */ if (dev->flags & ATA_DFLAG_DETACH) @@ -2192,8 +2193,8 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, if (ata_eh_skip_recovery(ap)) ehc->i.action = 0; - for (i = 0; i < ATA_MAX_DEVICES; i++) - ehc->classes[i] = ATA_DEV_UNKNOWN; + ata_link_for_each_dev(dev, &ap->link) + ehc->classes[dev->devno] = ATA_DEV_UNKNOWN; /* reset */ if (ehc->i.action & ATA_EH_RESET_MASK) { @@ -2241,8 +2242,8 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, out: if (rc) { - for (i = 0; i < ATA_MAX_DEVICES; i++) - ata_dev_disable(&ap->link.device[i]); + ata_link_for_each_dev(dev, &ap->link); + ata_dev_disable(dev); } DPRINTK("EXIT, rc=%d\n", rc); diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index ec0e2638200e..3d6d5f737994 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2425,7 +2425,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) static struct ata_device * ata_find_dev(struct ata_port *ap, int id) { - if (likely(id < ATA_MAX_DEVICES)) + if (likely(id < ata_link_max_devices(&ap->link))) return &ap->link.device[id]; return NULL; } @@ -2952,21 +2952,18 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync) int tries = 5; struct ata_device *last_failed_dev = NULL; struct ata_device *dev; - unsigned int i; if (ap->flags & ATA_FLAG_DISABLED) return; repeat: - for (i = 0; i < ATA_MAX_DEVICES; i++) { + ata_link_for_each_dev(dev, &ap->link) { struct scsi_device *sdev; - dev = &ap->link.device[i]; - if (!ata_dev_enabled(dev) || dev->sdev) continue; - sdev = __scsi_add_device(ap->scsi_host, 0, i, 0, NULL); + sdev = __scsi_add_device(ap->scsi_host, 0, dev->devno, 0, NULL); if (!IS_ERR(sdev)) { dev->sdev = sdev; scsi_device_put(sdev); @@ -2977,12 +2974,11 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync) * failure occurred, scan would have failed silently. Check * whether all devices are attached. */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - dev = &ap->link.device[i]; + ata_link_for_each_dev(dev, &ap->link) { if (ata_dev_enabled(dev) && !dev->sdev) break; } - if (i == ATA_MAX_DEVICES) + if (!dev) return; /* we're missing some SCSI devices */ @@ -3112,7 +3108,7 @@ void ata_scsi_hotplug(struct work_struct *work) { struct ata_port *ap = container_of(work, struct ata_port, hotplug_task.work); - int i; + struct ata_device *dev; if (ap->pflags & ATA_PFLAG_UNLOADING) { DPRINTK("ENTER/EXIT - unloading\n"); @@ -3122,8 +3118,7 @@ void ata_scsi_hotplug(struct work_struct *work) DPRINTK("ENTER\n"); /* unplug detached devices */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *dev = &ap->link.device[i]; + ata_link_for_each_dev(dev, &ap->link) { unsigned long flags; if (!(dev->flags & ATA_DFLAG_DETACHED)) @@ -3176,7 +3171,7 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, spin_lock_irqsave(ap->lock, flags); if (id == SCAN_WILD_CARD) { - ehi->probe_mask |= (1 << ATA_MAX_DEVICES) - 1; + ehi->probe_mask |= (1 << ata_link_max_devices(&ap->link)) - 1; ehi->action |= ATA_EH_SOFTRESET; } else { struct ata_device *dev = ata_find_dev(ap, id); @@ -3215,13 +3210,12 @@ void ata_scsi_dev_rescan(struct work_struct *work) { struct ata_port *ap = container_of(work, struct ata_port, scsi_rescan_task); + struct ata_device *dev; unsigned long flags; - unsigned int i; spin_lock_irqsave(ap->lock, flags); - for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *dev = &ap->link.device[i]; + ata_link_for_each_dev(dev, &ap->link) { struct scsi_device *sdev = dev->sdev; if (!ata_dev_enabled(dev) || !sdev) diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index ece1a28f0a4a..088eb1d23761 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -461,10 +461,9 @@ static unsigned int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc) static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused) { - int i; + struct ata_device *dev; - for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *dev = &ap->link.device[i]; + ata_link_for_each_dev(dev, &ap->link) { if (ata_dev_enabled(dev)) { /* We don't really care */ dev->pio_mode = XFER_PIO_0; diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index 3e2b8ce5fa37..7db315a9baad 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -28,10 +28,9 @@ static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device **error) { - int i; + struct ata_device *dev; - for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *dev = &ap->link.device[i]; + ata_link_for_each_dev(dev, &ap->link) { if (ata_dev_enabled(dev)) { ata_dev_printk(dev, KERN_INFO, "configured for PIO0\n"); dev->pio_mode = XFER_PIO_0; diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 4bcc0ae8d108..9d92843b033d 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c @@ -109,10 +109,9 @@ static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */ static int legacy_set_mode(struct ata_port *ap, struct ata_device **unused) { - int i; + struct ata_device *dev; - for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *dev = &ap->link.device[i]; + ata_link_for_each_dev(dev, &ap->link) { if (ata_dev_enabled(dev)) { ata_dev_printk(dev, KERN_INFO, "configured for PIO\n"); dev->pio_mode = XFER_PIO_0; diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c index fa780509a1dc..83c90cabc7ff 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c @@ -479,15 +479,14 @@ static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev) */ static int pdc2027x_set_mode(struct ata_port *ap, struct ata_device **r_failed) { - int i; - - i = ata_do_set_mode(ap, r_failed); - if (i < 0) - return i; + struct ata_device *dev; + int rc; - for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *dev = &ap->link.device[i]; + rc = ata_do_set_mode(ap, r_failed); + if (rc < 0) + return rc; + ata_link_for_each_dev(dev, &ap->link) { if (ata_dev_enabled(dev)) { pdc2027x_set_piomode(ap, dev); diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index e89656bffa84..ee1605bfc29f 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c @@ -32,11 +32,9 @@ static int pio_mask = 1; */ static int pata_platform_set_mode(struct ata_port *ap, struct ata_device **unused) { - int i; - - for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *dev = &ap->link.device[i]; + struct ata_device *dev; + ata_link_for_each_dev(dev, &ap->link) { if (ata_dev_enabled(dev)) { /* We don't really care */ dev->pio_mode = dev->xfer_mode = XFER_PIO_0; diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c index 57363c0ce068..300b3d5de81e 100644 --- a/drivers/ata/pata_rz1000.c +++ b/drivers/ata/pata_rz1000.c @@ -36,10 +36,9 @@ static int rz1000_set_mode(struct ata_port *ap, struct ata_device **unused) { - int i; + struct ata_device *dev; - for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *dev = &ap->link.device[i]; + ata_link_for_each_dev(dev, &ap->link) { if (ata_dev_enabled(dev)) { /* We don't really care */ dev->pio_mode = XFER_PIO_0; diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index 2ddbe4cc71e4..4c9295a49a49 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c @@ -303,22 +303,20 @@ static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed) struct ata_device *dev; void __iomem *mmio_base = host->iomap[SIL_MMIO_BAR]; void __iomem *addr = mmio_base + sil_port[ap->port_no].xfer_mode; - u32 tmp, dev_mode[2]; - unsigned int i; + u32 tmp, dev_mode[2] = { }; int rc; rc = ata_do_set_mode(ap, r_failed); if (rc) return rc; - for (i = 0; i < 2; i++) { - dev = &ap->link.device[i]; + ata_link_for_each_dev(dev, &ap->link) { if (!ata_dev_enabled(dev)) - dev_mode[i] = 0; /* PIO0/1/2 */ + dev_mode[dev->devno] = 0; /* PIO0/1/2 */ else if (dev->flags & ATA_DFLAG_PIO) - dev_mode[i] = 1; /* PIO3/4 */ + dev_mode[dev->devno] = 1; /* PIO3/4 */ else - dev_mode[i] = 3; /* UDMA */ + dev_mode[dev->devno] = 3; /* UDMA */ /* value 2 indicates MDMA */ } diff --git a/include/linux/libata.h b/include/linux/libata.h index ca4493125fa0..62fa8cf677a1 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1030,15 +1030,26 @@ static inline unsigned int ata_dev_absent(const struct ata_device *dev) } /* - * port helpers + * link helpers */ -static inline int ata_port_max_devices(const struct ata_port *ap) +static inline int ata_link_max_devices(const struct ata_link *link) { - if (ap->flags & ATA_FLAG_SLAVE_POSS) + if (link->ap->flags & ATA_FLAG_SLAVE_POSS) return 2; return 1; } +#define ata_port_for_each_link(lk, ap) \ + for ((lk) = &(ap)->link; (lk); (lk) = NULL) + +#define ata_link_for_each_dev(dev, link) \ + for ((dev) = (link)->device; \ + (dev) < (link)->device + ata_link_max_devices(link) || ((dev) = NULL); \ + (dev)++) + +#define ata_link_for_each_dev_reverse(dev, link) \ + for ((dev) = (link)->device + ata_link_max_devices(link) - 1; \ + (dev) >= (link)->device || ((dev) = NULL); (dev)--) static inline u8 ata_chk_status(struct ata_port *ap) { |