uipc_mbuf.c (78155) | uipc_mbuf.c (78508) |
---|---|
1/* 2 * Copyright (c) 1982, 1986, 1988, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 | 1/* 2 * Copyright (c) 1982, 1986, 1988, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 |
34 * $FreeBSD: head/sys/kern/uipc_mbuf.c 78155 2001-06-13 00:36:41Z peter $ | 34 * $FreeBSD: head/sys/kern/uipc_mbuf.c 78508 2001-06-20 19:48:35Z bmilekic $ |
35 */ 36 37#include "opt_param.h" 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/condvar.h> 41#include <sys/kernel.h> 42#include <sys/lock.h> --- 1030 unchanged lines hidden (view full) --- 1073 n->m_len = remain; 1074 m->m_len = len; 1075 n->m_next = m->m_next; 1076 m->m_next = NULL; 1077 return (n); 1078} 1079/* 1080 * Routine to copy from device local memory into mbufs. | 35 */ 36 37#include "opt_param.h" 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/condvar.h> 41#include <sys/kernel.h> 42#include <sys/lock.h> --- 1030 unchanged lines hidden (view full) --- 1073 n->m_len = remain; 1074 m->m_len = len; 1075 n->m_next = m->m_next; 1076 m->m_next = NULL; 1077 return (n); 1078} 1079/* 1080 * Routine to copy from device local memory into mbufs. |
1081 * Note that `off' argument is offset into first mbuf of target chain from 1082 * which to begin copying the data to. |
|
1081 */ 1082struct mbuf * | 1083 */ 1084struct mbuf * |
1083m_devget(char *buf, int totlen, int off0, struct ifnet *ifp, | 1085m_devget(char *buf, int totlen, int off, struct ifnet *ifp, |
1084 void (*copy)(char *from, caddr_t to, u_int len)) 1085{ 1086 struct mbuf *m; 1087 struct mbuf *top = 0, **mp = ⊤ | 1086 void (*copy)(char *from, caddr_t to, u_int len)) 1087{ 1088 struct mbuf *m; 1089 struct mbuf *top = 0, **mp = ⊤ |
1088 int off = off0, len; 1089 char *cp; 1090 char *epkt; | 1090 int len; |
1091 | 1091 |
1092 cp = buf; 1093 epkt = cp + totlen; 1094 if (off) { 1095 cp += off + 2 * sizeof(u_short); 1096 totlen -= 2 * sizeof(u_short); 1097 } | 1092 if (off < 0 || off > MHLEN) 1093 return (NULL); 1094 |
1098 MGETHDR(m, M_DONTWAIT, MT_DATA); 1099 if (m == NULL) 1100 return (NULL); 1101 m->m_pkthdr.rcvif = ifp; 1102 m->m_pkthdr.len = totlen; | 1095 MGETHDR(m, M_DONTWAIT, MT_DATA); 1096 if (m == NULL) 1097 return (NULL); 1098 m->m_pkthdr.rcvif = ifp; 1099 m->m_pkthdr.len = totlen; |
1103 m->m_len = MHLEN; | 1100 len = MHLEN; |
1104 1105 while (totlen > 0) { 1106 if (top) { 1107 MGET(m, M_DONTWAIT, MT_DATA); 1108 if (m == NULL) { 1109 m_freem(top); 1110 return (NULL); 1111 } | 1101 1102 while (totlen > 0) { 1103 if (top) { 1104 MGET(m, M_DONTWAIT, MT_DATA); 1105 if (m == NULL) { 1106 m_freem(top); 1107 return (NULL); 1108 } |
1112 m->m_len = MLEN; | 1109 len = MLEN; |
1113 } | 1110 } |
1114 len = min(totlen, epkt - cp); 1115 if (len >= MINCLSIZE) { | 1111 if (totlen + off >= MINCLSIZE) { |
1116 MCLGET(m, M_DONTWAIT); 1117 if (m->m_flags & M_EXT) | 1112 MCLGET(m, M_DONTWAIT); 1113 if (m->m_flags & M_EXT) |
1118 m->m_len = len = min(len, MCLBYTES); 1119 else 1120 len = m->m_len; | 1114 len = MCLBYTES; |
1121 } else { 1122 /* 1123 * Place initial small packet/header at end of mbuf. 1124 */ | 1115 } else { 1116 /* 1117 * Place initial small packet/header at end of mbuf. 1118 */ |
1125 if (len < m->m_len) { 1126 if (top == NULL && len + 1127 max_linkhdr <= m->m_len) 1128 m->m_data += max_linkhdr; 1129 m->m_len = len; 1130 } else 1131 len = m->m_len; | 1119 if (top == NULL && totlen + off + max_linkhdr <= len) { 1120 m->m_data += max_linkhdr; 1121 len -= max_linkhdr; 1122 } |
1132 } | 1123 } |
1124 if (off) { 1125 m->m_data += off; 1126 len -= off; 1127 off = 0; 1128 } 1129 m->m_len = len = min(totlen, len); |
|
1133 if (copy) | 1130 if (copy) |
1134 copy(cp, mtod(m, caddr_t), (unsigned)len); | 1131 copy(buf, mtod(m, caddr_t), (unsigned)len); |
1135 else | 1132 else |
1136 bcopy(cp, mtod(m, caddr_t), (unsigned)len); 1137 cp += len; | 1133 bcopy(buf, mtod(m, caddr_t), (unsigned)len); 1134 buf += len; |
1138 *mp = m; 1139 mp = &m->m_next; 1140 totlen -= len; | 1135 *mp = m; 1136 mp = &m->m_next; 1137 totlen -= len; |
1141 if (cp == epkt) 1142 cp = buf; | |
1143 } 1144 return (top); 1145} 1146 1147/* 1148 * Copy data from a buffer back into the indicated mbuf chain, 1149 * starting "off" bytes from the beginning, extending the mbuf 1150 * chain if necessary. --- 60 unchanged lines hidden --- | 1138 } 1139 return (top); 1140} 1141 1142/* 1143 * Copy data from a buffer back into the indicated mbuf chain, 1144 * starting "off" bytes from the beginning, extending the mbuf 1145 * chain if necessary. --- 60 unchanged lines hidden --- |