aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ipath
diff options
context:
space:
mode:
authorDave Olson <dave.olson@qlogic.com>2007-06-18 17:24:41 -0400
committerRoland Dreier <rolandd@cisco.com>2007-07-09 23:12:26 -0400
commit9380068fc2f230e7840ff87d3f1e6030ae2ee5e8 (patch)
tree693349ae9f8dc25156091f7834030b35e01f23e1 /drivers/infiniband/hw/ipath
parent561095f20eeb5c6c05c303bad8cdb3f8a80821bc (diff)
IB/ipath: Use S_ABORT not cancel and abort on exit freeze mode after recovery
This centralizes the use of the abort functionality, removes the unneeded buffer cancel (abort does the same thing), sets up to ignore launch errors after abort, same as cancel. We need abort on exit from freeze mode to avoid having buffers stuck in the busy state, if a user process happened to complete the send while we were in freeze mode doing the recovery. Signed-off-by: Dave Olson <dave.olson@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/ipath')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c57
-rw-r--r--drivers/infiniband/hw/ipath/ipath_iba6110.c13
-rw-r--r--drivers/infiniband/hw/ipath/ipath_iba6120.c16
-rw-r--r--drivers/infiniband/hw/ipath/ipath_init_chip.c6
-rw-r--r--drivers/infiniband/hw/ipath/ipath_intr.c13
-rw-r--r--drivers/infiniband/hw/ipath/ipath_kernel.h1
6 files changed, 68 insertions, 38 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index e9639860b48d..8b611796f33e 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -706,9 +706,9 @@ void ipath_disarm_piobufs(struct ipath_devdata *dd, unsigned first,
706 u64 sendctrl, sendorig; 706 u64 sendctrl, sendorig;
707 707
708 ipath_cdbg(PKT, "disarm %u PIObufs first=%u\n", cnt, first); 708 ipath_cdbg(PKT, "disarm %u PIObufs first=%u\n", cnt, first);
709 sendorig = dd->ipath_sendctrl | INFINIPATH_S_DISARM; 709 sendorig = dd->ipath_sendctrl;
710 for (i = first; i < last; i++) { 710 for (i = first; i < last; i++) {
711 sendctrl = sendorig | 711 sendctrl = sendorig | INFINIPATH_S_DISARM |
712 (i << INFINIPATH_S_DISARMPIOBUF_SHIFT); 712 (i << INFINIPATH_S_DISARMPIOBUF_SHIFT);
713 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 713 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
714 sendctrl); 714 sendctrl);
@@ -719,12 +719,12 @@ void ipath_disarm_piobufs(struct ipath_devdata *dd, unsigned first,
719 * while we were looping; no critical bits that would require 719 * while we were looping; no critical bits that would require
720 * locking. 720 * locking.
721 * 721 *
722 * Write a 0, and then the original value, reading scratch in 722 * disable PIOAVAILUPD, then re-enable, reading scratch in
723 * between. This seems to avoid a chip timing race that causes 723 * between. This seems to avoid a chip timing race that causes
724 * pioavail updates to memory to stop. 724 * pioavail updates to memory to stop.
725 */ 725 */
726 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 726 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
727 0); 727 sendorig & ~IPATH_S_PIOBUFAVAILUPD);
728 sendorig = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); 728 sendorig = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
729 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 729 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
730 dd->ipath_sendctrl); 730 dd->ipath_sendctrl);
@@ -1596,6 +1596,35 @@ int ipath_waitfor_mdio_cmdready(struct ipath_devdata *dd)
1596 return ret; 1596 return ret;
1597} 1597}
1598 1598
1599
1600/*
1601 * Flush all sends that might be in the ready to send state, as well as any
1602 * that are in the process of being sent. Used whenever we need to be
1603 * sure the send side is idle. Cleans up all buffer state by canceling
1604 * all pio buffers, and issuing an abort, which cleans up anything in the
1605 * launch fifo. The cancel is superfluous on some chip versions, but
1606 * it's safer to always do it.
1607 * PIOAvail bits are updated by the chip as if normal send had happened.
1608 */
1609void ipath_cancel_sends(struct ipath_devdata *dd)
1610{
1611 ipath_dbg("Cancelling all in-progress send buffers\n");
1612 dd->ipath_lastcancel = jiffies+HZ/2; /* skip armlaunch errs a bit */
1613 /*
1614 * the abort bit is auto-clearing. We read scratch to be sure
1615 * that cancels and the abort have taken effect in the chip.
1616 */
1617 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
1618 INFINIPATH_S_ABORT);
1619 ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
1620 ipath_disarm_piobufs(dd, 0,
1621 (unsigned)(dd->ipath_piobcnt2k + dd->ipath_piobcnt4k));
1622
1623 /* and again, be sure all have hit the chip */
1624 ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
1625}
1626
1627
1599static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which) 1628static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which)
1600{ 1629{
1601 static const char *what[4] = { 1630 static const char *what[4] = {
@@ -1617,14 +1646,8 @@ static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which)
1617 INFINIPATH_IBCS_LINKTRAININGSTATE_MASK]); 1646 INFINIPATH_IBCS_LINKTRAININGSTATE_MASK]);
1618 /* flush all queued sends when going to DOWN or INIT, to be sure that 1647 /* flush all queued sends when going to DOWN or INIT, to be sure that
1619 * they don't block MAD packets */ 1648 * they don't block MAD packets */
1620 if (!linkcmd || linkcmd == INFINIPATH_IBCC_LINKCMD_INIT) { 1649 if (!linkcmd || linkcmd == INFINIPATH_IBCC_LINKCMD_INIT)
1621 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 1650 ipath_cancel_sends(dd);
1622 INFINIPATH_S_ABORT);
1623 ipath_disarm_piobufs(dd, dd->ipath_lastport_piobuf,
1624 (unsigned)(dd->ipath_piobcnt2k +
1625 dd->ipath_piobcnt4k) -
1626 dd->ipath_lastport_piobuf);
1627 }
1628 1651
1629 ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl, 1652 ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl,
1630 dd->ipath_ibcctrl | which); 1653 dd->ipath_ibcctrl | which);
@@ -1967,17 +1990,9 @@ void ipath_shutdown_device(struct ipath_devdata *dd)
1967 */ 1990 */
1968 udelay(5); 1991 udelay(5);
1969 1992
1970 /*
1971 * abort any armed or launched PIO buffers that didn't go. (self
1972 * clearing). Will cause any packet currently being transmitted to
1973 * go out with an EBP, and may also cause a short packet error on
1974 * the receiver.
1975 */
1976 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
1977 INFINIPATH_S_ABORT);
1978
1979 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_DISABLE << 1993 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_DISABLE <<
1980 INFINIPATH_IBCC_LINKINITCMD_SHIFT); 1994 INFINIPATH_IBCC_LINKINITCMD_SHIFT);
1995 ipath_cancel_sends(dd);
1981 1996
1982 /* disable IBC */ 1997 /* disable IBC */
1983 dd->ipath_control &= ~INFINIPATH_C_LINKENABLE; 1998 dd->ipath_control &= ~INFINIPATH_C_LINKENABLE;
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6110.c b/drivers/infiniband/hw/ipath/ipath_iba6110.c
index d8ac9f18bf49..34d159ad97b4 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba6110.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba6110.c
@@ -509,6 +509,13 @@ static void ipath_ht_handle_hwerrors(struct ipath_devdata *dd, char *msg,
509 if (!hwerrs) { 509 if (!hwerrs) {
510 ipath_dbg("Clearing freezemode on ignored or " 510 ipath_dbg("Clearing freezemode on ignored or "
511 "recovered hardware error\n"); 511 "recovered hardware error\n");
512 /*
513 * clear all sends, becauase they have may been
514 * completed by usercode while in freeze mode, and
515 * therefore would not be sent, and eventually
516 * might cause the process to run out of bufs
517 */
518 ipath_cancel_sends(dd);
512 ctrl &= ~INFINIPATH_C_FREEZEMODE; 519 ctrl &= ~INFINIPATH_C_FREEZEMODE;
513 ipath_write_kreg(dd, dd->ipath_kregs->kr_control, 520 ipath_write_kreg(dd, dd->ipath_kregs->kr_control,
514 ctrl); 521 ctrl);
@@ -1566,11 +1573,6 @@ static int ipath_ht_early_init(struct ipath_devdata *dd)
1566 writel(16, piobuf); 1573 writel(16, piobuf);
1567 piobuf += pioincr; 1574 piobuf += pioincr;
1568 } 1575 }
1569 /*
1570 * self-clearing
1571 */
1572 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
1573 INFINIPATH_S_ABORT);
1574 1576
1575 ipath_get_eeprom_info(dd); 1577 ipath_get_eeprom_info(dd);
1576 if (dd->ipath_boardrev == 5 && dd->ipath_serial[0] == '1' && 1578 if (dd->ipath_boardrev == 5 && dd->ipath_serial[0] == '1' &&
@@ -1599,7 +1601,6 @@ static int ipath_ht_txe_recover(struct ipath_devdata *dd)
1599 } 1601 }
1600 dev_info(&dd->pcidev->dev, 1602 dev_info(&dd->pcidev->dev,
1601 "Recovering from TXE PIO parity error\n"); 1603 "Recovering from TXE PIO parity error\n");
1602 ipath_disarm_senderrbufs(dd, 1);
1603 return 1; 1604 return 1;
1604} 1605}
1605 1606
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c
index b931057bb3e8..0c34555d4979 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba6120.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c
@@ -430,8 +430,19 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
430 *dd->ipath_statusp |= IPATH_STATUS_HWERROR; 430 *dd->ipath_statusp |= IPATH_STATUS_HWERROR;
431 dd->ipath_flags &= ~IPATH_INITTED; 431 dd->ipath_flags &= ~IPATH_INITTED;
432 } else { 432 } else {
433 ipath_dbg("Clearing freezemode on ignored hardware " 433 static u32 freeze_cnt;
434 "error\n"); 434
435 freeze_cnt++;
436 ipath_dbg("Clearing freezemode on ignored or recovered "
437 "hardware error (%u)\n", freeze_cnt);
438 /*
439 * clear all sends, becauase they have may been
440 * completed by usercode while in freeze mode, and
441 * therefore would not be sent, and eventually
442 * might cause the process to run out of bufs
443 */
444 ipath_cancel_sends(dd);
445 ctrl &= ~INFINIPATH_C_FREEZEMODE;
435 ipath_write_kreg(dd, dd->ipath_kregs->kr_control, 446 ipath_write_kreg(dd, dd->ipath_kregs->kr_control,
436 dd->ipath_control); 447 dd->ipath_control);
437 } 448 }
@@ -1371,7 +1382,6 @@ static int ipath_pe_txe_recover(struct ipath_devdata *dd)
1371 dev_info(&dd->pcidev->dev, 1382 dev_info(&dd->pcidev->dev,
1372 "Recovering from TXE PIO parity error\n"); 1383 "Recovering from TXE PIO parity error\n");
1373 } 1384 }
1374 ipath_disarm_senderrbufs(dd, 1);
1375 return 1; 1385 return 1;
1376} 1386}
1377 1387
diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c
index 9f611553ffb3..5193d6945caa 100644
--- a/drivers/infiniband/hw/ipath/ipath_init_chip.c
+++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c
@@ -777,6 +777,12 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
777 piobufs, dd->ipath_pbufsport, uports); 777 piobufs, dd->ipath_pbufsport, uports);
778 778
779 dd->ipath_f_early_init(dd); 779 dd->ipath_f_early_init(dd);
780 /*
781 * cancel any possible active sends from early driver load.
782 * Follows early_init because some chips have to initialize
783 * PIO buffers in early_init to avoid false parity errors.
784 */
785 ipath_cancel_sends(dd);
780 786
781 /* early_init sets rcvhdrentsize and rcvhdrsize, so this must be 787 /* early_init sets rcvhdrentsize and rcvhdrsize, so this must be
782 * done after early_init */ 788 * done after early_init */
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c
index d9cdd00c8233..948091f7d5ac 100644
--- a/drivers/infiniband/hw/ipath/ipath_intr.c
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c
@@ -93,7 +93,8 @@ void ipath_disarm_senderrbufs(struct ipath_devdata *dd, int rewrite)
93 93
94 if (sbuf[0] || sbuf[1] || (piobcnt > 128 && (sbuf[2] || sbuf[3]))) { 94 if (sbuf[0] || sbuf[1] || (piobcnt > 128 && (sbuf[2] || sbuf[3]))) {
95 int i; 95 int i;
96 if (ipath_debug & (__IPATH_PKTDBG|__IPATH_DBG)) { 96 if (ipath_debug & (__IPATH_PKTDBG|__IPATH_DBG) &&
97 dd->ipath_lastcancel > jiffies) {
97 __IPATH_DBG_WHICH(__IPATH_PKTDBG|__IPATH_DBG, 98 __IPATH_DBG_WHICH(__IPATH_PKTDBG|__IPATH_DBG,
98 "SendbufErrs %lx %lx", sbuf[0], 99 "SendbufErrs %lx %lx", sbuf[0],
99 sbuf[1]); 100 sbuf[1]);
@@ -108,7 +109,8 @@ void ipath_disarm_senderrbufs(struct ipath_devdata *dd, int rewrite)
108 ipath_clrpiobuf(dd, i); 109 ipath_clrpiobuf(dd, i);
109 ipath_disarm_piobufs(dd, i, 1); 110 ipath_disarm_piobufs(dd, i, 1);
110 } 111 }
111 dd->ipath_lastcancel = jiffies+3; /* no armlaunch for a bit */ 112 /* ignore armlaunch errs for a bit */
113 dd->ipath_lastcancel = jiffies+3;
112 } 114 }
113} 115}
114 116
@@ -290,12 +292,7 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd,
290 * Flush all queued sends when link went to DOWN or INIT, 292 * Flush all queued sends when link went to DOWN or INIT,
291 * to be sure that they don't block SMA and other MAD packets 293 * to be sure that they don't block SMA and other MAD packets
292 */ 294 */
293 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 295 ipath_cancel_sends(dd);
294 INFINIPATH_S_ABORT);
295 ipath_disarm_piobufs(dd, dd->ipath_lastport_piobuf,
296 (unsigned)(dd->ipath_piobcnt2k +
297 dd->ipath_piobcnt4k) -
298 dd->ipath_lastport_piobuf);
299 } 296 }
300 else if (lstate == IPATH_IBSTATE_INIT || lstate == IPATH_IBSTATE_ARM || 297 else if (lstate == IPATH_IBSTATE_INIT || lstate == IPATH_IBSTATE_ARM ||
301 lstate == IPATH_IBSTATE_ACTIVE) { 298 lstate == IPATH_IBSTATE_ACTIVE) {
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index 2a4414b948ee..2e85aeca5eac 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -676,6 +676,7 @@ int ipath_unordered_wc(void);
676 676
677void ipath_disarm_piobufs(struct ipath_devdata *, unsigned first, 677void ipath_disarm_piobufs(struct ipath_devdata *, unsigned first,
678 unsigned cnt); 678 unsigned cnt);
679void ipath_cancel_sends(struct ipath_devdata *);
679 680
680int ipath_create_rcvhdrq(struct ipath_devdata *, struct ipath_portdata *); 681int ipath_create_rcvhdrq(struct ipath_devdata *, struct ipath_portdata *);
681void ipath_free_pddata(struct ipath_devdata *, struct ipath_portdata *); 682void ipath_free_pddata(struct ipath_devdata *, struct ipath_portdata *);