Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 59311
b: refs/heads/master
c: 9380068
h: refs/heads/master
i:
  59309: a5d1c61
  59307: 4a1b8e9
  59303: 18a335a
  59295: 69c1fac
v: v3
  • Loading branch information
Dave Olson authored and Roland Dreier committed Jul 10, 2007
1 parent 527226b commit fe45b18
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 39 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 561095f20eeb5c6c05c303bad8cdb3f8a80821bc
refs/heads/master: 9380068fc2f230e7840ff87d3f1e6030ae2ee5e8
57 changes: 36 additions & 21 deletions trunk/drivers/infiniband/hw/ipath/ipath_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -706,9 +706,9 @@ void ipath_disarm_piobufs(struct ipath_devdata *dd, unsigned first,
u64 sendctrl, sendorig;

ipath_cdbg(PKT, "disarm %u PIObufs first=%u\n", cnt, first);
sendorig = dd->ipath_sendctrl | INFINIPATH_S_DISARM;
sendorig = dd->ipath_sendctrl;
for (i = first; i < last; i++) {
sendctrl = sendorig |
sendctrl = sendorig | INFINIPATH_S_DISARM |
(i << INFINIPATH_S_DISARMPIOBUF_SHIFT);
ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
sendctrl);
Expand All @@ -719,12 +719,12 @@ void ipath_disarm_piobufs(struct ipath_devdata *dd, unsigned first,
* while we were looping; no critical bits that would require
* locking.
*
* Write a 0, and then the original value, reading scratch in
* disable PIOAVAILUPD, then re-enable, reading scratch in
* between. This seems to avoid a chip timing race that causes
* pioavail updates to memory to stop.
*/
ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
0);
sendorig & ~IPATH_S_PIOBUFAVAILUPD);
sendorig = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
dd->ipath_sendctrl);
Expand Down Expand Up @@ -1596,6 +1596,35 @@ int ipath_waitfor_mdio_cmdready(struct ipath_devdata *dd)
return ret;
}


/*
* Flush all sends that might be in the ready to send state, as well as any
* that are in the process of being sent. Used whenever we need to be
* sure the send side is idle. Cleans up all buffer state by canceling
* all pio buffers, and issuing an abort, which cleans up anything in the
* launch fifo. The cancel is superfluous on some chip versions, but
* it's safer to always do it.
* PIOAvail bits are updated by the chip as if normal send had happened.
*/
void ipath_cancel_sends(struct ipath_devdata *dd)
{
ipath_dbg("Cancelling all in-progress send buffers\n");
dd->ipath_lastcancel = jiffies+HZ/2; /* skip armlaunch errs a bit */
/*
* the abort bit is auto-clearing. We read scratch to be sure
* that cancels and the abort have taken effect in the chip.
*/
ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
INFINIPATH_S_ABORT);
ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
ipath_disarm_piobufs(dd, 0,
(unsigned)(dd->ipath_piobcnt2k + dd->ipath_piobcnt4k));

/* and again, be sure all have hit the chip */
ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
}


static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which)
{
static const char *what[4] = {
Expand All @@ -1617,14 +1646,8 @@ static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which)
INFINIPATH_IBCS_LINKTRAININGSTATE_MASK]);
/* flush all queued sends when going to DOWN or INIT, to be sure that
* they don't block MAD packets */
if (!linkcmd || linkcmd == INFINIPATH_IBCC_LINKCMD_INIT) {
ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
INFINIPATH_S_ABORT);
ipath_disarm_piobufs(dd, dd->ipath_lastport_piobuf,
(unsigned)(dd->ipath_piobcnt2k +
dd->ipath_piobcnt4k) -
dd->ipath_lastport_piobuf);
}
if (!linkcmd || linkcmd == INFINIPATH_IBCC_LINKCMD_INIT)
ipath_cancel_sends(dd);

ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl,
dd->ipath_ibcctrl | which);
Expand Down Expand Up @@ -1967,17 +1990,9 @@ void ipath_shutdown_device(struct ipath_devdata *dd)
*/
udelay(5);

/*
* abort any armed or launched PIO buffers that didn't go. (self
* clearing). Will cause any packet currently being transmitted to
* go out with an EBP, and may also cause a short packet error on
* the receiver.
*/
ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
INFINIPATH_S_ABORT);

ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_DISABLE <<
INFINIPATH_IBCC_LINKINITCMD_SHIFT);
ipath_cancel_sends(dd);

/* disable IBC */
dd->ipath_control &= ~INFINIPATH_C_LINKENABLE;
Expand Down
13 changes: 7 additions & 6 deletions trunk/drivers/infiniband/hw/ipath/ipath_iba6110.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,13 @@ static void ipath_ht_handle_hwerrors(struct ipath_devdata *dd, char *msg,
if (!hwerrs) {
ipath_dbg("Clearing freezemode on ignored or "
"recovered hardware error\n");
/*
* clear all sends, becauase they have may been
* completed by usercode while in freeze mode, and
* therefore would not be sent, and eventually
* might cause the process to run out of bufs
*/
ipath_cancel_sends(dd);
ctrl &= ~INFINIPATH_C_FREEZEMODE;
ipath_write_kreg(dd, dd->ipath_kregs->kr_control,
ctrl);
Expand Down Expand Up @@ -1566,11 +1573,6 @@ static int ipath_ht_early_init(struct ipath_devdata *dd)
writel(16, piobuf);
piobuf += pioincr;
}
/*
* self-clearing
*/
ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
INFINIPATH_S_ABORT);

ipath_get_eeprom_info(dd);
if (dd->ipath_boardrev == 5 && dd->ipath_serial[0] == '1' &&
Expand Down Expand Up @@ -1599,7 +1601,6 @@ static int ipath_ht_txe_recover(struct ipath_devdata *dd)
}
dev_info(&dd->pcidev->dev,
"Recovering from TXE PIO parity error\n");
ipath_disarm_senderrbufs(dd, 1);
return 1;
}

Expand Down
16 changes: 13 additions & 3 deletions trunk/drivers/infiniband/hw/ipath/ipath_iba6120.c
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,19 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
*dd->ipath_statusp |= IPATH_STATUS_HWERROR;
dd->ipath_flags &= ~IPATH_INITTED;
} else {
ipath_dbg("Clearing freezemode on ignored hardware "
"error\n");
static u32 freeze_cnt;

freeze_cnt++;
ipath_dbg("Clearing freezemode on ignored or recovered "
"hardware error (%u)\n", freeze_cnt);
/*
* clear all sends, becauase they have may been
* completed by usercode while in freeze mode, and
* therefore would not be sent, and eventually
* might cause the process to run out of bufs
*/
ipath_cancel_sends(dd);
ctrl &= ~INFINIPATH_C_FREEZEMODE;
ipath_write_kreg(dd, dd->ipath_kregs->kr_control,
dd->ipath_control);
}
Expand Down Expand Up @@ -1371,7 +1382,6 @@ static int ipath_pe_txe_recover(struct ipath_devdata *dd)
dev_info(&dd->pcidev->dev,
"Recovering from TXE PIO parity error\n");
}
ipath_disarm_senderrbufs(dd, 1);
return 1;
}

Expand Down
6 changes: 6 additions & 0 deletions trunk/drivers/infiniband/hw/ipath/ipath_init_chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,12 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
piobufs, dd->ipath_pbufsport, uports);

dd->ipath_f_early_init(dd);
/*
* cancel any possible active sends from early driver load.
* Follows early_init because some chips have to initialize
* PIO buffers in early_init to avoid false parity errors.
*/
ipath_cancel_sends(dd);

/* early_init sets rcvhdrentsize and rcvhdrsize, so this must be
* done after early_init */
Expand Down
13 changes: 5 additions & 8 deletions trunk/drivers/infiniband/hw/ipath/ipath_intr.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ void ipath_disarm_senderrbufs(struct ipath_devdata *dd, int rewrite)

if (sbuf[0] || sbuf[1] || (piobcnt > 128 && (sbuf[2] || sbuf[3]))) {
int i;
if (ipath_debug & (__IPATH_PKTDBG|__IPATH_DBG)) {
if (ipath_debug & (__IPATH_PKTDBG|__IPATH_DBG) &&
dd->ipath_lastcancel > jiffies) {
__IPATH_DBG_WHICH(__IPATH_PKTDBG|__IPATH_DBG,
"SendbufErrs %lx %lx", sbuf[0],
sbuf[1]);
Expand All @@ -108,7 +109,8 @@ void ipath_disarm_senderrbufs(struct ipath_devdata *dd, int rewrite)
ipath_clrpiobuf(dd, i);
ipath_disarm_piobufs(dd, i, 1);
}
dd->ipath_lastcancel = jiffies+3; /* no armlaunch for a bit */
/* ignore armlaunch errs for a bit */
dd->ipath_lastcancel = jiffies+3;
}
}

Expand Down Expand Up @@ -290,12 +292,7 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd,
* Flush all queued sends when link went to DOWN or INIT,
* to be sure that they don't block SMA and other MAD packets
*/
ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
INFINIPATH_S_ABORT);
ipath_disarm_piobufs(dd, dd->ipath_lastport_piobuf,
(unsigned)(dd->ipath_piobcnt2k +
dd->ipath_piobcnt4k) -
dd->ipath_lastport_piobuf);
ipath_cancel_sends(dd);
}
else if (lstate == IPATH_IBSTATE_INIT || lstate == IPATH_IBSTATE_ARM ||
lstate == IPATH_IBSTATE_ACTIVE) {
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/infiniband/hw/ipath/ipath_kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,7 @@ int ipath_unordered_wc(void);

void ipath_disarm_piobufs(struct ipath_devdata *, unsigned first,
unsigned cnt);
void ipath_cancel_sends(struct ipath_devdata *);

int ipath_create_rcvhdrq(struct ipath_devdata *, struct ipath_portdata *);
void ipath_free_pddata(struct ipath_devdata *, struct ipath_portdata *);
Expand Down

0 comments on commit fe45b18

Please sign in to comment.