diff options
author | Bryan O'Sullivan <bos@pathscale.com> | 2007-03-15 17:45:07 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2007-04-18 23:20:58 -0400 |
commit | 9783ab405844202b452ac673677e6c8f8c9a6a99 (patch) | |
tree | 32aac9ac3ff1089a7ecb05c4ef0b825a95227694 /drivers/infiniband/hw/ipath/ipath_iba6120.c | |
parent | 820054b7ca7a54ba94d89db4b3c53a24d2d66633 (diff) |
IB/ipath: Improve handling and reporting of parity errors
Mostly cleanup.
Signed-off-by: Dave Olson <dave.olson@qlogic.com>
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 | 58 |
1 files changed, 39 insertions, 19 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c index 5c50383880f2..aa2b51944331 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba6120.c +++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c | |||
@@ -321,6 +321,12 @@ static const struct ipath_hwerror_msgs ipath_6120_hwerror_msgs[] = { | |||
321 | INFINIPATH_HWE_MSG(SERDESPLLFAILED, "SerDes PLL"), | 321 | INFINIPATH_HWE_MSG(SERDESPLLFAILED, "SerDes PLL"), |
322 | }; | 322 | }; |
323 | 323 | ||
324 | #define TXE_PIO_PARITY ((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF | \ | ||
325 | INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC) \ | ||
326 | << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) | ||
327 | |||
328 | static int ipath_pe_txe_recover(struct ipath_devdata *); | ||
329 | |||
324 | /** | 330 | /** |
325 | * ipath_pe_handle_hwerrors - display hardware errors. | 331 | * ipath_pe_handle_hwerrors - display hardware errors. |
326 | * @dd: the infinipath device | 332 | * @dd: the infinipath device |
@@ -394,25 +400,8 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg, | |||
394 | * occur if a processor speculative read is done to the PIO | 400 | * occur if a processor speculative read is done to the PIO |
395 | * buffer while we are sending a packet, for example. | 401 | * buffer while we are sending a packet, for example. |
396 | */ | 402 | */ |
397 | if (hwerrs & ((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF | | 403 | if ((hwerrs & TXE_PIO_PARITY) && ipath_pe_txe_recover(dd)) |
398 | INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC) | 404 | hwerrs &= ~TXE_PIO_PARITY; |
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 | } | ||
416 | if (hwerrs) { | 405 | if (hwerrs) { |
417 | /* | 406 | /* |
418 | * if any set that we aren't ignoring only make the | 407 | * if any set that we aren't ignoring only make the |
@@ -581,6 +570,8 @@ static void ipath_pe_init_hwerrors(struct ipath_devdata *dd) | |||
581 | 570 | ||
582 | if (!(extsval & INFINIPATH_EXTS_MEMBIST_ENDTEST)) | 571 | if (!(extsval & INFINIPATH_EXTS_MEMBIST_ENDTEST)) |
583 | ipath_dev_err(dd, "MemBIST did not complete!\n"); | 572 | ipath_dev_err(dd, "MemBIST did not complete!\n"); |
573 | if (extsval & INFINIPATH_EXTS_MEMBIST_FOUND) | ||
574 | ipath_dbg("MemBIST corrected\n"); | ||
584 | 575 | ||
585 | val = ~0ULL; /* barring bugs, all hwerrors become interrupts, */ | 576 | val = ~0ULL; /* barring bugs, all hwerrors become interrupts, */ |
586 | 577 | ||
@@ -1330,6 +1321,35 @@ static void ipath_pe_free_irq(struct ipath_devdata *dd) | |||
1330 | dd->ipath_irq = 0; | 1321 | dd->ipath_irq = 0; |
1331 | } | 1322 | } |
1332 | 1323 | ||
1324 | /* | ||
1325 | * On platforms using this chip, and not having ordered WC stores, we | ||
1326 | * can get TXE parity errors due to speculative reads to the PIO buffers, | ||
1327 | * and this, due to a chip bug can result in (many) false parity error | ||
1328 | * reports. So it's a debug print on those, and an info print on systems | ||
1329 | * where the speculative reads don't occur. | ||
1330 | * Because we can get lots of false errors, we have no upper limit | ||
1331 | * on recovery attempts on those platforms. | ||
1332 | */ | ||
1333 | static int ipath_pe_txe_recover(struct ipath_devdata *dd) | ||
1334 | { | ||
1335 | if (ipath_unordered_wc()) | ||
1336 | ipath_dbg("Recovering from TXE PIO parity error\n"); | ||
1337 | else { | ||
1338 | int cnt = ++ipath_stats.sps_txeparity; | ||
1339 | if (cnt >= IPATH_MAX_PARITY_ATTEMPTS) { | ||
1340 | if (cnt == IPATH_MAX_PARITY_ATTEMPTS) | ||
1341 | ipath_dev_err(dd, | ||
1342 | "Too many attempts to recover from " | ||
1343 | "TXE parity, giving up\n"); | ||
1344 | return 0; | ||
1345 | } | ||
1346 | dev_info(&dd->pcidev->dev, | ||
1347 | "Recovering from TXE PIO parity error\n"); | ||
1348 | } | ||
1349 | ipath_disarm_senderrbufs(dd, 1); | ||
1350 | return 1; | ||
1351 | } | ||
1352 | |||
1333 | /** | 1353 | /** |
1334 | * ipath_init_iba6120_funcs - set up the chip-specific function pointers | 1354 | * ipath_init_iba6120_funcs - set up the chip-specific function pointers |
1335 | * @dd: the infinipath device | 1355 | * @dd: the infinipath device |