summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbmilekic <bmilekic@FreeBSD.org>2001-06-20 19:48:35 +0000
committerbmilekic <bmilekic@FreeBSD.org>2001-06-20 19:48:35 +0000
commit70d52016a3f34e35b033755b95ddad49e5f4c50c (patch)
treee79557908ee2eeed9a40c65a32399eb17abca830
parent398c0c0ca03faf96198e155dba0becba4e90d8da (diff)
downloadFreeBSD-src-70d52016a3f34e35b033755b95ddad49e5f4c50c.zip
FreeBSD-src-70d52016a3f34e35b033755b95ddad49e5f4c50c.tar.gz
Change m_devget()'s outdated and unused `offset' argument to actually mean
something: offset into the first mbuf of the target chain before copying the source data over. Make drivers using m_devget() with a first argument "data - ETHER_ALIGN" to use the offset argument to pass ETHER_ALIGN in. The way it was previously done is potentially dangerous if the source data was at the top of a page and the offset caused the previous page to be copied (if the previous page has not yet been appropriately mapped). The old `offset' argument in m_devget() is not used anywhere (it's always 0) and dates back to ~1995 (and earlier?) when support for ethernet trailers existed. With that support gone, it was merely collecting dust. Tested on alpha by: jlemon Partially submitted by: jlemon Reviewed by: jlemon MFC after: 3 weeks
-rw-r--r--sys/dev/dc/if_dc.c5
-rw-r--r--sys/dev/lge/if_lge.c5
-rw-r--r--sys/dev/nge/if_nge.c5
-rw-r--r--sys/dev/sf/if_sf.c5
-rw-r--r--sys/dev/sk/if_sk.c5
-rw-r--r--sys/dev/vr/if_vr.c5
-rw-r--r--sys/dev/vx/if_vx.c5
-rw-r--r--sys/kern/uipc_mbuf.c55
-rw-r--r--sys/pci/if_dc.c5
-rw-r--r--sys/pci/if_rl.c27
-rw-r--r--sys/pci/if_sf.c5
-rw-r--r--sys/pci/if_sis.c5
-rw-r--r--sys/pci/if_sk.c5
-rw-r--r--sys/pci/if_vr.c5
-rw-r--r--sys/pci/if_wb.c5
15 files changed, 57 insertions, 90 deletions
diff --git a/sys/dev/dc/if_dc.c b/sys/dev/dc/if_dc.c
index 83eb65e..0ef88c3 100644
--- a/sys/dev/dc/if_dc.c
+++ b/sys/dev/dc/if_dc.c
@@ -2502,15 +2502,14 @@ static void dc_rxeof(sc)
/* No errors; receive the packet. */
total_len -= ETHER_CRC_LEN;
- m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
- total_len + ETHER_ALIGN, 0, ifp, NULL);
+ m0 = m_devget(mtod(m, char *), total_len, ETHER_ALIGN, ifp,
+ NULL);
dc_newbuf(sc, i, m);
DC_INC(i, DC_RX_LIST_CNT);
if (m0 == NULL) {
ifp->if_ierrors++;
continue;
}
- m_adj(m0, ETHER_ALIGN);
m = m0;
ifp->if_ipackets++;
diff --git a/sys/dev/lge/if_lge.c b/sys/dev/lge/if_lge.c
index d6f9e80..1558004 100644
--- a/sys/dev/lge/if_lge.c
+++ b/sys/dev/lge/if_lge.c
@@ -993,8 +993,8 @@ static void lge_rxeof(sc, cnt)
}
if (lge_newbuf(sc, &LGE_RXTAIL(sc), NULL) == ENOBUFS) {
- m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
- total_len + ETHER_ALIGN, 0, ifp, NULL);
+ m0 = m_devget(mtod(m, char *), total_len, ETHER_ALIGN,
+ ifp, NULL);
lge_newbuf(sc, &LGE_RXTAIL(sc), m);
if (m0 == NULL) {
printf("lge%d: no receive buffers "
@@ -1003,7 +1003,6 @@ static void lge_rxeof(sc, cnt)
ifp->if_ierrors++;
continue;
}
- m_adj(m0, ETHER_ALIGN);
m = m0;
} else {
m->m_pkthdr.rcvif = ifp;
diff --git a/sys/dev/nge/if_nge.c b/sys/dev/nge/if_nge.c
index 9c15beb..65dd718 100644
--- a/sys/dev/nge/if_nge.c
+++ b/sys/dev/nge/if_nge.c
@@ -1278,8 +1278,8 @@ static void nge_rxeof(sc)
* only gigE chip I know of with alignment constraints
* on receive buffers. RX buffers must be 64-bit aligned.
*/
- m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
- total_len + ETHER_ALIGN, 0, ifp, NULL);
+ m0 = m_devget(mtod(m, char *), total_len, ETHER_ALIGN, ifp,
+ NULL);
nge_newbuf(sc, cur_rx, m);
if (m0 == NULL) {
printf("nge%d: no receive buffers "
@@ -1288,7 +1288,6 @@ static void nge_rxeof(sc)
ifp->if_ierrors++;
continue;
}
- m_adj(m0, ETHER_ALIGN);
m = m0;
ifp->if_ipackets++;
diff --git a/sys/dev/sf/if_sf.c b/sys/dev/sf/if_sf.c
index dd26fca..e0d0149 100644
--- a/sys/dev/sf/if_sf.c
+++ b/sys/dev/sf/if_sf.c
@@ -989,14 +989,13 @@ static void sf_rxeof(sc)
continue;
}
- m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
- cur_rx->sf_len + ETHER_ALIGN, 0, ifp, NULL);
+ m0 = m_devget(mtod(m, char *), cur_rx->sf_len, ETHER_ALIGN,
+ ifp, NULL);
sf_newbuf(sc, desc, m);
if (m0 == NULL) {
ifp->if_ierrors++;
continue;
}
- m_adj(m0, ETHER_ALIGN);
m = m0;
eh = mtod(m, struct ether_header *);
diff --git a/sys/dev/sk/if_sk.c b/sys/dev/sk/if_sk.c
index 83d5720..6c9ec6a 100644
--- a/sys/dev/sk/if_sk.c
+++ b/sys/dev/sk/if_sk.c
@@ -1579,8 +1579,8 @@ static void sk_rxeof(sc_if)
*/
if (sk_newbuf(sc_if, cur_rx, NULL) == ENOBUFS) {
struct mbuf *m0;
- m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
- total_len + ETHER_ALIGN, 0, ifp, NULL);
+ m0 = m_devget(mtod(m, char *), total_len, ETHER_ALIGN,
+ ifp, NULL);
sk_newbuf(sc_if, cur_rx, m);
if (m0 == NULL) {
printf("sk%d: no receive buffers "
@@ -1589,7 +1589,6 @@ static void sk_rxeof(sc_if)
ifp->if_ierrors++;
continue;
}
- m_adj(m0, ETHER_ALIGN);
m = m0;
} else {
m->m_pkthdr.rcvif = ifp;
diff --git a/sys/dev/vr/if_vr.c b/sys/dev/vr/if_vr.c
index 93fba3e..9ed0266 100644
--- a/sys/dev/vr/if_vr.c
+++ b/sys/dev/vr/if_vr.c
@@ -1029,14 +1029,13 @@ static void vr_rxeof(sc)
*/
total_len -= ETHER_CRC_LEN;
- m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
- total_len + ETHER_ALIGN, 0, ifp, NULL);
+ m0 = m_devget(mtod(m, char *), total_len, ETHER_ALIGN, ifp,
+ NULL);
vr_newbuf(sc, cur_rx, m);
if (m0 == NULL) {
ifp->if_ierrors++;
continue;
}
- m_adj(m0, ETHER_ALIGN);
m = m0;
ifp->if_ipackets++;
diff --git a/sys/dev/vx/if_vx.c b/sys/dev/vx/if_vx.c
index e1fa760..f475080 100644
--- a/sys/dev/vx/if_vx.c
+++ b/sys/dev/vx/if_vx.c
@@ -691,15 +691,12 @@ again:
{
struct mbuf *m0;
- m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
- m->m_pkthdr.len + ETHER_ALIGN, 0, ifp, NULL);
-
+ m0 = m_devget(mtod(m, char *), m->m_pkthdr.len, ETHER_ALIGN, ifp, NULL);
if (m0 == NULL) {
ifp->if_ierrors++;
goto abort;
}
- m_adj(m0, ETHER_ALIGN);
m_freem(m);
m = m0;
}
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index 4134623..a4d3674 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -1078,29 +1078,26 @@ extpacket:
}
/*
* Routine to copy from device local memory into mbufs.
+ * Note that `off' argument is offset into first mbuf of target chain from
+ * which to begin copying the data to.
*/
struct mbuf *
-m_devget(char *buf, int totlen, int off0, struct ifnet *ifp,
+m_devget(char *buf, int totlen, int off, struct ifnet *ifp,
void (*copy)(char *from, caddr_t to, u_int len))
{
struct mbuf *m;
struct mbuf *top = 0, **mp = &top;
- int off = off0, len;
- char *cp;
- char *epkt;
-
- cp = buf;
- epkt = cp + totlen;
- if (off) {
- cp += off + 2 * sizeof(u_short);
- totlen -= 2 * sizeof(u_short);
- }
+ int len;
+
+ if (off < 0 || off > MHLEN)
+ return (NULL);
+
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m == NULL)
return (NULL);
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = totlen;
- m->m_len = MHLEN;
+ len = MHLEN;
while (totlen > 0) {
if (top) {
@@ -1109,37 +1106,35 @@ m_devget(char *buf, int totlen, int off0, struct ifnet *ifp,
m_freem(top);
return (NULL);
}
- m->m_len = MLEN;
+ len = MLEN;
}
- len = min(totlen, epkt - cp);
- if (len >= MINCLSIZE) {
+ if (totlen + off >= MINCLSIZE) {
MCLGET(m, M_DONTWAIT);
if (m->m_flags & M_EXT)
- m->m_len = len = min(len, MCLBYTES);
- else
- len = m->m_len;
+ len = MCLBYTES;
} else {
/*
* Place initial small packet/header at end of mbuf.
*/
- if (len < m->m_len) {
- if (top == NULL && len +
- max_linkhdr <= m->m_len)
- m->m_data += max_linkhdr;
- m->m_len = len;
- } else
- len = m->m_len;
+ if (top == NULL && totlen + off + max_linkhdr <= len) {
+ m->m_data += max_linkhdr;
+ len -= max_linkhdr;
+ }
+ }
+ if (off) {
+ m->m_data += off;
+ len -= off;
+ off = 0;
}
+ m->m_len = len = min(totlen, len);
if (copy)
- copy(cp, mtod(m, caddr_t), (unsigned)len);
+ copy(buf, mtod(m, caddr_t), (unsigned)len);
else
- bcopy(cp, mtod(m, caddr_t), (unsigned)len);
- cp += len;
+ bcopy(buf, mtod(m, caddr_t), (unsigned)len);
+ buf += len;
*mp = m;
mp = &m->m_next;
totlen -= len;
- if (cp == epkt)
- cp = buf;
}
return (top);
}
diff --git a/sys/pci/if_dc.c b/sys/pci/if_dc.c
index 83eb65e..0ef88c3 100644
--- a/sys/pci/if_dc.c
+++ b/sys/pci/if_dc.c
@@ -2502,15 +2502,14 @@ static void dc_rxeof(sc)
/* No errors; receive the packet. */
total_len -= ETHER_CRC_LEN;
- m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
- total_len + ETHER_ALIGN, 0, ifp, NULL);
+ m0 = m_devget(mtod(m, char *), total_len, ETHER_ALIGN, ifp,
+ NULL);
dc_newbuf(sc, i, m);
DC_INC(i, DC_RX_LIST_CNT);
if (m0 == NULL) {
ifp->if_ierrors++;
continue;
}
- m_adj(m0, ETHER_ALIGN);
m = m0;
ifp->if_ipackets++;
diff --git a/sys/pci/if_rl.c b/sys/pci/if_rl.c
index 90dd737..269f293 100644
--- a/sys/pci/if_rl.c
+++ b/sys/pci/if_rl.c
@@ -1063,14 +1063,8 @@ static int rl_list_tx_init(sc)
* the 'rx status register' mentioned in the datasheet.
*
* Note: to make the Alpha happy, the frame payload needs to be aligned
- * on a 32-bit boundary. To achieve this, we cheat a bit by copying from
- * the ring buffer starting at an address two bytes before the actual
- * data location. We can then shave off the first two bytes using m_adj().
- * The reason we do this is because m_devget() doesn't let us specify an
- * offset into the mbuf storage space, so we have to artificially create
- * one. The ring is allocated in such a way that there are a few unused
- * bytes of space preceecing it so that it will be safe for us to do the
- * 2-byte backstep even if reading from the ring at offset 0.
+ * on a 32-bit boundary. To achieve this, we pass RL_ETHER_ALIGN (2 bytes)
+ * as the offset argument to m_devget().
*/
static void rl_rxeof(sc)
struct rl_softc *sc;
@@ -1148,32 +1142,25 @@ static void rl_rxeof(sc)
wrap = (sc->rl_cdata.rl_rx_buf + RL_RXBUFLEN) - rxbufpos;
if (total_len > wrap) {
- /*
- * Fool m_devget() into thinking we want to copy
- * the whole buffer so we don't end up fragmenting
- * the data.
- */
- m = m_devget(rxbufpos - RL_ETHER_ALIGN,
- total_len + RL_ETHER_ALIGN, 0, ifp, NULL);
+ m = m_devget(rxbufpos, total_len, RL_ETHER_ALIGN, ifp,
+ NULL);
if (m == NULL) {
ifp->if_ierrors++;
printf("rl%d: out of mbufs, tried to "
"copy %d bytes\n", sc->rl_unit, wrap);
} else {
- m_adj(m, RL_ETHER_ALIGN);
m_copyback(m, wrap, total_len - wrap,
sc->rl_cdata.rl_rx_buf);
}
cur_rx = (total_len - wrap + ETHER_CRC_LEN);
} else {
- m = m_devget(rxbufpos - RL_ETHER_ALIGN,
- total_len + RL_ETHER_ALIGN, 0, ifp, NULL);
+ m = m_devget(rxbufpos, total_len, RL_ETHER_ALIGN, ifp,
+ NULL);
if (m == NULL) {
ifp->if_ierrors++;
printf("rl%d: out of mbufs, tried to "
"copy %d bytes\n", sc->rl_unit, total_len);
- } else
- m_adj(m, RL_ETHER_ALIGN);
+ }
cur_rx += total_len + 4 + ETHER_CRC_LEN;
}
diff --git a/sys/pci/if_sf.c b/sys/pci/if_sf.c
index dd26fca..e0d0149 100644
--- a/sys/pci/if_sf.c
+++ b/sys/pci/if_sf.c
@@ -989,14 +989,13 @@ static void sf_rxeof(sc)
continue;
}
- m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
- cur_rx->sf_len + ETHER_ALIGN, 0, ifp, NULL);
+ m0 = m_devget(mtod(m, char *), cur_rx->sf_len, ETHER_ALIGN,
+ ifp, NULL);
sf_newbuf(sc, desc, m);
if (m0 == NULL) {
ifp->if_ierrors++;
continue;
}
- m_adj(m0, ETHER_ALIGN);
m = m0;
eh = mtod(m, struct ether_header *);
diff --git a/sys/pci/if_sis.c b/sys/pci/if_sis.c
index 8394674..c93fba3 100644
--- a/sys/pci/if_sis.c
+++ b/sys/pci/if_sis.c
@@ -1129,14 +1129,13 @@ static void sis_rxeof(sc)
}
/* No errors; receive the packet. */
- m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
- total_len + ETHER_ALIGN, 0, ifp, NULL);
+ m0 = m_devget(mtod(m, char *), total_len, ETHER_ALIGN, ifp,
+ NULL);
sis_newbuf(sc, cur_rx, m);
if (m0 == NULL) {
ifp->if_ierrors++;
continue;
}
- m_adj(m0, ETHER_ALIGN);
m = m0;
ifp->if_ipackets++;
diff --git a/sys/pci/if_sk.c b/sys/pci/if_sk.c
index 83d5720..6c9ec6a 100644
--- a/sys/pci/if_sk.c
+++ b/sys/pci/if_sk.c
@@ -1579,8 +1579,8 @@ static void sk_rxeof(sc_if)
*/
if (sk_newbuf(sc_if, cur_rx, NULL) == ENOBUFS) {
struct mbuf *m0;
- m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
- total_len + ETHER_ALIGN, 0, ifp, NULL);
+ m0 = m_devget(mtod(m, char *), total_len, ETHER_ALIGN,
+ ifp, NULL);
sk_newbuf(sc_if, cur_rx, m);
if (m0 == NULL) {
printf("sk%d: no receive buffers "
@@ -1589,7 +1589,6 @@ static void sk_rxeof(sc_if)
ifp->if_ierrors++;
continue;
}
- m_adj(m0, ETHER_ALIGN);
m = m0;
} else {
m->m_pkthdr.rcvif = ifp;
diff --git a/sys/pci/if_vr.c b/sys/pci/if_vr.c
index 93fba3e..9ed0266 100644
--- a/sys/pci/if_vr.c
+++ b/sys/pci/if_vr.c
@@ -1029,14 +1029,13 @@ static void vr_rxeof(sc)
*/
total_len -= ETHER_CRC_LEN;
- m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
- total_len + ETHER_ALIGN, 0, ifp, NULL);
+ m0 = m_devget(mtod(m, char *), total_len, ETHER_ALIGN, ifp,
+ NULL);
vr_newbuf(sc, cur_rx, m);
if (m0 == NULL) {
ifp->if_ierrors++;
continue;
}
- m_adj(m0, ETHER_ALIGN);
m = m0;
ifp->if_ipackets++;
diff --git a/sys/pci/if_wb.c b/sys/pci/if_wb.c
index 50de1fd..a03951b 100644
--- a/sys/pci/if_wb.c
+++ b/sys/pci/if_wb.c
@@ -1175,14 +1175,13 @@ static void wb_rxeof(sc)
*/
total_len -= ETHER_CRC_LEN;
- m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
- total_len + ETHER_ALIGN, 0, ifp, NULL);
+ m0 = m_devget(mtod(m, char *), total_len, ETHER_ALIGN, ifp,
+ NULL);
wb_newbuf(sc, cur_rx, m);
if (m0 == NULL) {
ifp->if_ierrors++;
break;
}
- m_adj(m0, ETHER_ALIGN);
m = m0;
ifp->if_ipackets++;
OpenPOWER on IntegriCloud