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.1 (Berkeley) 06/11/93 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 */ 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 371 /* 372 * Routine to determine if a device is a disk. 373 * 374 * A minimal stub routine can always return 0. 375 */ 376 isdisk(dev, type) 377 dev_t dev; 378 int type; 379 { 380 381 switch (major(dev)) { 382 case 0: 383 case 3: 384 if (type == VBLK) 385 return (1); 386 return (0); 387 case 4: 388 case 15: 389 if (type == VCHR) 390 return (1); 391 /* FALLTHROUGH */ 392 default: 393 return (0); 394 } 395 /* NOTREACHED */ 396 } 397 398 #define MAXDEV 43 399 static int chrtoblktbl[MAXDEV] = { 400 /* VCHR */ /* VBLK */ 401 /* 0 */ NODEV, 402 /* 1 */ NODEV, 403 /* 2 */ NODEV, 404 /* 3 */ NODEV, 405 /* 4 */ 0, 406 /* 5 */ NODEV, 407 /* 6 */ NODEV, 408 /* 7 */ NODEV, 409 /* 8 */ NODEV, 410 /* 9 */ NODEV, 411 /* 10 */ NODEV, 412 /* 11 */ NODEV, 413 /* 12 */ NODEV, 414 /* 13 */ NODEV, 415 /* 14 */ NODEV, 416 /* 15 */ 3, 417 /* 16 */ NODEV, 418 /* 17 */ NODEV, 419 /* 18 */ NODEV, 420 /* 19 */ NODEV, 421 /* 20 */ NODEV, 422 /* 21 */ NODEV, 423 /* 22 */ NODEV, 424 /* 23 */ NODEV, 425 /* 24 */ NODEV, 426 /* 25 */ NODEV, 427 /* 26 */ NODEV, 428 /* 27 */ NODEV, 429 /* 28 */ NODEV, 430 /* 29 */ NODEV, 431 /* 30 */ NODEV, 432 /* 31 */ NODEV, 433 /* 32 */ NODEV, 434 /* 33 */ NODEV, 435 /* 34 */ NODEV, 436 /* 35 */ NODEV, 437 /* 36 */ NODEV, 438 /* 37 */ NODEV, 439 /* 38 */ NODEV, 440 /* 39 */ NODEV, 441 /* 40 */ NODEV, 442 /* 41 */ NODEV, 443 /* 42 */ NODEV, 444 }; 445 /* 446 * Routine to convert from character to block device number. 447 * 448 * A minimal stub routine can always return NODEV. 449 */ 450 chrtoblk(dev) 451 dev_t dev; 452 { 453 int blkmaj; 454 455 if (major(dev) >= MAXDEV || (blkmaj = chrtoblktbl[major(dev)]) == NODEV) 456 return (NODEV); 457 return (makedev(blkmaj, minor(dev))); 458 } 459