summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/pci/if_xl.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/sys/pci/if_xl.c b/sys/pci/if_xl.c
index 3d47c69..a21a82c 100644
--- a/sys/pci/if_xl.c
+++ b/sys/pci/if_xl.c
@@ -29,7 +29,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: if_xl.c,v 1.5 1998/08/24 17:51:38 wpaul Exp $
+ * $Id: if_xl.c,v 1.46 1998/08/31 15:10:22 wpaul Exp $
*/
/*
@@ -124,7 +124,7 @@
#ifndef lint
static char rcsid[] =
- "$Id: if_xl.c,v 1.5 1998/08/24 17:51:38 wpaul Exp $";
+ "$Id: if_xl.c,v 1.46 1998/08/31 15:10:22 wpaul Exp $";
#endif
/*
@@ -1635,7 +1635,8 @@ static int xl_list_rx_init(sc)
for (i = 0; i < XL_RX_LIST_CNT; i++) {
cd->xl_rx_chain[i].xl_ptr =
(struct xl_list_onefrag *)&ld->xl_rx_list[i];
- xl_newbuf(sc, &cd->xl_rx_chain[i]);
+ if (xl_newbuf(sc, &cd->xl_rx_chain[i]) == ENOBUFS)
+ return(ENOBUFS);
if (i == (XL_RX_LIST_CNT - 1)) {
cd->xl_rx_chain[i].xl_next = &cd->xl_rx_chain[0];
ld->xl_rx_list[i].xl_next =
@@ -1663,14 +1664,15 @@ static int xl_newbuf(sc, c)
MGETHDR(m_new, M_DONTWAIT, MT_DATA);
if (m_new == NULL) {
- printf("xl%d: no memory for rx list",
- sc->xl_unit);
+ printf("xl%d: no memory for rx list -- packet dropped!\n",
+ sc->xl_unit);
return(ENOBUFS);
}
MCLGET(m_new, M_DONTWAIT);
if (!(m_new->m_flags & M_EXT)) {
- printf("xl%d: no memory for rx list", sc->xl_unit);
+ printf("xl%d: no memory for rx list -- packet dropped!\n",
+ sc->xl_unit);
m_freem(m_new);
return(ENOBUFS);
}
@@ -1703,6 +1705,8 @@ again:
while((rxstat = sc->xl_cdata.xl_rx_head->xl_ptr->xl_status)) {
cur_rx = sc->xl_cdata.xl_rx_head;
+ sc->xl_cdata.xl_rx_head = cur_rx->xl_next;
+
/*
* If an error occurs, update stats, clear the
* status word and leave the mbuf cluster in place:
@@ -1712,7 +1716,6 @@ again:
if (rxstat & XL_RXSTAT_UP_ERROR) {
ifp->if_ierrors++;
cur_rx->xl_ptr->xl_status = 0;
- sc->xl_cdata.xl_rx_head = cur_rx->xl_next;
continue;
}
@@ -1726,15 +1729,25 @@ again:
sc->xl_unit);
ifp->if_ierrors++;
cur_rx->xl_ptr->xl_status = 0;
- sc->xl_cdata.xl_rx_head = cur_rx->xl_next;
continue;
}
/* No errors; receive the packet. */
- sc->xl_cdata.xl_rx_head = cur_rx->xl_next;
m = cur_rx->xl_mbuf;
total_len = cur_rx->xl_ptr->xl_status & XL_RXSTAT_LENMASK;
- xl_newbuf(sc, cur_rx);
+
+ /*
+ * Try to conjure up a new mbuf cluster. If that
+ * fails, it means we have an out of memory condition and
+ * should leave the buffer in place and continue. This will
+ * result in a lost packet, but there's little else we
+ * can do in this situation.
+ */
+ if (xl_newbuf(sc, cur_rx) == ENOBUFS) {
+ ifp->if_ierrors++;
+ cur_rx->xl_ptr->xl_status = 0;
+ continue;
+ }
eh = mtod(m, struct ether_header *);
m->m_pkthdr.rcvif = ifp;
@@ -2250,8 +2263,10 @@ static void xl_init(xsc)
xl_wait(sc);
/* Init circular RX list. */
- if (xl_list_rx_init(sc)) {
- printf("xl%d: failed to set up rx lists\n", sc->xl_unit);
+ if (xl_list_rx_init(sc) == ENOBUFS) {
+ printf("xl%d: initialization failed: no "
+ "memory for rx buffers\n", sc->xl_unit);
+ xl_stop(sc);
return;
}
OpenPOWER on IntegriCloud