diff options
Diffstat (limited to 'drivers/ata/libata-eh.c')
-rw-r--r-- | drivers/ata/libata-eh.c | 142 |
1 files changed, 116 insertions, 26 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index c1db2f234d2e..99037a4860d9 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -1756,7 +1756,7 @@ static unsigned int ata_eh_speed_down_verdict(struct ata_device *dev) | |||
1756 | static unsigned int ata_eh_speed_down(struct ata_device *dev, | 1756 | static unsigned int ata_eh_speed_down(struct ata_device *dev, |
1757 | unsigned int eflags, unsigned int err_mask) | 1757 | unsigned int eflags, unsigned int err_mask) |
1758 | { | 1758 | { |
1759 | struct ata_link *link = dev->link; | 1759 | struct ata_link *link = ata_dev_phys_link(dev); |
1760 | int xfer_ok = 0; | 1760 | int xfer_ok = 0; |
1761 | unsigned int verdict; | 1761 | unsigned int verdict; |
1762 | unsigned int action = 0; | 1762 | unsigned int action = 0; |
@@ -1880,7 +1880,8 @@ static void ata_eh_link_autopsy(struct ata_link *link) | |||
1880 | for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { | 1880 | for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { |
1881 | struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag); | 1881 | struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag); |
1882 | 1882 | ||
1883 | if (!(qc->flags & ATA_QCFLAG_FAILED) || qc->dev->link != link) | 1883 | if (!(qc->flags & ATA_QCFLAG_FAILED) || |
1884 | ata_dev_phys_link(qc->dev) != link) | ||
1884 | continue; | 1885 | continue; |
1885 | 1886 | ||
1886 | /* inherit upper level err_mask */ | 1887 | /* inherit upper level err_mask */ |
@@ -1967,6 +1968,23 @@ void ata_eh_autopsy(struct ata_port *ap) | |||
1967 | ata_port_for_each_link(link, ap) | 1968 | ata_port_for_each_link(link, ap) |
1968 | ata_eh_link_autopsy(link); | 1969 | ata_eh_link_autopsy(link); |
1969 | 1970 | ||
1971 | /* Handle the frigging slave link. Autopsy is done similarly | ||
1972 | * but actions and flags are transferred over to the master | ||
1973 | * link and handled from there. | ||
1974 | */ | ||
1975 | if (ap->slave_link) { | ||
1976 | struct ata_eh_context *mehc = &ap->link.eh_context; | ||
1977 | struct ata_eh_context *sehc = &ap->slave_link->eh_context; | ||
1978 | |||
1979 | ata_eh_link_autopsy(ap->slave_link); | ||
1980 | |||
1981 | ata_eh_about_to_do(ap->slave_link, NULL, ATA_EH_ALL_ACTIONS); | ||
1982 | mehc->i.action |= sehc->i.action; | ||
1983 | mehc->i.dev_action[1] |= sehc->i.dev_action[1]; | ||
1984 | mehc->i.flags |= sehc->i.flags; | ||
1985 | ata_eh_done(ap->slave_link, NULL, ATA_EH_ALL_ACTIONS); | ||
1986 | } | ||
1987 | |||
1970 | /* Autopsy of fanout ports can affect host link autopsy. | 1988 | /* Autopsy of fanout ports can affect host link autopsy. |
1971 | * Perform host link autopsy last. | 1989 | * Perform host link autopsy last. |
1972 | */ | 1990 | */ |
@@ -2001,7 +2019,8 @@ static void ata_eh_link_report(struct ata_link *link) | |||
2001 | for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { | 2019 | for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { |
2002 | struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag); | 2020 | struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag); |
2003 | 2021 | ||
2004 | if (!(qc->flags & ATA_QCFLAG_FAILED) || qc->dev->link != link || | 2022 | if (!(qc->flags & ATA_QCFLAG_FAILED) || |
2023 | ata_dev_phys_link(qc->dev) != link || | ||
2005 | ((qc->flags & ATA_QCFLAG_QUIET) && | 2024 | ((qc->flags & ATA_QCFLAG_QUIET) && |
2006 | qc->err_mask == AC_ERR_DEV)) | 2025 | qc->err_mask == AC_ERR_DEV)) |
2007 | continue; | 2026 | continue; |
@@ -2068,7 +2087,7 @@ static void ata_eh_link_report(struct ata_link *link) | |||
2068 | char cdb_buf[70] = ""; | 2087 | char cdb_buf[70] = ""; |
2069 | 2088 | ||
2070 | if (!(qc->flags & ATA_QCFLAG_FAILED) || | 2089 | if (!(qc->flags & ATA_QCFLAG_FAILED) || |
2071 | qc->dev->link != link || !qc->err_mask) | 2090 | ata_dev_phys_link(qc->dev) != link || !qc->err_mask) |
2072 | continue; | 2091 | continue; |
2073 | 2092 | ||
2074 | if (qc->dma_dir != DMA_NONE) { | 2093 | if (qc->dma_dir != DMA_NONE) { |
@@ -2160,12 +2179,14 @@ void ata_eh_report(struct ata_port *ap) | |||
2160 | } | 2179 | } |
2161 | 2180 | ||
2162 | static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset, | 2181 | static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset, |
2163 | unsigned int *classes, unsigned long deadline) | 2182 | unsigned int *classes, unsigned long deadline, |
2183 | bool clear_classes) | ||
2164 | { | 2184 | { |
2165 | struct ata_device *dev; | 2185 | struct ata_device *dev; |
2166 | 2186 | ||
2167 | ata_link_for_each_dev(dev, link) | 2187 | if (clear_classes) |
2168 | classes[dev->devno] = ATA_DEV_UNKNOWN; | 2188 | ata_link_for_each_dev(dev, link) |
2189 | classes[dev->devno] = ATA_DEV_UNKNOWN; | ||
2169 | 2190 | ||
2170 | return reset(link, classes, deadline); | 2191 | return reset(link, classes, deadline); |
2171 | } | 2192 | } |
@@ -2187,17 +2208,20 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2187 | ata_reset_fn_t hardreset, ata_postreset_fn_t postreset) | 2208 | ata_reset_fn_t hardreset, ata_postreset_fn_t postreset) |
2188 | { | 2209 | { |
2189 | struct ata_port *ap = link->ap; | 2210 | struct ata_port *ap = link->ap; |
2211 | struct ata_link *slave = ap->slave_link; | ||
2190 | struct ata_eh_context *ehc = &link->eh_context; | 2212 | struct ata_eh_context *ehc = &link->eh_context; |
2213 | struct ata_eh_context *sehc = &slave->eh_context; | ||
2191 | unsigned int *classes = ehc->classes; | 2214 | unsigned int *classes = ehc->classes; |
2192 | unsigned int lflags = link->flags; | 2215 | unsigned int lflags = link->flags; |
2193 | int verbose = !(ehc->i.flags & ATA_EHI_QUIET); | 2216 | int verbose = !(ehc->i.flags & ATA_EHI_QUIET); |
2194 | int max_tries = 0, try = 0; | 2217 | int max_tries = 0, try = 0; |
2218 | struct ata_link *failed_link; | ||
2195 | struct ata_device *dev; | 2219 | struct ata_device *dev; |
2196 | unsigned long deadline, now; | 2220 | unsigned long deadline, now; |
2197 | ata_reset_fn_t reset; | 2221 | ata_reset_fn_t reset; |
2198 | unsigned long flags; | 2222 | unsigned long flags; |
2199 | u32 sstatus; | 2223 | u32 sstatus; |
2200 | int nr_known, rc; | 2224 | int nr_unknown, rc; |
2201 | 2225 | ||
2202 | /* | 2226 | /* |
2203 | * Prepare to reset | 2227 | * Prepare to reset |
@@ -2252,8 +2276,30 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2252 | } | 2276 | } |
2253 | 2277 | ||
2254 | if (prereset) { | 2278 | if (prereset) { |
2255 | rc = prereset(link, | 2279 | unsigned long deadline = ata_deadline(jiffies, |
2256 | ata_deadline(jiffies, ATA_EH_PRERESET_TIMEOUT)); | 2280 | ATA_EH_PRERESET_TIMEOUT); |
2281 | |||
2282 | if (slave) { | ||
2283 | sehc->i.action &= ~ATA_EH_RESET; | ||
2284 | sehc->i.action |= ehc->i.action; | ||
2285 | } | ||
2286 | |||
2287 | rc = prereset(link, deadline); | ||
2288 | |||
2289 | /* If present, do prereset on slave link too. Reset | ||
2290 | * is skipped iff both master and slave links report | ||
2291 | * -ENOENT or clear ATA_EH_RESET. | ||
2292 | */ | ||
2293 | if (slave && (rc == 0 || rc == -ENOENT)) { | ||
2294 | int tmp; | ||
2295 | |||
2296 | tmp = prereset(slave, deadline); | ||
2297 | if (tmp != -ENOENT) | ||
2298 | rc = tmp; | ||
2299 | |||
2300 | ehc->i.action |= sehc->i.action; | ||
2301 | } | ||
2302 | |||
2257 | if (rc) { | 2303 | if (rc) { |
2258 | if (rc == -ENOENT) { | 2304 | if (rc == -ENOENT) { |
2259 | ata_link_printk(link, KERN_DEBUG, | 2305 | ata_link_printk(link, KERN_DEBUG, |
@@ -2302,25 +2348,51 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2302 | else | 2348 | else |
2303 | ehc->i.flags |= ATA_EHI_DID_SOFTRESET; | 2349 | ehc->i.flags |= ATA_EHI_DID_SOFTRESET; |
2304 | 2350 | ||
2305 | rc = ata_do_reset(link, reset, classes, deadline); | 2351 | rc = ata_do_reset(link, reset, classes, deadline, true); |
2306 | if (rc && rc != -EAGAIN) | 2352 | if (rc && rc != -EAGAIN) { |
2353 | failed_link = link; | ||
2307 | goto fail; | 2354 | goto fail; |
2355 | } | ||
2356 | |||
2357 | /* hardreset slave link if existent */ | ||
2358 | if (slave && reset == hardreset) { | ||
2359 | int tmp; | ||
2360 | |||
2361 | if (verbose) | ||
2362 | ata_link_printk(slave, KERN_INFO, | ||
2363 | "hard resetting link\n"); | ||
2308 | 2364 | ||
2365 | ata_eh_about_to_do(slave, NULL, ATA_EH_RESET); | ||
2366 | tmp = ata_do_reset(slave, reset, classes, deadline, | ||
2367 | false); | ||
2368 | switch (tmp) { | ||
2369 | case -EAGAIN: | ||
2370 | rc = -EAGAIN; | ||
2371 | case 0: | ||
2372 | break; | ||
2373 | default: | ||
2374 | failed_link = slave; | ||
2375 | rc = tmp; | ||
2376 | goto fail; | ||
2377 | } | ||
2378 | } | ||
2379 | |||
2380 | /* perform follow-up SRST if necessary */ | ||
2309 | if (reset == hardreset && | 2381 | if (reset == hardreset && |
2310 | ata_eh_followup_srst_needed(link, rc, classes)) { | 2382 | ata_eh_followup_srst_needed(link, rc, classes)) { |
2311 | /* okay, let's do follow-up softreset */ | ||
2312 | reset = softreset; | 2383 | reset = softreset; |
2313 | 2384 | ||
2314 | if (!reset) { | 2385 | if (!reset) { |
2315 | ata_link_printk(link, KERN_ERR, | 2386 | ata_link_printk(link, KERN_ERR, |
2316 | "follow-up softreset required " | 2387 | "follow-up softreset required " |
2317 | "but no softreset avaliable\n"); | 2388 | "but no softreset avaliable\n"); |
2389 | failed_link = link; | ||
2318 | rc = -EINVAL; | 2390 | rc = -EINVAL; |
2319 | goto fail; | 2391 | goto fail; |
2320 | } | 2392 | } |
2321 | 2393 | ||
2322 | ata_eh_about_to_do(link, NULL, ATA_EH_RESET); | 2394 | ata_eh_about_to_do(link, NULL, ATA_EH_RESET); |
2323 | rc = ata_do_reset(link, reset, classes, deadline); | 2395 | rc = ata_do_reset(link, reset, classes, deadline, true); |
2324 | } | 2396 | } |
2325 | } else { | 2397 | } else { |
2326 | if (verbose) | 2398 | if (verbose) |
@@ -2341,7 +2413,7 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2341 | dev->pio_mode = XFER_PIO_0; | 2413 | dev->pio_mode = XFER_PIO_0; |
2342 | dev->flags &= ~ATA_DFLAG_SLEEPING; | 2414 | dev->flags &= ~ATA_DFLAG_SLEEPING; |
2343 | 2415 | ||
2344 | if (ata_link_offline(link)) | 2416 | if (ata_phys_link_offline(ata_dev_phys_link(dev))) |
2345 | continue; | 2417 | continue; |
2346 | 2418 | ||
2347 | /* apply class override */ | 2419 | /* apply class override */ |
@@ -2354,6 +2426,8 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2354 | /* record current link speed */ | 2426 | /* record current link speed */ |
2355 | if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0) | 2427 | if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0) |
2356 | link->sata_spd = (sstatus >> 4) & 0xf; | 2428 | link->sata_spd = (sstatus >> 4) & 0xf; |
2429 | if (slave && sata_scr_read(slave, SCR_STATUS, &sstatus) == 0) | ||
2430 | slave->sata_spd = (sstatus >> 4) & 0xf; | ||
2357 | 2431 | ||
2358 | /* thaw the port */ | 2432 | /* thaw the port */ |
2359 | if (ata_is_host_link(link)) | 2433 | if (ata_is_host_link(link)) |
@@ -2366,12 +2440,17 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2366 | * reset and here. This race is mediated by cross checking | 2440 | * reset and here. This race is mediated by cross checking |
2367 | * link onlineness and classification result later. | 2441 | * link onlineness and classification result later. |
2368 | */ | 2442 | */ |
2369 | if (postreset) | 2443 | if (postreset) { |
2370 | postreset(link, classes); | 2444 | postreset(link, classes); |
2445 | if (slave) | ||
2446 | postreset(slave, classes); | ||
2447 | } | ||
2371 | 2448 | ||
2372 | /* clear cached SError */ | 2449 | /* clear cached SError */ |
2373 | spin_lock_irqsave(link->ap->lock, flags); | 2450 | spin_lock_irqsave(link->ap->lock, flags); |
2374 | link->eh_info.serror = 0; | 2451 | link->eh_info.serror = 0; |
2452 | if (slave) | ||
2453 | slave->eh_info.serror = 0; | ||
2375 | spin_unlock_irqrestore(link->ap->lock, flags); | 2454 | spin_unlock_irqrestore(link->ap->lock, flags); |
2376 | 2455 | ||
2377 | /* Make sure onlineness and classification result correspond. | 2456 | /* Make sure onlineness and classification result correspond. |
@@ -2381,19 +2460,21 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2381 | * link onlineness and classification result, those conditions | 2460 | * link onlineness and classification result, those conditions |
2382 | * can be reliably detected and retried. | 2461 | * can be reliably detected and retried. |
2383 | */ | 2462 | */ |
2384 | nr_known = 0; | 2463 | nr_unknown = 0; |
2385 | ata_link_for_each_dev(dev, link) { | 2464 | ata_link_for_each_dev(dev, link) { |
2386 | /* convert all ATA_DEV_UNKNOWN to ATA_DEV_NONE */ | 2465 | /* convert all ATA_DEV_UNKNOWN to ATA_DEV_NONE */ |
2387 | if (classes[dev->devno] == ATA_DEV_UNKNOWN) | 2466 | if (classes[dev->devno] == ATA_DEV_UNKNOWN) { |
2388 | classes[dev->devno] = ATA_DEV_NONE; | 2467 | classes[dev->devno] = ATA_DEV_NONE; |
2389 | else | 2468 | if (ata_phys_link_online(ata_dev_phys_link(dev))) |
2390 | nr_known++; | 2469 | nr_unknown++; |
2470 | } | ||
2391 | } | 2471 | } |
2392 | 2472 | ||
2393 | if (classify && !nr_known && ata_link_online(link)) { | 2473 | if (classify && nr_unknown) { |
2394 | if (try < max_tries) { | 2474 | if (try < max_tries) { |
2395 | ata_link_printk(link, KERN_WARNING, "link online but " | 2475 | ata_link_printk(link, KERN_WARNING, "link online but " |
2396 | "device misclassified, retrying\n"); | 2476 | "device misclassified, retrying\n"); |
2477 | failed_link = link; | ||
2397 | rc = -EAGAIN; | 2478 | rc = -EAGAIN; |
2398 | goto fail; | 2479 | goto fail; |
2399 | } | 2480 | } |
@@ -2404,6 +2485,8 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2404 | 2485 | ||
2405 | /* reset successful, schedule revalidation */ | 2486 | /* reset successful, schedule revalidation */ |
2406 | ata_eh_done(link, NULL, ATA_EH_RESET); | 2487 | ata_eh_done(link, NULL, ATA_EH_RESET); |
2488 | if (slave) | ||
2489 | ata_eh_done(slave, NULL, ATA_EH_RESET); | ||
2407 | ehc->last_reset = jiffies; | 2490 | ehc->last_reset = jiffies; |
2408 | ehc->i.action |= ATA_EH_REVALIDATE; | 2491 | ehc->i.action |= ATA_EH_REVALIDATE; |
2409 | 2492 | ||
@@ -2411,6 +2494,8 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2411 | out: | 2494 | out: |
2412 | /* clear hotplug flag */ | 2495 | /* clear hotplug flag */ |
2413 | ehc->i.flags &= ~ATA_EHI_HOTPLUGGED; | 2496 | ehc->i.flags &= ~ATA_EHI_HOTPLUGGED; |
2497 | if (slave) | ||
2498 | sehc->i.flags &= ~ATA_EHI_HOTPLUGGED; | ||
2414 | 2499 | ||
2415 | spin_lock_irqsave(ap->lock, flags); | 2500 | spin_lock_irqsave(ap->lock, flags); |
2416 | ap->pflags &= ~ATA_PFLAG_RESETTING; | 2501 | ap->pflags &= ~ATA_PFLAG_RESETTING; |
@@ -2431,7 +2516,7 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2431 | if (time_before(now, deadline)) { | 2516 | if (time_before(now, deadline)) { |
2432 | unsigned long delta = deadline - now; | 2517 | unsigned long delta = deadline - now; |
2433 | 2518 | ||
2434 | ata_link_printk(link, KERN_WARNING, | 2519 | ata_link_printk(failed_link, KERN_WARNING, |
2435 | "reset failed (errno=%d), retrying in %u secs\n", | 2520 | "reset failed (errno=%d), retrying in %u secs\n", |
2436 | rc, DIV_ROUND_UP(jiffies_to_msecs(delta), 1000)); | 2521 | rc, DIV_ROUND_UP(jiffies_to_msecs(delta), 1000)); |
2437 | 2522 | ||
@@ -2439,8 +2524,13 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2439 | delta = schedule_timeout_uninterruptible(delta); | 2524 | delta = schedule_timeout_uninterruptible(delta); |
2440 | } | 2525 | } |
2441 | 2526 | ||
2442 | if (rc == -EPIPE || try == max_tries - 1) | 2527 | if (try == max_tries - 1) { |
2443 | sata_down_spd_limit(link); | 2528 | sata_down_spd_limit(link); |
2529 | if (slave) | ||
2530 | sata_down_spd_limit(slave); | ||
2531 | } else if (rc == -EPIPE) | ||
2532 | sata_down_spd_limit(failed_link); | ||
2533 | |||
2444 | if (hardreset) | 2534 | if (hardreset) |
2445 | reset = hardreset; | 2535 | reset = hardreset; |
2446 | goto retry; | 2536 | goto retry; |
@@ -2472,7 +2562,7 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, | |||
2472 | if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) { | 2562 | if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) { |
2473 | WARN_ON(dev->class == ATA_DEV_PMP); | 2563 | WARN_ON(dev->class == ATA_DEV_PMP); |
2474 | 2564 | ||
2475 | if (ata_link_offline(link)) { | 2565 | if (ata_phys_link_offline(ata_dev_phys_link(dev))) { |
2476 | rc = -EIO; | 2566 | rc = -EIO; |
2477 | goto err; | 2567 | goto err; |
2478 | } | 2568 | } |
@@ -2697,7 +2787,7 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err) | |||
2697 | /* This is the last chance, better to slow | 2787 | /* This is the last chance, better to slow |
2698 | * down than lose it. | 2788 | * down than lose it. |
2699 | */ | 2789 | */ |
2700 | sata_down_spd_limit(dev->link); | 2790 | sata_down_spd_limit(ata_dev_phys_link(dev)); |
2701 | ata_down_xfermask_limit(dev, ATA_DNXFER_PIO); | 2791 | ata_down_xfermask_limit(dev, ATA_DNXFER_PIO); |
2702 | } | 2792 | } |
2703 | } | 2793 | } |
@@ -2707,7 +2797,7 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err) | |||
2707 | ata_dev_disable(dev); | 2797 | ata_dev_disable(dev); |
2708 | 2798 | ||
2709 | /* detach if offline */ | 2799 | /* detach if offline */ |
2710 | if (ata_link_offline(dev->link)) | 2800 | if (ata_phys_link_offline(ata_dev_phys_link(dev))) |
2711 | ata_eh_detach_dev(dev); | 2801 | ata_eh_detach_dev(dev); |
2712 | 2802 | ||
2713 | /* schedule probe if necessary */ | 2803 | /* schedule probe if necessary */ |