1 /*- 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)conf.c 8.1 (Berkeley) 06/10/93 8 */ 9 10 #include <sys/param.h> 11 #include <sys/systm.h> 12 #include <sys/buf.h> 13 #include <sys/ioctl.h> 14 #include <sys/proc.h> 15 #include <sys/vnode.h> 16 #include <sys/tty.h> 17 #include <sys/conf.h> 18 19 int rawread __P((dev_t, struct uio *, int)); 20 int rawwrite __P((dev_t, struct uio *, int)); 21 int swstrategy __P((struct buf *)); 22 int ttselect __P((dev_t, int, struct proc *)); 23 24 #define dev_type_open(n) int n __P((dev_t, int, int, struct proc *)) 25 #define dev_type_close(n) int n __P((dev_t, int, int, struct proc *)) 26 #define dev_type_strategy(n) int n __P((struct buf *)) 27 #define dev_type_ioctl(n) \ 28 int n __P((dev_t, int, caddr_t, int, struct proc *)) 29 30 /* bdevsw-specific types */ 31 #define dev_type_dump(n) int n __P(()) 32 #define dev_type_size(n) int n __P((dev_t)) 33 34 #define dev_decl(n,t) __CONCAT(dev_type_,t)(__CONCAT(n,t)) 35 #define dev_init(c,n,t) \ 36 (c > 0 ? __CONCAT(n,t) : (__CONCAT(dev_type_,t)((*))) enxio) 37 38 /* bdevsw-specific initializations */ 39 #define dev_size_init(c,n) (c > 0 ? __CONCAT(n,size) : 0) 40 41 #define bdev_decl(n) \ 42 dev_decl(n,open); dev_decl(n,close); dev_decl(n,strategy); \ 43 dev_decl(n,ioctl); dev_decl(n,dump); dev_decl(n,size) 44 45 /* disk without close routine */ 46 #define bdev_disk_init(c,n) { \ 47 dev_init(c,n,open), (dev_type_close((*))) nullop, \ 48 dev_init(c,n,strategy), dev_init(c,n,ioctl), \ 49 dev_init(c,n,dump), dev_size_init(c,n), 0 } 50 51 /* disk with close routine */ 52 #define bdev_ldisk_init(c,n) { \ 53 dev_init(c,n,open), dev_init(c,n,close), \ 54 dev_init(c,n,strategy), dev_init(c,n,ioctl), \ 55 dev_init(c,n,dump), dev_size_init(c,n), 0 } 56 57 #define bdev_tape_init(c,n) { \ 58 dev_init(c,n,open), dev_init(c,n,close), \ 59 dev_init(c,n,strategy), dev_init(c,n,ioctl), \ 60 dev_init(c,n,dump), 0, B_TAPE } 61 62 #define bdev_swap_init() { \ 63 (dev_type_open((*))) enodev, (dev_type_close((*))) enodev, \ 64 swstrategy, (dev_type_ioctl((*))) enodev, \ 65 (dev_type_dump((*))) enodev, 0, 0 } 66 67 #define bdev_notdef() bdev_tape_init(0,no) 68 bdev_decl(no); /* dummy declarations */ 69 70 #include "ct.h" 71 #include "st.h" 72 #include "rd.h" 73 #include "sd.h" 74 #include "cd.h" 75 #include "vn.h" 76 77 bdev_decl(ct); 78 bdev_decl(st); 79 bdev_decl(rd); 80 bdev_decl(sd); 81 bdev_decl(cd); 82 bdev_decl(vn); 83 84 struct bdevsw bdevsw[] = 85 { 86 bdev_tape_init(NCT,ct), /* 0: cs80 cartridge tape */ 87 bdev_notdef(), /* 1 */ 88 bdev_ldisk_init(NRD,rd),/* 2: hpib disk */ 89 bdev_swap_init(), /* 3: swap pseudo-device */ 90 bdev_ldisk_init(NSD,sd),/* 4: scsi disk */ 91 bdev_disk_init(NCD,cd), /* 5: concatenated disk driver */ 92 bdev_disk_init(NVN,vn), /* 6: vnode disk driver (swap to files) */ 93 bdev_tape_init(NST,st), /* 7: exabyte tape */ 94 }; 95 96 int nblkdev = sizeof (bdevsw) / sizeof (bdevsw[0]); 97 98 /* cdevsw-specific types */ 99 #define dev_type_read(n) int n __P((dev_t, struct uio *, int)) 100 #define dev_type_write(n) int n __P((dev_t, struct uio *, int)) 101 #define dev_type_stop(n) int n __P((struct tty *, int)) 102 #define dev_type_reset(n) int n __P((int)) 103 #define dev_type_select(n) int n __P((dev_t, int, struct proc *)) 104 #define dev_type_map(n) int n __P(()) 105 106 #define cdev_decl(n) \ 107 dev_decl(n,open); dev_decl(n,close); dev_decl(n,read); \ 108 dev_decl(n,write); dev_decl(n,ioctl); dev_decl(n,stop); \ 109 dev_decl(n,reset); dev_decl(n,select); dev_decl(n,map); \ 110 dev_decl(n,strategy); extern struct tty __CONCAT(n,_tty)[] 111 112 #define dev_tty_init(c,n) (c > 0 ? __CONCAT(n,_tty) : 0) 113 114 /* open, read, write, ioctl, strategy */ 115 #define cdev_disk_init(c,n) { \ 116 dev_init(c,n,open), (dev_type_close((*))) nullop, dev_init(c,n,read), \ 117 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ 118 (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, \ 119 dev_init(c,n,strategy) } 120 121 /* open, close, read, write, ioctl, strategy */ 122 #define cdev_ldisk_init(c,n) { \ 123 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 124 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ 125 (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, \ 126 dev_init(c,n,strategy) } 127 128 /* open, close, read, write, ioctl, strategy */ 129 #define cdev_tape_init(c,n) { \ 130 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 131 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ 132 (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, \ 133 dev_init(c,n,strategy) } 134 135 /* open, close, read, write, ioctl, stop, tty */ 136 #define cdev_tty_init(c,n) { \ 137 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 138 dev_init(c,n,write), dev_init(c,n,ioctl), dev_init(c,n,stop), \ 139 (dev_type_reset((*))) nullop, dev_tty_init(c,n), ttselect, \ 140 (dev_type_map((*))) enodev, 0 } 141 142 #define cdev_notdef() { \ 143 (dev_type_open((*))) enodev, (dev_type_close((*))) enodev, \ 144 (dev_type_read((*))) enodev, (dev_type_write((*))) enodev, \ 145 (dev_type_ioctl((*))) enodev, (dev_type_stop((*))) enodev, \ 146 (dev_type_reset((*))) nullop, 0, seltrue, \ 147 (dev_type_map((*))) enodev, 0 } 148 149 cdev_decl(no); /* dummy declarations */ 150 151 cdev_decl(cn); 152 /* open, close, read, write, ioctl, select -- XXX should be a tty */ 153 #define cdev_cn_init(c,n) { \ 154 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 155 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) nullop, \ 156 (dev_type_reset((*))) nullop, 0, dev_init(c,n,select), \ 157 (dev_type_map((*))) enodev, 0 } 158 159 cdev_decl(ctty); 160 /* open, read, write, ioctl, select -- XXX should be a tty */ 161 #define cdev_ctty_init(c,n) { \ 162 dev_init(c,n,open), (dev_type_close((*))) nullop, dev_init(c,n,read), \ 163 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) nullop, \ 164 (dev_type_reset((*))) nullop, 0, dev_init(c,n,select), \ 165 (dev_type_map((*))) enodev, 0 } 166 167 dev_type_read(mmrw); 168 /* read/write */ 169 #define cdev_mm_init(c,n) { \ 170 (dev_type_open((*))) nullop, (dev_type_close((*))) nullop, mmrw, \ 171 mmrw, (dev_type_ioctl((*))) enodev, (dev_type_stop((*))) nullop, \ 172 (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, 0 } 173 174 /* read, write, strategy */ 175 #define cdev_swap_init(c,n) { \ 176 (dev_type_open((*))) nullop, (dev_type_close((*))) nullop, rawread, \ 177 rawwrite, (dev_type_ioctl((*))) enodev, (dev_type_stop((*))) enodev, \ 178 (dev_type_reset((*))) nullop, 0, (dev_type_select((*))) enodev, \ 179 (dev_type_map((*))) enodev, dev_init(c,n,strategy) } 180 181 #include "pty.h" 182 #define pts_tty pt_tty 183 #define ptsioctl ptyioctl 184 cdev_decl(pts); 185 #define ptc_tty pt_tty 186 #define ptcioctl ptyioctl 187 cdev_decl(ptc); 188 189 /* open, close, read, write, ioctl, tty, select */ 190 #define cdev_ptc_init(c,n) { \ 191 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 192 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) nullop, \ 193 (dev_type_reset((*))) nullop, dev_tty_init(c,n), dev_init(c,n,select), \ 194 (dev_type_map((*))) enodev, 0 } 195 196 cdev_decl(log); 197 /* open, close, read, ioctl, select -- XXX should be a generic device */ 198 #define cdev_log_init(c,n) { \ 199 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 200 (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \ 201 (dev_type_stop((*))) enodev, (dev_type_reset((*))) nullop, 0, \ 202 dev_init(c,n,select), (dev_type_map((*))) enodev, 0 } 203 204 cdev_decl(ct); 205 cdev_decl(st); 206 cdev_decl(sd); 207 cdev_decl(rd); 208 209 #include "grf.h" 210 cdev_decl(grf); 211 /* open, close, ioctl, select, map -- XXX should be a map device */ 212 #define cdev_grf_init(c,n) { \ 213 dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) nullop, \ 214 (dev_type_write((*))) nullop, dev_init(c,n,ioctl), \ 215 (dev_type_stop((*))) enodev, (dev_type_reset((*))) nullop, 0, \ 216 dev_init(c,n,select), dev_init(c,n,map), 0 } 217 218 #include "ppi.h" 219 cdev_decl(ppi); 220 /* open, close, read, write, ioctl -- XXX should be a generic device */ 221 #define cdev_ppi_init(c,n) { \ 222 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 223 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ 224 (dev_type_reset((*))) nullop, 0, (dev_type_select((*))) enodev, \ 225 (dev_type_map((*))) enodev, 0 } 226 227 #include "dca.h" 228 cdev_decl(dca); 229 230 #include "ite.h" 231 cdev_decl(ite); 232 /* open, close, read, write, ioctl, tty -- XXX should be a tty! */ 233 #define cdev_ite_init(c,n) { \ 234 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 235 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ 236 (dev_type_reset((*))) nullop, dev_tty_init(c,n), ttselect, \ 237 (dev_type_map((*))) enodev, 0 } 238 239 /* XXX shouldn't this be optional? */ 240 cdev_decl(hil); 241 /* open, close, read, ioctl, select, map -- XXX should be a map device */ 242 #define cdev_hil_init(c,n) { \ 243 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 244 (dev_type_write((*))) nullop, dev_init(c,n,ioctl), \ 245 (dev_type_stop((*))) enodev, (dev_type_reset((*))) nullop, 0, \ 246 dev_init(c,n,select), dev_init(c,n,map), 0 } 247 248 #include "dcm.h" 249 cdev_decl(dcm); 250 251 cdev_decl(cd); 252 253 cdev_decl(vn); 254 /* open, read, write, ioctl -- XXX should be a disk */ 255 #define cdev_vn_init(c,n) { \ 256 dev_init(c,n,open), (dev_type_close((*))) nullop, dev_init(c,n,read), \ 257 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ 258 (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, \ 259 0 } 260 261 dev_type_open(fdopen); 262 /* open */ 263 #define cdev_fd_init(c,n) { \ 264 dev_init(c,n,open), (dev_type_close((*))) enodev, \ 265 (dev_type_read((*))) enodev, (dev_type_write((*))) enodev, \ 266 (dev_type_ioctl((*))) enodev, (dev_type_stop((*))) enodev, \ 267 (dev_type_reset((*))) enodev, 0, (dev_type_select((*))) enodev, \ 268 (dev_type_map((*))) enodev, 0 } 269 270 #include "bpfilter.h" 271 cdev_decl(bpf); 272 /* open, close, read, write, ioctl, select -- XXX should be generic device */ 273 #define cdev_bpf_init(c,n) { \ 274 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 275 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ 276 (dev_type_reset((*))) enodev, 0, dev_init(c,n,select), \ 277 (dev_type_map((*))) enodev, 0 } 278 279 struct cdevsw cdevsw[] = 280 { 281 cdev_cn_init(1,cn), /* 0: virtual console */ 282 cdev_ctty_init(1,ctty), /* 1: controlling terminal */ 283 cdev_mm_init(1,mm), /* 2: /dev/{null,mem,kmem,...} */ 284 cdev_swap_init(1,sw), /* 3: /dev/drum (swap pseudo-device) */ 285 cdev_tty_init(NPTY,pts), /* 4: pseudo-tty slave */ 286 cdev_ptc_init(NPTY,ptc), /* 5: pseudo-tty master */ 287 cdev_log_init(1,log), /* 6: /dev/klog */ 288 cdev_tape_init(NCT,ct), /* 7: cs80 cartridge tape */ 289 cdev_ldisk_init(NSD,sd), /* 8: scsi disk */ 290 cdev_ldisk_init(NRD,rd), /* 9: hpib disk */ 291 cdev_grf_init(NGRF,grf), /* 10: frame buffer */ 292 cdev_ppi_init(NPPI,ppi), /* 11: printer/plotter interface */ 293 cdev_tty_init(NDCA,dca), /* 12: built-in single-port serial */ 294 cdev_ite_init(NITE,ite), /* 13: console terminal emulator */ 295 cdev_hil_init(1,hil), /* 14: human interface loop */ 296 cdev_tty_init(NDCM,dcm), /* 15: 4-port serial */ 297 cdev_notdef(), /* 16 */ 298 cdev_disk_init(NCD,cd), /* 17: concatenated disk */ 299 cdev_notdef(), /* 18 */ 300 cdev_vn_init(NVN,vn), /* 19: vnode disk */ 301 cdev_tape_init(NST,st), /* 20: exabyte tape */ 302 cdev_fd_init(1,fd), /* 21: file descriptor pseudo-dev */ 303 cdev_bpf_init(NBPFILTER,bpf), /* 22: berkeley packet filter */ 304 }; 305 306 int nchrdev = sizeof (cdevsw) / sizeof (cdevsw[0]); 307 308 int mem_no = 2; /* major device number of memory special file */ 309 310 /* 311 * Swapdev is a fake device implemented 312 * in sw.c used only internally to get to swstrategy. 313 * It cannot be provided to the users, because the 314 * swstrategy routine munches the b_dev and b_blkno entries 315 * before calling the appropriate driver. This would horribly 316 * confuse, e.g. the hashing routines. Instead, /dev/drum is 317 * provided as a character (raw) device. 318 */ 319 dev_t swapdev = makedev(3, 0); 320 321 /* 322 * Routine that identifies /dev/mem and /dev/kmem. 323 * 324 * A minimal stub routine can always return 0. 325 */ 326 iskmemdev(dev) 327 dev_t dev; 328 { 329 330 if (major(dev) == 2 && (minor(dev) == 0 || minor(dev) == 1)) 331 return (1); 332 return (0); 333 } 334 335 /* 336 * Routine to determine if a device is a disk. 337 * 338 * A minimal stub routine can always return 0. 339 */ 340 isdisk(dev, type) 341 dev_t dev; 342 int type; 343 { 344 345 switch (major(dev)) { 346 case 2: 347 case 4: 348 case 5: 349 case 6: 350 if (type == VBLK) 351 return (1); 352 return (0); 353 case 8: 354 case 9: 355 case 17: 356 case 19: 357 if (type == VCHR) 358 return (1); 359 /* fall through */ 360 default: 361 return (0); 362 } 363 /* NOTREACHED */ 364 } 365 366 #define MAXDEV 21 367 static int chrtoblktbl[MAXDEV] = { 368 /* VCHR */ /* VBLK */ 369 /* 0 */ NODEV, 370 /* 1 */ NODEV, 371 /* 2 */ NODEV, 372 /* 3 */ NODEV, 373 /* 4 */ NODEV, 374 /* 5 */ NODEV, 375 /* 6 */ NODEV, 376 /* 7 */ 0, 377 /* 8 */ 4, 378 /* 9 */ 2, 379 /* 10 */ NODEV, 380 /* 11 */ NODEV, 381 /* 12 */ NODEV, 382 /* 13 */ NODEV, 383 /* 14 */ NODEV, 384 /* 15 */ NODEV, 385 /* 16 */ NODEV, 386 /* 17 */ 5, 387 /* 18 */ NODEV, 388 /* 19 */ 6, 389 /* 20 */ 7, 390 }; 391 /* 392 * Routine to convert from character to block device number. 393 * 394 * A minimal stub routine can always return NODEV. 395 */ 396 chrtoblk(dev) 397 dev_t dev; 398 { 399 int blkmaj; 400 401 if (major(dev) >= MAXDEV || (blkmaj = chrtoblktbl[major(dev)]) == NODEV) 402 return (NODEV); 403 return (makedev(blkmaj, minor(dev))); 404 } 405