Module Name: src
Committed By: riz
Date: Tue Apr 5 06:12:46 UTC 2011
Modified Files:
src/sys/dev/pci [netbsd-5]: if_jme.c
Log Message:
Pull up following revision(s) (requested by bouyer in ticket #1588):
sys/dev/pci/if_jme.c: revision 1.17
Some bus_dma(9)-related and memory allocation fixes:
- always bus_dmamap_unload() before recycling a receive descriptor
- make sure to not sleep from interrupt context: call bus_dmamap_load with
M_NOWAIT, and create dma maps BUS_DMA_ALLOCNOW.
- if a receive descriptor has a NULL mbuf try to allocate a new one, don't
try to receive it.
To generate a diff of this commit:
cvs rdiff -u -r1.4.6.3 -r1.4.6.4 src/sys/dev/pci/if_jme.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/pci/if_jme.c
diff -u src/sys/dev/pci/if_jme.c:1.4.6.3 src/sys/dev/pci/if_jme.c:1.4.6.4
--- src/sys/dev/pci/if_jme.c:1.4.6.3 Sun Jan 16 12:51:59 2011
+++ src/sys/dev/pci/if_jme.c Tue Apr 5 06:12:46 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: if_jme.c,v 1.4.6.3 2011/01/16 12:51:59 bouyer Exp $ */
+/* $NetBSD: if_jme.c,v 1.4.6.4 2011/04/05 06:12:46 riz Exp $ */
/*
* Copyright (c) 2008 Manuel Bouyer. All rights reserved.
@@ -63,7 +63,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_jme.c,v 1.4.6.3 2011/01/16 12:51:59 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_jme.c,v 1.4.6.4 2011/04/05 06:12:46 riz Exp $");
#include <sys/param.h>
@@ -447,13 +447,14 @@
for (i = 0; i < JME_NBUFS; i++) {
sc->jme_txmbuf[i] = sc->jme_rxmbuf[i] = NULL;
if (bus_dmamap_create(sc->jme_dmatag, JME_MAX_TX_LEN,
- JME_NBUFS, JME_MAX_TX_LEN, 0, BUS_DMA_NOWAIT,
+ JME_NBUFS, JME_MAX_TX_LEN, 0,
+ BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
&sc->jme_txmbufm[i]) != 0) {
aprint_error_dev(self, "can't allocate DMA TX map\n");
return;
}
if (bus_dmamap_create(sc->jme_dmatag, JME_MAX_RX_LEN,
- 1, JME_MAX_RX_LEN, 0, BUS_DMA_NOWAIT,
+ 1, JME_MAX_RX_LEN, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
&sc->jme_rxmbufm[i]) != 0) {
aprint_error_dev(self, "can't allocate DMA RX map\n");
return;
@@ -705,6 +706,8 @@
}
map = sc->jme_rxmbufm[i];
m->m_len = m->m_pkthdr.len = m->m_ext.ext_size;
+ KASSERT(m->m_len == MCLBYTES);
+
error = bus_dmamap_load_mbuf(sc->jme_dmatag, map, m,
BUS_DMA_READ|BUS_DMA_NOWAIT);
if (error) {
@@ -1050,6 +1053,7 @@
static void
jme_intr_rx(jme_softc_t *sc) {
struct mbuf *m, *mhead;
+ bus_dmamap_t mmap;
struct ifnet *ifp = &sc->jme_if;
uint32_t flags, buflen;
int i, ipackets, nsegs, seg, error;
@@ -1063,7 +1067,7 @@
sc->jme_rx_cons, le32toh(sc->jme_rxring[sc->jme_rx_cons].flags));
#endif
ipackets = 0;
- while((le32toh(sc->jme_rxring[ sc->jme_rx_cons].flags) & JME_RD_OWN)
+ while((le32toh(sc->jme_rxring[sc->jme_rx_cons].flags) & JME_RD_OWN)
== 0) {
i = sc->jme_rx_cons;
desc = &sc->jme_rxring[i];
@@ -1071,11 +1075,19 @@
printf("rxintr i %d flags 0x%x buflen 0x%x\n",
i, le32toh(desc->flags), le32toh(desc->buflen));
#endif
+ if (sc->jme_rxmbuf[i] == NULL) {
+ if ((error = jme_add_rxbuf(sc, NULL)) != 0) {
+ aprint_error_dev(sc->jme_dev,
+ "can't add new mbuf to empty slot: %d\n",
+ error);
+ break;
+ }
+ JME_DESC_INC(sc->jme_rx_cons, JME_NBUFS);
+ i = sc->jme_rx_cons;
+ continue;
+ }
if ((le32toh(desc->buflen) & JME_RD_VALID) == 0)
break;
- bus_dmamap_sync(sc->jme_dmatag, sc->jme_rxmbufm[i], 0,
- sc->jme_rxmbufm[i]->dm_mapsize, BUS_DMASYNC_POSTREAD);
- bus_dmamap_unload(sc->jme_dmatag, sc->jme_rxmbufm[i]);
buflen = le32toh(desc->buflen);
nsegs = JME_RX_NSEGS(buflen);
@@ -1093,6 +1105,10 @@
for (seg = 0; seg < nsegs; seg++) {
m = sc->jme_rxmbuf[i];
sc->jme_rxmbuf[i] = NULL;
+ mmap = sc->jme_rxmbufm[i];
+ bus_dmamap_sync(sc->jme_dmatag, mmap, 0,
+ mmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(sc->jme_dmatag, mmap);
if ((error = jme_add_rxbuf(sc, m)) != 0)
aprint_error_dev(sc->jme_dev,
"can't reuse mbuf: %d\n", error);
@@ -1104,11 +1120,24 @@
/* receive this packet */
mhead = m = sc->jme_rxmbuf[i];
sc->jme_rxmbuf[i] = NULL;
+ mmap = sc->jme_rxmbufm[i];
+ bus_dmamap_sync(sc->jme_dmatag, mmap, 0,
+ mmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(sc->jme_dmatag, mmap);
/* add a new buffer to chain */
- if (jme_add_rxbuf(sc, NULL) == ENOBUFS) {
- for (seg = 0; seg < nsegs; seg++) {
+ if (jme_add_rxbuf(sc, NULL) != 0) {
+ if ((error = jme_add_rxbuf(sc, m)) != 0)
+ aprint_error_dev(sc->jme_dev,
+ "can't reuse mbuf: %d\n", error);
+ JME_DESC_INC(sc->jme_rx_cons, JME_NBUFS);
+ i = sc->jme_rx_cons;
+ for (seg = 1; seg < nsegs; seg++) {
m = sc->jme_rxmbuf[i];
sc->jme_rxmbuf[i] = NULL;
+ mmap = sc->jme_rxmbufm[i];
+ bus_dmamap_sync(sc->jme_dmatag, mmap, 0,
+ mmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(sc->jme_dmatag, mmap);
if ((error = jme_add_rxbuf(sc, m)) != 0)
aprint_error_dev(sc->jme_dev,
"can't reuse mbuf: %d\n", error);
@@ -1130,7 +1159,13 @@
i = sc->jme_rx_cons;
m = sc->jme_rxmbuf[i];
sc->jme_rxmbuf[i] = NULL;
- (void)jme_add_rxbuf(sc, NULL);
+ mmap = sc->jme_rxmbufm[i];
+ bus_dmamap_sync(sc->jme_dmatag, mmap, 0,
+ mmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(sc->jme_dmatag, mmap);
+ if ((error = jme_add_rxbuf(sc, NULL)) != 0)
+ aprint_error_dev(sc->jme_dev,
+ "can't add new mbuf: %d\n", error);
m->m_flags &= ~M_PKTHDR;
m_cat(mhead, m);
JME_DESC_INC(sc->jme_rx_cons, JME_NBUFS);
@@ -1427,7 +1462,7 @@
txd = &sc->jme_txring[prod];
error = bus_dmamap_load_mbuf(sc->jme_dmatag, sc->jme_txmbufm[prod],
- *m_head, BUS_DMA_WRITE);
+ *m_head, BUS_DMA_NOWAIT | BUS_DMA_WRITE);
if (error) {
if (error == EFBIG) {
log(LOG_ERR, "%s: Tx packet consumes too many "