diff options
author | bmilekic <bmilekic@FreeBSD.org> | 2001-06-20 19:48:35 +0000 |
---|---|---|
committer | bmilekic <bmilekic@FreeBSD.org> | 2001-06-20 19:48:35 +0000 |
commit | 70d52016a3f34e35b033755b95ddad49e5f4c50c (patch) | |
tree | e79557908ee2eeed9a40c65a32399eb17abca830 /sys/kern | |
parent | 398c0c0ca03faf96198e155dba0becba4e90d8da (diff) | |
download | FreeBSD-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
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/uipc_mbuf.c | 55 |
1 files changed, 25 insertions, 30 deletions
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 = ⊤ - 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); } |