]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/sys/memdesc.h
unbound: Vendor import 1.19.3
[FreeBSD/FreeBSD.git] / sys / sys / memdesc.h
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2012 EMC Corp.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * 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 AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 #ifndef _SYS_MEMDESC_H_
30 #define _SYS_MEMDESC_H_
31
32 struct bio;
33 struct bus_dma_segment;
34 struct uio;
35 struct mbuf;
36 struct vm_page;
37 union ccb;
38
39 /*
40  * struct memdesc encapsulates various memory descriptors and provides
41  * abstract access to them.
42  */
43 struct memdesc {
44         union {
45                 void                    *md_vaddr;
46                 vm_paddr_t              md_paddr;
47                 struct bus_dma_segment  *md_list;
48                 struct uio              *md_uio;
49                 struct mbuf             *md_mbuf;
50                 struct vm_page          **md_ma;
51         } u;
52         union {                         /* type specific data. */
53                 size_t          md_len; /* VADDR, PADDR, VMPAGES */
54                 int             md_nseg; /* VLIST, PLIST */
55         };
56         union {
57                 uint32_t        md_offset; /* VMPAGES */
58         };
59         uint32_t        md_type;        /* Type of memory. */
60 };
61
62 #define MEMDESC_VADDR   1       /* Contiguous virtual address. */
63 #define MEMDESC_PADDR   2       /* Contiguous physical address. */
64 #define MEMDESC_VLIST   3       /* scatter/gather list of kva addresses. */
65 #define MEMDESC_PLIST   4       /* scatter/gather list of physical addresses. */
66 #define MEMDESC_UIO     6       /* Pointer to a uio (any io). */
67 #define MEMDESC_MBUF    7       /* Pointer to a mbuf (network io). */
68 #define MEMDESC_VMPAGES 8       /* Pointer to array of VM pages. */
69
70 static inline struct memdesc
71 memdesc_vaddr(void *vaddr, size_t len)
72 {
73         struct memdesc mem;
74
75         mem.u.md_vaddr = vaddr;
76         mem.md_len = len;
77         mem.md_type = MEMDESC_VADDR;
78
79         return (mem);
80 }
81
82 static inline struct memdesc
83 memdesc_paddr(vm_paddr_t paddr, size_t len)
84 {
85         struct memdesc mem;
86
87         mem.u.md_paddr = paddr;
88         mem.md_len = len;
89         mem.md_type = MEMDESC_PADDR;
90
91         return (mem);
92 }
93
94 static inline struct memdesc
95 memdesc_vlist(struct bus_dma_segment *vlist, int sglist_cnt)
96 {
97         struct memdesc mem;
98
99         mem.u.md_list = vlist;
100         mem.md_nseg = sglist_cnt;
101         mem.md_type = MEMDESC_VLIST;
102
103         return (mem);
104 }
105
106 static inline struct memdesc
107 memdesc_plist(struct bus_dma_segment *plist, int sglist_cnt)
108 {
109         struct memdesc mem;
110
111         mem.u.md_list = plist;
112         mem.md_nseg = sglist_cnt;
113         mem.md_type = MEMDESC_PLIST;
114
115         return (mem);
116 }
117
118 static inline struct memdesc
119 memdesc_uio(struct uio *uio)
120 {
121         struct memdesc mem;
122
123         mem.u.md_uio = uio;
124         mem.md_type = MEMDESC_UIO;
125
126         return (mem);
127 }
128
129 static inline struct memdesc
130 memdesc_mbuf(struct mbuf *mbuf)
131 {
132         struct memdesc mem;
133
134         mem.u.md_mbuf = mbuf;
135         mem.md_type = MEMDESC_MBUF;
136
137         return (mem);
138 }
139
140 static inline struct memdesc
141 memdesc_vmpages(struct vm_page **ma, size_t len, u_int ma_offset)
142 {
143         struct memdesc mem;
144
145         mem.u.md_ma = ma;
146         mem.md_len = len;
147         mem.md_type = MEMDESC_VMPAGES;
148         mem.md_offset = ma_offset;
149
150         return (mem);
151 }
152
153 struct memdesc  memdesc_bio(struct bio *bio);
154 struct memdesc  memdesc_ccb(union ccb *ccb);
155
156 /*
157  * Similar to m_copyback/data, *_copyback copy data from the 'src'
158  * buffer into the memory descriptor's data buffer while *_copydata
159  * copy data from the memory descriptor's data buffer into the the
160  * 'dst' buffer.
161  */
162 void    memdesc_copyback(struct memdesc *mem, int off, int size,
163     const void *src);
164 void    memdesc_copydata(struct memdesc *mem, int off, int size, void *dst);
165
166 /*
167  * This routine constructs a chain of M_EXT mbufs backed by a data
168  * buffer described by a memory descriptor.  Some buffers may require
169  * multiple mbufs.  For memory descriptors using unmapped storage
170  * (e.g. memdesc_vmpages), M_EXTPG mbufs are used.
171  *
172  * Since memory descriptors are not an actual buffer, just a
173  * description of the buffer, the caller is required to supply a
174  * couple of helper routines to manage allocation of the raw mbufs and
175  * associate them with a reference to the underlying buffer.
176  *
177  * The memdesc_alloc_ext_mbuf_t callback is passed the callback
178  * argument as its first argument, the how flag as its second
179  * argument, and the pointer and length of a KVA buffer.  This
180  * callback should allocate an mbuf for the KVA buffer, either by
181  * making a copy of the data or using m_extaddref().
182  *
183  * The memdesc_alloc_extpg_mbuf_t callback is passed the callback
184  * argument as its first argument and the how flag as its second
185  * argument.  It should return an empty mbuf allocated by
186  * mb_alloc_ext_pgs.
187  *
188  * If either of the callbacks returns NULL, any partially allocated
189  * chain is freed and this routine returns NULL.
190  *
191  * If can_truncate is true, then this function might return a short
192  * chain to avoid gratuitously splitting up a page.
193  */
194 typedef struct mbuf *memdesc_alloc_ext_mbuf_t(void *, int, void *, size_t);
195 typedef struct mbuf *memdesc_alloc_extpg_mbuf_t(void *, int);
196
197 struct mbuf *memdesc_alloc_ext_mbufs(struct memdesc *mem,
198     memdesc_alloc_ext_mbuf_t *ext_alloc,
199     memdesc_alloc_extpg_mbuf_t *extpg_alloc, void *cb_arg, int how,
200     size_t offset, size_t len, size_t *actual_len, bool can_truncate);
201
202 #endif /* _SYS_MEMDESC_H_ */