FreeBSD/Linux Kernel Cross Reference
sys/sys/lkm.h
1 /*
2 * Header file used by loadable kernel modules and loadable kernel module
3 * utilities.
4 *
5 * 23 Jan 93 Terry Lambert Original
6 *
7 * Copyright (c) 1992 Terrence R. Lambert.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by Terrence R. Lambert.
21 * 4. The name Terrence R. Lambert may not be used to endorse or promote
22 * products derived from this software without specific prior written
23 * permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY TERRENCE R. LAMBERT ``AS IS'' AND ANY
26 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE TERRENCE R. LAMBERT BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 * $FreeBSD$
38 */
39
40 #ifndef _SYS_LKM_H_
41 #define _SYS_LKM_H_
42
43 /*
44 * Supported module types
45 */
46 typedef enum loadmod {
47 LM_SYSCALL,
48 LM_VFS,
49 LM_DEV,
50 LM_STRMOD,
51 LM_EXEC,
52 LM_MISC
53 } MODTYPE;
54
55
56 #define LKM_VERSION 1 /* version of module loader */
57 #define MAXLKMNAME 32
58
59 /****************************************************************************/
60
61 #ifdef KERNEL
62
63
64 /*
65 * Loadable system call
66 */
67 struct lkm_syscall {
68 MODTYPE lkm_type;
69 int lkm_ver;
70 const char *lkm_name;
71 u_long lkm_offset; /* save/assign area */
72 struct sysent *lkm_sysent;
73 struct sysent lkm_oldent; /* save area for unload */
74 };
75
76 /*
77 * Loadable file system
78 */
79 struct lkm_vfs {
80 MODTYPE lkm_type;
81 int lkm_ver;
82 const char *lkm_name;
83 u_long lkm_offset;
84 struct linker_set *lkm_vnodeops;
85 struct vfsconf *lkm_vfsconf;
86 };
87
88 /*
89 * Supported device module types
90 */
91 typedef enum devtype {
92 LM_DT_BLOCK,
93 LM_DT_CHAR
94 } DEVTYPE;
95
96 /*
97 * Loadable device driver
98 */
99 struct lkm_dev {
100 MODTYPE lkm_type;
101 int lkm_ver;
102 const char *lkm_name;
103 u_long lkm_offset;
104 DEVTYPE lkm_devtype;
105 union {
106 void *anon;
107 struct cdevsw *bdev;
108 struct cdevsw *cdev;
109 } lkm_dev;
110 union {
111 struct cdevsw *bdev;
112 struct cdevsw *cdev;
113 } lkm_olddev;
114 };
115
116 /*
117 * Loadable streams module
118 */
119 struct lkm_strmod {
120 MODTYPE lkm_type;
121 int lkm_ver;
122 const char *lkm_name;
123 u_long lkm_offset;
124 /*
125 * Removed: future release
126 */
127 };
128
129 /*
130 * Exec loader
131 */
132 struct lkm_exec {
133 MODTYPE lkm_type;
134 int lkm_ver;
135 const char *lkm_name;
136 u_long lkm_offset;
137 const struct execsw *lkm_exec;
138 struct execsw lkm_oldexec;
139 };
140
141 /*
142 * Miscellaneous module (complex load/unload, potentially complex stat
143 */
144 struct lkm_misc {
145 MODTYPE lkm_type;
146 int lkm_ver;
147 const char *lkm_name;
148 u_long lkm_offset;
149 };
150
151 /*
152 * Any module (to get type and name info without knowing type)
153 */
154 struct lkm_any {
155 MODTYPE lkm_type;
156 int lkm_ver;
157 const char *lkm_name;
158 u_long lkm_offset;
159 };
160
161
162 /*
163 * Generic reference ala XEvent to allow single entry point in the xxxinit()
164 * routine.
165 */
166 union lkm_generic {
167 struct lkm_any *lkm_any;
168 struct lkm_syscall *lkm_syscall;
169 struct lkm_vfs *lkm_vfs;
170 struct lkm_dev *lkm_dev;
171 struct lkm_strmod *lkm_strmod;
172 struct lkm_exec *lkm_exec;
173 struct lkm_misc *lkm_misc;
174 };
175
176 union lkm_all {
177 struct lkm_any lkm_any;
178 struct lkm_syscall lkm_syscall;
179 struct lkm_vfs lkm_vfs;
180 struct lkm_dev lkm_dev;
181 struct lkm_strmod lkm_strmod;
182 struct lkm_exec lkm_exec;
183 struct lkm_misc lkm_misc;
184 };
185
186 /*
187 * Per module information structure
188 */
189 struct lkm_table {
190 int type;
191 u_long size;
192 u_long offset;
193 u_long area;
194 char used;
195
196 int ver; /* version (INIT) */
197 int refcnt; /* reference count (INIT) */
198 int depcnt; /* dependency count (INIT) */
199 int id; /* identifier (INIT) */
200
201 int (*entry) __P((struct lkm_table *, int, int));
202 /* entry function */
203 union lkm_generic private; /* module private data */
204 };
205
206
207 #define LKM_E_LOAD 1
208 #define LKM_E_UNLOAD 2
209 #define LKM_E_STAT 3
210
211 /* Flag to indicate that LKM should select the slot, etc. Supported by:
212 * devslot in MOD_DEV
213 */
214 #define LKM_ANON ((u_long)-1)
215
216 /* XXX wcd.c pokes around in the lkm private structure, so until that
217 * is fixed here is a way to export the structure name.
218 */
219 #define MOD_PRIVATE(name) name ## _mod_struct
220
221 #define MOD_DECL(name) \
222 static int name ## _load __P((struct lkm_table *lkmtp, int cmd)); \
223 static int name ## _unload __P((struct lkm_table *lkmtp, int cmd)); \
224 int name ## _mod __P((struct lkm_table *lkmtp, int cmd, int ver))
225
226 #define MOD_SYSCALL(name,callslot,sysentp) \
227 static struct lkm_syscall MOD_PRIVATE(name) = { \
228 LM_SYSCALL, \
229 LKM_VERSION, \
230 #name, \
231 callslot, \
232 sysentp \
233 }
234
235 #define MOD_VFS(name,vnodeops,vfsconf) \
236 static struct lkm_vfs MOD_PRIVATE(name) = { \
237 LM_VFS, \
238 LKM_VERSION, \
239 #name, \
240 0, \
241 vnodeops, \
242 vfsconf \
243 }
244
245 #define MOD_DEV(name,devtype,devslot,devp) \
246 MOD_DECL(name); \
247 static struct lkm_dev MOD_PRIVATE(name) = { \
248 LM_DEV, \
249 LKM_VERSION, \
250 #name ## "_mod", \
251 devslot, \
252 devtype, \
253 { (void *)devp } \
254 }
255
256 #define MOD_EXEC(name,execslot,execsw) \
257 MOD_DECL(name); \
258 static struct lkm_exec MOD_PRIVATE(name) = { \
259 LM_EXEC, \
260 LKM_VERSION, \
261 #name ## "_mod", \
262 execslot, \
263 execsw \
264 }
265
266 #define MOD_MISC(name) \
267 MOD_DECL(name); \
268 static struct lkm_misc MOD_PRIVATE(name) = { \
269 LM_MISC, \
270 LKM_VERSION, \
271 #name ## "_mod" \
272 }
273
274 /*
275 * MOD_DISPATCH -- body function for use in module entry point function;
276 * generally, the function body will consist entirely of a single
277 * MOD_DISPATCH line.
278 *
279 * Call load/unload/stat on each corresponding entry instance. "cmd" is
280 * passed to each function so that a single function can be used if desired.
281 *
282 */
283 #define MOD_DISPATCH(name,lkmtp,cmd,ver,load,unload,stat) \
284 if (ver != LKM_VERSION) \
285 return EINVAL; /* version mismatch */ \
286 switch (cmd) { \
287 int error; \
288 case LKM_E_LOAD: \
289 lkmtp->private.lkm_any = \
290 (struct lkm_any *)& MOD_PRIVATE(name) ; \
291 if (lkmexists(lkmtp)) /* !!! */ \
292 return EEXIST; \
293 if ((error = load(lkmtp, cmd))) \
294 return error; \
295 break; \
296 case LKM_E_UNLOAD: \
297 if ((error = unload(lkmtp, cmd))) \
298 return error; \
299 break; \
300 case LKM_E_STAT: \
301 if ((error = stat(lkmtp, cmd))) \
302 return error; \
303 break; \
304 } \
305 return lkmdispatch(lkmtp, cmd);
306
307 /* Provide a backward compatible stub that will generate compile time errors.
308 * When fixing, prefer MOD_DISPATCH to be consistent with the others.
309 */
310 #define DISPATCH(name,lkmtp,cmd,ver,load,unload,stat) \
311 MOD_DISPATCH(name,lkmtp,cmd,ver,load,unload,stat)
312
313 int lkmdispatch __P((struct lkm_table *lkmtp, int cmd));
314 int lkmexists __P((struct lkm_table *lkmtp));
315 int lkm_nullcmd __P((struct lkm_table *lkmtp, int cmd));
316
317 #endif /* KERNEL */
318
319 /****************************************************************************/
320
321 /*
322 * IOCTL's recognized by /dev/lkm
323 */
324 #define LMRESERV _IOWR('K', 0, struct lmc_resrv)
325 #define LMLOADBUF _IOW('K', 1, struct lmc_loadbuf)
326 #define LMUNRESRV _IO('K', 2)
327 #define LMREADY _IOW('K', 3, int)
328
329 #define LMLOAD _IOW('K', 9, struct lmc_load)
330 #define LMUNLOAD _IOWR('K', 10, struct lmc_unload)
331 #define LMSTAT _IOWR('K', 11, struct lmc_stat)
332
333 #define MODIOBUF 512 /* # of bytes at a time to loadbuf */
334
335 /*
336 * IOCTL arguments
337 */
338
339
340 /*
341 * Reserve a page-aligned block of kernel memory for the module
342 */
343 struct lmc_resrv {
344 u_long size; /* IN: size of module to reserve */
345 const char *name; /* IN: name (must be provided */
346 int slot; /* OUT: allocated slot (module ID) */
347 u_long addr; /* OUT: Link-to address */
348 };
349
350
351 /*
352 * Copy a buffer at a time into the allocated area in the kernel; writes
353 * are assumed to occur contiguously.
354 */
355 struct lmc_loadbuf {
356 int cnt; /* IN: # of chars pointed to by data */
357 char *data; /* IN: pointer to data buffer */
358 };
359
360
361 /*
362 * Load a module (assumes it's been mmapped to address before call)
363 */
364 struct lmc_load {
365 caddr_t address; /* IN: user space mmap address */
366 int status; /* OUT: status of operation */
367 int id; /* OUT: module ID if loaded */
368 };
369
370 /*
371 * Unload a module (by name/id)
372 */
373 struct lmc_unload {
374 int id; /* IN: module ID to unload */
375 const char *name; /* IN: module name to unload if id -1 */
376 int status; /* OUT: status of operation */
377 };
378
379
380 /*
381 * Get module information for a given id (or name if id == -1).
382 */
383 struct lmc_stat {
384 int id; /* IN: module ID to unload */
385 char name[MAXLKMNAME]; /* IN/OUT: name of module */
386 u_long offset; /* OUT: target table offset */
387 MODTYPE type; /* OUT: type of module */
388 u_long area; /* OUT: kernel load addr */
389 u_long size; /* OUT: module size (pages) */
390 u_long private; /* OUT: module private data */
391 int ver; /* OUT: lkm compile version */
392 };
393
394 #endif /* !_SYS_LKM_H_ */
Cache object: 1cc1c5698e456896f944694625cd0422
|