PERFORCE change 169356 for review
Alexander Motin
mav at FreeBSD.org
Sat Oct 10 11:01:06 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=169356
Change 169356 by mav at mav_mavtest on 2009/10/10 11:00:11
Detect more fatal SATA errors. AMD AHCI controllers may not report
SATA protocol errors as fatal, requiring recovery,
causing timeout on next command.
Affected files ...
.. //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.c#64 edit
Differences ...
==== //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.c#64 (text+ko) ====
@@ -866,15 +866,11 @@
}
static void
-ahci_phy_check_events(device_t dev)
+ahci_phy_check_events(device_t dev, u_int32_t serr)
{
struct ahci_channel *ch = device_get_softc(dev);
- u_int32_t error = ATA_INL(ch->r_mem, AHCI_P_SERR);
- /* Clear error bits/interrupt */
- ATA_OUTL(ch->r_mem, AHCI_P_SERR, error);
- /* If we have a connection event, deal with it */
- if ((error & ATA_SE_PHY_CHANGED) && (ch->pm_level == 0)) {
+ if ((serr & ATA_SE_PHY_CHANGED) && (ch->pm_level == 0)) {
u_int32_t status = ATA_INL(ch->r_mem, AHCI_P_SSTS);
if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) &&
((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) &&
@@ -944,7 +940,7 @@
{
device_t dev = (device_t)data;
struct ahci_channel *ch = device_get_softc(dev);
- uint32_t istatus, sstatus, cstatus, sntf = 0, ok, err;
+ uint32_t istatus, sstatus, cstatus, serr = 0, sntf = 0, ok, err;
enum ahci_err_type et;
int i, ccs, ncq_err = 0;
@@ -959,14 +955,20 @@
if ((istatus & AHCI_P_IX_SDB) && (ch->caps & AHCI_CAP_SSNTF))
sntf = ATA_INL(ch->r_mem, AHCI_P_SNTF);
/* Process PHY events */
- if (istatus & (AHCI_P_IX_PRC | AHCI_P_IX_PC))
- ahci_phy_check_events(dev);
+ if (istatus & (AHCI_P_IX_PC | AHCI_P_IX_PRC | AHCI_P_IX_OF |
+ AHCI_P_IX_IF | AHCI_P_IX_HBD | AHCI_P_IX_HBF | AHCI_P_IX_TFE)) {
+ serr = ATA_INL(ch->r_mem, AHCI_P_SERR);
+ if (serr) {
+ ATA_OUTL(ch->r_mem, AHCI_P_SERR, serr);
+ ahci_phy_check_events(dev, serr);
+ }
+ }
/* Process command errors */
- if (istatus & (AHCI_P_IX_IF | AHCI_P_IX_HBD | AHCI_P_IX_HBF |
- AHCI_P_IX_TFE | AHCI_P_IX_OF)) {
-//device_printf(dev, "%s ERROR is %08x cs %08x ss %08x rs %08x tfd %02x serr %08x\n",
-// __func__, istatus, cstatus, sstatus, ch->rslots, ATA_INL(ch->r_mem, AHCI_P_TFD),
-// ATA_INL(ch->r_mem, AHCI_P_SERR));
+ if (istatus & (AHCI_P_IX_OF | AHCI_P_IX_IF |
+ AHCI_P_IX_HBD | AHCI_P_IX_HBF | AHCI_P_IX_TFE)) {
+device_printf(dev, "%s ERROR is %08x cs %08x ss %08x rs %08x tfd %02x serr %08x\n",
+ __func__, istatus, cstatus, sstatus, ch->rslots, ATA_INL(ch->r_mem, AHCI_P_TFD),
+ serr);
ccs = (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_CCS_MASK)
>> AHCI_P_CMD_CCS_SHIFT;
err = ch->rslots & (cstatus | sstatus);
@@ -997,7 +999,14 @@
/* XXX: reqests in loading state. */
if (((err >> i) & 1) == 0)
continue;
- if (istatus & AHCI_P_IX_TFE) {
+ if ((istatus & AHCI_P_IX_IF) ||
+ (serr & (ATA_SE_HOST_ERR | ATA_SE_PROT_ERR |
+ ATA_SE_COMM_ERR | ATA_SE_DATA_ERR))) {
+ if (ch->numtslots == 0 && i != ccs)
+ et = AHCI_ERR_INNOCENT;
+ else
+ et = AHCI_ERR_SATA;
+ } else if (istatus & AHCI_P_IX_TFE) {
/* Task File Error */
if (ch->numtslots == 0) {
/* Untagged operation. */
@@ -1010,9 +1019,6 @@
et = AHCI_ERR_NCQ;
ncq_err = 1;
}
- } else if (istatus & AHCI_P_IX_IF) {
- /* SATA error */
- et = AHCI_ERR_SATA;
} else
et = AHCI_ERR_INVALID;
ahci_end_transaction(&ch->slot[i], et);
@@ -1253,6 +1259,11 @@
return;
device_printf(dev, "Timeout on slot %d\n", slot->slot);
+device_printf(dev, "%s is %08x cs %08x ss %08x rs %08x tfd %02x serr %08x\n",
+ __func__, ATA_INL(ch->r_mem, AHCI_P_IS),
+ ATA_INL(ch->r_mem, AHCI_P_CI),
+ ATA_INL(ch->r_mem, AHCI_P_SACT), ch->rslots, ATA_INL(ch->r_mem, AHCI_P_TFD),
+ ATA_INL(ch->r_mem, AHCI_P_SERR));
/* Kick controller into sane state. */
ahci_stop(ch->dev);
ahci_start(ch->dev);
More information about the p4-projects
mailing list