1 /*
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Kazumasa Utashiro of Software Research Associates, Inc.
7 *
8 * %sccs.include.redist.c%
9 *
10 * @(#)conf.c 8.3 (Berkeley) 11/21/94
11 */
12
13 #include <sys/param.h>
14 #include <sys/systm.h>
15 #include <sys/buf.h>
16 #include <sys/ioctl.h>
17 #include <sys/proc.h>
18 #include <sys/vnode.h>
19 #include <sys/tty.h>
20 #include <sys/conf.h>
21
22 int rawread __P((dev_t, struct uio *, int));
23 int rawwrite __P((dev_t, struct uio *, int));
24 int swstrategy __P((struct buf *));
25 int ttselect __P((dev_t, int, struct proc *));
26
27 #define dev_type_open(n) int n __P((dev_t, int, int, struct proc *))
28 #define dev_type_close(n) int n __P((dev_t, int, int, struct proc *))
29 #define dev_type_strategy(n) int n __P((struct buf *))
30 #define dev_type_ioctl(n) \
31 int n __P((dev_t, int, caddr_t, int, struct proc *))
32
33 /* bdevsw-specific types */
34 #define dev_type_dump(n) int n __P((dev_t))
35 #define dev_type_size(n) int n __P((dev_t))
36
37 #define dev_decl(n,t) __CONCAT(dev_type_,t)(__CONCAT(n,t))
38 #define dev_init(c,n,t) \
39 (c > 0 ? __CONCAT(n,t) : (__CONCAT(dev_type_,t)((*))) enxio)
40
41 /* bdevsw-specific initializations */
42 #define dev_size_init(c,n) (c > 0 ? __CONCAT(n,size) : 0)
43
44 #define bdev_decl(n) \
45 dev_decl(n,open); dev_decl(n,close); dev_decl(n,strategy); \
46 dev_decl(n,ioctl); dev_decl(n,dump); dev_decl(n,size)
47
48 #define bdev_disk_init(c,n) { \
49 dev_init(c,n,open), (dev_type_close((*))) nullop, \
50 dev_init(c,n,strategy), dev_init(c,n,ioctl), \
51 dev_init(c,n,dump), dev_size_init(c,n), 0 }
52
53 #define bdev_tape_init(c,n) { \
54 dev_init(c,n,open), dev_init(c,n,close), \
55 dev_init(c,n,strategy), dev_init(c,n,ioctl), \
56 dev_init(c,n,dump), 0, B_TAPE }
57
58 #define bdev_swap_init() { \
59 (dev_type_open((*))) enodev, (dev_type_close((*))) enodev, \
60 swstrategy, (dev_type_ioctl((*))) enodev, \
61 (dev_type_dump((*))) enodev, 0, 0 }
62
63 #define bdev_notdef() bdev_tape_init(0,no)
64 bdev_decl(no); /* dummy declarations */
65
66 #include "sd.h"
67 #define sd_b_ioctl sdioctl
68 #define sd_b_strategy sdstrategy
69 #define sd_b_dump sddump
70 #define sd_b_size sdsize
71 bdev_decl(sd_b_);
72
73 #include "fd.h"
74 #define fd_b_ioctl fdioctl
75 #define fd_b_strategy fdstrategy
76 #define fd_b_dump fddump
77 #define fd_b_size fdsize
78 bdev_decl(fd_b_);
79
80 #include "vn.h"
81 bdev_decl(vn);
82
83 struct bdevsw bdevsw[] =
84 {
85 bdev_disk_init(NSD,sd_b_), /* 0: SCSI disk */
86 bdev_disk_init(NFD,fd_b_), /* 1: floppy disk */
87 bdev_notdef(), /* 2 */
88 bdev_disk_init(NVN,vn), /* 3: vnode disk driver (swap to files) */
89 bdev_swap_init(), /* 4: swap pseudo-device */
90 };
91
92 int nblkdev = sizeof (bdevsw) / sizeof (bdevsw[0]);
93
94 /* cdevsw-specific types */
95 #define dev_type_read(n) int n __P((dev_t, struct uio *, int))
96 #define dev_type_write(n) int n __P((dev_t, struct uio *, int))
97 #define dev_type_stop(n) int n __P((struct tty *, int))
98 #define dev_type_reset(n) int n __P((int))
99 #define dev_type_select(n) int n __P((dev_t, int, struct proc *))
100 #define dev_type_map(n) int n __P(())
101
102 #define cdev_decl(n) \
103 dev_decl(n,open); dev_decl(n,close); dev_decl(n,read); \
104 dev_decl(n,write); dev_decl(n,ioctl); dev_decl(n,stop); \
105 dev_decl(n,reset); dev_decl(n,select); dev_decl(n,map); \
106 dev_decl(n,strategy); extern struct tty __CONCAT(n,_tty)[]
107
108 #define dev_tty_init(c,n) (c > 0 ? __CONCAT(n,_tty) : 0)
109
110 /* open, read, write, ioctl, strategy */
111 #define cdev_disk_init(c,n) { \
112 dev_init(c,n,open), (dev_type_close((*))) nullop, dev_init(c,n,read), \
113 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \
114 (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, \
115 dev_init(c,n,strategy) }
116
117 /* open, close, read, write, ioctl, strategy */
118 #define cdev_tape_init(c,n) { \
119 dev_init(c,n,open), dev_init(c,n,close), rawread, \
120 rawwrite, dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \
121 (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, \
122 dev_init(c,n,strategy) }
123
124 /* open, close, read, write, ioctl, stop, tty */
125 #define cdev_tty_init(c,n) { \
126 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
127 dev_init(c,n,write), dev_init(c,n,ioctl), dev_init(c,n,stop), \
128 (dev_type_reset((*))) nullop, dev_tty_init(c,n), ttselect, \
129 (dev_type_map((*))) enodev, 0 }
130
131 #define cdev_notdef() { \
132 (dev_type_open((*))) enodev, (dev_type_close((*))) enodev, \
133 (dev_type_read((*))) enodev, (dev_type_write((*))) enodev, \
134 (dev_type_ioctl((*))) enodev, (dev_type_stop((*))) enodev, \
135 (dev_type_reset((*))) nullop, 0, seltrue, \
136 (dev_type_map((*))) enodev, 0 }
137
138 /* open, close, read, write, ioctl -- XXX should be tty */
139 #define cdev_vc_init(c,n) { \
140 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
141 dev_init(c,n,write), dev_init(c,n,ioctl), dev_init(c,n,stop), \
142 (dev_type_reset((*))) nullop, 0, dev_init(c,n,select), \
143 (dev_type_map((*))) enodev, 0 }
144
145 cdev_decl(no); /* dummy declarations */
146
147 #include "rs.h"
148 cdev_decl(rs);
149 cdev_decl(vc);
150
151 #include "bm.h"
152 cdev_decl(cn);
153
154 cdev_decl(ctty);
155 /* open, read, write, ioctl, select -- XXX should be a tty */
156 #define cdev_ctty_init(c,n) { \
157 dev_init(c,n,open), (dev_type_close((*))) nullop, dev_init(c,n,read), \
158 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) nullop, \
159 (dev_type_reset((*))) nullop, 0, dev_init(c,n,select), \
160 (dev_type_map((*))) enodev, 0 }
161
162 dev_type_read(mmrw);
163 /* read/write */
164 #define cdev_mm_init(c,n) { \
165 (dev_type_open((*))) nullop, (dev_type_close((*))) nullop, mmrw, \
166 mmrw, (dev_type_ioctl((*))) enodev, (dev_type_stop((*))) nullop, \
167 (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, 0 }
168
169 #include "sd.h"
170 #define sd_c_read sdread
171 #define sd_c_write sdwrite
172 #define sd_c_ioctl sdioctl
173 #define sd_c_reset sdreset
174 #define sd_c_strategy sdstrategy
175 #define sd_c_dump sddump
176 #define sd_c_size sdsize
177 cdev_decl(sd_c_);
178
179 #include "fd.h"
180 #define fd_c_read fdread
181 #define fd_c_write fdwrite
182 #define fd_c_ioctl fdioctl
183 #define fd_c_reset fdreset
184 #define fd_c_strategy fdstrategy
185 #define fd_c_dump fddump
186 #define fd_c_size fdsize
187 cdev_decl(fd_c_);
188
189 #include "lp.h"
190 cdev_decl(lp);
191
192 /* read, write, strategy */
193 #define cdev_swap_init(c,n) { \
194 (dev_type_open((*))) nullop, (dev_type_close((*))) nullop, rawread, \
195 rawwrite, (dev_type_ioctl((*))) enodev, (dev_type_stop((*))) enodev, \
196 (dev_type_reset((*))) nullop, 0, (dev_type_select((*))) enodev, \
197 (dev_type_map((*))) enodev, dev_init(c,n,strategy) }
198
199 #include "pty.h"
200 #define pts_tty pt_tty
201 #define ptsioctl ptyioctl
202 cdev_decl(pts);
203 #define ptc_tty pt_tty
204 #define ptcioctl ptyioctl
205 cdev_decl(ptc);
206
207 /* open, close, read, write, ioctl, tty, select */
208 #define cdev_ptc_init(c,n) { \
209 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
210 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) nullop, \
211 (dev_type_reset((*))) nullop, dev_tty_init(c,n), dev_init(c,n,select), \
212 (dev_type_map((*))) enodev, 0 }
213
214 #include "kb.h"
215 cdev_decl(kb);
216 /* open, close, write, ioctl */
217 #define cdev_kb_init(c,n) { \
218 dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
219 dev_init(c,n,write), dev_init(c,n,ioctl), \
220 (dev_type_stop((*))) enodev, (dev_type_reset((*))) nullop, 0, \
221 seltrue, (dev_type_map((*))) enodev, \
222 0 }
223
224 #include "ms.h"
225 #define msmap msmmap
226 cdev_decl(ms);
227 /* open, close, read, write, ioctl, select */
228 #define cdev_ms_init(c,n) { \
229 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
230 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \
231 (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, \
232 0 }
233
234 #include "fb.h"
235 cdev_decl(fb);
236 /* open, close, ioctl, mmap */
237 #define cdev_fb_init(c,n) { \
238 dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
239 (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \
240 (dev_type_stop((*))) enodev, \
241 (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, 0 }
242 /*
243 (dev_type_reset((*))) nullop, 0, seltrue, dev_init(c,n,map), 0 }
244 */
245
246 #include "st.h"
247 cdev_decl(st);
248
249 #include "lb.h"
250 cdev_decl(lbp);
251
252 #include "ir.h"
253 cdev_decl(ir);
254 /* open, close, read, ioctl */
255 #define cdev_ir_init(c,n) { \
256 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
257 (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \
258 (dev_type_stop((*))) enodev, (dev_type_reset((*))) nullop, 0, \
259 seltrue, (dev_type_map((*))) enodev, 0 }
260
261 cdev_decl(log);
262 /* open, close, read, ioctl, select -- XXX should be a generic device */
263 #define cdev_log_init(c,n) { \
264 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
265 (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \
266 (dev_type_stop((*))) enodev, (dev_type_reset((*))) nullop, 0, \
267 dev_init(c,n,select), (dev_type_map((*))) enodev, 0 }
268
269 dev_type_open(fdopen);
270 /* open */
271 #define cdev_fd_init(c,n) { \
272 dev_init(c,n,open), (dev_type_close((*))) enodev, \
273 (dev_type_read((*))) enodev, (dev_type_write((*))) enodev, \
274 (dev_type_ioctl((*))) enodev, (dev_type_stop((*))) enodev, \
275 (dev_type_reset((*))) enodev, 0, (dev_type_select((*))) enodev, \
276 (dev_type_map((*))) enodev, 0 }
277
278 cdev_decl(vn);
279 /* open, read, write, ioctl -- XXX should be a disk */
280 #define cdev_vn_init(c,n) { \
281 dev_init(c,n,open), (dev_type_close((*))) nullop, dev_init(c,n,read), \
282 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \
283 (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, \
284 0 }
285
286 #include "bpfilter.h"
287 cdev_decl(bpf);
288 /* open, close, read, write, ioctl, select -- XXX should be generic device */
289 #define cdev_bpf_init(c,n) { \
290 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
291 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \
292 (dev_type_reset((*))) enodev, 0, dev_init(c,n,select), \
293 (dev_type_map((*))) enodev, 0 }
294
295 struct cdevsw cdevsw[] =
296 {
297 cdev_vc_init(1,vc), /* 0: virtual console */
298 cdev_tty_init(NRS,rs), /* 1: rs232c */
299 cdev_ctty_init(1,ctty), /* 2: controlling terminal */
300 cdev_mm_init(1,mm), /* 3: /dev/{null,mem,kmem,...} */
301 cdev_disk_init(NSD,sd_c_), /* 4: scsi disk */
302 cdev_disk_init(NFD,fd_c_), /* 5: floppy disk */
303 cdev_disk_init(NLP,lp), /* 6: printer */
304 cdev_swap_init(1,sw), /* 7: /dev/drum (swap pseudo-device) */
305 cdev_tty_init(NPTY,pts), /* 8: pseudo-tty slave */
306 cdev_ptc_init(NPTY,ptc), /* 9: pseudo-tty master */
307 cdev_notdef(), /* 10: md (sony memory disk) */
308 cdev_kb_init(NKB,kb), /* 11: keyboard */
309 cdev_ms_init(NMS,ms), /* 12: mouse */
310 cdev_fd_init(1,fd), /* 13: file descriptor pseudo-dev */
311 cdev_fb_init(NFB,fb), /* 14: frame buffer */
312 cdev_vn_init(NVN,vn), /* 15: vnode disk */
313 cdev_tape_init(NST,st), /* 16: scsi tape */
314 cdev_kb_init(NLB,lbp), /* 17: lbp */
315 cdev_ir_init(NIR,ir), /* 18: image reader */
316 cdev_notdef(), /* 19: vme */
317 cdev_notdef(), /* 20: gpib */
318 cdev_notdef(), /* 21: rd */
319 cdev_tty_init(NBM,cn), /* 22: console display device */
320 cdev_notdef(), /* 23: ether */
321 cdev_bpf_init(NBPFILTER,bpf), /* 24: berkeley packet filter */
322 cdev_notdef(), /* 25 */
323 cdev_notdef(), /* 26 */
324 cdev_notdef(), /* 27 */
325 cdev_notdef(), /* 28: scsi */
326 cdev_notdef(), /* 29: sony shm */
327 cdev_notdef(), /* 30: sony semaphoe? */
328 cdev_notdef(), /* 31: vvcrs */
329 cdev_notdef(), /* 32: fddi */
330 cdev_log_init(1,log), /* 33: /dev/klog */
331 cdev_notdef(), /* 34: image board */
332 cdev_notdef(), /* 35: sb? */
333 cdev_notdef(), /* 36: sbe? */
334 cdev_notdef(), /* 37: vd (safs) */
335 cdev_notdef(), /* 38: xd (safs) */
336 cdev_notdef(), /* 39: isdn */
337 cdev_notdef(), /* 40: rb */
338 cdev_notdef(), /* 41: gs */
339 cdev_notdef(), /* 42: rx */
340 };
341
342 int nchrdev = sizeof (cdevsw) / sizeof (cdevsw[0]);
343
344 int mem_no = 2; /* major device number of memory special file */
345
346 /*
347 * Swapdev is a fake device implemented
348 * in sw.c used only internally to get to swstrategy.
349 * It cannot be provided to the users, because the
350 * swstrategy routine munches the b_dev and b_blkno entries
351 * before calling the appropriate driver. This would horribly
352 * confuse, e.g. the hashing routines. Instead, /dev/drum is
353 * provided as a character (raw) device.
354 */
355 dev_t swapdev = makedev(1, 0);
356
357 /*
358 * Routine that identifies /dev/mem and /dev/kmem.
359 *
360 * A minimal stub routine can always return 0.
361 */
iskmemdev(dev)362 iskmemdev(dev)
363 dev_t dev;
364 {
365
366 if (major(dev) == 3 && (minor(dev) == 0 || minor(dev) == 1))
367 return (1);
368 return (0);
369 }
370
iszerodev(dev)371 iszerodev(dev)
372 dev_t dev;
373 {
374 return (major(dev) == 3 && minor(dev) == 12);
375 }
376
377 /*
378 * Routine to determine if a device is a tty.
379 *
380 * A minimal stub routine can always return 0.
381 */
istty(dev)382 istty(dev)
383 dev_t dev;
384 {
385
386 switch (major(dev)) {
387 case 0:
388 case 1:
389 case 2:
390 case 8:
391 case 9:
392 case 11:
393 return (1);
394 default:
395 return (0);
396 }
397 }
398
399 /*
400 * Routine to determine if a device is a disk.
401 *
402 * A minimal stub routine can always return 0.
403 */
isdisk(dev,type)404 isdisk(dev, type)
405 dev_t dev;
406 int type;
407 {
408
409 switch (major(dev)) {
410 case 0:
411 case 3:
412 if (type == VBLK)
413 return (1);
414 return (0);
415 case 4:
416 case 15:
417 if (type == VCHR)
418 return (1);
419 /* FALLTHROUGH */
420 default:
421 return (0);
422 }
423 /* NOTREACHED */
424 }
425
426 #define MAXDEV 43
427 static int chrtoblktbl[MAXDEV] = {
428 /* VCHR */ /* VBLK */
429 /* 0 */ NODEV,
430 /* 1 */ NODEV,
431 /* 2 */ NODEV,
432 /* 3 */ NODEV,
433 /* 4 */ 0,
434 /* 5 */ NODEV,
435 /* 6 */ NODEV,
436 /* 7 */ NODEV,
437 /* 8 */ NODEV,
438 /* 9 */ NODEV,
439 /* 10 */ NODEV,
440 /* 11 */ NODEV,
441 /* 12 */ NODEV,
442 /* 13 */ NODEV,
443 /* 14 */ NODEV,
444 /* 15 */ 3,
445 /* 16 */ NODEV,
446 /* 17 */ NODEV,
447 /* 18 */ NODEV,
448 /* 19 */ NODEV,
449 /* 20 */ NODEV,
450 /* 21 */ NODEV,
451 /* 22 */ NODEV,
452 /* 23 */ NODEV,
453 /* 24 */ NODEV,
454 /* 25 */ NODEV,
455 /* 26 */ NODEV,
456 /* 27 */ NODEV,
457 /* 28 */ NODEV,
458 /* 29 */ NODEV,
459 /* 30 */ NODEV,
460 /* 31 */ NODEV,
461 /* 32 */ NODEV,
462 /* 33 */ NODEV,
463 /* 34 */ NODEV,
464 /* 35 */ NODEV,
465 /* 36 */ NODEV,
466 /* 37 */ NODEV,
467 /* 38 */ NODEV,
468 /* 39 */ NODEV,
469 /* 40 */ NODEV,
470 /* 41 */ NODEV,
471 /* 42 */ NODEV,
472 };
473 /*
474 * Routine to convert from character to block device number.
475 *
476 * A minimal stub routine can always return NODEV.
477 */
chrtoblk(dev)478 chrtoblk(dev)
479 dev_t dev;
480 {
481 int blkmaj;
482
483 if (major(dev) >= MAXDEV || (blkmaj = chrtoblktbl[major(dev)]) == NODEV)
484 return (NODEV);
485 return (makedev(blkmaj, minor(dev)));
486 }
487