summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>2000-09-21 04:03:53 +0000
committerJason Wright <jason@cvs.openbsd.org>2000-09-21 04:03:53 +0000
commit602f45f538b0b8bad26e52f8463692aaacfbad9b (patch)
tree1b2b36dcc027dde274ef0f6e2c920f0da1ec5a64
parent0143671bbe11b6f4420babb02f6ac4c8e99a9e61 (diff)
Patch from FreeBSD (wpaul):
Fix the tl driver so it doesn't run off the end of the RX descriptor list and panic in out of mbufs condition.
-rw-r--r--sys/dev/pci/if_tl.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/sys/dev/pci/if_tl.c b/sys/dev/pci/if_tl.c
index ce1c9ab8a24..8bf42724b14 100644
--- a/sys/dev/pci/if_tl.c
+++ b/sys/dev/pci/if_tl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_tl.c,v 1.12 2000/06/20 03:24:21 aaron Exp $ */
+/* $OpenBSD: if_tl.c,v 1.13 2000/09/21 04:03:52 jason Exp $ */
/*
* Copyright (c) 1997, 1998
@@ -1462,10 +1462,10 @@ int tl_newbuf(sc, c)
c->tl_mbuf = m_new;
c->tl_next = NULL;
c->tl_ptr->tlist_frsize = MCLBYTES;
- c->tl_ptr->tlist_cstat = TL_CSTAT_READY;
c->tl_ptr->tlist_fptr = 0;
c->tl_ptr->tl_frag.tlist_dadr = vtophys(mtod(m_new, caddr_t));
c->tl_ptr->tl_frag.tlist_dcnt = MCLBYTES;
+ c->tl_ptr->tlist_cstat = TL_CSTAT_READY;
return(0);
}
@@ -1506,9 +1506,11 @@ int tl_intvec_rxeof(xsc, type)
sc = xsc;
ifp = &sc->arpcom.ac_if;
- while(sc->tl_cdata.tl_rx_head->tl_ptr->tlist_cstat & TL_CSTAT_FRAMECMP){
- r++;
+ while(sc->tl_cdata.tl_rx_head != NULL) {
cur_rx = sc->tl_cdata.tl_rx_head;
+ if (!(cur_rx->tl_ptr->tlist_cstat & TL_CSTAT_FRAMECMP))
+ break;
+ r++;
sc->tl_cdata.tl_rx_head = cur_rx->tl_next;
m = cur_rx->tl_mbuf;
total_len = cur_rx->tl_ptr->tlist_frsize;
@@ -1579,13 +1581,17 @@ int tl_intvec_rxeoc(xsc, type)
{
struct tl_softc *sc;
int r;
+ struct tl_chain_data *cd;
sc = xsc;
+ cd = &sc->tl_cdata;
/* Flush out the receive queue and ack RXEOF interrupts. */
r = tl_intvec_rxeof(xsc, type);
CMD_PUT(sc, TL_CMD_ACK | r | (type & ~(0x00100000)));
r = 1;
+ cd->tl_rx_head = &cd->tl_rx_chain[0];
+ cd->tl_rx_tail = &cd->tl_rx_chain[TL_RX_LIST_CNT - 1];
CSR_WRITE_4(sc, TL_CH_PARM, vtophys(sc->tl_cdata.tl_rx_head->tl_ptr));
r |= (TL_CMD_GO|TL_CMD_RT);
return(r);