aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-eh.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-eh.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-eh.c')
-rw-r--r--drivers/ata/libata-eh.c84
1 files changed, 37 insertions, 47 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 32da9a93ce44..d673f3712bdc 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -422,7 +422,7 @@ static void ata_eh_clear_action(struct ata_link *link, struct ata_device *dev,
422 422
423 if (!dev) { 423 if (!dev) {
424 ehi->action &= ~action; 424 ehi->action &= ~action;
425 ata_link_for_each_dev(tdev, link) 425 ata_for_each_dev(tdev, link, ALL)
426 ehi->dev_action[tdev->devno] &= ~action; 426 ehi->dev_action[tdev->devno] &= ~action;
427 } else { 427 } else {
428 /* doesn't make sense for port-wide EH actions */ 428 /* doesn't make sense for port-wide EH actions */
@@ -430,7 +430,7 @@ static void ata_eh_clear_action(struct ata_link *link, struct ata_device *dev,
430 430
431 /* break ehi->action into ehi->dev_action */ 431 /* break ehi->action into ehi->dev_action */
432 if (ehi->action & action) { 432 if (ehi->action & action) {
433 ata_link_for_each_dev(tdev, link) 433 ata_for_each_dev(tdev, link, ALL)
434 ehi->dev_action[tdev->devno] |= 434 ehi->dev_action[tdev->devno] |=
435 ehi->action & action; 435 ehi->action & action;
436 ehi->action &= ~action; 436 ehi->action &= ~action;
@@ -592,7 +592,7 @@ void ata_scsi_error(struct Scsi_Host *host)
592 /* fetch & clear EH info */ 592 /* fetch & clear EH info */
593 spin_lock_irqsave(ap->lock, flags); 593 spin_lock_irqsave(ap->lock, flags);
594 594
595 __ata_port_for_each_link(link, ap) { 595 ata_for_each_link(link, ap, HOST_FIRST) {
596 struct ata_eh_context *ehc = &link->eh_context; 596 struct ata_eh_context *ehc = &link->eh_context;
597 struct ata_device *dev; 597 struct ata_device *dev;
598 598
@@ -600,12 +600,9 @@ void ata_scsi_error(struct Scsi_Host *host)
600 link->eh_context.i = link->eh_info; 600 link->eh_context.i = link->eh_info;
601 memset(&link->eh_info, 0, sizeof(link->eh_info)); 601 memset(&link->eh_info, 0, sizeof(link->eh_info));
602 602
603 ata_link_for_each_dev(dev, link) { 603 ata_for_each_dev(dev, link, ENABLED) {
604 int devno = dev->devno; 604 int devno = dev->devno;
605 605
606 if (!ata_dev_enabled(dev))
607 continue;
608
609 ehc->saved_xfer_mode[devno] = dev->xfer_mode; 606 ehc->saved_xfer_mode[devno] = dev->xfer_mode;
610 if (ata_ncq_enabled(dev)) 607 if (ata_ncq_enabled(dev))
611 ehc->saved_ncq_enabled |= 1 << devno; 608 ehc->saved_ncq_enabled |= 1 << devno;
@@ -644,7 +641,7 @@ void ata_scsi_error(struct Scsi_Host *host)
644 } 641 }
645 642
646 /* this run is complete, make sure EH info is clear */ 643 /* this run is complete, make sure EH info is clear */
647 __ata_port_for_each_link(link, ap) 644 ata_for_each_link(link, ap, HOST_FIRST)
648 memset(&link->eh_info, 0, sizeof(link->eh_info)); 645 memset(&link->eh_info, 0, sizeof(link->eh_info));
649 646
650 /* Clear host_eh_scheduled while holding ap->lock such 647 /* Clear host_eh_scheduled while holding ap->lock such
@@ -1025,7 +1022,7 @@ int sata_async_notification(struct ata_port *ap)
1025 struct ata_link *link; 1022 struct ata_link *link;
1026 1023
1027 /* check and notify ATAPI AN */ 1024 /* check and notify ATAPI AN */
1028 ata_port_for_each_link(link, ap) { 1025 ata_for_each_link(link, ap, EDGE) {
1029 if (!(sntf & (1 << link->pmp))) 1026 if (!(sntf & (1 << link->pmp)))
1030 continue; 1027 continue;
1031 1028
@@ -2005,7 +2002,7 @@ void ata_eh_autopsy(struct ata_port *ap)
2005{ 2002{
2006 struct ata_link *link; 2003 struct ata_link *link;
2007 2004
2008 ata_port_for_each_link(link, ap) 2005 ata_for_each_link(link, ap, EDGE)
2009 ata_eh_link_autopsy(link); 2006 ata_eh_link_autopsy(link);
2010 2007
2011 /* Handle the frigging slave link. Autopsy is done similarly 2008 /* Handle the frigging slave link. Autopsy is done similarly
@@ -2219,7 +2216,7 @@ void ata_eh_report(struct ata_port *ap)
2219{ 2216{
2220 struct ata_link *link; 2217 struct ata_link *link;
2221 2218
2222 __ata_port_for_each_link(link, ap) 2219 ata_for_each_link(link, ap, HOST_FIRST)
2223 ata_eh_link_report(link); 2220 ata_eh_link_report(link);
2224} 2221}
2225 2222
@@ -2230,7 +2227,7 @@ static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset,
2230 struct ata_device *dev; 2227 struct ata_device *dev;
2231 2228
2232 if (clear_classes) 2229 if (clear_classes)
2233 ata_link_for_each_dev(dev, link) 2230 ata_for_each_dev(dev, link, ALL)
2234 classes[dev->devno] = ATA_DEV_UNKNOWN; 2231 classes[dev->devno] = ATA_DEV_UNKNOWN;
2235 2232
2236 return reset(link, classes, deadline); 2233 return reset(link, classes, deadline);
@@ -2294,7 +2291,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
2294 2291
2295 ata_eh_about_to_do(link, NULL, ATA_EH_RESET); 2292 ata_eh_about_to_do(link, NULL, ATA_EH_RESET);
2296 2293
2297 ata_link_for_each_dev(dev, link) { 2294 ata_for_each_dev(dev, link, ALL) {
2298 /* If we issue an SRST then an ATA drive (not ATAPI) 2295 /* If we issue an SRST then an ATA drive (not ATAPI)
2299 * may change configuration and be in PIO0 timing. If 2296 * may change configuration and be in PIO0 timing. If
2300 * we do a hard reset (or are coming from power on) 2297 * we do a hard reset (or are coming from power on)
@@ -2355,7 +2352,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
2355 "port disabled. ignoring.\n"); 2352 "port disabled. ignoring.\n");
2356 ehc->i.action &= ~ATA_EH_RESET; 2353 ehc->i.action &= ~ATA_EH_RESET;
2357 2354
2358 ata_link_for_each_dev(dev, link) 2355 ata_for_each_dev(dev, link, ALL)
2359 classes[dev->devno] = ATA_DEV_NONE; 2356 classes[dev->devno] = ATA_DEV_NONE;
2360 2357
2361 rc = 0; 2358 rc = 0;
@@ -2369,7 +2366,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
2369 * bang classes and return. 2366 * bang classes and return.
2370 */ 2367 */
2371 if (reset && !(ehc->i.action & ATA_EH_RESET)) { 2368 if (reset && !(ehc->i.action & ATA_EH_RESET)) {
2372 ata_link_for_each_dev(dev, link) 2369 ata_for_each_dev(dev, link, ALL)
2373 classes[dev->devno] = ATA_DEV_NONE; 2370 classes[dev->devno] = ATA_DEV_NONE;
2374 rc = 0; 2371 rc = 0;
2375 goto out; 2372 goto out;
@@ -2454,7 +2451,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
2454 /* 2451 /*
2455 * Post-reset processing 2452 * Post-reset processing
2456 */ 2453 */
2457 ata_link_for_each_dev(dev, link) { 2454 ata_for_each_dev(dev, link, ALL) {
2458 /* After the reset, the device state is PIO 0 and the 2455 /* After the reset, the device state is PIO 0 and the
2459 * controller state is undefined. Reset also wakes up 2456 * controller state is undefined. Reset also wakes up
2460 * drives from sleeping mode. 2457 * drives from sleeping mode.
@@ -2510,7 +2507,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
2510 * can be reliably detected and retried. 2507 * can be reliably detected and retried.
2511 */ 2508 */
2512 nr_unknown = 0; 2509 nr_unknown = 0;
2513 ata_link_for_each_dev(dev, link) { 2510 ata_for_each_dev(dev, link, ALL) {
2514 /* convert all ATA_DEV_UNKNOWN to ATA_DEV_NONE */ 2511 /* convert all ATA_DEV_UNKNOWN to ATA_DEV_NONE */
2515 if (classes[dev->devno] == ATA_DEV_UNKNOWN) { 2512 if (classes[dev->devno] == ATA_DEV_UNKNOWN) {
2516 classes[dev->devno] = ATA_DEV_NONE; 2513 classes[dev->devno] = ATA_DEV_NONE;
@@ -2619,8 +2616,8 @@ static inline void ata_eh_pull_park_action(struct ata_port *ap)
2619 2616
2620 spin_lock_irqsave(ap->lock, flags); 2617 spin_lock_irqsave(ap->lock, flags);
2621 INIT_COMPLETION(ap->park_req_pending); 2618 INIT_COMPLETION(ap->park_req_pending);
2622 ata_port_for_each_link(link, ap) { 2619 ata_for_each_link(link, ap, EDGE) {
2623 ata_link_for_each_dev(dev, link) { 2620 ata_for_each_dev(dev, link, ALL) {
2624 struct ata_eh_info *ehi = &link->eh_info; 2621 struct ata_eh_info *ehi = &link->eh_info;
2625 2622
2626 link->eh_context.i.dev_action[dev->devno] |= 2623 link->eh_context.i.dev_action[dev->devno] |=
@@ -2675,7 +2672,7 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
2675 * be done backwards such that PDIAG- is released by the slave 2672 * be done backwards such that PDIAG- is released by the slave
2676 * device before the master device is identified. 2673 * device before the master device is identified.
2677 */ 2674 */
2678 ata_link_for_each_dev_reverse(dev, link) { 2675 ata_for_each_dev(dev, link, ALL_REVERSE) {
2679 unsigned int action = ata_eh_dev_action(dev); 2676 unsigned int action = ata_eh_dev_action(dev);
2680 unsigned int readid_flags = 0; 2677 unsigned int readid_flags = 0;
2681 2678
@@ -2744,7 +2741,7 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
2744 /* Configure new devices forward such that user doesn't see 2741 /* Configure new devices forward such that user doesn't see
2745 * device detection messages backwards. 2742 * device detection messages backwards.
2746 */ 2743 */
2747 ata_link_for_each_dev(dev, link) { 2744 ata_for_each_dev(dev, link, ALL) {
2748 if (!(new_mask & (1 << dev->devno)) || 2745 if (!(new_mask & (1 << dev->devno)) ||
2749 dev->class == ATA_DEV_PMP) 2746 dev->class == ATA_DEV_PMP)
2750 continue; 2747 continue;
@@ -2793,10 +2790,7 @@ int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
2793 int rc; 2790 int rc;
2794 2791
2795 /* if data transfer is verified, clear DUBIOUS_XFER on ering top */ 2792 /* if data transfer is verified, clear DUBIOUS_XFER on ering top */
2796 ata_link_for_each_dev(dev, link) { 2793 ata_for_each_dev(dev, link, ENABLED) {
2797 if (!ata_dev_enabled(dev))
2798 continue;
2799
2800 if (!(dev->flags & ATA_DFLAG_DUBIOUS_XFER)) { 2794 if (!(dev->flags & ATA_DFLAG_DUBIOUS_XFER)) {
2801 struct ata_ering_entry *ent; 2795 struct ata_ering_entry *ent;
2802 2796
@@ -2813,14 +2807,11 @@ int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
2813 rc = ata_do_set_mode(link, r_failed_dev); 2807 rc = ata_do_set_mode(link, r_failed_dev);
2814 2808
2815 /* if transfer mode has changed, set DUBIOUS_XFER on device */ 2809 /* if transfer mode has changed, set DUBIOUS_XFER on device */
2816 ata_link_for_each_dev(dev, link) { 2810 ata_for_each_dev(dev, link, ENABLED) {
2817 struct ata_eh_context *ehc = &link->eh_context; 2811 struct ata_eh_context *ehc = &link->eh_context;
2818 u8 saved_xfer_mode = ehc->saved_xfer_mode[dev->devno]; 2812 u8 saved_xfer_mode = ehc->saved_xfer_mode[dev->devno];
2819 u8 saved_ncq = !!(ehc->saved_ncq_enabled & (1 << dev->devno)); 2813 u8 saved_ncq = !!(ehc->saved_ncq_enabled & (1 << dev->devno));
2820 2814
2821 if (!ata_dev_enabled(dev))
2822 continue;
2823
2824 if (dev->xfer_mode != saved_xfer_mode || 2815 if (dev->xfer_mode != saved_xfer_mode ||
2825 ata_ncq_enabled(dev) != saved_ncq) 2816 ata_ncq_enabled(dev) != saved_ncq)
2826 dev->flags |= ATA_DFLAG_DUBIOUS_XFER; 2817 dev->flags |= ATA_DFLAG_DUBIOUS_XFER;
@@ -2881,9 +2872,8 @@ static int ata_link_nr_enabled(struct ata_link *link)
2881 struct ata_device *dev; 2872 struct ata_device *dev;
2882 int cnt = 0; 2873 int cnt = 0;
2883 2874
2884 ata_link_for_each_dev(dev, link) 2875 ata_for_each_dev(dev, link, ENABLED)
2885 if (ata_dev_enabled(dev)) 2876 cnt++;
2886 cnt++;
2887 return cnt; 2877 return cnt;
2888} 2878}
2889 2879
@@ -2892,7 +2882,7 @@ static int ata_link_nr_vacant(struct ata_link *link)
2892 struct ata_device *dev; 2882 struct ata_device *dev;
2893 int cnt = 0; 2883 int cnt = 0;
2894 2884
2895 ata_link_for_each_dev(dev, link) 2885 ata_for_each_dev(dev, link, ALL)
2896 if (dev->class == ATA_DEV_UNKNOWN) 2886 if (dev->class == ATA_DEV_UNKNOWN)
2897 cnt++; 2887 cnt++;
2898 return cnt; 2888 return cnt;
@@ -2918,7 +2908,7 @@ static int ata_eh_skip_recovery(struct ata_link *link)
2918 return 0; 2908 return 0;
2919 2909
2920 /* skip if class codes for all vacant slots are ATA_DEV_NONE */ 2910 /* skip if class codes for all vacant slots are ATA_DEV_NONE */
2921 ata_link_for_each_dev(dev, link) { 2911 ata_for_each_dev(dev, link, ALL) {
2922 if (dev->class == ATA_DEV_UNKNOWN && 2912 if (dev->class == ATA_DEV_UNKNOWN &&
2923 ehc->classes[dev->devno] != ATA_DEV_NONE) 2913 ehc->classes[dev->devno] != ATA_DEV_NONE)
2924 return 0; 2914 return 0;
@@ -3026,7 +3016,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
3026 DPRINTK("ENTER\n"); 3016 DPRINTK("ENTER\n");
3027 3017
3028 /* prep for recovery */ 3018 /* prep for recovery */
3029 ata_port_for_each_link(link, ap) { 3019 ata_for_each_link(link, ap, EDGE) {
3030 struct ata_eh_context *ehc = &link->eh_context; 3020 struct ata_eh_context *ehc = &link->eh_context;
3031 3021
3032 /* re-enable link? */ 3022 /* re-enable link? */
@@ -3038,7 +3028,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
3038 ata_eh_done(link, NULL, ATA_EH_ENABLE_LINK); 3028 ata_eh_done(link, NULL, ATA_EH_ENABLE_LINK);
3039 } 3029 }
3040 3030
3041 ata_link_for_each_dev(dev, link) { 3031 ata_for_each_dev(dev, link, ALL) {
3042 if (link->flags & ATA_LFLAG_NO_RETRY) 3032 if (link->flags & ATA_LFLAG_NO_RETRY)
3043 ehc->tries[dev->devno] = 1; 3033 ehc->tries[dev->devno] = 1;
3044 else 3034 else
@@ -3068,19 +3058,19 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
3068 goto out; 3058 goto out;
3069 3059
3070 /* prep for EH */ 3060 /* prep for EH */
3071 ata_port_for_each_link(link, ap) { 3061 ata_for_each_link(link, ap, EDGE) {
3072 struct ata_eh_context *ehc = &link->eh_context; 3062 struct ata_eh_context *ehc = &link->eh_context;
3073 3063
3074 /* skip EH if possible. */ 3064 /* skip EH if possible. */
3075 if (ata_eh_skip_recovery(link)) 3065 if (ata_eh_skip_recovery(link))
3076 ehc->i.action = 0; 3066 ehc->i.action = 0;
3077 3067
3078 ata_link_for_each_dev(dev, link) 3068 ata_for_each_dev(dev, link, ALL)
3079 ehc->classes[dev->devno] = ATA_DEV_UNKNOWN; 3069 ehc->classes[dev->devno] = ATA_DEV_UNKNOWN;
3080 } 3070 }
3081 3071
3082 /* reset */ 3072 /* reset */
3083 ata_port_for_each_link(link, ap) { 3073 ata_for_each_link(link, ap, EDGE) {
3084 struct ata_eh_context *ehc = &link->eh_context; 3074 struct ata_eh_context *ehc = &link->eh_context;
3085 3075
3086 if (!(ehc->i.action & ATA_EH_RESET)) 3076 if (!(ehc->i.action & ATA_EH_RESET))
@@ -3105,8 +3095,8 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
3105 ata_eh_pull_park_action(ap); 3095 ata_eh_pull_park_action(ap);
3106 3096
3107 deadline = jiffies; 3097 deadline = jiffies;
3108 ata_port_for_each_link(link, ap) { 3098 ata_for_each_link(link, ap, EDGE) {
3109 ata_link_for_each_dev(dev, link) { 3099 ata_for_each_dev(dev, link, ALL) {
3110 struct ata_eh_context *ehc = &link->eh_context; 3100 struct ata_eh_context *ehc = &link->eh_context;
3111 unsigned long tmp; 3101 unsigned long tmp;
3112 3102
@@ -3134,8 +3124,8 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
3134 deadline = wait_for_completion_timeout(&ap->park_req_pending, 3124 deadline = wait_for_completion_timeout(&ap->park_req_pending,
3135 deadline - now); 3125 deadline - now);
3136 } while (deadline); 3126 } while (deadline);
3137 ata_port_for_each_link(link, ap) { 3127 ata_for_each_link(link, ap, EDGE) {
3138 ata_link_for_each_dev(dev, link) { 3128 ata_for_each_dev(dev, link, ALL) {
3139 if (!(link->eh_context.unloaded_mask & 3129 if (!(link->eh_context.unloaded_mask &
3140 (1 << dev->devno))) 3130 (1 << dev->devno)))
3141 continue; 3131 continue;
@@ -3146,7 +3136,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
3146 } 3136 }
3147 3137
3148 /* the rest */ 3138 /* the rest */
3149 ata_port_for_each_link(link, ap) { 3139 ata_for_each_link(link, ap, EDGE) {
3150 struct ata_eh_context *ehc = &link->eh_context; 3140 struct ata_eh_context *ehc = &link->eh_context;
3151 3141
3152 /* revalidate existing devices and attach new ones */ 3142 /* revalidate existing devices and attach new ones */
@@ -3172,7 +3162,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
3172 * disrupting the current users of the device. 3162 * disrupting the current users of the device.
3173 */ 3163 */
3174 if (ehc->i.flags & ATA_EHI_DID_RESET) { 3164 if (ehc->i.flags & ATA_EHI_DID_RESET) {
3175 ata_link_for_each_dev(dev, link) { 3165 ata_for_each_dev(dev, link, ALL) {
3176 if (dev->class != ATA_DEV_ATAPI) 3166 if (dev->class != ATA_DEV_ATAPI)
3177 continue; 3167 continue;
3178 rc = atapi_eh_clear_ua(dev); 3168 rc = atapi_eh_clear_ua(dev);
@@ -3183,7 +3173,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
3183 3173
3184 /* configure link power saving */ 3174 /* configure link power saving */
3185 if (ehc->i.action & ATA_EH_LPM) 3175 if (ehc->i.action & ATA_EH_LPM)
3186 ata_link_for_each_dev(dev, link) 3176 ata_for_each_dev(dev, link, ALL)
3187 ata_dev_enable_pm(dev, ap->pm_policy); 3177 ata_dev_enable_pm(dev, ap->pm_policy);
3188 3178
3189 /* this link is okay now */ 3179 /* this link is okay now */
@@ -3288,7 +3278,7 @@ void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
3288 rc = ata_eh_recover(ap, prereset, softreset, hardreset, postreset, 3278 rc = ata_eh_recover(ap, prereset, softreset, hardreset, postreset,
3289 NULL); 3279 NULL);
3290 if (rc) { 3280 if (rc) {
3291 ata_link_for_each_dev(dev, &ap->link) 3281 ata_for_each_dev(dev, &ap->link, ALL)
3292 ata_dev_disable(dev); 3282 ata_dev_disable(dev);
3293 } 3283 }
3294 3284