diff options
author | Bryan O'Sullivan <bos@pathscale.com> | 2006-09-28 12:00:18 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2006-09-28 14:17:03 -0400 |
commit | 89d1e09b6a6d844ef327937f41658a426be42501 (patch) | |
tree | 5730241c737baf67b0b1ddf89ff38f6936d649c4 /drivers/infiniband/hw/ipath/ipath_iba6120.c | |
parent | 510847750c9d26052a71631e0fcad9e7f7a5f369 (diff) |
IB/ipath: Fix and recover TXE piobuf and PBC parity errors
We can sometimes trigger parity errors due to processor speculative
reads to our write-combined memory (mostly seen on Woodcrest). Add a
stats counter for these.
Factored out the sendbuffererror buffer cancellation code so it can be
used in the new handling; suppress likely subsequent error messages if
within two jiffies of the cancellation.
Also restore 2 dropped TXE lines on hwe_bitsextant noticed while
debugging.
Signed-off-by: Bryan O'Sullivan <bryan.osullivan@qlogic.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_iba6120.c')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_iba6120.c | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c index 08a44dd9ed6f..024b6aa320f1 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba6120.c +++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c | |||
@@ -370,7 +370,10 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg, | |||
370 | * make sure we get this much out, unless told to be quiet, | 370 | * make sure we get this much out, unless told to be quiet, |
371 | * or it's occurred within the last 5 seconds | 371 | * or it's occurred within the last 5 seconds |
372 | */ | 372 | */ |
373 | if ((hwerrs & ~dd->ipath_lasthwerror) || | 373 | if ((hwerrs & ~(dd->ipath_lasthwerror | |
374 | ((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF | | ||
375 | INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC) | ||
376 | << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT))) || | ||
374 | (ipath_debug & __IPATH_VERBDBG)) | 377 | (ipath_debug & __IPATH_VERBDBG)) |
375 | dev_info(&dd->pcidev->dev, "Hardware error: hwerr=0x%llx " | 378 | dev_info(&dd->pcidev->dev, "Hardware error: hwerr=0x%llx " |
376 | "(cleared)\n", (unsigned long long) hwerrs); | 379 | "(cleared)\n", (unsigned long long) hwerrs); |
@@ -383,6 +386,33 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg, | |||
383 | 386 | ||
384 | ctrl = ipath_read_kreg32(dd, dd->ipath_kregs->kr_control); | 387 | ctrl = ipath_read_kreg32(dd, dd->ipath_kregs->kr_control); |
385 | if (ctrl & INFINIPATH_C_FREEZEMODE) { | 388 | if (ctrl & INFINIPATH_C_FREEZEMODE) { |
389 | /* | ||
390 | * parity errors in send memory are recoverable, | ||
391 | * just cancel the send (if indicated in * sendbuffererror), | ||
392 | * count the occurrence, unfreeze (if no other handled | ||
393 | * hardware error bits are set), and continue. They can | ||
394 | * occur if a processor speculative read is done to the PIO | ||
395 | * buffer while we are sending a packet, for example. | ||
396 | */ | ||
397 | if (hwerrs & ((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF | | ||
398 | INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC) | ||
399 | << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT)) { | ||
400 | ipath_stats.sps_txeparity++; | ||
401 | ipath_dbg("Recovering from TXE parity error (%llu), " | ||
402 | "hwerrstatus=%llx\n", | ||
403 | (unsigned long long) ipath_stats.sps_txeparity, | ||
404 | (unsigned long long) hwerrs); | ||
405 | ipath_disarm_senderrbufs(dd); | ||
406 | hwerrs &= ~((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF | | ||
407 | INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC) | ||
408 | << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT); | ||
409 | if (!hwerrs) { /* else leave in freeze mode */ | ||
410 | ipath_write_kreg(dd, | ||
411 | dd->ipath_kregs->kr_control, | ||
412 | dd->ipath_control); | ||
413 | return; | ||
414 | } | ||
415 | } | ||
386 | if (hwerrs) { | 416 | if (hwerrs) { |
387 | /* | 417 | /* |
388 | * if any set that we aren't ignoring only make the | 418 | * if any set that we aren't ignoring only make the |
@@ -406,9 +436,8 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg, | |||
406 | } else { | 436 | } else { |
407 | ipath_dbg("Clearing freezemode on ignored hardware " | 437 | ipath_dbg("Clearing freezemode on ignored hardware " |
408 | "error\n"); | 438 | "error\n"); |
409 | ctrl &= ~INFINIPATH_C_FREEZEMODE; | ||
410 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, | 439 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, |
411 | ctrl); | 440 | dd->ipath_control); |
412 | } | 441 | } |
413 | } | 442 | } |
414 | 443 | ||
@@ -880,6 +909,8 @@ static void ipath_init_pe_variables(struct ipath_devdata *dd) | |||
880 | dd->ipath_hwe_bitsextant = | 909 | dd->ipath_hwe_bitsextant = |
881 | (INFINIPATH_HWE_RXEMEMPARITYERR_MASK << | 910 | (INFINIPATH_HWE_RXEMEMPARITYERR_MASK << |
882 | INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT) | | 911 | INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT) | |
912 | (INFINIPATH_HWE_TXEMEMPARITYERR_MASK << | ||
913 | INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) | | ||
883 | (INFINIPATH_HWE_PCIEMEMPARITYERR_MASK << | 914 | (INFINIPATH_HWE_PCIEMEMPARITYERR_MASK << |
884 | INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT) | | 915 | INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT) | |
885 | INFINIPATH_HWE_PCIE1PLLFAILED | | 916 | INFINIPATH_HWE_PCIE1PLLFAILED | |