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