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
This commit is contained in:
parent
5a69ac96f5
commit
f5eece3fb9
@ -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++;
|
||||
|
@ -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;
|
||||
|
@ -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++;
|
||||
|
@ -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 *);
|
||||
|
@ -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;
|
||||
|
@ -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++;
|
||||
|
@ -691,15 +691,12 @@ vxread(sc)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -1078,29 +1078,26 @@ m_split(struct mbuf *m0, int len0, int wait)
|
||||
}
|
||||
/*
|
||||
* 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;
|
||||
int len;
|
||||
|
||||
if (off < 0 || off > MHLEN)
|
||||
return (NULL);
|
||||
|
||||
cp = buf;
|
||||
epkt = cp + totlen;
|
||||
if (off) {
|
||||
cp += off + 2 * sizeof(u_short);
|
||||
totlen -= 2 * sizeof(u_short);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
@ -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++;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 *);
|
||||
|
@ -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++;
|
||||
|
@ -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;
|
||||
|
@ -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++;
|
||||
|
@ -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++;
|
||||
|
Loading…
Reference in New Issue
Block a user