]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - 6/sys/dev/cxgb/sys/mvec.h
merge fix for boot-time hang on centos' xen
[FreeBSD/FreeBSD.git] / 6 / 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$
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