summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2005-10-18 00:12:10 +0000
committerBrad Smith <brad@cvs.openbsd.org>2005-10-18 00:12:10 +0000
commitce6302f31ccc74d4a37d88e5751704a0fd03610b (patch)
tree43901131fc60d05cc107bf5106435db1cd0285ea /sys
parent1bdf6a2788aacc347eefdfae577ececbda1934fc (diff)
Make sure that if_timer does not get reset if there are packets
still queued for transmission. This should solve the problem of the device stalling on transmissions if some link event prevents transmission. From luigi FreeBSD ok pedro@ hshoexer@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/if_sis.c30
1 files changed, 10 insertions, 20 deletions
diff --git a/sys/dev/pci/if_sis.c b/sys/dev/pci/if_sis.c
index 276caf4de0c..021862bb9d6 100644
--- a/sys/dev/pci/if_sis.c
+++ b/sys/dev/pci/if_sis.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_sis.c,v 1.55 2005/10/17 05:02:50 brad Exp $ */
+/* $OpenBSD: if_sis.c,v 1.56 2005/10/18 00:12:09 brad Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
* Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
@@ -1425,22 +1425,18 @@ void sis_rxeoc(sc)
void sis_txeof(sc)
struct sis_softc *sc;
{
- struct sis_desc *cur_tx = NULL;
struct ifnet *ifp;
u_int32_t idx;
ifp = &sc->arpcom.ac_if;
- /* Clear the timeout timer. */
- ifp->if_timer = 0;
-
/*
* Go through our tx list and free mbufs for those
* frames that have been transmitted.
*/
- idx = sc->sis_cdata.sis_tx_cons;
- while (idx != sc->sis_cdata.sis_tx_prod) {
- cur_tx = &sc->sis_ldata->sis_tx_list[idx];
+ for (idx = sc->sis_cdata.sis_tx_cons; sc->sis_cdata.sis_tx_cnt > 0;
+ sc->sis_cdata.sis_tx_cnt--, SIS_INC(idx, SIS_TX_LIST_CNT)) {
+ struct sis_desc *cur_tx = &sc->sis_ldata->sis_tx_list[idx];
bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
((caddr_t)cur_tx - sc->sc_listkva),
@@ -1450,11 +1446,8 @@ void sis_txeof(sc)
if (SIS_OWNDESC(cur_tx))
break;
- if (cur_tx->sis_ctl & SIS_CMDSTS_MORE) {
- sc->sis_cdata.sis_tx_cnt--;
- SIS_INC(idx, SIS_TX_LIST_CNT);
+ if (cur_tx->sis_ctl & SIS_CMDSTS_MORE)
continue;
- }
if (!(cur_tx->sis_ctl & SIS_CMDSTS_PKT_OK)) {
ifp->if_oerrors++;
@@ -1479,18 +1472,15 @@ void sis_txeof(sc)
m_freem(cur_tx->sis_mbuf);
cur_tx->sis_mbuf = NULL;
}
-
- sc->sis_cdata.sis_tx_cnt--;
- SIS_INC(idx, SIS_TX_LIST_CNT);
- ifp->if_timer = 0;
}
- sc->sis_cdata.sis_tx_cons = idx;
-
- if (cur_tx != NULL)
+ if (idx != sc->sis_cdata.sis_tx_cons) {
+ /* we freed up some buffers */
+ sc->sis_cdata.sis_tx_cons = idx;
ifp->if_flags &= ~IFF_OACTIVE;
+ }
- return;
+ ifp->if_timer = (sc->sis_cdata.sis_tx_cnt == 0) ? 0 : 5;
}
void sis_tick(xsc)