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 * Ralph Campbell. 7 * 8 * %sccs.include.redist.c% 9 * 10 * @(#)conf.c 8.4 (Berkeley) 06/02/95 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 void 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) void n __P((struct buf *)) 30 #define dev_type_ioctl(n) \ 31 int n __P((dev_t, u_long, 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 #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), D_DISK } 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, D_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, (dev_type_size((*))) enodev, 0 } 62 63 #define bdev_notdef() bdev_tape_init(0,no) 64 bdev_decl(no); /* dummy declarations */ 65 66 #include "rz.h" 67 #include "vn.h" 68 69 bdev_decl(rz); 70 bdev_decl(vn); 71 72 struct bdevsw bdevsw[] = 73 { 74 bdev_disk_init(NRZ,rz), /* 0: SCSI disk */ 75 bdev_swap_init(), /* 1: swap pseudo-device */ 76 bdev_disk_init(NVN,vn), /* 2: vnode disk driver (swap to files) */ 77 }; 78 79 int nblkdev = sizeof (bdevsw) / sizeof (bdevsw[0]); 80 81 /* cdevsw-specific types */ 82 #define dev_type_read(n) int n __P((dev_t, struct uio *, int)) 83 #define dev_type_write(n) int n __P((dev_t, struct uio *, int)) 84 #define dev_type_stop(n) int n __P((struct tty *, int)) 85 #define dev_type_reset(n) int n __P((int)) 86 #define dev_type_select(n) int n __P((dev_t, int, struct proc *)) 87 #define dev_type_map(n) int n __P(()) 88 89 #define cdev_decl(n) \ 90 dev_decl(n,open); dev_decl(n,close); dev_decl(n,read); \ 91 dev_decl(n,write); dev_decl(n,ioctl); dev_decl(n,stop); \ 92 dev_decl(n,reset); dev_decl(n,select); dev_decl(n,map); \ 93 dev_decl(n,strategy); extern struct tty __CONCAT(n,_tty)[] 94 95 #define dev_tty_init(c,n) (c > 0 ? __CONCAT(n,_tty) : 0) 96 97 /* open, read, write, ioctl, strategy */ 98 #define cdev_disk_init(c,n) { \ 99 dev_init(c,n,open), (dev_type_close((*))) nullop, dev_init(c,n,read), \ 100 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ 101 (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, \ 102 dev_init(c,n,strategy), D_DISK } 103 104 /* open, close, read, write, ioctl, strategy */ 105 #define cdev_tape_init(c,n) { \ 106 dev_init(c,n,open), dev_init(c,n,close), rawread, \ 107 rawwrite, dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ 108 (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, \ 109 dev_init(c,n,strategy), D_TAPE } 110 111 /* open, close, read, write, ioctl, stop, tty */ 112 #define cdev_tty_init(c,n) { \ 113 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 114 dev_init(c,n,write), dev_init(c,n,ioctl), dev_init(c,n,stop), \ 115 (dev_type_reset((*))) nullop, dev_tty_init(c,n), ttselect, \ 116 (dev_type_map((*))) enodev, 0, D_TTY } 117 118 /* open, close, read, write, ioctl, select -- XXX should be a tty */ 119 #define cdev_cn_init(c,n) { \ 120 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 121 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) nullop, \ 122 (dev_type_reset((*))) nullop, 0, dev_init(c,n,select), \ 123 (dev_type_map((*))) enodev, 0, D_TTY } 124 125 #define cdev_notdef() { \ 126 (dev_type_open((*))) enodev, (dev_type_close((*))) enodev, \ 127 (dev_type_read((*))) enodev, (dev_type_write((*))) enodev, \ 128 (dev_type_ioctl((*))) enodev, (dev_type_stop((*))) enodev, \ 129 (dev_type_reset((*))) nullop, 0, seltrue, \ 130 (dev_type_map((*))) enodev, 0 } 131 132 cdev_decl(no); /* dummy declarations */ 133 134 cdev_decl(cn); /* console interface */ 135 136 cdev_decl(ctty); 137 /* open, read, write, ioctl, select -- XXX should be a tty */ 138 #define cdev_ctty_init(c,n) { \ 139 dev_init(c,n,open), (dev_type_close((*))) nullop, dev_init(c,n,read), \ 140 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) nullop, \ 141 (dev_type_reset((*))) nullop, 0, dev_init(c,n,select), \ 142 (dev_type_map((*))) enodev, 0, D_TTY } 143 144 dev_type_read(mmrw); 145 /* read/write */ 146 #define cdev_mm_init(c,n) { \ 147 (dev_type_open((*))) nullop, (dev_type_close((*))) nullop, mmrw, \ 148 mmrw, (dev_type_ioctl((*))) enodev, (dev_type_stop((*))) nullop, \ 149 (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, 0 } 150 151 /* read, write, strategy */ 152 #define cdev_swap_init(c,n) { \ 153 (dev_type_open((*))) nullop, (dev_type_close((*))) nullop, rawread, \ 154 rawwrite, (dev_type_ioctl((*))) enodev, (dev_type_stop((*))) enodev, \ 155 (dev_type_reset((*))) nullop, 0, (dev_type_select((*))) enodev, \ 156 (dev_type_map((*))) enodev, dev_init(c,n,strategy) } 157 158 #include "pty.h" 159 #define pts_tty pt_tty 160 #define ptsioctl ptyioctl 161 cdev_decl(pts); 162 #define ptc_tty pt_tty 163 #define ptcioctl ptyioctl 164 cdev_decl(ptc); 165 166 /* open, close, read, write, ioctl, tty, select */ 167 #define cdev_ptc_init(c,n) { \ 168 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 169 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) nullop, \ 170 (dev_type_reset((*))) nullop, dev_tty_init(c,n), dev_init(c,n,select), \ 171 (dev_type_map((*))) enodev, 0, D_TTY } 172 173 cdev_decl(log); 174 /* open, close, read, ioctl, select -- XXX should be a generic device */ 175 #define cdev_log_init(c,n) { \ 176 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 177 (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \ 178 (dev_type_stop((*))) enodev, (dev_type_reset((*))) nullop, 0, \ 179 dev_init(c,n,select), (dev_type_map((*))) enodev, 0 } 180 181 dev_type_open(fdopen); 182 /* open */ 183 #define cdev_fd_init(c,n) { \ 184 dev_init(c,n,open), (dev_type_close((*))) enodev, \ 185 (dev_type_read((*))) enodev, (dev_type_write((*))) enodev, \ 186 (dev_type_ioctl((*))) enodev, (dev_type_stop((*))) enodev, \ 187 (dev_type_reset((*))) enodev, 0, (dev_type_select((*))) enodev, \ 188 (dev_type_map((*))) enodev, 0 } 189 190 #include "pm.h" 191 cdev_decl(pm); 192 #define cdev_pm_init(c,n) { \ 193 dev_init(c,n,open), dev_init(c,n,close), \ 194 (dev_type_read((*))) nullop, (dev_type_write((*))) nullop, \ 195 dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ 196 (dev_type_reset((*))) nullop, 0, dev_init(c,n,select), \ 197 dev_init(c,n,map), 0 } 198 199 cdev_decl(rz); 200 201 #include "tz.h" 202 cdev_decl(tz); 203 204 cdev_decl(vn); 205 /* open, read, write, ioctl -- XXX should be a disk */ 206 #define cdev_vn_init(c,n) { \ 207 dev_init(c,n,open), (dev_type_close((*))) nullop, dev_init(c,n,read), \ 208 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ 209 (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, \ 210 (dev_type_strategy((*))) nullop, D_DISK } 211 212 #include "bpfilter.h" 213 cdev_decl(bpf); 214 /* open, close, read, write, ioctl, select -- XXX should be generic device */ 215 #define cdev_bpf_init(c,n) { \ 216 dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 217 dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ 218 (dev_type_reset((*))) enodev, 0, dev_init(c,n,select), \ 219 (dev_type_map((*))) enodev, 0 } 220 221 #include "cfb.h" 222 cdev_decl(cfb); 223 224 #include "xcfb.h" 225 cdev_decl(xcfb); 226 227 #include "mfb.h" 228 cdev_decl(mfb); 229 230 #include "dtop.h" 231 cdev_decl(dtop); 232 233 #include "scc.h" 234 cdev_decl(scc); 235 236 #include "dc.h" 237 cdev_decl(dc); 238 239 struct cdevsw cdevsw[] = 240 { 241 cdev_cn_init(1,cn), /* 0: virtual console */ 242 cdev_ctty_init(1,ctty), /* 1: controlling terminal */ 243 cdev_mm_init(1,mm), /* 2: /dev/{null,mem,kmem,...} */ 244 cdev_swap_init(1,sw), /* 3: /dev/drum (swap pseudo-device) */ 245 cdev_tty_init(NPTY,pts), /* 4: pseudo-tty slave */ 246 cdev_ptc_init(NPTY,ptc), /* 5: pseudo-tty master */ 247 cdev_log_init(1,log), /* 6: /dev/klog */ 248 cdev_fd_init(1,fd), /* 7: file descriptor pseudo-dev */ 249 cdev_pm_init(NPM,pm), /* 8: frame buffer */ 250 cdev_disk_init(NRZ,rz), /* 9: SCSI disk */ 251 cdev_tape_init(NTZ,tz), /* 10: SCSI tape */ 252 cdev_vn_init(NVN,vn), /* 11: vnode disk */ 253 cdev_bpf_init(NBPFILTER,bpf), /* 12: berkeley packet filter */ 254 cdev_pm_init(NCFB,cfb), /* 13: color frame buffer */ 255 cdev_pm_init(NXCFB,xcfb), /* 14: maxine color frame buffer */ 256 cdev_tty_init(NDTOP,dtop), /* 15: desktop bus interface */ 257 cdev_tty_init(NDC,dc), /* 16: dc7085 serial interface */ 258 cdev_tty_init(NSCC,scc), /* 17: scc 82530 serial interface */ 259 cdev_pm_init(NMFB,mfb), /* 18: mono frame buffer */ 260 }; 261 262 int nchrdev = sizeof (cdevsw) / sizeof (cdevsw[0]); 263 264 int mem_no = 2; /* major device number of memory special file */ 265 266 /* 267 * Swapdev is a fake device implemented 268 * in sw.c used only internally to get to swstrategy. 269 * It cannot be provided to the users, because the 270 * swstrategy routine munches the b_dev and b_blkno entries 271 * before calling the appropriate driver. This would horribly 272 * confuse, e.g. the hashing routines. Instead, /dev/drum is 273 * provided as a character (raw) device. 274 */ 275 dev_t swapdev = makedev(1, 0); 276 277 /* 278 * Routine that identifies /dev/mem and /dev/kmem. 279 * 280 * A minimal stub routine can always return 0. 281 */ 282 iskmemdev(dev) 283 dev_t dev; 284 { 285 286 return (major(dev) == 2 && minor(dev) < 2); 287 } 288 289 iszerodev(dev) 290 dev_t dev; 291 { 292 return (major(dev) == 2 && minor(dev) == 12); 293 } 294 295 #define MAXDEV 19 296 static int chrtoblktbl[MAXDEV] = { 297 /* VCHR */ /* VBLK */ 298 /* 0 */ NODEV, 299 /* 1 */ NODEV, 300 /* 2 */ NODEV, 301 /* 3 */ NODEV, 302 /* 4 */ NODEV, 303 /* 5 */ NODEV, 304 /* 6 */ NODEV, 305 /* 7 */ NODEV, 306 /* 8 */ NODEV, 307 /* 9 */ 0, 308 /* 10 */ NODEV, 309 /* 11 */ 2, 310 /* 12 */ NODEV, 311 /* 13 */ NODEV, 312 /* 14 */ NODEV, 313 /* 15 */ NODEV, 314 /* 16 */ NODEV, 315 /* 17 */ NODEV, 316 /* 18 */ NODEV, 317 }; 318 /* 319 * Routine to convert from character to block device number. 320 * 321 * A minimal stub routine can always return NODEV. 322 */ 323 chrtoblk(dev) 324 dev_t dev; 325 { 326 int blkmaj; 327 328 if (major(dev) >= MAXDEV || (blkmaj = chrtoblktbl[major(dev)]) == NODEV) 329 return (NODEV); 330 return (makedev(blkmaj, minor(dev))); 331 } 332