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