diff options
author | Tejun Heo <tj@kernel.org> | 2008-11-03 06:03:17 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-12-28 22:43:20 -0500 |
commit | 1eca4365be25c540650693e941bc06a66cf38f94 (patch) | |
tree | e3ed82850da00308180bf166118f9f9e69d92898 /drivers/ata/libata-core.c | |
parent | 3c92ec8ae91ecf59d88c798301833d7cf83f2179 (diff) |
libata: beef up iterators
There currently are the following looping constructs.
* __ata_port_for_each_link() for all available links
* ata_port_for_each_link() for edge links
* ata_link_for_each_dev() for all devices
* ata_link_for_each_dev_reverse() for all devices in reverse order
Now there's a need for looping construct which is similar to
__ata_port_for_each_link() but iterates over PMP links before the host
link. Instead of adding another one with long name, do the following
cleanup.
* Implement and export ata_link_next() and ata_dev_next() which take
@mode parameter and can be used to build custom loop.
* Implement ata_for_each_link() and ata_for_each_dev() which take
looping mode explicitly.
The following iteration modes are implemented.
* ATA_LITER_EDGE : loop over edge links
* ATA_LITER_HOST_FIRST : loop over all links, host link first
* ATA_LITER_PMP_FIRST : loop over all links, PMP links first
* ATA_DITER_ENABLED : loop over enabled devices
* ATA_DITER_ENABLED_REVERSE : loop over enabled devices in reverse order
* ATA_DITER_ALL : loop over all devices
* ATA_DITER_ALL_REVERSE : loop over all devices in reverse order
This change removes exlicit device enabledness checks from many loops
and makes it clear which ones are iterated over in which direction.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r-- | drivers/ata/libata-core.c | 183 |
1 files changed, 122 insertions, 61 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index bc6695e3c848..ffd98e4e65b4 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -163,43 +163,119 @@ MODULE_LICENSE("GPL"); | |||
163 | MODULE_VERSION(DRV_VERSION); | 163 | MODULE_VERSION(DRV_VERSION); |
164 | 164 | ||
165 | 165 | ||
166 | /* | 166 | /** |
167 | * Iterator helpers. Don't use directly. | 167 | * ata_link_next - link iteration helper |
168 | * @link: the previous link, NULL to start | ||
169 | * @ap: ATA port containing links to iterate | ||
170 | * @mode: iteration mode, one of ATA_LITER_* | ||
171 | * | ||
172 | * LOCKING: | ||
173 | * Host lock or EH context. | ||
168 | * | 174 | * |
169 | * LOCKING: | 175 | * RETURNS: |
170 | * Host lock or EH context. | 176 | * Pointer to the next link. |
171 | */ | 177 | */ |
172 | struct ata_link *__ata_port_next_link(struct ata_port *ap, | 178 | struct ata_link *ata_link_next(struct ata_link *link, struct ata_port *ap, |
173 | struct ata_link *link, bool dev_only) | 179 | enum ata_link_iter_mode mode) |
174 | { | 180 | { |
181 | BUG_ON(mode != ATA_LITER_EDGE && | ||
182 | mode != ATA_LITER_PMP_FIRST && mode != ATA_LITER_HOST_FIRST); | ||
183 | |||
175 | /* NULL link indicates start of iteration */ | 184 | /* NULL link indicates start of iteration */ |
176 | if (!link) { | 185 | if (!link) |
177 | if (dev_only && sata_pmp_attached(ap)) | 186 | switch (mode) { |
178 | return ap->pmp_link; | 187 | case ATA_LITER_EDGE: |
179 | return &ap->link; | 188 | case ATA_LITER_PMP_FIRST: |
180 | } | 189 | if (sata_pmp_attached(ap)) |
190 | return ap->pmp_link; | ||
191 | /* fall through */ | ||
192 | case ATA_LITER_HOST_FIRST: | ||
193 | return &ap->link; | ||
194 | } | ||
181 | 195 | ||
182 | /* we just iterated over the host master link, what's next? */ | 196 | /* we just iterated over the host link, what's next? */ |
183 | if (link == &ap->link) { | 197 | if (link == &ap->link) |
184 | if (!sata_pmp_attached(ap)) { | 198 | switch (mode) { |
185 | if (unlikely(ap->slave_link) && !dev_only) | 199 | case ATA_LITER_HOST_FIRST: |
200 | if (sata_pmp_attached(ap)) | ||
201 | return ap->pmp_link; | ||
202 | /* fall through */ | ||
203 | case ATA_LITER_PMP_FIRST: | ||
204 | if (unlikely(ap->slave_link)) | ||
186 | return ap->slave_link; | 205 | return ap->slave_link; |
206 | /* fall through */ | ||
207 | case ATA_LITER_EDGE: | ||
187 | return NULL; | 208 | return NULL; |
188 | } | 209 | } |
189 | return ap->pmp_link; | ||
190 | } | ||
191 | 210 | ||
192 | /* slave_link excludes PMP */ | 211 | /* slave_link excludes PMP */ |
193 | if (unlikely(link == ap->slave_link)) | 212 | if (unlikely(link == ap->slave_link)) |
194 | return NULL; | 213 | return NULL; |
195 | 214 | ||
196 | /* iterate to the next PMP link */ | 215 | /* we were over a PMP link */ |
197 | if (++link < ap->pmp_link + ap->nr_pmp_links) | 216 | if (++link < ap->pmp_link + ap->nr_pmp_links) |
198 | return link; | 217 | return link; |
218 | |||
219 | if (mode == ATA_LITER_PMP_FIRST) | ||
220 | return &ap->link; | ||
221 | |||
199 | return NULL; | 222 | return NULL; |
200 | } | 223 | } |
201 | 224 | ||
202 | /** | 225 | /** |
226 | * ata_dev_next - device iteration helper | ||
227 | * @dev: the previous device, NULL to start | ||
228 | * @link: ATA link containing devices to iterate | ||
229 | * @mode: iteration mode, one of ATA_DITER_* | ||
230 | * | ||
231 | * LOCKING: | ||
232 | * Host lock or EH context. | ||
233 | * | ||
234 | * RETURNS: | ||
235 | * Pointer to the next device. | ||
236 | */ | ||
237 | struct ata_device *ata_dev_next(struct ata_device *dev, struct ata_link *link, | ||
238 | enum ata_dev_iter_mode mode) | ||
239 | { | ||
240 | BUG_ON(mode != ATA_DITER_ENABLED && mode != ATA_DITER_ENABLED_REVERSE && | ||
241 | mode != ATA_DITER_ALL && mode != ATA_DITER_ALL_REVERSE); | ||
242 | |||
243 | /* NULL dev indicates start of iteration */ | ||
244 | if (!dev) | ||
245 | switch (mode) { | ||
246 | case ATA_DITER_ENABLED: | ||
247 | case ATA_DITER_ALL: | ||
248 | dev = link->device; | ||
249 | goto check; | ||
250 | case ATA_DITER_ENABLED_REVERSE: | ||
251 | case ATA_DITER_ALL_REVERSE: | ||
252 | dev = link->device + ata_link_max_devices(link) - 1; | ||
253 | goto check; | ||
254 | } | ||
255 | |||
256 | next: | ||
257 | /* move to the next one */ | ||
258 | switch (mode) { | ||
259 | case ATA_DITER_ENABLED: | ||
260 | case ATA_DITER_ALL: | ||
261 | if (++dev < link->device + ata_link_max_devices(link)) | ||
262 | goto check; | ||
263 | return NULL; | ||
264 | case ATA_DITER_ENABLED_REVERSE: | ||
265 | case ATA_DITER_ALL_REVERSE: | ||
266 | if (--dev >= link->device) | ||
267 | goto check; | ||
268 | return NULL; | ||
269 | } | ||
270 | |||
271 | check: | ||
272 | if ((mode == ATA_DITER_ENABLED || mode == ATA_DITER_ENABLED_REVERSE) && | ||
273 | !ata_dev_enabled(dev)) | ||
274 | goto next; | ||
275 | return dev; | ||
276 | } | ||
277 | |||
278 | /** | ||
203 | * ata_dev_phys_link - find physical link for a device | 279 | * ata_dev_phys_link - find physical link for a device |
204 | * @dev: ATA device to look up physical link for | 280 | * @dev: ATA device to look up physical link for |
205 | * | 281 | * |
@@ -1107,8 +1183,8 @@ static void ata_lpm_enable(struct ata_host *host) | |||
1107 | 1183 | ||
1108 | for (i = 0; i < host->n_ports; i++) { | 1184 | for (i = 0; i < host->n_ports; i++) { |
1109 | ap = host->ports[i]; | 1185 | ap = host->ports[i]; |
1110 | ata_port_for_each_link(link, ap) { | 1186 | ata_for_each_link(link, ap, EDGE) { |
1111 | ata_link_for_each_dev(dev, link) | 1187 | ata_for_each_dev(dev, link, ALL) |
1112 | ata_dev_disable_pm(dev); | 1188 | ata_dev_disable_pm(dev); |
1113 | } | 1189 | } |
1114 | } | 1190 | } |
@@ -2594,11 +2670,11 @@ int ata_bus_probe(struct ata_port *ap) | |||
2594 | 2670 | ||
2595 | ata_port_probe(ap); | 2671 | ata_port_probe(ap); |
2596 | 2672 | ||
2597 | ata_link_for_each_dev(dev, &ap->link) | 2673 | ata_for_each_dev(dev, &ap->link, ALL) |
2598 | tries[dev->devno] = ATA_PROBE_MAX_TRIES; | 2674 | tries[dev->devno] = ATA_PROBE_MAX_TRIES; |
2599 | 2675 | ||
2600 | retry: | 2676 | retry: |
2601 | ata_link_for_each_dev(dev, &ap->link) { | 2677 | ata_for_each_dev(dev, &ap->link, ALL) { |
2602 | /* If we issue an SRST then an ATA drive (not ATAPI) | 2678 | /* If we issue an SRST then an ATA drive (not ATAPI) |
2603 | * may change configuration and be in PIO0 timing. If | 2679 | * may change configuration and be in PIO0 timing. If |
2604 | * we do a hard reset (or are coming from power on) | 2680 | * we do a hard reset (or are coming from power on) |
@@ -2620,7 +2696,7 @@ int ata_bus_probe(struct ata_port *ap) | |||
2620 | /* reset and determine device classes */ | 2696 | /* reset and determine device classes */ |
2621 | ap->ops->phy_reset(ap); | 2697 | ap->ops->phy_reset(ap); |
2622 | 2698 | ||
2623 | ata_link_for_each_dev(dev, &ap->link) { | 2699 | ata_for_each_dev(dev, &ap->link, ALL) { |
2624 | if (!(ap->flags & ATA_FLAG_DISABLED) && | 2700 | if (!(ap->flags & ATA_FLAG_DISABLED) && |
2625 | dev->class != ATA_DEV_UNKNOWN) | 2701 | dev->class != ATA_DEV_UNKNOWN) |
2626 | classes[dev->devno] = dev->class; | 2702 | classes[dev->devno] = dev->class; |
@@ -2636,7 +2712,7 @@ int ata_bus_probe(struct ata_port *ap) | |||
2636 | specific sequence bass-ackwards so that PDIAG- is released by | 2712 | specific sequence bass-ackwards so that PDIAG- is released by |
2637 | the slave device */ | 2713 | the slave device */ |
2638 | 2714 | ||
2639 | ata_link_for_each_dev_reverse(dev, &ap->link) { | 2715 | ata_for_each_dev(dev, &ap->link, ALL_REVERSE) { |
2640 | if (tries[dev->devno]) | 2716 | if (tries[dev->devno]) |
2641 | dev->class = classes[dev->devno]; | 2717 | dev->class = classes[dev->devno]; |
2642 | 2718 | ||
@@ -2653,24 +2729,19 @@ int ata_bus_probe(struct ata_port *ap) | |||
2653 | if (ap->ops->cable_detect) | 2729 | if (ap->ops->cable_detect) |
2654 | ap->cbl = ap->ops->cable_detect(ap); | 2730 | ap->cbl = ap->ops->cable_detect(ap); |
2655 | 2731 | ||
2656 | /* We may have SATA bridge glue hiding here irrespective of the | 2732 | /* We may have SATA bridge glue hiding here irrespective of |
2657 | reported cable types and sensed types */ | 2733 | * the reported cable types and sensed types. When SATA |
2658 | ata_link_for_each_dev(dev, &ap->link) { | 2734 | * drives indicate we have a bridge, we don't know which end |
2659 | if (!ata_dev_enabled(dev)) | 2735 | * of the link the bridge is which is a problem. |
2660 | continue; | 2736 | */ |
2661 | /* SATA drives indicate we have a bridge. We don't know which | 2737 | ata_for_each_dev(dev, &ap->link, ENABLED) |
2662 | end of the link the bridge is which is a problem */ | ||
2663 | if (ata_id_is_sata(dev->id)) | 2738 | if (ata_id_is_sata(dev->id)) |
2664 | ap->cbl = ATA_CBL_SATA; | 2739 | ap->cbl = ATA_CBL_SATA; |
2665 | } | ||
2666 | 2740 | ||
2667 | /* After the identify sequence we can now set up the devices. We do | 2741 | /* After the identify sequence we can now set up the devices. We do |
2668 | this in the normal order so that the user doesn't get confused */ | 2742 | this in the normal order so that the user doesn't get confused */ |
2669 | 2743 | ||
2670 | ata_link_for_each_dev(dev, &ap->link) { | 2744 | ata_for_each_dev(dev, &ap->link, ENABLED) { |
2671 | if (!ata_dev_enabled(dev)) | ||
2672 | continue; | ||
2673 | |||
2674 | ap->link.eh_context.i.flags |= ATA_EHI_PRINTINFO; | 2745 | ap->link.eh_context.i.flags |= ATA_EHI_PRINTINFO; |
2675 | rc = ata_dev_configure(dev); | 2746 | rc = ata_dev_configure(dev); |
2676 | ap->link.eh_context.i.flags &= ~ATA_EHI_PRINTINFO; | 2747 | ap->link.eh_context.i.flags &= ~ATA_EHI_PRINTINFO; |
@@ -2683,9 +2754,8 @@ int ata_bus_probe(struct ata_port *ap) | |||
2683 | if (rc) | 2754 | if (rc) |
2684 | goto fail; | 2755 | goto fail; |
2685 | 2756 | ||
2686 | ata_link_for_each_dev(dev, &ap->link) | 2757 | ata_for_each_dev(dev, &ap->link, ENABLED) |
2687 | if (ata_dev_enabled(dev)) | 2758 | return 0; |
2688 | return 0; | ||
2689 | 2759 | ||
2690 | /* no device present, disable port */ | 2760 | /* no device present, disable port */ |
2691 | ata_port_disable(ap); | 2761 | ata_port_disable(ap); |
@@ -3331,13 +3401,10 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) | |||
3331 | int rc = 0, used_dma = 0, found = 0; | 3401 | int rc = 0, used_dma = 0, found = 0; |
3332 | 3402 | ||
3333 | /* step 1: calculate xfer_mask */ | 3403 | /* step 1: calculate xfer_mask */ |
3334 | ata_link_for_each_dev(dev, link) { | 3404 | ata_for_each_dev(dev, link, ENABLED) { |
3335 | unsigned long pio_mask, dma_mask; | 3405 | unsigned long pio_mask, dma_mask; |
3336 | unsigned int mode_mask; | 3406 | unsigned int mode_mask; |
3337 | 3407 | ||
3338 | if (!ata_dev_enabled(dev)) | ||
3339 | continue; | ||
3340 | |||
3341 | mode_mask = ATA_DMA_MASK_ATA; | 3408 | mode_mask = ATA_DMA_MASK_ATA; |
3342 | if (dev->class == ATA_DEV_ATAPI) | 3409 | if (dev->class == ATA_DEV_ATAPI) |
3343 | mode_mask = ATA_DMA_MASK_ATAPI; | 3410 | mode_mask = ATA_DMA_MASK_ATAPI; |
@@ -3366,10 +3433,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) | |||
3366 | goto out; | 3433 | goto out; |
3367 | 3434 | ||
3368 | /* step 2: always set host PIO timings */ | 3435 | /* step 2: always set host PIO timings */ |
3369 | ata_link_for_each_dev(dev, link) { | 3436 | ata_for_each_dev(dev, link, ENABLED) { |
3370 | if (!ata_dev_enabled(dev)) | ||
3371 | continue; | ||
3372 | |||
3373 | if (dev->pio_mode == 0xff) { | 3437 | if (dev->pio_mode == 0xff) { |
3374 | ata_dev_printk(dev, KERN_WARNING, "no PIO support\n"); | 3438 | ata_dev_printk(dev, KERN_WARNING, "no PIO support\n"); |
3375 | rc = -EINVAL; | 3439 | rc = -EINVAL; |
@@ -3383,8 +3447,8 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) | |||
3383 | } | 3447 | } |
3384 | 3448 | ||
3385 | /* step 3: set host DMA timings */ | 3449 | /* step 3: set host DMA timings */ |
3386 | ata_link_for_each_dev(dev, link) { | 3450 | ata_for_each_dev(dev, link, ENABLED) { |
3387 | if (!ata_dev_enabled(dev) || !ata_dma_enabled(dev)) | 3451 | if (!ata_dma_enabled(dev)) |
3388 | continue; | 3452 | continue; |
3389 | 3453 | ||
3390 | dev->xfer_mode = dev->dma_mode; | 3454 | dev->xfer_mode = dev->dma_mode; |
@@ -3394,11 +3458,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) | |||
3394 | } | 3458 | } |
3395 | 3459 | ||
3396 | /* step 4: update devices' xfer mode */ | 3460 | /* step 4: update devices' xfer mode */ |
3397 | ata_link_for_each_dev(dev, link) { | 3461 | ata_for_each_dev(dev, link, ENABLED) { |
3398 | /* don't update suspended devices' xfer mode */ | ||
3399 | if (!ata_dev_enabled(dev)) | ||
3400 | continue; | ||
3401 | |||
3402 | rc = ata_dev_set_mode(dev); | 3462 | rc = ata_dev_set_mode(dev); |
3403 | if (rc) | 3463 | if (rc) |
3404 | goto out; | 3464 | goto out; |
@@ -4263,9 +4323,9 @@ static int cable_is_40wire(struct ata_port *ap) | |||
4263 | * - if you have a non detect capable drive you don't want it | 4323 | * - if you have a non detect capable drive you don't want it |
4264 | * to colour the choice | 4324 | * to colour the choice |
4265 | */ | 4325 | */ |
4266 | ata_port_for_each_link(link, ap) { | 4326 | ata_for_each_link(link, ap, EDGE) { |
4267 | ata_link_for_each_dev(dev, link) { | 4327 | ata_for_each_dev(dev, link, ENABLED) { |
4268 | if (ata_dev_enabled(dev) && !ata_is_40wire(dev)) | 4328 | if (!ata_is_40wire(dev)) |
4269 | return 0; | 4329 | return 0; |
4270 | } | 4330 | } |
4271 | } | 4331 | } |
@@ -5218,7 +5278,7 @@ static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg, | |||
5218 | } | 5278 | } |
5219 | 5279 | ||
5220 | ap->pflags |= ATA_PFLAG_PM_PENDING; | 5280 | ap->pflags |= ATA_PFLAG_PM_PENDING; |
5221 | __ata_port_for_each_link(link, ap) { | 5281 | ata_for_each_link(link, ap, HOST_FIRST) { |
5222 | link->eh_info.action |= action; | 5282 | link->eh_info.action |= action; |
5223 | link->eh_info.flags |= ehi_flags; | 5283 | link->eh_info.flags |= ehi_flags; |
5224 | } | 5284 | } |
@@ -6063,9 +6123,9 @@ static void ata_port_detach(struct ata_port *ap) | |||
6063 | /* EH is now guaranteed to see UNLOADING - EH context belongs | 6123 | /* EH is now guaranteed to see UNLOADING - EH context belongs |
6064 | * to us. Restore SControl and disable all existing devices. | 6124 | * to us. Restore SControl and disable all existing devices. |
6065 | */ | 6125 | */ |
6066 | __ata_port_for_each_link(link, ap) { | 6126 | ata_for_each_link(link, ap, HOST_FIRST) { |
6067 | sata_scr_write(link, SCR_CONTROL, link->saved_scontrol & 0xff0); | 6127 | sata_scr_write(link, SCR_CONTROL, link->saved_scontrol & 0xff0); |
6068 | ata_link_for_each_dev(dev, link) | 6128 | ata_for_each_dev(dev, link, ALL) |
6069 | ata_dev_disable(dev); | 6129 | ata_dev_disable(dev); |
6070 | } | 6130 | } |
6071 | 6131 | ||
@@ -6528,7 +6588,8 @@ EXPORT_SYMBOL_GPL(ata_base_port_ops); | |||
6528 | EXPORT_SYMBOL_GPL(sata_port_ops); | 6588 | EXPORT_SYMBOL_GPL(sata_port_ops); |
6529 | EXPORT_SYMBOL_GPL(ata_dummy_port_ops); | 6589 | EXPORT_SYMBOL_GPL(ata_dummy_port_ops); |
6530 | EXPORT_SYMBOL_GPL(ata_dummy_port_info); | 6590 | EXPORT_SYMBOL_GPL(ata_dummy_port_info); |
6531 | EXPORT_SYMBOL_GPL(__ata_port_next_link); | 6591 | EXPORT_SYMBOL_GPL(ata_link_next); |
6592 | EXPORT_SYMBOL_GPL(ata_dev_next); | ||
6532 | EXPORT_SYMBOL_GPL(ata_std_bios_param); | 6593 | EXPORT_SYMBOL_GPL(ata_std_bios_param); |
6533 | EXPORT_SYMBOL_GPL(ata_host_init); | 6594 | EXPORT_SYMBOL_GPL(ata_host_init); |
6534 | EXPORT_SYMBOL_GPL(ata_host_alloc); | 6595 | EXPORT_SYMBOL_GPL(ata_host_alloc); |