summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/io/iprb/iprb.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/io/iprb/iprb.c')
-rw-r--r--usr/src/uts/common/io/iprb/iprb.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/usr/src/uts/common/io/iprb/iprb.c b/usr/src/uts/common/io/iprb/iprb.c
index 0dfcce6e12..cfcc1938af 100644
--- a/usr/src/uts/common/io/iprb/iprb.c
+++ b/usr/src/uts/common/io/iprb/iprb.c
@@ -11,6 +11,8 @@
/*
* Copyright 2014 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2021 OmniOS Community Edition (OmniOSce) Association.
+ * Copyright 2022 Oxide Computer Company
*/
/*
@@ -787,10 +789,9 @@ iprb_cmd_submit(iprb_t *ip, uint16_t cmd)
iprb_dma_t *
iprb_cmd_next(iprb_t *ip)
{
- if (ip->cmd_count == NUM_TX) {
+ if (ip->cmd_count >= NUM_TX) {
return (NULL);
}
- ASSERT(ip->cmd_count < NUM_TX);
return (&ip->cmds[ip->cmd_head]);
}
@@ -960,6 +961,7 @@ iprb_start(iprb_t *ip)
/* Reset pointers */
ip->cmd_head = ip->cmd_tail = 0;
ip->cmd_last = NUM_TX - 1;
+ ip->cmd_count = 0;
if (iprb_cmd_ready(ip) != DDI_SUCCESS)
return (DDI_FAILURE);
@@ -975,7 +977,7 @@ iprb_start(iprb_t *ip)
/* Send a NOP. This will be the first command seen by the device. */
cb = iprb_cmd_next(ip);
- ASSERT(cb);
+ VERIFY3P(cb, !=, NULL);
if (iprb_cmd_submit(ip, CB_CMD_NOP) != DDI_SUCCESS)
return (DDI_FAILURE);
@@ -1671,6 +1673,13 @@ iprb_periodic(void *arg)
/* update the statistics */
mutex_enter(&ip->culock);
+ /*
+ * The watchdog timer is updated when we send frames or when we reclaim
+ * completed commands. When the link is idle for long periods it is
+ * possible we will have done neither of these things, so reclaim
+ * explicitly before checking for a transmit stall:
+ */
+ iprb_cmd_reclaim(ip);
if (ip->tx_wdog && ((gethrtime() - ip->tx_wdog) > ip->tx_timeout)) {
/* transmit/CU hang? */
cmn_err(CE_CONT, "?CU stalled, resetting.\n");