1/*
2 * Copyright (c) 2000, 2001 Boris Popov
3 * 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
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *    This product includes software developed by Boris Popov.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * $FreeBSD: src/sys/sys/mchain.h,v 1.1 2001/02/24 15:44:30 bp Exp $
33 */
34
35/*
36 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
37 * Use is subject to license terms.
38 */
39
40#ifndef _MCHAIN_H_
41#define	_MCHAIN_H_
42
43#include <sys/types.h>
44#include <sys/isa_defs.h>
45#include <sys/byteorder.h>
46
47#ifdef _LITTLE_ENDIAN
48
49/* little-endian values on little-endian */
50#define	htoles(x)	((uint16_t)(x))
51#define	letohs(x)	((uint16_t)(x))
52#define	htolel(x)	((uint32_t)(x))
53#define	letohl(x)	((uint32_t)(x))
54#define	htoleq(x)	((uint64_t)(x))
55#define	letohq(x)	((uint64_t)(x))
56
57/*
58 * big-endian values on little-endian (swap)
59 *
60 * Use the BSWAP macros because they're fastest, and they're
61 * available in all environments where we use this header.
62 */
63#define	htobes(x)	BSWAP_16(x)
64#define	betohs(x)	BSWAP_16(x)
65#define	htobel(x)	BSWAP_32(x)
66#define	betohl(x)	BSWAP_32(x)
67#define	htobeq(x)	BSWAP_64(x)
68#define	betohq(x)	BSWAP_64(x)
69
70#else	/* (BYTE_ORDER == LITTLE_ENDIAN) */
71
72/* little-endian values on big-endian (swap) */
73#define	letohs(x) 	BSWAP_16(x)
74#define	htoles(x) 	BSWAP_16(x)
75#define	letohl(x) 	BSWAP_32(x)
76#define	htolel(x) 	BSWAP_32(x)
77#define	letohq(x)	BSWAP_64(x)
78#define	htoleq(x)	BSWAP_64(x)
79
80/* big-endian values on big-endian */
81#define	htobes(x)	((uint16_t)(x))
82#define	betohs(x)	((uint16_t)(x))
83#define	htobel(x)	((uint32_t)(x))
84#define	betohl(x)	((uint32_t)(x))
85#define	htobeq(x)	((uint64_t)(x))
86#define	betohq(x)	((uint64_t)(x))
87#endif	/* (BYTE_ORDER == LITTLE_ENDIAN) */
88
89
90/*
91 * Additions for Solaris to replace things that came from
92 * <sys/mbuf.h> in the Darwin code.  These are mostly just
93 * wrappers for streams functions.  See: subr_mchain.c
94 */
95
96#ifdef _KERNEL
97
98/*
99 * BSD-style mbuf "shim" for kernel code.  Note, this
100 * does NOT implement BSD mbufs in the kernel.  Rather,
101 * macros and wrapper functions are used so that code
102 * fomerly using mbuf_t now use STREAMS mblk_t instead.
103 */
104
105#include <sys/stream.h> /* mblk_t */
106typedef mblk_t mbuf_t;
107
108/* BEGIN CSTYLED */
109/*
110 * BSD-style mbufs, vs SysV-style mblks:
111 * One big difference: the mbuf payload is:
112 *   m_data ... (m_data + m_len)
113 * In Unix STREAMS, the mblk payload is:
114 *   b_rptr ... b_wptr
115 *
116 * Here are some handy conversion notes:
117 *
118 * struct mbuf                     struct mblk
119 *   m->m_next                       m->b_cont
120 *   m->m_nextpkt                    m->b_next
121 *   m->m_data                       m->b_rptr
122 *   m->m_len                        MBLKL(m)
123 *   m->m_dat[]                      m->b_datap->db_base
124 *   &m->m_dat[MLEN]                 m->b_datap->db_lim
125 *   M_TRAILINGSPACE(m)              MBLKTAIL(m)
126 *   m_freem(m)                      freemsg(m)
127 *
128 * Note that mbufs chains also have a special "packet" header,
129 * which has the length of the whole message.  In STREAMS one
130 * typically just calls msgdsize(m) to get that.
131 */
132/* END CSTYLED */
133
134#define	mtod(m, t) ((t)((m)->b_rptr))
135
136/* length arg for m_copym to "copy all" */
137#define	M_COPYALL		-1
138
139mblk_t *m_copym(mblk_t *, int, int, int);
140mblk_t *m_pullup(mblk_t *, int);
141mblk_t *m_split(mblk_t *, int, int);
142void m_cat(mblk_t *, mblk_t *);
143#define	m_freem(x)	freemsg(x)
144mblk_t *m_getblk(int, int);
145int  m_fixhdr(mblk_t *m);
146
147#else	/* _KERNEL */
148
149/*
150 * BSD-style mbuf work-alike, for user-level.
151 * See libsmbfs mbuf.c
152 */
153typedef struct mbuf {
154	int		m_len;
155	int		m_maxlen;
156	char		*m_data;
157	struct mbuf	*m_next;
158} mbuf_t;
159
160#define	mtod(m, t)	((t)(m)->m_data)
161
162int m_get(int, mbuf_t **);
163void m_freem(mbuf_t *);
164
165#endif	/* _KERNEL */
166
167/*
168 * BSD-style mbchain/mdchain work-alike
169 */
170
171/*
172 * Type of copy for mb_{put|get}_mem()
173 */
174#define	MB_MSYSTEM	0		/* use bcopy() */
175#define	MB_MUSER	1		/* use copyin()/copyout() */
176#define	MB_MINLINE	2		/* use an inline copy loop */
177#define	MB_MZERO	3		/* bzero(), mb_put_mem only */
178#define	MB_MCUSTOM	4		/* use an user defined function */
179
180#ifdef _KERNEL
181
182struct mbchain {
183	mblk_t *mb_top;
184	mblk_t *mb_cur;
185	uint_t mb_count;
186};
187typedef struct mbchain mbchain_t;
188
189struct mdchain {
190	mblk_t *md_top;		/* head of mblk chain */
191	mblk_t *md_cur;		/* current mblk */
192	uchar_t *md_pos;	/* position in md_cur */
193	/* NB: md_pos is same type as mblk_t b_rptr, b_wptr members. */
194};
195typedef struct mdchain mdchain_t;
196
197mblk_t *mb_detach(mbchain_t *mbp);
198int  mb_fixhdr(mbchain_t *mbp);
199int  mb_put_uio(mbchain_t *mbp, uio_t *uiop, size_t size);
200
201void md_append_record(mdchain_t *mdp, mblk_t *top);
202void md_next_record(mdchain_t *mdp);
203int  md_get_uio(mdchain_t *mdp, uio_t *uiop, size_t size);
204
205#else	/* _KERNEL */
206
207/*
208 * user-level code uses the same struct for both (MB, MD)
209 */
210typedef struct mbdata {
211	mbuf_t	*mb_top;	/* head of mbuf chain */
212	mbuf_t	*mb_cur;	/* current mbuf */
213	char	*mb_pos;	/* position in mb_cur (get) */
214	/* NB: mb_pos is same type as mbuf_t m_data member. */
215	int	mb_count;	/* bytes marshalled (put) */
216} mbdata_t;
217typedef struct mbdata mbchain_t;
218typedef struct mbdata mdchain_t;
219
220#endif	/* _KERNEL */
221
222int  mb_init(mbchain_t *);
223void mb_initm(mbchain_t *, mbuf_t *);
224void mb_done(mbchain_t *);
225void *mb_reserve(mbchain_t *, int size);
226
227int  mb_put_padbyte(mbchain_t *mbp);
228int  mb_put_uint8(mbchain_t *, uint8_t);
229int  mb_put_uint16be(mbchain_t *, uint16_t);
230int  mb_put_uint16le(mbchain_t *, uint16_t);
231int  mb_put_uint32be(mbchain_t *, uint32_t);
232int  mb_put_uint32le(mbchain_t *, uint32_t);
233int  mb_put_uint64be(mbchain_t *, uint64_t);
234int  mb_put_uint64le(mbchain_t *, uint64_t);
235int  mb_put_mem(mbchain_t *, const void *, int, int);
236int  mb_put_mbuf(mbchain_t *, mbuf_t *);
237
238int  md_init(mdchain_t *mdp);
239void md_initm(mdchain_t *mbp, mbuf_t *m);
240void md_done(mdchain_t *mdp);
241
242int  md_get_uint8(mdchain_t *, uint8_t *);
243int  md_get_uint16be(mdchain_t *, uint16_t *);
244int  md_get_uint16le(mdchain_t *, uint16_t *);
245int  md_get_uint32be(mdchain_t *, uint32_t *);
246int  md_get_uint32le(mdchain_t *, uint32_t *);
247int  md_get_uint64be(mdchain_t *, uint64_t *);
248int  md_get_uint64le(mdchain_t *, uint64_t *);
249int  md_get_mem(mdchain_t *, void *, int, int);
250int  md_get_mbuf(mdchain_t *, int, mbuf_t **);
251
252#endif	/* !_MCHAIN_H_ */
253