diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2005-10-18 00:12:10 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2005-10-18 00:12:10 +0000 |
commit | ce6302f31ccc74d4a37d88e5751704a0fd03610b (patch) | |
tree | 43901131fc60d05cc107bf5106435db1cd0285ea /sys/dev/pci/if_sis.c | |
parent | 1bdf6a2788aacc347eefdfae577ececbda1934fc (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/dev/pci/if_sis.c')
-rw-r--r-- | sys/dev/pci/if_sis.c | 30 |
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) |