FreeBSD/Linux Kernel Cross Reference
sys/dev/cxgb/sys/mvec.h
1 /**************************************************************************
2 *
3 * Copyright (c) 2007, Kip Macy kmacy@freebsd.org
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * 2. The name of Kip Macy nor the names of other
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $FreeBSD: releng/6.4/sys/dev/cxgb/sys/mvec.h 171884 2007-08-18 09:10:26Z kmacy $
29 *
30 ***************************************************************************/
31
32 #ifndef _MVEC_H_
33 #define _MVEC_H_
34
35 #define mtomv(m) ((struct mbuf_vec *)((m)->m_pktdat))
36
37 #define M_IOVEC 0x100000 /* mbuf immediate data area is used for cluster ptrs */
38 #define EXT_MBUF 7
39 #define MBUF_IOV_TYPE_MASK ((1<<3)-1)
40 #define mbuf_vec_set_type(mv, i, type) \
41 (mv)->mv_vec[(i)].mi_flags = (((mv)->mv_vec[(i)].mi_flags \
42 & ~MBUF_IOV_TYPE_MASK) | type)
43
44 #define mbuf_vec_get_type(mv, i) \
45 ((mv)->mv_vec[(i)].mi_flags & MBUF_IOV_TYPE_MASK)
46
47
48 struct mbuf_iovec {
49 uint16_t mi_flags; /* per-cluster flags */
50 uint16_t mi_len; /* length of cluster */
51 uint32_t mi_offset; /* data offsets into cluster */
52 caddr_t mi_base; /* pointers to cluster */
53 volatile uint32_t *mi_refcnt; /* refcnt for cluster*/
54 #ifdef __i386__
55 void *mi_args; /* for sf_buf */
56 #endif
57 };
58
59 #define MAX_MBUF_IOV ((MHLEN-8)/sizeof(struct mbuf_iovec))
60 struct mbuf_vec {
61 uint16_t mv_first; /* first valid cluster */
62 uint16_t mv_count; /* # of clusters */
63 uint32_t mv_flags; /* flags for iovec */
64 struct mbuf_iovec mv_vec[MAX_MBUF_IOV];
65 };
66
67 static __inline int
68 m_gettype(int size)
69 {
70 int type;
71
72 switch (size) {
73 case MSIZE:
74 type = EXT_MBUF;
75 break;
76 case MCLBYTES:
77 type = EXT_CLUSTER;
78 break;
79 #if MJUMPAGESIZE != MCLBYTES
80 case MJUMPAGESIZE:
81 type = EXT_JUMBOP;
82 break;
83 #endif
84 case MJUM9BYTES:
85 type = EXT_JUMBO9;
86 break;
87 case MJUM16BYTES:
88 type = EXT_JUMBO16;
89 break;
90 default:
91 panic("%s: m_getjcl: invalid cluster size", __func__);
92 }
93
94 return (type);
95 }
96
97 static __inline void
98 m_cljset(struct mbuf *m, void *cl, int type)
99 {
100 uma_zone_t zone;
101 int size;
102
103 switch (type) {
104 case EXT_CLUSTER:
105 size = MCLBYTES;
106 zone = zone_clust;
107 break;
108 #if MJUMPAGESIZE != MCLBYTES
109 case EXT_JUMBOP:
110 size = MJUMPAGESIZE;
111 zone = zone_jumbop;
112 break;
113 #endif
114 case EXT_JUMBO9:
115 size = MJUM9BYTES;
116 zone = zone_jumbo9;
117 break;
118 case EXT_JUMBO16:
119 size = MJUM16BYTES;
120 zone = zone_jumbo16;
121 break;
122 default:
123 panic("unknown cluster type");
124 break;
125 }
126
127 m->m_data = m->m_ext.ext_buf = cl;
128 m->m_ext.ext_free = m->m_ext.ext_args = NULL;
129 m->m_ext.ext_size = size;
130 m->m_ext.ext_type = type;
131 m->m_ext.ref_cnt = uma_find_refcnt(zone, cl);
132 if (*m->m_ext.ref_cnt == 0)
133 *m->m_ext.ref_cnt = 1;
134
135 m->m_flags |= M_EXT;
136
137 }
138
139
140 int _m_explode(struct mbuf *);
141 int _m_collapse(struct mbuf *, int maxbufs, struct mbuf **);
142 void mb_free_vec(struct mbuf *m);
143
144 static __inline void
145 m_iovinit(struct mbuf *m)
146 {
147 struct mbuf_vec *mv = mtomv(m);
148
149 mv->mv_first = mv->mv_count = 0;
150 m->m_pkthdr.len = m->m_len = 0;
151 m->m_flags |= M_IOVEC;
152 }
153
154 static __inline void
155 m_iovappend(struct mbuf *m, caddr_t cl, int size, int len, int offset)
156 {
157 struct mbuf_vec *mv = mtomv(m);
158 struct mbuf_iovec *iov;
159 int idx = mv->mv_first + mv->mv_count;
160
161 KASSERT(idx <= MAX_MBUF_IOV, ("tried to append too many clusters to mbuf iovec"));
162 if ((m->m_flags & M_EXT) != 0)
163 panic("invalid flags in %s", __func__);
164
165 if (mv->mv_count == 0)
166 m->m_data = (caddr_t)(cl + offset);
167
168 iov = &mv->mv_vec[idx];
169 iov->mi_flags = m_gettype(size);
170 iov->mi_base = cl;
171 iov->mi_len = len;
172 iov->mi_offset = offset;
173 m->m_pkthdr.len += len;
174 m->m_len += len;
175 mv->mv_count++;
176 }
177
178 static __inline int
179 m_explode(struct mbuf *m)
180 {
181 if ((m->m_flags & M_IOVEC) == 0)
182 return (0);
183
184 return _m_explode(m);
185 }
186
187 static __inline int
188 m_collapse(struct mbuf *m, int maxbufs, struct mbuf **mnew)
189 {
190 #if (!defined(__sparc64__) && !defined(__sun4v__))
191 if (m->m_next == NULL)
192 #endif
193 {
194 *mnew = m;
195 return (0);
196 }
197 return _m_collapse(m, maxbufs, mnew);
198 }
199
200 static __inline struct mbuf *
201 m_free_vec(struct mbuf *m)
202 {
203 struct mbuf *n = m->m_next;
204
205 if (m->m_flags & M_IOVEC)
206 mb_free_vec(m);
207 else if (m->m_flags & M_EXT)
208 mb_free_ext(m);
209 else
210 uma_zfree(zone_mbuf, m);
211 return (n);
212 }
213
214 static __inline void
215 m_freem_vec(struct mbuf *m)
216 {
217 while (m != NULL)
218 m = m_free_vec(m);
219 }
220
221 static __inline uma_zone_t
222 m_getzonefromtype(int type)
223 {
224 uma_zone_t zone;
225
226 switch (type) {
227 case EXT_MBUF:
228 zone = zone_mbuf;
229 break;
230 case EXT_CLUSTER:
231 zone = zone_clust;
232 break;
233 #if MJUMPAGESIZE != MCLBYTES
234 case EXT_JUMBOP:
235 zone = zone_jumbop;
236 break;
237 #endif
238 case EXT_JUMBO9:
239 zone = zone_jumbo9;
240 break;
241 case EXT_JUMBO16:
242 zone = zone_jumbo16;
243 break;
244 #ifndef PACKET_ZONE_DISABLED
245 case EXT_PACKET:
246 zone = zone_pack;
247 break;
248 #endif
249 default:
250 panic("%s: invalid cluster type %d", __func__, type);
251 }
252 return (zone);
253 }
254
255 #if (!defined(__sparc64__) && !defined(__sun4v__))
256 int
257 bus_dmamap_load_mvec_sg(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0,
258 bus_dma_segment_t *segs, int *nsegs, int flags);
259
260 #else
261 #define bus_dmamap_load_mvec_sg bus_dmamap_load_mbuf_sg
262 #endif
263
264 #endif
Cache object: a3a8719442f8e9009e8d33aee68c3148
|