149610Sdonn /*- 263157Sbostic * Copyright (c) 1991, 1993 363157Sbostic * The Regents of the University of California. All rights reserved. 441475Smckusick * 541475Smckusick * %sccs.include.redist.c% 641475Smckusick * 7*68130Smckusick * @(#)conf.c 8.4 (Berkeley) 01/03/95 841475Smckusick */ 941475Smckusick 1056508Sbostic #include <sys/param.h> 1156508Sbostic #include <sys/systm.h> 1256508Sbostic #include <sys/buf.h> 1356508Sbostic #include <sys/ioctl.h> 1456508Sbostic #include <sys/proc.h> 1559487Smckusick #include <sys/vnode.h> 1656508Sbostic #include <sys/tty.h> 1756508Sbostic #include <sys/conf.h> 1841475Smckusick 1949623Skarels int rawread __P((dev_t, struct uio *, int)); 2049623Skarels int rawwrite __P((dev_t, struct uio *, int)); 2149623Skarels int swstrategy __P((struct buf *)); 2249623Skarels int ttselect __P((dev_t, int, struct proc *)); 2341475Smckusick 2449623Skarels #define dev_type_open(n) int n __P((dev_t, int, int, struct proc *)) 2549623Skarels #define dev_type_close(n) int n __P((dev_t, int, int, struct proc *)) 2649623Skarels #define dev_type_strategy(n) int n __P((struct buf *)) 2749623Skarels #define dev_type_ioctl(n) \ 2849623Skarels int n __P((dev_t, int, caddr_t, int, struct proc *)) 2949610Sdonn 3049610Sdonn /* bdevsw-specific types */ 3152520Smckusick #define dev_type_dump(n) int n __P(()) 3249623Skarels #define dev_type_size(n) int n __P((dev_t)) 3349610Sdonn 3449623Skarels #define dev_decl(n,t) __CONCAT(dev_type_,t)(__CONCAT(n,t)) 3549610Sdonn #define dev_init(c,n,t) \ 3649623Skarels (c > 0 ? __CONCAT(n,t) : (__CONCAT(dev_type_,t)((*))) enxio) 3749610Sdonn 3849610Sdonn /* bdevsw-specific initializations */ 3949623Skarels #define dev_size_init(c,n) (c > 0 ? __CONCAT(n,size) : 0) 4049610Sdonn 4149623Skarels #define bdev_decl(n) \ 4249623Skarels dev_decl(n,open); dev_decl(n,close); dev_decl(n,strategy); \ 4349623Skarels dev_decl(n,ioctl); dev_decl(n,dump); dev_decl(n,size) 4449610Sdonn 4557336Shibler /* disk without close routine */ 4649623Skarels #define bdev_disk_init(c,n) { \ 4749623Skarels dev_init(c,n,open), (dev_type_close((*))) nullop, \ 4849623Skarels dev_init(c,n,strategy), dev_init(c,n,ioctl), \ 4949623Skarels dev_init(c,n,dump), dev_size_init(c,n), 0 } 5049610Sdonn 5157336Shibler /* disk with close routine */ 5257336Shibler #define bdev_ldisk_init(c,n) { \ 5357336Shibler dev_init(c,n,open), dev_init(c,n,close), \ 5457336Shibler dev_init(c,n,strategy), dev_init(c,n,ioctl), \ 55*68130Smckusick dev_init(c,n,dump), dev_size_init(c,n), D_DISK } 5657336Shibler 5749623Skarels #define bdev_tape_init(c,n) { \ 5849623Skarels dev_init(c,n,open), dev_init(c,n,close), \ 5949623Skarels dev_init(c,n,strategy), dev_init(c,n,ioctl), \ 60*68130Smckusick dev_init(c,n,dump), 0, D_TAPE } 6149610Sdonn 6249623Skarels #define bdev_swap_init() { \ 6349623Skarels (dev_type_open((*))) enodev, (dev_type_close((*))) enodev, \ 6449623Skarels swstrategy, (dev_type_ioctl((*))) enodev, \ 65*68130Smckusick (dev_type_dump((*))) enodev, 0 } 6649610Sdonn 6749623Skarels #define bdev_notdef() bdev_tape_init(0,no) 6849610Sdonn bdev_decl(no); /* dummy declarations */ 6949610Sdonn 7041475Smckusick #include "ct.h" 7149912Smckusick #include "st.h" 7241475Smckusick #include "rd.h" 7341475Smckusick #include "sd.h" 7441475Smckusick #include "cd.h" 7549328Shibler #include "vn.h" 7649610Sdonn 7749610Sdonn bdev_decl(ct); 7849912Smckusick bdev_decl(st); 7949610Sdonn bdev_decl(rd); 8049610Sdonn bdev_decl(sd); 8149610Sdonn bdev_decl(cd); 8249610Sdonn bdev_decl(vn); 8349610Sdonn 8441475Smckusick struct bdevsw bdevsw[] = 8541475Smckusick { 8649610Sdonn bdev_tape_init(NCT,ct), /* 0: cs80 cartridge tape */ 8749610Sdonn bdev_notdef(), /* 1 */ 8857336Shibler bdev_ldisk_init(NRD,rd),/* 2: hpib disk */ 8949610Sdonn bdev_swap_init(), /* 3: swap pseudo-device */ 9057336Shibler bdev_ldisk_init(NSD,sd),/* 4: scsi disk */ 9149610Sdonn bdev_disk_init(NCD,cd), /* 5: concatenated disk driver */ 9249610Sdonn bdev_disk_init(NVN,vn), /* 6: vnode disk driver (swap to files) */ 9349912Smckusick bdev_tape_init(NST,st), /* 7: exabyte tape */ 9441475Smckusick }; 9549610Sdonn 9641475Smckusick int nblkdev = sizeof (bdevsw) / sizeof (bdevsw[0]); 9741475Smckusick 9849610Sdonn /* cdevsw-specific types */ 9949623Skarels #define dev_type_read(n) int n __P((dev_t, struct uio *, int)) 10049623Skarels #define dev_type_write(n) int n __P((dev_t, struct uio *, int)) 10149623Skarels #define dev_type_stop(n) int n __P((struct tty *, int)) 10249623Skarels #define dev_type_reset(n) int n __P((int)) 10349610Sdonn #define dev_type_select(n) int n __P((dev_t, int, struct proc *)) 10449610Sdonn #define dev_type_map(n) int n __P(()) 10541475Smckusick 10649623Skarels #define cdev_decl(n) \ 10749623Skarels dev_decl(n,open); dev_decl(n,close); dev_decl(n,read); \ 10849623Skarels dev_decl(n,write); dev_decl(n,ioctl); dev_decl(n,stop); \ 10949623Skarels dev_decl(n,reset); dev_decl(n,select); dev_decl(n,map); \ 11049623Skarels dev_decl(n,strategy); extern struct tty __CONCAT(n,_tty)[] 11141475Smckusick 11249610Sdonn #define dev_tty_init(c,n) (c > 0 ? __CONCAT(n,_tty) : 0) 11341475Smckusick 11449610Sdonn /* open, read, write, ioctl, strategy */ 11549623Skarels #define cdev_disk_init(c,n) { \ 11649623Skarels dev_init(c,n,open), (dev_type_close((*))) nullop, dev_init(c,n,read), \ 11749623Skarels dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ 11849623Skarels (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, \ 119*68130Smckusick dev_init(c,n,strategy), D_DISK } 12049610Sdonn 12149610Sdonn /* open, close, read, write, ioctl, strategy */ 12257336Shibler #define cdev_ldisk_init(c,n) { \ 12357336Shibler dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 12457336Shibler dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ 12557336Shibler (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, \ 126*68130Smckusick dev_init(c,n,strategy), D_TAPE } 12757336Shibler 12857336Shibler /* open, close, read, write, ioctl, strategy */ 12949623Skarels #define cdev_tape_init(c,n) { \ 13049623Skarels dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 13149623Skarels dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ 13249623Skarels (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, \ 13349623Skarels dev_init(c,n,strategy) } 13449610Sdonn 13549610Sdonn /* open, close, read, write, ioctl, stop, tty */ 13649623Skarels #define cdev_tty_init(c,n) { \ 13749623Skarels dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 13849623Skarels dev_init(c,n,write), dev_init(c,n,ioctl), dev_init(c,n,stop), \ 13949623Skarels (dev_type_reset((*))) nullop, dev_tty_init(c,n), ttselect, \ 140*68130Smckusick (dev_type_map((*))) enodev, 0, D_TTY } 14149610Sdonn 14249623Skarels #define cdev_notdef() { \ 14349623Skarels (dev_type_open((*))) enodev, (dev_type_close((*))) enodev, \ 14449623Skarels (dev_type_read((*))) enodev, (dev_type_write((*))) enodev, \ 14549623Skarels (dev_type_ioctl((*))) enodev, (dev_type_stop((*))) enodev, \ 14649623Skarels (dev_type_reset((*))) nullop, 0, seltrue, \ 14749623Skarels (dev_type_map((*))) enodev, 0 } 14849610Sdonn 14949610Sdonn cdev_decl(no); /* dummy declarations */ 15049610Sdonn 15149610Sdonn cdev_decl(cn); 15249610Sdonn /* open, close, read, write, ioctl, select -- XXX should be a tty */ 15349623Skarels #define cdev_cn_init(c,n) { \ 15449623Skarels dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 15549623Skarels dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) nullop, \ 15649623Skarels (dev_type_reset((*))) nullop, 0, dev_init(c,n,select), \ 157*68130Smckusick (dev_type_map((*))) enodev, 0, D_TTY } 15849610Sdonn 15949610Sdonn cdev_decl(ctty); 16049610Sdonn /* open, read, write, ioctl, select -- XXX should be a tty */ 16149623Skarels #define cdev_ctty_init(c,n) { \ 16249623Skarels dev_init(c,n,open), (dev_type_close((*))) nullop, dev_init(c,n,read), \ 16349623Skarels dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) nullop, \ 16449623Skarels (dev_type_reset((*))) nullop, 0, dev_init(c,n,select), \ 165*68130Smckusick (dev_type_map((*))) enodev, 0, D_TTY } 16649610Sdonn 16749610Sdonn dev_type_read(mmrw); 16864848Shibler dev_type_map(mmmap); 16964848Shibler /* read, write, mmap */ 17049623Skarels #define cdev_mm_init(c,n) { \ 17149623Skarels (dev_type_open((*))) nullop, (dev_type_close((*))) nullop, mmrw, \ 17249623Skarels mmrw, (dev_type_ioctl((*))) enodev, (dev_type_stop((*))) nullop, \ 17364848Shibler (dev_type_reset((*))) nullop, 0, seltrue, mmmap, 0 } 17449610Sdonn 17549610Sdonn /* read, write, strategy */ 17649623Skarels #define cdev_swap_init(c,n) { \ 17749623Skarels (dev_type_open((*))) nullop, (dev_type_close((*))) nullop, rawread, \ 17849623Skarels rawwrite, (dev_type_ioctl((*))) enodev, (dev_type_stop((*))) enodev, \ 17949623Skarels (dev_type_reset((*))) nullop, 0, (dev_type_select((*))) enodev, \ 18049623Skarels (dev_type_map((*))) enodev, dev_init(c,n,strategy) } 18149610Sdonn 18241475Smckusick #include "pty.h" 18349610Sdonn #define pts_tty pt_tty 18449610Sdonn #define ptsioctl ptyioctl 18549610Sdonn cdev_decl(pts); 18649610Sdonn #define ptc_tty pt_tty 18749610Sdonn #define ptcioctl ptyioctl 18849610Sdonn cdev_decl(ptc); 18941475Smckusick 19049610Sdonn /* open, close, read, write, ioctl, tty, select */ 19149623Skarels #define cdev_ptc_init(c,n) { \ 19249623Skarels dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 19349623Skarels dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) nullop, \ 19449623Skarels (dev_type_reset((*))) nullop, dev_tty_init(c,n), dev_init(c,n,select), \ 195*68130Smckusick (dev_type_map((*))) enodev, 0, D_TTY } 19649610Sdonn 19749610Sdonn cdev_decl(log); 19849610Sdonn /* open, close, read, ioctl, select -- XXX should be a generic device */ 19949623Skarels #define cdev_log_init(c,n) { \ 20049623Skarels dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 20149623Skarels (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \ 20249623Skarels (dev_type_stop((*))) enodev, (dev_type_reset((*))) nullop, 0, \ 20349623Skarels dev_init(c,n,select), (dev_type_map((*))) enodev, 0 } 20449610Sdonn 20549610Sdonn cdev_decl(ct); 20649912Smckusick cdev_decl(st); 20749610Sdonn cdev_decl(sd); 20849610Sdonn cdev_decl(rd); 20949610Sdonn 21053933Shibler #include "grf.h" 21149610Sdonn cdev_decl(grf); 21249610Sdonn /* open, close, ioctl, select, map -- XXX should be a map device */ 21349623Skarels #define cdev_grf_init(c,n) { \ 21449623Skarels dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) nullop, \ 21549623Skarels (dev_type_write((*))) nullop, dev_init(c,n,ioctl), \ 21649623Skarels (dev_type_stop((*))) enodev, (dev_type_reset((*))) nullop, 0, \ 21749623Skarels dev_init(c,n,select), dev_init(c,n,map), 0 } 21849610Sdonn 21941475Smckusick #include "ppi.h" 22049610Sdonn cdev_decl(ppi); 22149610Sdonn /* open, close, read, write, ioctl -- XXX should be a generic device */ 22249623Skarels #define cdev_ppi_init(c,n) { \ 22349623Skarels dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 224*68130Smckusick dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) nullop, \ 22549623Skarels (dev_type_reset((*))) nullop, 0, (dev_type_select((*))) enodev, \ 22649623Skarels (dev_type_map((*))) enodev, 0 } 22741475Smckusick 22849610Sdonn #include "dca.h" 22949610Sdonn cdev_decl(dca); 23049610Sdonn 23141475Smckusick #include "ite.h" 23249610Sdonn cdev_decl(ite); 23349610Sdonn /* open, close, read, write, ioctl, tty -- XXX should be a tty! */ 23449623Skarels #define cdev_ite_init(c,n) { \ 23549623Skarels dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 23649623Skarels dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ 23749623Skarels (dev_type_reset((*))) nullop, dev_tty_init(c,n), ttselect, \ 238*68130Smckusick (dev_type_map((*))) enodev, 0, D_TTY } 23941475Smckusick 24049610Sdonn /* XXX shouldn't this be optional? */ 24149610Sdonn cdev_decl(hil); 24249610Sdonn /* open, close, read, ioctl, select, map -- XXX should be a map device */ 24349623Skarels #define cdev_hil_init(c,n) { \ 24449623Skarels dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 24549623Skarels (dev_type_write((*))) nullop, dev_init(c,n,ioctl), \ 24649623Skarels (dev_type_stop((*))) enodev, (dev_type_reset((*))) nullop, 0, \ 24749623Skarels dev_init(c,n,select), dev_init(c,n,map), 0 } 24841475Smckusick 24941475Smckusick #include "dcm.h" 25049610Sdonn cdev_decl(dcm); 25141475Smckusick 25249610Sdonn cdev_decl(cd); 25349610Sdonn 25449610Sdonn cdev_decl(vn); 25549610Sdonn /* open, read, write, ioctl -- XXX should be a disk */ 25649623Skarels #define cdev_vn_init(c,n) { \ 25749623Skarels dev_init(c,n,open), (dev_type_close((*))) nullop, dev_init(c,n,read), \ 25849623Skarels dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ 25949623Skarels (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, \ 260*68130Smckusick (dev_type_strategy((*))) nullop, D_DISK } 26147583Smccanne 26249610Sdonn dev_type_open(fdopen); 26349610Sdonn /* open */ 26449623Skarels #define cdev_fd_init(c,n) { \ 26549623Skarels dev_init(c,n,open), (dev_type_close((*))) enodev, \ 26649623Skarels (dev_type_read((*))) enodev, (dev_type_write((*))) enodev, \ 26749623Skarels (dev_type_ioctl((*))) enodev, (dev_type_stop((*))) enodev, \ 26849623Skarels (dev_type_reset((*))) enodev, 0, (dev_type_select((*))) enodev, \ 26949623Skarels (dev_type_map((*))) enodev, 0 } 27041475Smckusick 27149610Sdonn #include "bpfilter.h" 27249610Sdonn cdev_decl(bpf); 27349610Sdonn /* open, close, read, write, ioctl, select -- XXX should be generic device */ 27449623Skarels #define cdev_bpf_init(c,n) { \ 27549623Skarels dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ 27649623Skarels dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ 27749623Skarels (dev_type_reset((*))) enodev, 0, dev_init(c,n,select), \ 27849623Skarels (dev_type_map((*))) enodev, 0 } 27947581Skarels 28041475Smckusick struct cdevsw cdevsw[] = 28141475Smckusick { 28249610Sdonn cdev_cn_init(1,cn), /* 0: virtual console */ 28349610Sdonn cdev_ctty_init(1,ctty), /* 1: controlling terminal */ 28449610Sdonn cdev_mm_init(1,mm), /* 2: /dev/{null,mem,kmem,...} */ 28549610Sdonn cdev_swap_init(1,sw), /* 3: /dev/drum (swap pseudo-device) */ 28649610Sdonn cdev_tty_init(NPTY,pts), /* 4: pseudo-tty slave */ 28749610Sdonn cdev_ptc_init(NPTY,ptc), /* 5: pseudo-tty master */ 28849610Sdonn cdev_log_init(1,log), /* 6: /dev/klog */ 28949610Sdonn cdev_tape_init(NCT,ct), /* 7: cs80 cartridge tape */ 29057336Shibler cdev_ldisk_init(NSD,sd), /* 8: scsi disk */ 29157336Shibler cdev_ldisk_init(NRD,rd), /* 9: hpib disk */ 29253933Shibler cdev_grf_init(NGRF,grf), /* 10: frame buffer */ 29349610Sdonn cdev_ppi_init(NPPI,ppi), /* 11: printer/plotter interface */ 29449610Sdonn cdev_tty_init(NDCA,dca), /* 12: built-in single-port serial */ 29549610Sdonn cdev_ite_init(NITE,ite), /* 13: console terminal emulator */ 29649610Sdonn cdev_hil_init(1,hil), /* 14: human interface loop */ 29749610Sdonn cdev_tty_init(NDCM,dcm), /* 15: 4-port serial */ 29849610Sdonn cdev_notdef(), /* 16 */ 29949610Sdonn cdev_disk_init(NCD,cd), /* 17: concatenated disk */ 30054866Smckusick cdev_notdef(), /* 18 */ 30149610Sdonn cdev_vn_init(NVN,vn), /* 19: vnode disk */ 30249912Smckusick cdev_tape_init(NST,st), /* 20: exabyte tape */ 30349610Sdonn cdev_fd_init(1,fd), /* 21: file descriptor pseudo-dev */ 30449610Sdonn cdev_bpf_init(NBPFILTER,bpf), /* 22: berkeley packet filter */ 30541475Smckusick }; 30649610Sdonn 30741475Smckusick int nchrdev = sizeof (cdevsw) / sizeof (cdevsw[0]); 30841475Smckusick 30941475Smckusick int mem_no = 2; /* major device number of memory special file */ 31041475Smckusick 31141475Smckusick /* 31241475Smckusick * Swapdev is a fake device implemented 31341475Smckusick * in sw.c used only internally to get to swstrategy. 31441475Smckusick * It cannot be provided to the users, because the 31541475Smckusick * swstrategy routine munches the b_dev and b_blkno entries 31641475Smckusick * before calling the appropriate driver. This would horribly 31741475Smckusick * confuse, e.g. the hashing routines. Instead, /dev/drum is 31841475Smckusick * provided as a character (raw) device. 31941475Smckusick */ 32041475Smckusick dev_t swapdev = makedev(3, 0); 32159487Smckusick 32259487Smckusick /* 32359487Smckusick * Routine that identifies /dev/mem and /dev/kmem. 32459487Smckusick * 32559487Smckusick * A minimal stub routine can always return 0. 32659487Smckusick */ 32759487Smckusick iskmemdev(dev) 32859487Smckusick dev_t dev; 32959487Smckusick { 33059487Smckusick 33164848Shibler return (major(dev) == 2 && minor(dev) < 2); 33259487Smckusick } 33359487Smckusick 33464848Shibler iszerodev(dev) 33564848Shibler dev_t dev; 33664848Shibler { 33764848Shibler 33864848Shibler return (major(dev) == 2 && minor(dev) == 12); 33964848Shibler } 34064848Shibler 34159487Smckusick #define MAXDEV 21 34259487Smckusick static int chrtoblktbl[MAXDEV] = { 34359487Smckusick /* VCHR */ /* VBLK */ 34459487Smckusick /* 0 */ NODEV, 34559487Smckusick /* 1 */ NODEV, 34659487Smckusick /* 2 */ NODEV, 34759487Smckusick /* 3 */ NODEV, 34859487Smckusick /* 4 */ NODEV, 34959487Smckusick /* 5 */ NODEV, 35059487Smckusick /* 6 */ NODEV, 35159487Smckusick /* 7 */ 0, 35259487Smckusick /* 8 */ 4, 35359487Smckusick /* 9 */ 2, 35459487Smckusick /* 10 */ NODEV, 35559487Smckusick /* 11 */ NODEV, 35659487Smckusick /* 12 */ NODEV, 35759487Smckusick /* 13 */ NODEV, 35859487Smckusick /* 14 */ NODEV, 35959487Smckusick /* 15 */ NODEV, 36059487Smckusick /* 16 */ NODEV, 36159487Smckusick /* 17 */ 5, 36259487Smckusick /* 18 */ NODEV, 36359487Smckusick /* 19 */ 6, 36459487Smckusick /* 20 */ 7, 36559487Smckusick }; 36659487Smckusick /* 36759487Smckusick * Routine to convert from character to block device number. 36859487Smckusick * 36959487Smckusick * A minimal stub routine can always return NODEV. 37059487Smckusick */ 37159487Smckusick chrtoblk(dev) 37259487Smckusick dev_t dev; 37359487Smckusick { 37459487Smckusick int blkmaj; 37559487Smckusick 37659487Smckusick if (major(dev) >= MAXDEV || (blkmaj = chrtoblktbl[major(dev)]) == NODEV) 37759487Smckusick return (NODEV); 37859487Smckusick return (makedev(blkmaj, minor(dev))); 37959487Smckusick } 380