diff options
author | Tejun Heo <htejun@gmail.com> | 2007-10-30 21:17:03 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-11-03 08:46:54 -0400 |
commit | 416dc9ed206bba09807300ee5f155a81cebbd4a1 (patch) | |
tree | 483a86db1dbcdb443962f9597531ea0541ef61e6 /drivers/ata/libata-eh.c | |
parent | cd955463bb4e96cfec18a0e5b6887c6797fb821d (diff) |
libata: cosmetic clean up / reorganization of ata_eh_reset()
Clean up and reorganize ata_eh_reset() to ease further changes.
* Cache ARRAY_SIZE(ata_eh_reset_timeouts) in @max_tries.
* Cache link->flags in @lflags.
* Move failure handling block to the end of the function and unnest
both success and failure handling blocks.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/libata-eh.c')
-rw-r--r-- | drivers/ata/libata-eh.c | 112 |
1 files changed, 56 insertions, 56 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 53b2348a364d..dae2174f3877 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -2065,16 +2065,19 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2065 | ata_prereset_fn_t prereset, ata_reset_fn_t softreset, | 2065 | ata_prereset_fn_t prereset, ata_reset_fn_t softreset, |
2066 | ata_reset_fn_t hardreset, ata_postreset_fn_t postreset) | 2066 | ata_reset_fn_t hardreset, ata_postreset_fn_t postreset) |
2067 | { | 2067 | { |
2068 | const int max_tries = ARRAY_SIZE(ata_eh_reset_timeouts); | ||
2068 | struct ata_port *ap = link->ap; | 2069 | struct ata_port *ap = link->ap; |
2069 | struct ata_eh_context *ehc = &link->eh_context; | 2070 | struct ata_eh_context *ehc = &link->eh_context; |
2070 | unsigned int *classes = ehc->classes; | 2071 | unsigned int *classes = ehc->classes; |
2072 | unsigned int lflags = link->flags; | ||
2071 | int verbose = !(ehc->i.flags & ATA_EHI_QUIET); | 2073 | int verbose = !(ehc->i.flags & ATA_EHI_QUIET); |
2072 | int try = 0; | 2074 | int try = 0; |
2073 | struct ata_device *dev; | 2075 | struct ata_device *dev; |
2074 | unsigned long deadline; | 2076 | unsigned long deadline, now; |
2075 | unsigned int tmp_action; | 2077 | unsigned int tmp_action; |
2076 | ata_reset_fn_t reset; | 2078 | ata_reset_fn_t reset; |
2077 | unsigned long flags; | 2079 | unsigned long flags; |
2080 | u32 sstatus; | ||
2078 | int rc; | 2081 | int rc; |
2079 | 2082 | ||
2080 | /* about to reset */ | 2083 | /* about to reset */ |
@@ -2106,7 +2109,7 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2106 | /* Determine which reset to use and record in ehc->i.action. | 2109 | /* Determine which reset to use and record in ehc->i.action. |
2107 | * prereset() may examine and modify it. | 2110 | * prereset() may examine and modify it. |
2108 | */ | 2111 | */ |
2109 | if (softreset && (!hardreset || (!(link->flags & ATA_LFLAG_NO_SRST) && | 2112 | if (softreset && (!hardreset || (!(lflags & ATA_LFLAG_NO_SRST) && |
2110 | !sata_set_spd_needed(link) && | 2113 | !sata_set_spd_needed(link) && |
2111 | !(ehc->i.action & ATA_EH_HARDRESET)))) | 2114 | !(ehc->i.action & ATA_EH_HARDRESET)))) |
2112 | tmp_action = ATA_EH_SOFTRESET; | 2115 | tmp_action = ATA_EH_SOFTRESET; |
@@ -2188,7 +2191,7 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2188 | rc = ata_do_reset(link, reset, classes, deadline); | 2191 | rc = ata_do_reset(link, reset, classes, deadline); |
2189 | 2192 | ||
2190 | if (rc == 0 && classify && classes[0] == ATA_DEV_UNKNOWN && | 2193 | if (rc == 0 && classify && classes[0] == ATA_DEV_UNKNOWN && |
2191 | !(link->flags & ATA_LFLAG_ASSUME_CLASS)) { | 2194 | !(lflags & ATA_LFLAG_ASSUME_CLASS)) { |
2192 | ata_link_printk(link, KERN_ERR, | 2195 | ata_link_printk(link, KERN_ERR, |
2193 | "classification failed\n"); | 2196 | "classification failed\n"); |
2194 | rc = -EINVAL; | 2197 | rc = -EINVAL; |
@@ -2196,67 +2199,42 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2196 | } | 2199 | } |
2197 | } | 2200 | } |
2198 | 2201 | ||
2199 | /* if we skipped follow-up srst, clear rc */ | 2202 | /* -EAGAIN can happen if we skipped followup SRST */ |
2200 | if (rc == -EAGAIN) | 2203 | if (rc && rc != -EAGAIN) |
2201 | rc = 0; | 2204 | goto fail; |
2202 | |||
2203 | if (rc && rc != -ERESTART && try < ARRAY_SIZE(ata_eh_reset_timeouts)) { | ||
2204 | unsigned long now = jiffies; | ||
2205 | 2205 | ||
2206 | if (time_before(now, deadline)) { | 2206 | ata_link_for_each_dev(dev, link) { |
2207 | unsigned long delta = deadline - now; | 2207 | /* After the reset, the device state is PIO 0 and the |
2208 | 2208 | * controller state is undefined. Reset also wakes up | |
2209 | ata_link_printk(link, KERN_WARNING, "reset failed " | 2209 | * drives from sleeping mode. |
2210 | "(errno=%d), retrying in %u secs\n", | 2210 | */ |
2211 | rc, (jiffies_to_msecs(delta) + 999) / 1000); | 2211 | dev->pio_mode = XFER_PIO_0; |
2212 | dev->flags &= ~ATA_DFLAG_SLEEPING; | ||
2212 | 2213 | ||
2213 | while (delta) | 2214 | if (ata_link_offline(link)) |
2214 | delta = schedule_timeout_uninterruptible(delta); | 2215 | continue; |
2215 | } | ||
2216 | 2216 | ||
2217 | if (rc == -EPIPE || | 2217 | /* apply class override and convert UNKNOWN to NONE */ |
2218 | try == ARRAY_SIZE(ata_eh_reset_timeouts) - 1) | 2218 | if (lflags & ATA_LFLAG_ASSUME_ATA) |
2219 | sata_down_spd_limit(link); | 2219 | classes[dev->devno] = ATA_DEV_ATA; |
2220 | if (hardreset) | 2220 | else if (lflags & ATA_LFLAG_ASSUME_SEMB) |
2221 | reset = hardreset; | 2221 | classes[dev->devno] = ATA_DEV_SEMB_UNSUP; /* not yet */ |
2222 | goto retry; | 2222 | else if (classes[dev->devno] == ATA_DEV_UNKNOWN) |
2223 | classes[dev->devno] = ATA_DEV_NONE; | ||
2223 | } | 2224 | } |
2224 | 2225 | ||
2225 | if (rc == 0) { | 2226 | /* record current link speed */ |
2226 | u32 sstatus; | 2227 | if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0) |
2227 | 2228 | link->sata_spd = (sstatus >> 4) & 0xf; | |
2228 | ata_link_for_each_dev(dev, link) { | ||
2229 | /* After the reset, the device state is PIO 0 | ||
2230 | * and the controller state is undefined. | ||
2231 | * Reset also wakes up drives from sleeping | ||
2232 | * mode. | ||
2233 | */ | ||
2234 | dev->pio_mode = XFER_PIO_0; | ||
2235 | dev->flags &= ~ATA_DFLAG_SLEEPING; | ||
2236 | |||
2237 | if (ata_link_offline(link)) | ||
2238 | continue; | ||
2239 | |||
2240 | /* apply class override and convert UNKNOWN to NONE */ | ||
2241 | if (link->flags & ATA_LFLAG_ASSUME_ATA) | ||
2242 | classes[dev->devno] = ATA_DEV_ATA; | ||
2243 | else if (link->flags & ATA_LFLAG_ASSUME_SEMB) | ||
2244 | classes[dev->devno] = ATA_DEV_SEMB_UNSUP; /* not yet */ | ||
2245 | else if (classes[dev->devno] == ATA_DEV_UNKNOWN) | ||
2246 | classes[dev->devno] = ATA_DEV_NONE; | ||
2247 | } | ||
2248 | 2229 | ||
2249 | /* record current link speed */ | 2230 | if (postreset) |
2250 | if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0) | 2231 | postreset(link, classes); |
2251 | link->sata_spd = (sstatus >> 4) & 0xf; | ||
2252 | 2232 | ||
2253 | if (postreset) | 2233 | /* reset successful, schedule revalidation */ |
2254 | postreset(link, classes); | 2234 | ata_eh_done(link, NULL, ehc->i.action & ATA_EH_RESET_MASK); |
2235 | ehc->i.action |= ATA_EH_REVALIDATE; | ||
2255 | 2236 | ||
2256 | /* reset successful, schedule revalidation */ | 2237 | rc = 0; |
2257 | ata_eh_done(link, NULL, ehc->i.action & ATA_EH_RESET_MASK); | ||
2258 | ehc->i.action |= ATA_EH_REVALIDATE; | ||
2259 | } | ||
2260 | out: | 2238 | out: |
2261 | /* clear hotplug flag */ | 2239 | /* clear hotplug flag */ |
2262 | ehc->i.flags &= ~ATA_EHI_HOTPLUGGED; | 2240 | ehc->i.flags &= ~ATA_EHI_HOTPLUGGED; |
@@ -2266,6 +2244,28 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2266 | spin_unlock_irqrestore(ap->lock, flags); | 2244 | spin_unlock_irqrestore(ap->lock, flags); |
2267 | 2245 | ||
2268 | return rc; | 2246 | return rc; |
2247 | |||
2248 | fail: | ||
2249 | if (rc == -ERESTART || try >= max_tries) | ||
2250 | goto out; | ||
2251 | |||
2252 | now = jiffies; | ||
2253 | if (time_before(now, deadline)) { | ||
2254 | unsigned long delta = deadline - now; | ||
2255 | |||
2256 | ata_link_printk(link, KERN_WARNING, "reset failed " | ||
2257 | "(errno=%d), retrying in %u secs\n", | ||
2258 | rc, (jiffies_to_msecs(delta) + 999) / 1000); | ||
2259 | |||
2260 | while (delta) | ||
2261 | delta = schedule_timeout_uninterruptible(delta); | ||
2262 | } | ||
2263 | |||
2264 | if (rc == -EPIPE || try == max_tries - 1) | ||
2265 | sata_down_spd_limit(link); | ||
2266 | if (hardreset) | ||
2267 | reset = hardreset; | ||
2268 | goto retry; | ||
2269 | } | 2269 | } |
2270 | 2270 | ||
2271 | static int ata_eh_revalidate_and_attach(struct ata_link *link, | 2271 | static int ata_eh_revalidate_and_attach(struct ata_link *link, |