From ce6302f31ccc74d4a37d88e5751704a0fd03610b Mon Sep 17 00:00:00 2001 From: Brad Smith Date: Tue, 18 Oct 2005 00:12:10 +0000 Subject: 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@ --- sys/dev/pci/if_sis.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) (limited to 'sys') 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 . 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) -- cgit v1.2.3