Commit | Line | Data |
---|---|---|
335dda38 | 1 | /* |
0e9b9130 | 2 | * Copyright (c) 2003,2004,2007 The DragonFly Project. All rights reserved. |
07dfa375 | 3 | * |
8c10bfcf MD |
4 | * This code is derived from software contributed to The DragonFly Project |
5 | * by Matthew Dillon <dillon@backplane.com> | |
07dfa375 | 6 | * |
335dda38 MD |
7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | |
07dfa375 | 10 | * |
335dda38 MD |
11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | |
13 | * 2. Redistributions in binary form must reproduce the above copyright | |
8c10bfcf MD |
14 | * notice, this list of conditions and the following disclaimer in |
15 | * the documentation and/or other materials provided with the | |
16 | * distribution. | |
17 | * 3. Neither the name of The DragonFly Project nor the names of its | |
18 | * contributors may be used to endorse or promote products derived | |
19 | * from this software without specific, prior written permission. | |
07dfa375 | 20 | * |
8c10bfcf MD |
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
22 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |
24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |
25 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |
26 | * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, | |
27 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
28 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | |
29 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
30 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |
31 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
335dda38 | 32 | * SUCH DAMAGE. |
335dda38 MD |
33 | */ |
34 | ||
35 | #ifndef _SYS_DEVICE_H_ | |
36 | #define _SYS_DEVICE_H_ | |
37 | ||
c672274b | 38 | #ifdef _KERNEL |
1bd40720 MD |
39 | #ifndef _SYS_TYPES_H_ |
40 | #include <sys/types.h> | |
41 | #endif | |
0e9b9130 MD |
42 | #ifndef _SYS_TREE_H_ |
43 | #include <sys/tree.h> | |
44 | #endif | |
a3d02589 MD |
45 | #ifndef _SYS_SYSLINK_RPC_H_ |
46 | #include <sys/syslink_rpc.h> | |
335dda38 MD |
47 | #endif |
48 | ||
b13267a5 | 49 | struct cdev; |
cd29885a | 50 | struct ucred; |
b96f3782 | 51 | struct devfs_bitmap; |
0adbcbd6 | 52 | struct vm_page; |
64b5a8a5 | 53 | struct vm_map_backing; |
3064590a | 54 | struct vnode; |
b13267a5 | 55 | |
335dda38 | 56 | /* |
fef8985e | 57 | * This structure is at the base of every device args structure |
335dda38 | 58 | */ |
fef8985e MD |
59 | struct dev_generic_args { |
60 | struct syslink_desc *a_desc; | |
b13267a5 | 61 | struct cdev *a_dev; |
335dda38 MD |
62 | }; |
63 | ||
fef8985e MD |
64 | typedef struct dev_generic_args dev_default_args; |
65 | ||
335dda38 | 66 | /* |
b13267a5 | 67 | * int d_open(cdev_t dev, int oflags, int devtype, struct ucred *cred) |
335dda38 | 68 | */ |
fef8985e MD |
69 | struct dev_open_args { |
70 | struct dev_generic_args a_head; | |
71 | int a_oflags; | |
72 | int a_devtype; | |
73 | struct ucred *a_cred; | |
5bd45597 | 74 | struct file **a_fpp; |
335dda38 MD |
75 | }; |
76 | ||
77 | /* | |
b13267a5 | 78 | * int d_close(cdev_t dev, int fflag, int devtype) |
335dda38 | 79 | */ |
fef8985e MD |
80 | struct dev_close_args { |
81 | struct dev_generic_args a_head; | |
82 | int a_fflag; | |
83 | int a_devtype; | |
ce486e08 | 84 | struct file *a_fp; |
335dda38 MD |
85 | }; |
86 | ||
87 | /* | |
b13267a5 | 88 | * int d_read(cdev_t dev, struct uio *uio, int ioflag) |
335dda38 | 89 | */ |
fef8985e MD |
90 | struct dev_read_args { |
91 | struct dev_generic_args a_head; | |
92 | struct uio *a_uio; | |
93 | int a_ioflag; | |
8c530b23 | 94 | struct file *a_fp; |
335dda38 MD |
95 | }; |
96 | ||
97 | /* | |
b13267a5 | 98 | * int d_write(cdev_t dev, struct uio *uio, int ioflag) |
335dda38 | 99 | */ |
fef8985e MD |
100 | struct dev_write_args { |
101 | struct dev_generic_args a_head; | |
102 | struct uio *a_uio; | |
103 | int a_ioflag; | |
8c530b23 | 104 | struct file *a_fp; |
335dda38 MD |
105 | }; |
106 | ||
107 | /* | |
b13267a5 | 108 | * int d_ioctl(cdev_t dev, u_long cmd, caddr_t data, int fflag, |
87baaf0c | 109 | * struct ucred *cred, struct sysmsg *msg) |
335dda38 | 110 | */ |
fef8985e MD |
111 | struct dev_ioctl_args { |
112 | struct dev_generic_args a_head; | |
113 | u_long a_cmd; | |
114 | caddr_t a_data; | |
115 | int a_fflag; | |
116 | struct ucred *a_cred; | |
87baaf0c | 117 | struct sysmsg *a_sysmsg; |
8c530b23 | 118 | struct file *a_fp; |
335dda38 MD |
119 | }; |
120 | ||
335dda38 | 121 | /* |
b13267a5 | 122 | * int d_mmap(cdev_t dev, vm_offset_t offset, int nprot) |
335dda38 | 123 | */ |
fef8985e MD |
124 | struct dev_mmap_args { |
125 | struct dev_generic_args a_head; | |
126 | vm_offset_t a_offset; | |
127 | int a_nprot; | |
76f1911e | 128 | int64_t a_result; /* page number */ |
8c530b23 | 129 | struct file *a_fp; |
335dda38 MD |
130 | }; |
131 | ||
290740e3 JH |
132 | /* |
133 | * int d_mmap_single(cdev_t dev, vm_ooffset_t *offset, vm_size_t size, | |
134 | * struct vm_object **object, int nprot) | |
135 | */ | |
136 | struct dev_mmap_single_args { | |
137 | struct dev_generic_args a_head; | |
138 | vm_ooffset_t *a_offset; | |
139 | vm_size_t a_size; | |
140 | struct vm_object **a_object; | |
141 | int a_nprot; | |
8c530b23 | 142 | struct file *a_fp; |
290740e3 JH |
143 | }; |
144 | ||
335dda38 | 145 | /* |
b13267a5 | 146 | * void d_strategy(cdev_t dev, struct bio *bio) |
335dda38 | 147 | */ |
fef8985e MD |
148 | struct dev_strategy_args { |
149 | struct dev_generic_args a_head; | |
150 | struct bio *a_bio; | |
335dda38 MD |
151 | }; |
152 | ||
153 | /* | |
b24cd69c AH |
154 | * void d_dump(cdev_t dev, void *virtual, vm_offset_t physical, |
155 | off_t offset, size_t length) | |
335dda38 | 156 | */ |
fef8985e MD |
157 | struct dev_dump_args { |
158 | struct dev_generic_args a_head; | |
e0fc5693 MD |
159 | u_int64_t a_count; |
160 | u_int64_t a_blkno; | |
fef8985e | 161 | u_int a_secsize; |
b24cd69c AH |
162 | void *a_virtual; |
163 | vm_offset_t a_physical; | |
164 | off_t a_offset; | |
165 | size_t a_length; | |
fef8985e MD |
166 | }; |
167 | ||
168 | /* | |
b13267a5 | 169 | * int d_psize(cdev_t dev) |
fef8985e MD |
170 | */ |
171 | struct dev_psize_args { | |
172 | struct dev_generic_args a_head; | |
e0fc5693 | 173 | int64_t a_result; |
335dda38 MD |
174 | }; |
175 | ||
176 | /* | |
b13267a5 | 177 | * int d_kqfilter(cdev_t dev, struct knote *kn) |
335dda38 | 178 | */ |
fef8985e MD |
179 | struct dev_kqfilter_args { |
180 | struct dev_generic_args a_head; | |
181 | struct knote *a_kn; | |
182 | int a_result; | |
8c530b23 | 183 | struct file *a_fp; |
fef8985e MD |
184 | }; |
185 | ||
a32446b7 MD |
186 | /* |
187 | * int d_clone(cdev_t dev); | |
188 | */ | |
fef8985e MD |
189 | struct dev_clone_args { |
190 | struct dev_generic_args a_head; | |
cd29885a | 191 | |
07dfa375 AH |
192 | struct cdev *a_dev; |
193 | const char *a_name; | |
194 | size_t a_namelen; | |
195 | struct ucred *a_cred; | |
196 | int a_mode; | |
335dda38 MD |
197 | }; |
198 | ||
a32446b7 MD |
199 | /* |
200 | * int d_revoke(cdev_t dev) | |
201 | */ | |
202 | struct dev_revoke_args { | |
203 | struct dev_generic_args a_head; | |
204 | }; | |
205 | ||
335dda38 | 206 | /* |
fef8985e MD |
207 | * Typedefs to help drivers declare the driver routines and such |
208 | */ | |
209 | typedef int d_default_t (struct dev_generic_args *ap); | |
210 | typedef int d_open_t (struct dev_open_args *ap); | |
211 | typedef int d_close_t (struct dev_close_args *ap); | |
212 | typedef int d_read_t (struct dev_read_args *ap); | |
213 | typedef int d_write_t (struct dev_write_args *ap); | |
214 | typedef int d_ioctl_t (struct dev_ioctl_args *ap); | |
fef8985e | 215 | typedef int d_mmap_t (struct dev_mmap_args *ap); |
290740e3 | 216 | typedef int d_mmap_single_t (struct dev_mmap_single_args *ap); |
fef8985e MD |
217 | typedef int d_strategy_t (struct dev_strategy_args *ap); |
218 | typedef int d_dump_t (struct dev_dump_args *ap); | |
219 | typedef int d_psize_t (struct dev_psize_args *ap); | |
220 | typedef int d_kqfilter_t (struct dev_kqfilter_args *ap); | |
221 | typedef int d_clone_t (struct dev_clone_args *ap); | |
a32446b7 | 222 | typedef int d_revoke_t (struct dev_revoke_args *ap); |
fef8985e MD |
223 | |
224 | /* | |
225 | * Character device switch table. | |
226 | * | |
227 | * NOTE: positions are hard coded for static structure initialization. | |
228 | */ | |
229 | struct dev_ops { | |
230 | struct { | |
231 | const char *name; /* base name, e.g. 'da' */ | |
e94d6677 SW |
232 | int maj; /* major device number */ |
233 | u_int flags; /* D_XXX flags */ | |
7cbab9da | 234 | void *data; /* custom driver data */ |
e94d6677 SW |
235 | int refs; /* ref count */ |
236 | int id; | |
fef8985e MD |
237 | } head; |
238 | ||
239 | #define dev_ops_first_field d_default | |
240 | d_default_t *d_default; | |
241 | d_open_t *d_open; | |
242 | d_close_t *d_close; | |
243 | d_read_t *d_read; | |
244 | d_write_t *d_write; | |
245 | d_ioctl_t *d_ioctl; | |
fef8985e | 246 | d_mmap_t *d_mmap; |
290740e3 | 247 | d_mmap_single_t *d_mmap_single; |
fef8985e MD |
248 | d_strategy_t *d_strategy; |
249 | d_dump_t *d_dump; | |
250 | d_psize_t *d_psize; | |
251 | d_kqfilter_t *d_kqfilter; | |
252 | d_clone_t *d_clone; /* clone from base dev_ops */ | |
a32446b7 | 253 | d_revoke_t *d_revoke; |
64b5a8a5 MD |
254 | int (*d_uksmap)(struct vm_map_backing *ba, int op, |
255 | struct cdev *dev, struct vm_page *fake); | |
0adbcbd6 | 256 | #define dev_ops_last_field d_uksmap |
fef8985e | 257 | }; |
c672274b | 258 | #endif /* _KERNEL */ |
fef8985e MD |
259 | |
260 | /* | |
261 | * Types for d_flags. | |
335dda38 | 262 | */ |
fef8985e MD |
263 | #define D_TAPE 0x0001 |
264 | #define D_DISK 0x0002 | |
265 | #define D_TTY 0x0004 | |
266 | #define D_MEM 0x0008 | |
267 | ||
268 | #define D_TYPEMASK 0xffff | |
c0885fab | 269 | #define D_SEEKABLE (D_TAPE | D_DISK | D_MEM) |
fef8985e MD |
270 | |
271 | /* | |
272 | * Flags for d_flags. | |
32c821cf MD |
273 | * |
274 | * D_NOEMERGPGR Indicates complex layering, the emergency pager | |
275 | * should skip buffers related to such devices. | |
fef8985e | 276 | */ |
c672274b | 277 | #ifdef _KERNEL |
fef8985e | 278 | #define D_MEMDISK 0x00010000 /* memory type disk */ |
eaa61c9d | 279 | #define D_UNUSED17 0x00020000 /* was: nagged about missing make_dev() */ |
fef8985e MD |
280 | #define D_CANFREE 0x00040000 /* can free blocks */ |
281 | #define D_TRACKCLOSE 0x00080000 /* track all closes */ | |
282 | #define D_MASTER 0x00100000 /* used by pty/tty code */ | |
32c821cf | 283 | #define D_NOEMERGPGR 0x00200000 /* too complex for emergency pager */ |
9f889dc4 | 284 | #define D_MPSAFE 0x00400000 /* all dev_d*() calls are MPSAFE */ |
d32579c3 | 285 | #define D_KVABIO 0x00800000 /* device support KVABIO API */ |
0c5ceff2 | 286 | #define D_QUICK 0x01000000 /* no fancy open/close support needed*/ |
c672274b | 287 | #endif |
fef8985e MD |
288 | |
289 | /* | |
290 | * A union of all possible argument structures. | |
291 | */ | |
eaa61c9d | 292 | #if 0 |
fef8985e MD |
293 | union dev_args_union { |
294 | struct dev_generic_args du_head; | |
295 | struct dev_open_args du_open; | |
296 | struct dev_close_args du_close; | |
297 | struct dev_read_args du_read; | |
298 | struct dev_write_args du_write; | |
299 | struct dev_ioctl_args du_ioctl; | |
fef8985e MD |
300 | struct dev_mmap_args du_mmap; |
301 | struct dev_strategy_args du_strategy; | |
302 | struct dev_dump_args du_dump; | |
303 | struct dev_psize_args du_psize; | |
304 | struct dev_kqfilter_args du_kqfilter; | |
305 | struct dev_clone_args du_clone; | |
306 | }; | |
eaa61c9d | 307 | #endif |
fef8985e | 308 | |
c672274b | 309 | #ifdef _KERNEL |
fef8985e MD |
310 | /* |
311 | * Linking structure for mask/match registration | |
312 | */ | |
313 | struct dev_ops_link { | |
314 | struct dev_ops_link *next; | |
315 | u_int mask; | |
316 | u_int match; | |
317 | struct dev_ops *ops; | |
318 | }; | |
335dda38 | 319 | |
0e9b9130 MD |
320 | struct dev_ops_maj { |
321 | RB_ENTRY(dev_ops_maj) rbnode; /* red-black tree of major nums */ | |
322 | struct dev_ops_link *link; | |
323 | int maj; | |
324 | }; | |
325 | ||
326 | RB_HEAD(dev_ops_rb_tree, dev_ops_maj); | |
327 | RB_PROTOTYPE2(dev_ops_rb_tree, dev_ops_maj, rbnode, rb_dev_ops_compare, int); | |
c672274b | 328 | #endif /* _KERNEL */ |
0e9b9130 | 329 | |
335dda38 MD |
330 | #ifdef _KERNEL |
331 | ||
fef8985e MD |
332 | extern struct dev_ops dead_dev_ops; |
333 | ||
335dda38 | 334 | struct disk; |
87baaf0c | 335 | struct sysmsg; |
335dda38 | 336 | |
3064590a | 337 | int dev_dopen(cdev_t dev, int oflags, int devtype, struct ucred *cred, |
5bd45597 | 338 | struct file **fpp, struct vnode *vp); |
ce486e08 | 339 | int dev_dclose(cdev_t dev, int fflag, int devtype, struct file *fp); |
b13267a5 MD |
340 | void dev_dstrategy(cdev_t dev, struct bio *bio); |
341 | void dev_dstrategy_chain(cdev_t dev, struct bio *bio); | |
8c530b23 JH |
342 | int dev_dioctl(cdev_t dev, u_long cmd, caddr_t data, |
343 | int fflag, struct ucred *cred, struct sysmsg *msg, struct file *fp); | |
b24cd69c AH |
344 | int dev_ddump(cdev_t dev, void *virtual, vm_offset_t physical, off_t offset, |
345 | size_t length); | |
e0fc5693 | 346 | int64_t dev_dpsize(cdev_t dev); |
8c530b23 JH |
347 | int dev_dread(cdev_t dev, struct uio *uio, int ioflag, struct file *fp); |
348 | int dev_dwrite(cdev_t dev, struct uio *uio, int ioflag, struct file *fp); | |
349 | int dev_dkqfilter(cdev_t dev, struct knote *kn, struct file *fp); | |
76f1911e | 350 | int64_t dev_dmmap(cdev_t dev, vm_offset_t offset, int nprot, struct file *fp); |
290740e3 | 351 | int dev_dmmap_single(cdev_t dev, vm_ooffset_t *offset, vm_size_t size, |
8c530b23 | 352 | struct vm_object **object, int nprot, struct file *fp); |
b13267a5 | 353 | int dev_dclone(cdev_t dev); |
a32446b7 | 354 | int dev_drevoke(cdev_t dev); |
b13267a5 | 355 | |
ca464209 | 356 | int dev_drefs(cdev_t dev); |
b13267a5 MD |
357 | const char *dev_dname(cdev_t dev); |
358 | int dev_dmaj(cdev_t dev); | |
359 | int dev_dflags(cdev_t dev); | |
fef8985e MD |
360 | int dev_doperate(struct dev_generic_args *ap); |
361 | int dev_doperate_ops(struct dev_ops *, struct dev_generic_args *ap); | |
362 | ||
fef8985e MD |
363 | d_open_t nullopen; |
364 | d_close_t nullclose; | |
365 | ||
366 | extern struct syslink_desc dev_default_desc; | |
367 | extern struct syslink_desc dev_open_desc; | |
368 | extern struct syslink_desc dev_close_desc; | |
369 | extern struct syslink_desc dev_read_desc; | |
370 | extern struct syslink_desc dev_write_desc; | |
371 | extern struct syslink_desc dev_ioctl_desc; | |
372 | extern struct syslink_desc dev_dump_desc; | |
373 | extern struct syslink_desc dev_psize_desc; | |
fef8985e | 374 | extern struct syslink_desc dev_mmap_desc; |
290740e3 | 375 | extern struct syslink_desc dev_mmap_single_desc; |
c295c5d2 | 376 | extern struct syslink_desc dev_strategy_desc; |
fef8985e MD |
377 | extern struct syslink_desc dev_kqfilter_desc; |
378 | extern struct syslink_desc dev_clone_desc; | |
379 | ||
380 | void compile_dev_ops(struct dev_ops *); | |
cd29885a MD |
381 | int dev_ops_remove_all(struct dev_ops *ops); |
382 | int dev_ops_remove_minor(struct dev_ops *ops, int minor); | |
b13267a5 MD |
383 | struct dev_ops *dev_ops_intercept(cdev_t, struct dev_ops *); |
384 | void dev_ops_restore(cdev_t, struct dev_ops *); | |
fef8985e | 385 | |
807bfb5d | 386 | #define MAKEDEV_MINNBUF 14 |
387 | char *makedev_unit_b32(char *nbuf, uintmax_t num); | |
b13267a5 | 388 | cdev_t make_dev(struct dev_ops *ops, int minor, uid_t uid, gid_t gid, |
fef8985e | 389 | int perms, const char *fmt, ...) __printflike(6, 7); |
8f960aa9 AH |
390 | cdev_t make_dev_covering(struct dev_ops *ops, struct dev_ops *bops, int minor, |
391 | uid_t uid, gid_t gid, int perms, const char *fmt, ...) __printflike(7, 8); | |
cd29885a MD |
392 | cdev_t make_only_dev(struct dev_ops *ops, int minor, uid_t uid, gid_t gid, |
393 | int perms, const char *fmt, ...) __printflike(6, 7); | |
cc754c81 AH |
394 | cdev_t make_only_dev_covering(struct dev_ops *ops, struct dev_ops *bops, int minor, |
395 | uid_t uid, gid_t gid, int perms, const char *fmt, ...) __printflike(7,8); | |
cd29885a | 396 | cdev_t make_only_devfs_dev(struct dev_ops *ops, int minor, uid_t uid, gid_t gid, |
fcefa6f2 | 397 | int perms, const char *fmt, ...) __printflike(6, 7); |
cd29885a | 398 | void destroy_only_dev(cdev_t dev); |
fcefa6f2 | 399 | int make_dev_alias(cdev_t target, const char *fmt, ...) __printflike(2, 3); |
8312ca30 | 400 | int destroy_dev_alias(cdev_t target, const char *fmt, ...) __printflike(2, 3); |
b96f3782 | 401 | cdev_t make_autoclone_dev(struct dev_ops *ops, struct devfs_bitmap *bitmap, |
fcefa6f2 SW |
402 | d_clone_t *nhandler, uid_t uid, gid_t gid, int perms, |
403 | const char *fmt, ...) __printflike(7, 8); | |
07dfa375 | 404 | void destroy_autoclone_dev(cdev_t dev, struct devfs_bitmap *bitmap); |
2a32d680 MD |
405 | void sync_devs(void); |
406 | ||
335dda38 MD |
407 | #endif |
408 | ||
409 | #endif | |
410 |