diff options
Diffstat (limited to 'drivers/ata/libata-eh.c')
-rw-r--r-- | drivers/ata/libata-eh.c | 99 |
1 files changed, 35 insertions, 64 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index a5830329eda4..f7cae6400155 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -1079,16 +1079,9 @@ void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev, | |||
1079 | 1079 | ||
1080 | spin_lock_irqsave(ap->lock, flags); | 1080 | spin_lock_irqsave(ap->lock, flags); |
1081 | 1081 | ||
1082 | /* Reset is represented by combination of actions and EHI | 1082 | /* suck in and clear reset modifier */ |
1083 | * flags. Suck in all related bits before clearing eh_info to | 1083 | if (action & ATA_EH_RESET) { |
1084 | * avoid losing requested action. | ||
1085 | */ | ||
1086 | if (action & ATA_EH_RESET_MASK) { | ||
1087 | ehc->i.action |= ehi->action & ATA_EH_RESET_MASK; | ||
1088 | ehc->i.flags |= ehi->flags & ATA_EHI_RESET_MODIFIER_MASK; | 1084 | ehc->i.flags |= ehi->flags & ATA_EHI_RESET_MODIFIER_MASK; |
1089 | |||
1090 | /* make sure all reset actions are cleared & clear EHI flags */ | ||
1091 | action |= ATA_EH_RESET_MASK; | ||
1092 | ehi->flags &= ~ATA_EHI_RESET_MODIFIER_MASK; | 1085 | ehi->flags &= ~ATA_EHI_RESET_MODIFIER_MASK; |
1093 | } | 1086 | } |
1094 | 1087 | ||
@@ -1117,11 +1110,9 @@ void ata_eh_done(struct ata_link *link, struct ata_device *dev, | |||
1117 | { | 1110 | { |
1118 | struct ata_eh_context *ehc = &link->eh_context; | 1111 | struct ata_eh_context *ehc = &link->eh_context; |
1119 | 1112 | ||
1120 | /* if reset is complete, clear all reset actions & reset modifier */ | 1113 | /* if reset is complete, clear reset modifier */ |
1121 | if (action & ATA_EH_RESET_MASK) { | 1114 | if (action & ATA_EH_RESET) |
1122 | action |= ATA_EH_RESET_MASK; | ||
1123 | ehc->i.flags &= ~ATA_EHI_RESET_MODIFIER_MASK; | 1115 | ehc->i.flags &= ~ATA_EHI_RESET_MODIFIER_MASK; |
1124 | } | ||
1125 | 1116 | ||
1126 | ata_eh_clear_action(link, dev, &ehc->i, action); | 1117 | ata_eh_clear_action(link, dev, &ehc->i, action); |
1127 | } | 1118 | } |
@@ -1329,20 +1320,20 @@ static void ata_eh_analyze_serror(struct ata_link *link) | |||
1329 | 1320 | ||
1330 | if (serror & SERR_PERSISTENT) { | 1321 | if (serror & SERR_PERSISTENT) { |
1331 | err_mask |= AC_ERR_ATA_BUS; | 1322 | err_mask |= AC_ERR_ATA_BUS; |
1332 | action |= ATA_EH_HARDRESET; | 1323 | action |= ATA_EH_RESET; |
1333 | } | 1324 | } |
1334 | if (serror & | 1325 | if (serror & |
1335 | (SERR_DATA_RECOVERED | SERR_COMM_RECOVERED | SERR_DATA)) { | 1326 | (SERR_DATA_RECOVERED | SERR_COMM_RECOVERED | SERR_DATA)) { |
1336 | err_mask |= AC_ERR_ATA_BUS; | 1327 | err_mask |= AC_ERR_ATA_BUS; |
1337 | action |= ATA_EH_SOFTRESET; | 1328 | action |= ATA_EH_RESET; |
1338 | } | 1329 | } |
1339 | if (serror & SERR_PROTOCOL) { | 1330 | if (serror & SERR_PROTOCOL) { |
1340 | err_mask |= AC_ERR_HSM; | 1331 | err_mask |= AC_ERR_HSM; |
1341 | action |= ATA_EH_SOFTRESET; | 1332 | action |= ATA_EH_RESET; |
1342 | } | 1333 | } |
1343 | if (serror & SERR_INTERNAL) { | 1334 | if (serror & SERR_INTERNAL) { |
1344 | err_mask |= AC_ERR_SYSTEM; | 1335 | err_mask |= AC_ERR_SYSTEM; |
1345 | action |= ATA_EH_HARDRESET; | 1336 | action |= ATA_EH_RESET; |
1346 | } | 1337 | } |
1347 | 1338 | ||
1348 | /* Determine whether a hotplug event has occurred. Both | 1339 | /* Determine whether a hotplug event has occurred. Both |
@@ -1448,7 +1439,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, | |||
1448 | 1439 | ||
1449 | if ((stat & (ATA_BUSY | ATA_DRQ | ATA_DRDY)) != ATA_DRDY) { | 1440 | if ((stat & (ATA_BUSY | ATA_DRQ | ATA_DRDY)) != ATA_DRDY) { |
1450 | qc->err_mask |= AC_ERR_HSM; | 1441 | qc->err_mask |= AC_ERR_HSM; |
1451 | return ATA_EH_SOFTRESET; | 1442 | return ATA_EH_RESET; |
1452 | } | 1443 | } |
1453 | 1444 | ||
1454 | if (stat & (ATA_ERR | ATA_DF)) | 1445 | if (stat & (ATA_ERR | ATA_DF)) |
@@ -1484,7 +1475,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, | |||
1484 | } | 1475 | } |
1485 | 1476 | ||
1486 | if (qc->err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT | AC_ERR_ATA_BUS)) | 1477 | if (qc->err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT | AC_ERR_ATA_BUS)) |
1487 | action |= ATA_EH_SOFTRESET; | 1478 | action |= ATA_EH_RESET; |
1488 | 1479 | ||
1489 | return action; | 1480 | return action; |
1490 | } | 1481 | } |
@@ -1685,7 +1676,7 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev, | |||
1685 | if (verdict & ATA_EH_SPDN_SPEED_DOWN) { | 1676 | if (verdict & ATA_EH_SPDN_SPEED_DOWN) { |
1686 | /* speed down SATA link speed if possible */ | 1677 | /* speed down SATA link speed if possible */ |
1687 | if (sata_down_spd_limit(link) == 0) { | 1678 | if (sata_down_spd_limit(link) == 0) { |
1688 | action |= ATA_EH_HARDRESET; | 1679 | action |= ATA_EH_RESET; |
1689 | goto done; | 1680 | goto done; |
1690 | } | 1681 | } |
1691 | 1682 | ||
@@ -1705,7 +1696,7 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev, | |||
1705 | dev->spdn_cnt++; | 1696 | dev->spdn_cnt++; |
1706 | 1697 | ||
1707 | if (ata_down_xfermask_limit(dev, sel) == 0) { | 1698 | if (ata_down_xfermask_limit(dev, sel) == 0) { |
1708 | action |= ATA_EH_SOFTRESET; | 1699 | action |= ATA_EH_RESET; |
1709 | goto done; | 1700 | goto done; |
1710 | } | 1701 | } |
1711 | } | 1702 | } |
@@ -1719,7 +1710,7 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev, | |||
1719 | (dev->xfer_shift != ATA_SHIFT_PIO)) { | 1710 | (dev->xfer_shift != ATA_SHIFT_PIO)) { |
1720 | if (ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO) == 0) { | 1711 | if (ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO) == 0) { |
1721 | dev->spdn_cnt = 0; | 1712 | dev->spdn_cnt = 0; |
1722 | action |= ATA_EH_SOFTRESET; | 1713 | action |= ATA_EH_RESET; |
1723 | goto done; | 1714 | goto done; |
1724 | } | 1715 | } |
1725 | } | 1716 | } |
@@ -1764,9 +1755,9 @@ static void ata_eh_link_autopsy(struct ata_link *link) | |||
1764 | ehc->i.serror |= serror; | 1755 | ehc->i.serror |= serror; |
1765 | ata_eh_analyze_serror(link); | 1756 | ata_eh_analyze_serror(link); |
1766 | } else if (rc != -EOPNOTSUPP) { | 1757 | } else if (rc != -EOPNOTSUPP) { |
1767 | /* SError read failed, force hardreset and probing */ | 1758 | /* SError read failed, force reset and probing */ |
1768 | ata_ehi_schedule_probe(&ehc->i); | 1759 | ata_ehi_schedule_probe(&ehc->i); |
1769 | ehc->i.action |= ATA_EH_HARDRESET; | 1760 | ehc->i.action |= ATA_EH_RESET; |
1770 | ehc->i.err_mask |= AC_ERR_OTHER; | 1761 | ehc->i.err_mask |= AC_ERR_OTHER; |
1771 | } | 1762 | } |
1772 | 1763 | ||
@@ -1814,7 +1805,7 @@ static void ata_eh_link_autopsy(struct ata_link *link) | |||
1814 | /* enforce default EH actions */ | 1805 | /* enforce default EH actions */ |
1815 | if (ap->pflags & ATA_PFLAG_FROZEN || | 1806 | if (ap->pflags & ATA_PFLAG_FROZEN || |
1816 | all_err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT)) | 1807 | all_err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT)) |
1817 | ehc->i.action |= ATA_EH_SOFTRESET; | 1808 | ehc->i.action |= ATA_EH_RESET; |
1818 | else if (((eflags & ATA_EFLAG_IS_IO) && all_err_mask) || | 1809 | else if (((eflags & ATA_EFLAG_IS_IO) && all_err_mask) || |
1819 | (!(eflags & ATA_EFLAG_IS_IO) && (all_err_mask & ~AC_ERR_DEV))) | 1810 | (!(eflags & ATA_EFLAG_IS_IO) && (all_err_mask & ~AC_ERR_DEV))) |
1820 | ehc->i.action |= ATA_EH_REVALIDATE; | 1811 | ehc->i.action |= ATA_EH_REVALIDATE; |
@@ -2118,7 +2109,6 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2118 | int try = 0; | 2109 | int try = 0; |
2119 | struct ata_device *dev; | 2110 | struct ata_device *dev; |
2120 | unsigned long deadline, now; | 2111 | unsigned long deadline, now; |
2121 | unsigned int tmp_action; | ||
2122 | ata_reset_fn_t reset; | 2112 | ata_reset_fn_t reset; |
2123 | unsigned long flags; | 2113 | unsigned long flags; |
2124 | u32 sstatus; | 2114 | u32 sstatus; |
@@ -2129,7 +2119,7 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2129 | ap->pflags |= ATA_PFLAG_RESETTING; | 2119 | ap->pflags |= ATA_PFLAG_RESETTING; |
2130 | spin_unlock_irqrestore(ap->lock, flags); | 2120 | spin_unlock_irqrestore(ap->lock, flags); |
2131 | 2121 | ||
2132 | ata_eh_about_to_do(link, NULL, ehc->i.action & ATA_EH_RESET_MASK); | 2122 | ata_eh_about_to_do(link, NULL, ATA_EH_RESET); |
2133 | 2123 | ||
2134 | ata_link_for_each_dev(dev, link) { | 2124 | ata_link_for_each_dev(dev, link) { |
2135 | /* If we issue an SRST then an ATA drive (not ATAPI) | 2125 | /* If we issue an SRST then an ATA drive (not ATAPI) |
@@ -2159,17 +2149,15 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2159 | goto done; | 2149 | goto done; |
2160 | } | 2150 | } |
2161 | 2151 | ||
2162 | /* Determine which reset to use and record in ehc->i.action. | 2152 | /* prefer hardreset */ |
2163 | * prereset() may examine and modify it. | 2153 | ehc->i.action &= ~ATA_EH_RESET; |
2164 | */ | 2154 | if (hardreset) { |
2165 | if (softreset && (!hardreset || (!(lflags & ATA_LFLAG_NO_SRST) && | 2155 | reset = hardreset; |
2166 | !sata_set_spd_needed(link) && | 2156 | ehc->i.action = ATA_EH_HARDRESET; |
2167 | !(ehc->i.action & ATA_EH_HARDRESET)))) | 2157 | } else { |
2168 | tmp_action = ATA_EH_SOFTRESET; | 2158 | reset = softreset; |
2169 | else | 2159 | ehc->i.action = ATA_EH_SOFTRESET; |
2170 | tmp_action = ATA_EH_HARDRESET; | 2160 | } |
2171 | |||
2172 | ehc->i.action = (ehc->i.action & ~ATA_EH_RESET_MASK) | tmp_action; | ||
2173 | 2161 | ||
2174 | if (prereset) { | 2162 | if (prereset) { |
2175 | rc = prereset(link, jiffies + ATA_EH_PRERESET_TIMEOUT); | 2163 | rc = prereset(link, jiffies + ATA_EH_PRERESET_TIMEOUT); |
@@ -2177,7 +2165,7 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2177 | if (rc == -ENOENT) { | 2165 | if (rc == -ENOENT) { |
2178 | ata_link_printk(link, KERN_DEBUG, | 2166 | ata_link_printk(link, KERN_DEBUG, |
2179 | "port disabled. ignoring.\n"); | 2167 | "port disabled. ignoring.\n"); |
2180 | ehc->i.action &= ~ATA_EH_RESET_MASK; | 2168 | ehc->i.action &= ~ATA_EH_RESET; |
2181 | 2169 | ||
2182 | ata_link_for_each_dev(dev, link) | 2170 | ata_link_for_each_dev(dev, link) |
2183 | classes[dev->devno] = ATA_DEV_NONE; | 2171 | classes[dev->devno] = ATA_DEV_NONE; |
@@ -2190,12 +2178,8 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2190 | } | 2178 | } |
2191 | } | 2179 | } |
2192 | 2180 | ||
2193 | /* prereset() might have modified ehc->i.action */ | 2181 | /* prereset() might have cleared ATA_EH_RESET */ |
2194 | if (ehc->i.action & ATA_EH_HARDRESET) | 2182 | if (!(ehc->i.action & ATA_EH_RESET)) { |
2195 | reset = hardreset; | ||
2196 | else if (ehc->i.action & ATA_EH_SOFTRESET) | ||
2197 | reset = softreset; | ||
2198 | else { | ||
2199 | /* prereset told us not to reset, bang classes and return */ | 2183 | /* prereset told us not to reset, bang classes and return */ |
2200 | ata_link_for_each_dev(dev, link) | 2184 | ata_link_for_each_dev(dev, link) |
2201 | classes[dev->devno] = ATA_DEV_NONE; | 2185 | classes[dev->devno] = ATA_DEV_NONE; |
@@ -2203,14 +2187,6 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2203 | goto out; | 2187 | goto out; |
2204 | } | 2188 | } |
2205 | 2189 | ||
2206 | /* did prereset() screw up? if so, fix up to avoid oopsing */ | ||
2207 | if (!reset) { | ||
2208 | if (softreset) | ||
2209 | reset = softreset; | ||
2210 | else | ||
2211 | reset = hardreset; | ||
2212 | } | ||
2213 | |||
2214 | retry: | 2190 | retry: |
2215 | deadline = jiffies + ata_eh_reset_timeouts[try++]; | 2191 | deadline = jiffies + ata_eh_reset_timeouts[try++]; |
2216 | 2192 | ||
@@ -2240,7 +2216,7 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2240 | goto fail; | 2216 | goto fail; |
2241 | } | 2217 | } |
2242 | 2218 | ||
2243 | ata_eh_about_to_do(link, NULL, ATA_EH_RESET_MASK); | 2219 | ata_eh_about_to_do(link, NULL, ATA_EH_RESET); |
2244 | rc = ata_do_reset(link, reset, classes, deadline); | 2220 | rc = ata_do_reset(link, reset, classes, deadline); |
2245 | } | 2221 | } |
2246 | 2222 | ||
@@ -2290,7 +2266,7 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2290 | postreset(link, classes); | 2266 | postreset(link, classes); |
2291 | 2267 | ||
2292 | /* reset successful, schedule revalidation */ | 2268 | /* reset successful, schedule revalidation */ |
2293 | ata_eh_done(link, NULL, ehc->i.action & ATA_EH_RESET_MASK); | 2269 | ata_eh_done(link, NULL, ATA_EH_RESET); |
2294 | ehc->i.action |= ATA_EH_REVALIDATE; | 2270 | ehc->i.action |= ATA_EH_REVALIDATE; |
2295 | 2271 | ||
2296 | rc = 0; | 2272 | rc = 0; |
@@ -2548,7 +2524,7 @@ static int ata_eh_schedule_probe(struct ata_device *dev) | |||
2548 | ata_eh_detach_dev(dev); | 2524 | ata_eh_detach_dev(dev); |
2549 | ata_dev_init(dev); | 2525 | ata_dev_init(dev); |
2550 | ehc->did_probe_mask |= (1 << dev->devno); | 2526 | ehc->did_probe_mask |= (1 << dev->devno); |
2551 | ehc->i.action |= ATA_EH_SOFTRESET; | 2527 | ehc->i.action |= ATA_EH_RESET; |
2552 | ehc->saved_xfer_mode[dev->devno] = 0; | 2528 | ehc->saved_xfer_mode[dev->devno] = 0; |
2553 | ehc->saved_ncq_enabled &= ~(1 << dev->devno); | 2529 | ehc->saved_ncq_enabled &= ~(1 << dev->devno); |
2554 | 2530 | ||
@@ -2592,12 +2568,7 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err) | |||
2592 | 2568 | ||
2593 | return 1; | 2569 | return 1; |
2594 | } else { | 2570 | } else { |
2595 | /* soft didn't work? be haaaaard */ | 2571 | ehc->i.action |= ATA_EH_RESET; |
2596 | if (ehc->i.flags & ATA_EHI_DID_RESET) | ||
2597 | ehc->i.action |= ATA_EH_HARDRESET; | ||
2598 | else | ||
2599 | ehc->i.action |= ATA_EH_SOFTRESET; | ||
2600 | |||
2601 | return 0; | 2572 | return 0; |
2602 | } | 2573 | } |
2603 | } | 2574 | } |
@@ -2690,7 +2661,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
2690 | ehc->i.action = 0; | 2661 | ehc->i.action = 0; |
2691 | 2662 | ||
2692 | /* do we need to reset? */ | 2663 | /* do we need to reset? */ |
2693 | if (ehc->i.action & ATA_EH_RESET_MASK) | 2664 | if (ehc->i.action & ATA_EH_RESET) |
2694 | reset = 1; | 2665 | reset = 1; |
2695 | 2666 | ||
2696 | ata_link_for_each_dev(dev, link) | 2667 | ata_link_for_each_dev(dev, link) |
@@ -2708,7 +2679,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
2708 | ata_port_for_each_link(link, ap) { | 2679 | ata_port_for_each_link(link, ap) { |
2709 | struct ata_eh_context *ehc = &link->eh_context; | 2680 | struct ata_eh_context *ehc = &link->eh_context; |
2710 | 2681 | ||
2711 | if (!(ehc->i.action & ATA_EH_RESET_MASK)) | 2682 | if (!(ehc->i.action & ATA_EH_RESET)) |
2712 | continue; | 2683 | continue; |
2713 | 2684 | ||
2714 | rc = ata_eh_reset(link, ata_link_nr_vacant(link), | 2685 | rc = ata_eh_reset(link, ata_link_nr_vacant(link), |