diff options
Diffstat (limited to 'drivers/scsi/libata-eh.c')
-rw-r--r-- | drivers/scsi/libata-eh.c | 69 |
1 files changed, 44 insertions, 25 deletions
diff --git a/drivers/scsi/libata-eh.c b/drivers/scsi/libata-eh.c index b3095fd92863..2c34af99627d 100644 --- a/drivers/scsi/libata-eh.c +++ b/drivers/scsi/libata-eh.c | |||
@@ -763,12 +763,27 @@ static void ata_eh_about_to_do(struct ata_port *ap, struct ata_device *dev, | |||
763 | unsigned int action) | 763 | unsigned int action) |
764 | { | 764 | { |
765 | unsigned long flags; | 765 | unsigned long flags; |
766 | struct ata_eh_info *ehi = &ap->eh_info; | ||
767 | struct ata_eh_context *ehc = &ap->eh_context; | ||
766 | 768 | ||
767 | spin_lock_irqsave(ap->lock, flags); | 769 | spin_lock_irqsave(ap->lock, flags); |
768 | 770 | ||
769 | ata_eh_clear_action(dev, &ap->eh_info, action); | 771 | /* Reset is represented by combination of actions and EHI |
772 | * flags. Suck in all related bits before clearing eh_info to | ||
773 | * avoid losing requested action. | ||
774 | */ | ||
775 | if (action & ATA_EH_RESET_MASK) { | ||
776 | ehc->i.action |= ehi->action & ATA_EH_RESET_MASK; | ||
777 | ehc->i.flags |= ehi->flags & ATA_EHI_RESET_MODIFIER_MASK; | ||
778 | |||
779 | /* make sure all reset actions are cleared & clear EHI flags */ | ||
780 | action |= ATA_EH_RESET_MASK; | ||
781 | ehi->flags &= ~ATA_EHI_RESET_MODIFIER_MASK; | ||
782 | } | ||
783 | |||
784 | ata_eh_clear_action(dev, ehi, action); | ||
770 | 785 | ||
771 | if (!(ap->eh_context.i.flags & ATA_EHI_QUIET)) | 786 | if (!(ehc->i.flags & ATA_EHI_QUIET)) |
772 | ap->pflags |= ATA_PFLAG_RECOVERED; | 787 | ap->pflags |= ATA_PFLAG_RECOVERED; |
773 | 788 | ||
774 | spin_unlock_irqrestore(ap->lock, flags); | 789 | spin_unlock_irqrestore(ap->lock, flags); |
@@ -789,6 +804,12 @@ static void ata_eh_about_to_do(struct ata_port *ap, struct ata_device *dev, | |||
789 | static void ata_eh_done(struct ata_port *ap, struct ata_device *dev, | 804 | static void ata_eh_done(struct ata_port *ap, struct ata_device *dev, |
790 | unsigned int action) | 805 | unsigned int action) |
791 | { | 806 | { |
807 | /* if reset is complete, clear all reset actions & reset modifier */ | ||
808 | if (action & ATA_EH_RESET_MASK) { | ||
809 | action |= ATA_EH_RESET_MASK; | ||
810 | ap->eh_context.i.flags &= ~ATA_EHI_RESET_MODIFIER_MASK; | ||
811 | } | ||
812 | |||
792 | ata_eh_clear_action(dev, &ap->eh_context.i, action); | 813 | ata_eh_clear_action(dev, &ap->eh_context.i, action); |
793 | } | 814 | } |
794 | 815 | ||
@@ -1275,8 +1296,6 @@ static int ata_eh_speed_down(struct ata_device *dev, int is_io, | |||
1275 | static void ata_eh_autopsy(struct ata_port *ap) | 1296 | static void ata_eh_autopsy(struct ata_port *ap) |
1276 | { | 1297 | { |
1277 | struct ata_eh_context *ehc = &ap->eh_context; | 1298 | struct ata_eh_context *ehc = &ap->eh_context; |
1278 | unsigned int action = ehc->i.action; | ||
1279 | struct ata_device *failed_dev = NULL; | ||
1280 | unsigned int all_err_mask = 0; | 1299 | unsigned int all_err_mask = 0; |
1281 | int tag, is_io = 0; | 1300 | int tag, is_io = 0; |
1282 | u32 serror; | 1301 | u32 serror; |
@@ -1293,7 +1312,7 @@ static void ata_eh_autopsy(struct ata_port *ap) | |||
1293 | ehc->i.serror |= serror; | 1312 | ehc->i.serror |= serror; |
1294 | ata_eh_analyze_serror(ap); | 1313 | ata_eh_analyze_serror(ap); |
1295 | } else if (rc != -EOPNOTSUPP) | 1314 | } else if (rc != -EOPNOTSUPP) |
1296 | action |= ATA_EH_HARDRESET; | 1315 | ehc->i.action |= ATA_EH_HARDRESET; |
1297 | 1316 | ||
1298 | /* analyze NCQ failure */ | 1317 | /* analyze NCQ failure */ |
1299 | ata_eh_analyze_ncq_error(ap); | 1318 | ata_eh_analyze_ncq_error(ap); |
@@ -1314,7 +1333,7 @@ static void ata_eh_autopsy(struct ata_port *ap) | |||
1314 | qc->err_mask |= ehc->i.err_mask; | 1333 | qc->err_mask |= ehc->i.err_mask; |
1315 | 1334 | ||
1316 | /* analyze TF */ | 1335 | /* analyze TF */ |
1317 | action |= ata_eh_analyze_tf(qc, &qc->result_tf); | 1336 | ehc->i.action |= ata_eh_analyze_tf(qc, &qc->result_tf); |
1318 | 1337 | ||
1319 | /* DEV errors are probably spurious in case of ATA_BUS error */ | 1338 | /* DEV errors are probably spurious in case of ATA_BUS error */ |
1320 | if (qc->err_mask & AC_ERR_ATA_BUS) | 1339 | if (qc->err_mask & AC_ERR_ATA_BUS) |
@@ -1328,11 +1347,11 @@ static void ata_eh_autopsy(struct ata_port *ap) | |||
1328 | /* SENSE_VALID trumps dev/unknown error and revalidation */ | 1347 | /* SENSE_VALID trumps dev/unknown error and revalidation */ |
1329 | if (qc->flags & ATA_QCFLAG_SENSE_VALID) { | 1348 | if (qc->flags & ATA_QCFLAG_SENSE_VALID) { |
1330 | qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER); | 1349 | qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER); |
1331 | action &= ~ATA_EH_REVALIDATE; | 1350 | ehc->i.action &= ~ATA_EH_REVALIDATE; |
1332 | } | 1351 | } |
1333 | 1352 | ||
1334 | /* accumulate error info */ | 1353 | /* accumulate error info */ |
1335 | failed_dev = qc->dev; | 1354 | ehc->i.dev = qc->dev; |
1336 | all_err_mask |= qc->err_mask; | 1355 | all_err_mask |= qc->err_mask; |
1337 | if (qc->flags & ATA_QCFLAG_IO) | 1356 | if (qc->flags & ATA_QCFLAG_IO) |
1338 | is_io = 1; | 1357 | is_io = 1; |
@@ -1341,25 +1360,22 @@ static void ata_eh_autopsy(struct ata_port *ap) | |||
1341 | /* enforce default EH actions */ | 1360 | /* enforce default EH actions */ |
1342 | if (ap->pflags & ATA_PFLAG_FROZEN || | 1361 | if (ap->pflags & ATA_PFLAG_FROZEN || |
1343 | all_err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT)) | 1362 | all_err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT)) |
1344 | action |= ATA_EH_SOFTRESET; | 1363 | ehc->i.action |= ATA_EH_SOFTRESET; |
1345 | else if (all_err_mask) | 1364 | else if (all_err_mask) |
1346 | action |= ATA_EH_REVALIDATE; | 1365 | ehc->i.action |= ATA_EH_REVALIDATE; |
1347 | 1366 | ||
1348 | /* if we have offending qcs and the associated failed device */ | 1367 | /* if we have offending qcs and the associated failed device */ |
1349 | if (failed_dev) { | 1368 | if (ehc->i.dev) { |
1350 | /* speed down */ | 1369 | /* speed down */ |
1351 | action |= ata_eh_speed_down(failed_dev, is_io, all_err_mask); | 1370 | ehc->i.action |= ata_eh_speed_down(ehc->i.dev, is_io, |
1371 | all_err_mask); | ||
1352 | 1372 | ||
1353 | /* perform per-dev EH action only on the offending device */ | 1373 | /* perform per-dev EH action only on the offending device */ |
1354 | ehc->i.dev_action[failed_dev->devno] |= | 1374 | ehc->i.dev_action[ehc->i.dev->devno] |= |
1355 | action & ATA_EH_PERDEV_MASK; | 1375 | ehc->i.action & ATA_EH_PERDEV_MASK; |
1356 | action &= ~ATA_EH_PERDEV_MASK; | 1376 | ehc->i.action &= ~ATA_EH_PERDEV_MASK; |
1357 | } | 1377 | } |
1358 | 1378 | ||
1359 | /* record autopsy result */ | ||
1360 | ehc->i.dev = failed_dev; | ||
1361 | ehc->i.action |= action; | ||
1362 | |||
1363 | DPRINTK("EXIT\n"); | 1379 | DPRINTK("EXIT\n"); |
1364 | } | 1380 | } |
1365 | 1381 | ||
@@ -1482,6 +1498,9 @@ static int ata_eh_reset(struct ata_port *ap, int classify, | |||
1482 | ata_reset_fn_t reset; | 1498 | ata_reset_fn_t reset; |
1483 | int i, did_followup_srst, rc; | 1499 | int i, did_followup_srst, rc; |
1484 | 1500 | ||
1501 | /* about to reset */ | ||
1502 | ata_eh_about_to_do(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK); | ||
1503 | |||
1485 | /* Determine which reset to use and record in ehc->i.action. | 1504 | /* Determine which reset to use and record in ehc->i.action. |
1486 | * prereset() may examine and modify it. | 1505 | * prereset() may examine and modify it. |
1487 | */ | 1506 | */ |
@@ -1530,8 +1549,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, | |||
1530 | ata_port_printk(ap, KERN_INFO, "%s resetting port\n", | 1549 | ata_port_printk(ap, KERN_INFO, "%s resetting port\n", |
1531 | reset == softreset ? "soft" : "hard"); | 1550 | reset == softreset ? "soft" : "hard"); |
1532 | 1551 | ||
1533 | /* reset */ | 1552 | /* mark that this EH session started with reset */ |
1534 | ata_eh_about_to_do(ap, NULL, ATA_EH_RESET_MASK); | ||
1535 | ehc->i.flags |= ATA_EHI_DID_RESET; | 1553 | ehc->i.flags |= ATA_EHI_DID_RESET; |
1536 | 1554 | ||
1537 | rc = ata_do_reset(ap, reset, classes); | 1555 | rc = ata_do_reset(ap, reset, classes); |
@@ -1594,7 +1612,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, | |||
1594 | postreset(ap, classes); | 1612 | postreset(ap, classes); |
1595 | 1613 | ||
1596 | /* reset successful, schedule revalidation */ | 1614 | /* reset successful, schedule revalidation */ |
1597 | ata_eh_done(ap, NULL, ATA_EH_RESET_MASK); | 1615 | ata_eh_done(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK); |
1598 | ehc->i.action |= ATA_EH_REVALIDATE; | 1616 | ehc->i.action |= ATA_EH_REVALIDATE; |
1599 | } | 1617 | } |
1600 | 1618 | ||
@@ -1847,15 +1865,16 @@ static int ata_eh_skip_recovery(struct ata_port *ap) | |||
1847 | for (i = 0; i < ata_port_max_devices(ap); i++) { | 1865 | for (i = 0; i < ata_port_max_devices(ap); i++) { |
1848 | struct ata_device *dev = &ap->device[i]; | 1866 | struct ata_device *dev = &ap->device[i]; |
1849 | 1867 | ||
1850 | if (ata_dev_absent(dev) || ata_dev_ready(dev)) | 1868 | if (!(dev->flags & ATA_DFLAG_SUSPENDED)) |
1851 | break; | 1869 | break; |
1852 | } | 1870 | } |
1853 | 1871 | ||
1854 | if (i == ata_port_max_devices(ap)) | 1872 | if (i == ata_port_max_devices(ap)) |
1855 | return 1; | 1873 | return 1; |
1856 | 1874 | ||
1857 | /* always thaw frozen port and recover failed devices */ | 1875 | /* thaw frozen port, resume link and recover failed devices */ |
1858 | if (ap->pflags & ATA_PFLAG_FROZEN || ata_port_nr_enabled(ap)) | 1876 | if ((ap->pflags & ATA_PFLAG_FROZEN) || |
1877 | (ehc->i.flags & ATA_EHI_RESUME_LINK) || ata_port_nr_enabled(ap)) | ||
1859 | return 0; | 1878 | return 0; |
1860 | 1879 | ||
1861 | /* skip if class codes for all vacant slots are ATA_DEV_NONE */ | 1880 | /* skip if class codes for all vacant slots are ATA_DEV_NONE */ |