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_intr.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_intr.c')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_intr.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c index 24853310df1c..45d033169c6e 100644 --- a/drivers/infiniband/hw/ipath/ipath_intr.c +++ b/drivers/infiniband/hw/ipath/ipath_intr.c | |||
@@ -38,10 +38,39 @@ | |||
38 | #include "ipath_common.h" | 38 | #include "ipath_common.h" |
39 | 39 | ||
40 | /* | 40 | /* |
41 | * clear (write) a pio buffer, to clear a parity error. This routine | ||
42 | * should only be called when in freeze mode, and the buffer should be | ||
43 | * canceled afterwards. | ||
44 | */ | ||
45 | static void ipath_clrpiobuf(struct ipath_devdata *dd, u32 pnum) | ||
46 | { | ||
47 | u32 __iomem *pbuf; | ||
48 | u32 dwcnt; /* dword count to write */ | ||
49 | if (pnum < dd->ipath_piobcnt2k) { | ||
50 | pbuf = (u32 __iomem *) (dd->ipath_pio2kbase + pnum * | ||
51 | dd->ipath_palign); | ||
52 | dwcnt = dd->ipath_piosize2k >> 2; | ||
53 | } | ||
54 | else { | ||
55 | pbuf = (u32 __iomem *) (dd->ipath_pio4kbase + | ||
56 | (pnum - dd->ipath_piobcnt2k) * dd->ipath_4kalign); | ||
57 | dwcnt = dd->ipath_piosize4k >> 2; | ||
58 | } | ||
59 | dev_info(&dd->pcidev->dev, | ||
60 | "Rewrite PIO buffer %u, to recover from parity error\n", | ||
61 | pnum); | ||
62 | *pbuf = dwcnt+1; /* no flush required, since already in freeze */ | ||
63 | while(--dwcnt) | ||
64 | *pbuf++ = 0; | ||
65 | } | ||
66 | |||
67 | /* | ||
41 | * Called when we might have an error that is specific to a particular | 68 | * Called when we might have an error that is specific to a particular |
42 | * PIO buffer, and may need to cancel that buffer, so it can be re-used. | 69 | * PIO buffer, and may need to cancel that buffer, so it can be re-used. |
70 | * If rewrite is true, and bits are set in the sendbufferror registers, | ||
71 | * we'll write to the buffer, for error recovery on parity errors. | ||
43 | */ | 72 | */ |
44 | void ipath_disarm_senderrbufs(struct ipath_devdata *dd) | 73 | void ipath_disarm_senderrbufs(struct ipath_devdata *dd, int rewrite) |
45 | { | 74 | { |
46 | u32 piobcnt; | 75 | u32 piobcnt; |
47 | unsigned long sbuf[4]; | 76 | unsigned long sbuf[4]; |
@@ -74,8 +103,11 @@ void ipath_disarm_senderrbufs(struct ipath_devdata *dd) | |||
74 | } | 103 | } |
75 | 104 | ||
76 | for (i = 0; i < piobcnt; i++) | 105 | for (i = 0; i < piobcnt; i++) |
77 | if (test_bit(i, sbuf)) | 106 | if (test_bit(i, sbuf)) { |
107 | if (rewrite) | ||
108 | ipath_clrpiobuf(dd, i); | ||
78 | ipath_disarm_piobufs(dd, i, 1); | 109 | ipath_disarm_piobufs(dd, i, 1); |
110 | } | ||
79 | dd->ipath_lastcancel = jiffies+3; /* no armlaunch for a bit */ | 111 | dd->ipath_lastcancel = jiffies+3; /* no armlaunch for a bit */ |
80 | } | 112 | } |
81 | } | 113 | } |
@@ -114,7 +146,7 @@ static u64 handle_e_sum_errs(struct ipath_devdata *dd, ipath_err_t errs) | |||
114 | { | 146 | { |
115 | u64 ignore_this_time = 0; | 147 | u64 ignore_this_time = 0; |
116 | 148 | ||
117 | ipath_disarm_senderrbufs(dd); | 149 | ipath_disarm_senderrbufs(dd, 0); |
118 | if ((errs & E_SUM_LINK_PKTERRS) && | 150 | if ((errs & E_SUM_LINK_PKTERRS) && |
119 | !(dd->ipath_flags & IPATH_LINKACTIVE)) { | 151 | !(dd->ipath_flags & IPATH_LINKACTIVE)) { |
120 | /* | 152 | /* |