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: src/sys/sys/lkm.h,v 1.12.2.3 1999/09/05 08:22:32 peter Exp $
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 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 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 char *lkm_name;
103 u_long lkm_offset;
104 DEVTYPE lkm_devtype;
105 union {
106 void *anon;
107 struct bdevsw *bdev;
108 struct cdevsw *cdev;
109 } lkm_dev;
110 union {
111 struct bdevsw *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 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 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 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 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 #define MOD_DECL(name) \
212 static int name ## _load __P((struct lkm_table *lkmtp, int cmd)); \
213 static int name ## _unload __P((struct lkm_table *lkmtp, int cmd)); \
214 int name ## _mod __P((struct lkm_table *lkmtp, int cmd, int ver)) \
215
216 #define MOD_SYSCALL(name,callslot,sysentp) \
217 static struct lkm_syscall _module = { \
218 LM_SYSCALL, \
219 LKM_VERSION, \
220 name, \
221 callslot, \
222 sysentp \
223 }
224
225 #define MOD_VFS(name,vfsslot,vnodeops,vfsconf) \
226 static struct lkm_vfs _module = { \
227 LM_VFS, \
228 LKM_VERSION, \
229 name, \
230 vfsslot, \
231 vnodeops, \
232 vfsconf \
233 }
234
235 #define MOD_DEV(name,devtype,devslot,devp) \
236 MOD_DECL(name); \
237 static struct lkm_dev _module = { \
238 LM_DEV, \
239 LKM_VERSION, \
240 #name ## "_mod", \
241 devslot, \
242 devtype, \
243 (void *)devp \
244 }
245
246 #define MOD_EXEC(name,execslot,execsw) \
247 MOD_DECL(name); \
248 static struct lkm_exec _module = { \
249 LM_EXEC, \
250 LKM_VERSION, \
251 #name ## "_mod", \
252 execslot, \
253 execsw \
254 }
255
256 #define MOD_MISC(name) \
257 MOD_DECL(name); \
258 static struct lkm_misc _module = { \
259 LM_MISC, \
260 LKM_VERSION, \
261 #name ## "_mod" \
262 }
263
264 /*
265 * MOD_DISPATCH -- FreeBSD 3.0+ style envocation.
266 This simply reorders the arguments and calls the previous DISPATCH
267 entry point. This is here only to help backport new lkm's to 2.2.x.
268 One should not think that the rest of the 3.0 lkm changes have been
269 added. This is only an API change.
270 */
271 #define MOD_DISPATCH(name,lkmtp,cmd,ver,load,unload,stat) \
272 DISPATCH(lkmtp,cmd,ver,load,unload,stat)
273
274 /*
275 * DISPATCH -- body function for use in module entry point function;
276 * generally, the function body will consist entirely of a single
277 * 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 #define DISPATCH(lkmtp,cmd,ver,load,unload,stat) \
283 if (ver != LKM_VERSION) \
284 return EINVAL; /* version mismatch */ \
285 switch (cmd) { \
286 int error; \
287 case LKM_E_LOAD: \
288 lkmtp->private.lkm_any = (struct lkm_any *)&_module; \
289 if (lkmexists(lkmtp)) /* !!! */ \
290 return EEXIST; \
291 if ((error = load(lkmtp, cmd))) \
292 return error; \
293 break; \
294 case LKM_E_UNLOAD: \
295 if ((error = unload(lkmtp, cmd))) \
296 return error; \
297 break; \
298 case LKM_E_STAT: \
299 if ((error = stat(lkmtp, cmd))) \
300 return error; \
301 break; \
302 } \
303 return lkmdispatch(lkmtp, cmd);
304
305 int lkmdispatch __P((struct lkm_table *lkmtp, int cmd));
306 int lkmexists __P((struct lkm_table *lkmtp));
307 int lkm_nullcmd __P((struct lkm_table *lkmtp, int cmd));
308
309 #endif /* KERNEL */
310
311 /****************************************************************************/
312
313 /*
314 * IOCTL's recognized by /dev/lkm
315 */
316 #define LMRESERV _IOWR('K', 0, struct lmc_resrv)
317 #define LMLOADBUF _IOW('K', 1, struct lmc_loadbuf)
318 #define LMUNRESRV _IO('K', 2)
319 #define LMREADY _IOW('K', 3, int)
320
321 #define LMLOAD _IOW('K', 9, struct lmc_load)
322 #define LMUNLOAD _IOWR('K', 10, struct lmc_unload)
323 #define LMSTAT _IOWR('K', 11, struct lmc_stat)
324
325 #define MODIOBUF 512 /* # of bytes at a time to loadbuf */
326
327 /*
328 * IOCTL arguments
329 */
330
331
332 /*
333 * Reserve a page-aligned block of kernel memory for the module
334 */
335 struct lmc_resrv {
336 u_long size; /* IN: size of module to reserve */
337 char *name; /* IN: name (must be provided */
338 int slot; /* OUT: allocated slot (module ID) */
339 u_long addr; /* OUT: Link-to address */
340 };
341
342
343 /*
344 * Copy a buffer at a time into the allocated area in the kernel; writes
345 * are assumed to occur contiguously.
346 */
347 struct lmc_loadbuf {
348 int cnt; /* IN: # of chars pointed to by data */
349 char *data; /* IN: pointer to data buffer */
350 };
351
352
353 /*
354 * Load a module (assumes it's been mmapped to address before call)
355 */
356 struct lmc_load {
357 caddr_t address; /* IN: user space mmap address */
358 int status; /* OUT: status of operation */
359 int id; /* OUT: module ID if loaded */
360 };
361
362 /*
363 * Unload a module (by name/id)
364 */
365 struct lmc_unload {
366 int id; /* IN: module ID to unload */
367 char *name; /* IN: module name to unload if id -1 */
368 int status; /* OUT: status of operation */
369 };
370
371
372 /*
373 * Get module information for a given id (or name if id == -1).
374 */
375 struct lmc_stat {
376 int id; /* IN: module ID to unload */
377 char name[MAXLKMNAME]; /* IN/OUT: name of module */
378 u_long offset; /* OUT: target table offset */
379 MODTYPE type; /* OUT: type of module */
380 u_long area; /* OUT: kernel load addr */
381 u_long size; /* OUT: module size (pages) */
382 u_long private; /* OUT: module private data */
383 int ver; /* OUT: lkm compile version */
384 };
385
386 #endif /* !_SYS_LKM_H_ */
Cache object: 0113d967ae8ad35d1f96c43c31b19cc0
|