aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-core.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2008-11-03 06:03:17 -0500
committerJeff Garzik <jgarzik@redhat.com>2008-12-28 22:43:20 -0500
commit1eca4365be25c540650693e941bc06a66cf38f94 (patch)
treee3ed82850da00308180bf166118f9f9e69d92898 /drivers/ata/libata-core.c
parent3c92ec8ae91ecf59d88c798301833d7cf83f2179 (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.c183
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");
163MODULE_VERSION(DRV_VERSION); 163MODULE_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 */
172struct ata_link *__ata_port_next_link(struct ata_port *ap, 178struct 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 */
237struct 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);
6528EXPORT_SYMBOL_GPL(sata_port_ops); 6588EXPORT_SYMBOL_GPL(sata_port_ops);
6529EXPORT_SYMBOL_GPL(ata_dummy_port_ops); 6589EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
6530EXPORT_SYMBOL_GPL(ata_dummy_port_info); 6590EXPORT_SYMBOL_GPL(ata_dummy_port_info);
6531EXPORT_SYMBOL_GPL(__ata_port_next_link); 6591EXPORT_SYMBOL_GPL(ata_link_next);
6592EXPORT_SYMBOL_GPL(ata_dev_next);
6532EXPORT_SYMBOL_GPL(ata_std_bios_param); 6593EXPORT_SYMBOL_GPL(ata_std_bios_param);
6533EXPORT_SYMBOL_GPL(ata_host_init); 6594EXPORT_SYMBOL_GPL(ata_host_init);
6534EXPORT_SYMBOL_GPL(ata_host_alloc); 6595EXPORT_SYMBOL_GPL(ata_host_alloc);