aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-eh.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2008-07-31 04:02:43 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-09-29 00:25:28 -0400
commitb1c72916abbdd0a55015c87358536ca0ebaf6735 (patch)
tree1064fe92f2c3600dd6587c880d907020896b3348 /drivers/ata/libata-eh.c
parentb5b3fa386b8f96c7fa92e507e5deddc2637924b4 (diff)
libata: implement slave_link
Explanation taken from the comment of ata_slave_link_init(). In libata, a port contains links and a link contains devices. There is single host link but if a PMP is attached to it, there can be multiple fan-out links. On SATA, there's usually a single device connected to a link but PATA and SATA controllers emulating TF based interface can have two - master and slave. However, there are a few controllers which don't fit into this abstraction too well - SATA controllers which emulate TF interface with both master and slave devices but also have separate SCR register sets for each device. These controllers need separate links for physical link handling (e.g. onlineness, link speed) but should be treated like a traditional M/S controller for everything else (e.g. command issue, softreset). slave_link is libata's way of handling this class of controllers without impacting core layer too much. For anything other than physical link handling, the default host link is used for both master and slave. For physical link handling, separate @ap->slave_link is used. All dirty details are implemented inside libata core layer. From LLD's POV, the only difference is that prereset, hardreset and postreset are called once more for the slave link, so the reset sequence looks like the following. prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) -> softreset(M) -> postreset(M) -> postreset(S) Note that softreset is called only for the master. Softreset resets both M/S by definition, so SRST on master should handle both (the standard method will work just fine). As slave_link excludes PMP support and only code paths which deal with the attributes of physical link are affected, all the changes are localized to libata.h, libata-core.c and libata-eh.c. * ata_is_host_link() updated so that slave_link is considered as host link too. * iterator extended to iterate over the slave_link when using the underbarred version. * force param handling updated such that devno 16 is mapped to the slave link/device. * ata_link_on/offline() updated to return the combined result from master and slave link. ata_phys_link_on/offline() are the direct versions. * EH autopsy and report are performed separately for master slave links. Reset is udpated to implement the above described reset sequence. Except for reset update, most changes are minor, many of them just modifying dev->link to ata_dev_phys_link(dev) or using phys online test instead. After this update, LLDs can take full advantage of per-dev SCR registers by simply turning on slave link. 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.c142
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)
1756static unsigned int ata_eh_speed_down(struct ata_device *dev, 1756static 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
2162static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset, 2181static 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 */