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 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. |
1081 * Note that `off' argument is offset into first mbuf of target chain from 1082 * which to begin copying the data to. |
1083 */ 1084struct mbuf * |
1085m_devget(char *buf, int totlen, int off, struct ifnet *ifp, |
1086 void (*copy)(char *from, caddr_t to, u_int len)) 1087{ 1088 struct mbuf *m; 1089 struct mbuf *top = 0, **mp = ⊤ |
1090 int len; |
1091 |
1092 if (off < 0 || off > MHLEN) 1093 return (NULL); 1094 |
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; |
1100 len = MHLEN; |
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 } |
1109 len = MLEN; |
1110 } |
1111 if (totlen + off >= MINCLSIZE) { |
1112 MCLGET(m, M_DONTWAIT); 1113 if (m->m_flags & M_EXT) |
1114 len = MCLBYTES; |
1115 } else { 1116 /* 1117 * Place initial small packet/header at end of mbuf. 1118 */ |
1119 if (top == NULL && totlen + off + max_linkhdr <= len) { 1120 m->m_data += max_linkhdr; 1121 len -= max_linkhdr; 1122 } |
1123 } |
1124 if (off) { 1125 m->m_data += off; 1126 len -= off; 1127 off = 0; 1128 } 1129 m->m_len = len = min(totlen, len); |
1130 if (copy) |
1131 copy(buf, mtod(m, caddr_t), (unsigned)len); |
1132 else |
1133 bcopy(buf, mtod(m, caddr_t), (unsigned)len); 1134 buf += len; |
1135 *mp = m; 1136 mp = &m->m_next; 1137 totlen -= len; |
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 --- |