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:
Bosko Milekic 2001-06-20 19:48:35 +00:00
parent 5a69ac96f5
commit f5eece3fb9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=78508
15 changed files with 56 additions and 89 deletions

View File

@ -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++;

View File

@ -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;

View File

@ -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++;

View File

@ -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 *);

View File

@ -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;

View File

@ -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++;

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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++;

View File

@ -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;
}

View File

@ -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 *);

View File

@ -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++;

View File

@ -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;

View File

@ -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++;

View File

@ -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++;