revert between 56095 -> 55830 in arch
[AROS.git] / workbench / network / stacks / AROSTCP / bsdsocket / net / sana2copybuff.c
blobc41b3438dae89685e3a765c03cc86b94647d98f3
1 /*
2 * Copyright (C) 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>
3 * Helsinki University of Technology, Finland.
4 * All rights reserved.
5 * Copyright (C) 2005 Neil Cafferkey
6 * Copyright (C) 2005 Pavel Fedin
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20 * MA 02111-1307, USA.
24 #include <conf.h>
26 #include <aros/asmcall.h>
28 #include <sys/param.h>
29 #include <sys/systm.h>
30 #include <sys/malloc.h>
31 #include <sys/mbuf.h>
32 #include <sys/socket.h>
33 #include <sys/socketvar.h>
34 #include <sys/syslog.h>
35 #include <sys/synch.h>
37 #include <net/if.h>
39 #if INET
40 #include <netinet/in.h>
41 #include <netinet/in_systm.h>
42 #include <netinet/in_var.h>
43 #include <netinet/ip.h>
44 #endif
46 #include <net/if_sana.h>
47 #include <api/amiga_raf.h>
48 #define bcopy(a,b,c) CopyMem((APTR)(a),b,c)
51 * allocate mbufs for the size MTU at free_chain for read request
53 #if 0 /* old one */
54 BOOL
55 ioip_alloc_mbuf(struct IOIPReq *s2rp, ULONG MTU)
57 register struct mbuf *m, *n;
58 register int len = 0;
60 n = s2rp->ioip_reserved;
62 /* Check for packet header */
63 if (n && (n->m_flags & M_PKTHDR)) {
64 /* There is already a full packet */
65 return TRUE;
68 /* Prepend by a packet header */
69 MGETHDR(m, M_NOWAIT, MT_HEADER);
70 if (m) {
71 m->m_len = len = MHLEN;
72 s2rp->ioip_reserved = m;
73 m->m_next = n;
75 /* Find the end of the free chain */ /* ASSUME THAT THESE HAVE CLUSTERS */
76 while (n = m->m_next) {
77 len += n->m_len; m = n;
81 * add new (cluster)mbufs to get the desired size
83 while (len < MTU) {
84 MGET(n, M_NOWAIT, MT_DATA);
85 if (n != NULL) {
86 MCLGET(n, M_NOWAIT);
87 if (n->m_ext.ext_buf != NULL) {
88 n->m_len = n->m_ext.ext_size;
89 len += n->m_ext.ext_size;
91 else {
92 m_free(n);
93 break;
95 m = m->m_next = n;
97 else
98 break;
101 s2rp->ioip_reserved->m_pkthdr.len = len;
103 if (len < MTU) {
104 m_freem(s2rp->ioip_reserved);
105 s2rp->ioip_reserved = NULL;
106 return FALSE;
109 return TRUE;
111 #else
112 BOOL
113 ioip_alloc_mbuf(struct IOIPReq *s2rp, ULONG MTU)
115 register struct mbuf *m, *n;
116 register int len;
119 * s2rp->ioip_reserved is either NULL, or an mbuf chain, possibly having
120 * packet header in the first one.
122 n = s2rp->ioip_reserved;
124 /* Check for packet header */
125 if (n && (n->m_flags & M_PKTHDR)) {
127 * chain already has the packet header
129 m = n;
130 len = m->m_len;
132 else {
133 /* Prepend by a packet header */
134 MGETHDR(m, M_NOWAIT, MT_HEADER);
135 if (m) {
136 m->m_len = len = MHLEN;
137 s2rp->ioip_reserved = m;
138 m->m_next = n;
140 else
141 goto fail;
144 * Now m points to the start of the mbuf chain. The first mbuf has
145 * a packet header.
148 /* Find the end of the free chain */ /* ASSUME THAT THESE HAVE CLUSTERS */
149 while (n = m->m_next) {
150 len += n->m_len; m = n;
154 * Now len has the total length of the mbuf chain, add new
155 * (cluster)mbufs to get the desired size (MTU).
157 while (len < MTU) {
158 MGET(n, M_NOWAIT, MT_DATA);
159 if (n != NULL) {
160 MCLGET(n, M_NOWAIT);
161 if (n->m_ext.ext_buf != NULL) {
162 len += n->m_len = n->m_ext.ext_size;
164 else {
165 m_free(n);
166 goto fail;
168 m = m->m_next = n;
170 else
171 goto fail;
173 s2rp->ioip_reserved->m_pkthdr.len = len;
174 return TRUE;
176 fail:
177 m_freem(s2rp->ioip_reserved);
178 s2rp->ioip_reserved = NULL;
179 return FALSE;
181 #endif
184 * Copy data from an mbuf chain starting from the beginning,
185 * continuing for "n" bytes, into the indicated continuous buffer.
187 * NOTE: this WILL be called from INTERRUPTS, so compile with stack checking
188 * disabled and use __saveds if near data is needed.
190 /*static SAVEDS BOOL m_copy_from_mbuf(
191 REG(a0, BYTE *to),
192 REG(a1, struct IOIPReq *from),
193 REG(d0, ULONG n))*/
194 AROS_UFH3(BOOL, m_copy_from_mbuf,
195 AROS_UFHA(BYTE *, to, A0),
196 AROS_UFHA(struct IOIPReq *, from, A1),
197 AROS_UFHA(ULONG, n, D0))
199 AROS_USERFUNC_INIT
200 register struct mbuf *m = from->ioip_packet;
201 register unsigned count;
203 while (n > 0) {
204 #if DIAGNOSTIC
205 if (m == 0) {
206 log(LOG_ERR, "m_copy_from_buff: mbuf chain short");
207 return FALSE;
209 #endif
210 count = MIN(m->m_len, n);
211 bcopy(mtod(m, caddr_t), to, count);
212 n -= count;
213 to += count;
214 m = m->m_next;
216 return TRUE;
217 AROS_USERFUNC_EXIT
221 * Copy data from an continuous buffer 'from' to preallocated mbuf chain
222 * starting from the beginning, continuing for "n" bytes.
223 * Mbufs in the preallocated chain must have their m_len field set to maximum
224 * amount of data that they can have.
226 * NOTE: this WILL be called from INTERRUPTS, so compile with stack checking
227 * disabled and use __saveds if near data is needed.
229 /*static SAVEDS BOOL m_copy_to_mbuf(
230 REG(a0, struct IOIPReq* to),
231 REG(a1, BYTE *from),
232 REG(d0, ULONG n))*/
233 AROS_UFH3(BOOL, m_copy_to_mbuf,
234 AROS_UFHA(struct IOIPReq *, to, A0),
235 AROS_UFHA(BYTE *, from, A1),
236 AROS_UFHA(ULONG, n, D0))
238 AROS_USERFUNC_INIT
239 register struct mbuf *f, *m = to->ioip_reserved;
240 unsigned totlen = n;
242 #if DIAGNOSTIC
243 if (!(m->m_flags & M_PKTHDR)) {
244 log(LOG_ERR, "m_copy_to_buff: mbuf chain has no header");
245 return FALSE;
247 #endif
249 while (n > 0) {
250 #if DIAGNOSTIC
251 if (m == 0) {
252 log(LOG_ERR, "m_copy_to_buff: mbuf chain short, "
253 "packet len =%lu, reserved =%lu, "
254 "wiretype =%lu, mtu =%lu",
255 totlen, to->ioip_reserved->m_pkthdr.len,
256 to->ioip_s2.ios2_PacketType,
257 (ULONG)to->ioip_if->ss_if.if_mtu);
258 return FALSE;
260 #endif
261 if (n < m->m_len)
262 m->m_len = n;
263 bcopy(from, mtod(m, caddr_t), m->m_len);
264 from += m->m_len;
265 n -= m->m_len;
266 if (n > 0)
267 m = m->m_next;
271 * move the packet to the field 'ioip_packet',
272 * set total length of the packet and terminate it.
274 f = m->m_next; /* first free mbuf */
275 m->m_next = NULL; /* terminate the chain */
277 to->ioip_packet = to->ioip_reserved;
278 to->ioip_packet->m_pkthdr.len = totlen; /* set packet length */
279 to->ioip_reserved = f; /* leftover mbufs */
282 * More mbuf flags and interface pointer must be set later
284 return TRUE;
285 AROS_USERFUNC_EXIT
288 struct TagItem buffermanagement[3] = {
289 { S2_CopyToBuff, (IPTR)AROS_ASMSYMNAME(m_copy_to_mbuf) },
290 { S2_CopyFromBuff, (IPTR)AROS_ASMSYMNAME(m_copy_from_mbuf) },
291 { TAG_END, }