aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-eh.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-01-23 10:05:14 -0500
committerJeff Garzik <jgarzik@redhat.com>2008-04-17 15:44:15 -0400
commitcf48062658e7ab3bc55e10c65676c3c73c16f8bf (patch)
tree9a50a016ceb6051d8a30a43ea39f2a4d3d25570e /drivers/ata/libata-eh.c
parent4b119e21d0c66c22e8ca03df05d9de623d0eb50f (diff)
libata: prefer hardreset
When both soft and hard resets are available, libata preferred softreset till now. The logic behind it was to be softer to devices; however, this doesn't really help much. Rationales for the change: * BIOS may freeze lock certain things during boot and softreset can't unlock those. This by itself is okay but during operation PHY event or other error conditions can trigger hardreset and the device may end up with different configuration. For example, after a hardreset, previously unlockable HPA can be unlocked resulting in different device size and thus revalidation failure. Similar condition can occur during or after resume. * Certain ATAPI devices require hardreset to recover after certain error conditions. On PATA, this is done by issuing the DEVICE RESET command. On SATA, COMRESET has equivalent effect. The problem is that DEVICE RESET needs its own execution protocol. For SFF controllers with bare TF access, it can be easily implemented but more advanced controllers (e.g. ahci and sata_sil24) require specialized implementations. Simply using hardreset solves the problem nicely. * COMRESET initialization sequence is the norm in SATA land and many SATA devices don't work properly if only SRST is used. For example, some PMPs behave this way and libata works around by always issuing hardreset if the host supports PMP. Like the above example, libata has developed a number of mechanisms aiming to promote softreset to hardreset if softreset is not going to work. This approach is time consuming and error prone. Also, note that, dependingon how you read the specs, it could be argued that PMP fan-out ports require COMRESET to start operation. In fact, all the PMPs on the market except one don't work properly if COMRESET is not issued to fan-out ports after PMP reset. * COMRESET is an integral part of SATA connection and any working device should be able to handle COMRESET properly. After all, it's the way to signal hardreset during reboot. This is the most used and recommended (at least by the ahci spec) method of resetting devices. So, this patch makes libata prefer hardreset over softreset by making the following changes. * Rename ATA_EH_RESET_MASK to ATA_EH_RESET and use it whereever ATA_EH_{SOFT|HARD}RESET used to be used. ATA_EH_{SOFT|HARD}RESET is now only used to tell prereset whether soft or hard reset will be issued. * Strip out now unneeded promote-to-hardreset logics from ata_eh_reset(), ata_std_prereset(), sata_pmp_std_prereset() and other places. Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'drivers/ata/libata-eh.c')
-rw-r--r--drivers/ata/libata-eh.c99
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),