Commit | Line | Data |
---|---|---|
a0422ac5 AF |
1 | /*- |
2 | * Copyright (c) 1992 OMRON Corporation. | |
ad787160 C |
3 | * Copyright (c) 1991, 1992, 1993 |
4 | * The Regents of the University of California. All rights reserved. | |
a0422ac5 | 5 | * |
ad787160 C |
6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | |
14 | * 3. All advertising materials mentioning features or use of this software | |
15 | * must display the following acknowledgement: | |
16 | * This product includes software developed by the University of | |
17 | * California, Berkeley and its contributors. | |
18 | * 4. Neither the name of the University nor the names of its contributors | |
19 | * may be used to endorse or promote products derived from this software | |
20 | * without specific prior written permission. | |
21 | * | |
22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
32 | * SUCH DAMAGE. | |
a0422ac5 | 33 | * |
d8fbd58f | 34 | * from: hp300/hp300/conf.c 7.16 (Berkeley) 4/28/93 |
a0422ac5 | 35 | * |
ad787160 | 36 | * @(#)conf.c 8.1 (Berkeley) 6/10/93 |
a0422ac5 AF |
37 | */ |
38 | ||
3e27060a AF |
39 | #include <sys/param.h> |
40 | #include <sys/systm.h> | |
41 | #include <sys/buf.h> | |
42 | #include <sys/ioctl.h> | |
43 | #include <sys/proc.h> | |
d8fbd58f | 44 | #include <sys/vnode.h> |
3e27060a AF |
45 | #include <sys/tty.h> |
46 | #include <sys/conf.h> | |
a0422ac5 AF |
47 | |
48 | int rawread __P((dev_t, struct uio *, int)); | |
49 | int rawwrite __P((dev_t, struct uio *, int)); | |
50 | int swstrategy __P((struct buf *)); | |
51 | int ttselect __P((dev_t, int, struct proc *)); | |
52 | ||
53 | #define dev_type_open(n) int n __P((dev_t, int, int, struct proc *)) | |
54 | #define dev_type_close(n) int n __P((dev_t, int, int, struct proc *)) | |
55 | #define dev_type_strategy(n) int n __P((struct buf *)) | |
56 | #define dev_type_ioctl(n) \ | |
57 | int n __P((dev_t, int, caddr_t, int, struct proc *)) | |
58 | ||
59 | /* bdevsw-specific types */ | |
60 | #define dev_type_dump(n) int n __P(()) | |
61 | #define dev_type_size(n) int n __P((dev_t)) | |
62 | ||
63 | #define dev_decl(n,t) __CONCAT(dev_type_,t)(__CONCAT(n,t)) | |
64 | #define dev_init(c,n,t) \ | |
65 | (c > 0 ? __CONCAT(n,t) : (__CONCAT(dev_type_,t)((*))) enxio) | |
66 | ||
67 | /* bdevsw-specific initializations */ | |
68 | #define dev_size_init(c,n) (c > 0 ? __CONCAT(n,size) : 0) | |
69 | ||
70 | #define bdev_decl(n) \ | |
71 | dev_decl(n,open); dev_decl(n,close); dev_decl(n,strategy); \ | |
72 | dev_decl(n,ioctl); dev_decl(n,dump); dev_decl(n,size) | |
73 | ||
5456a133 | 74 | /* disk without close routine */ |
a0422ac5 AF |
75 | #define bdev_disk_init(c,n) { \ |
76 | dev_init(c,n,open), (dev_type_close((*))) nullop, \ | |
77 | dev_init(c,n,strategy), dev_init(c,n,ioctl), \ | |
78 | dev_init(c,n,dump), dev_size_init(c,n), 0 } | |
79 | ||
5456a133 AF |
80 | /* disk with close routine */ |
81 | #define bdev_ldisk_init(c,n) { \ | |
82 | dev_init(c,n,open), dev_init(c,n,close), \ | |
83 | dev_init(c,n,strategy), dev_init(c,n,ioctl), \ | |
84 | dev_init(c,n,dump), dev_size_init(c,n), 0 } | |
85 | ||
a0422ac5 AF |
86 | #define bdev_tape_init(c,n) { \ |
87 | dev_init(c,n,open), dev_init(c,n,close), \ | |
88 | dev_init(c,n,strategy), dev_init(c,n,ioctl), \ | |
89 | dev_init(c,n,dump), 0, B_TAPE } | |
90 | ||
91 | #define bdev_swap_init() { \ | |
92 | (dev_type_open((*))) enodev, (dev_type_close((*))) enodev, \ | |
93 | swstrategy, (dev_type_ioctl((*))) enodev, \ | |
94 | (dev_type_dump((*))) enodev, 0, 0 } | |
95 | ||
96 | #define bdev_notdef() bdev_tape_init(0,no) | |
a154dbec | 97 | |
a0422ac5 AF |
98 | bdev_decl(no); /* dummy declarations */ |
99 | ||
100 | #include "st.h" | |
101 | #include "sd.h" | |
102 | #include "vn.h" | |
103 | ||
104 | bdev_decl(st); | |
105 | bdev_decl(sd); | |
106 | bdev_decl(vn); | |
107 | ||
108 | struct bdevsw bdevsw[] = | |
109 | { | |
110 | bdev_notdef(), /* 0 */ | |
111 | bdev_notdef(), /* 1 */ | |
5456a133 | 112 | bdev_notdef(), /* 2 */ |
a0422ac5 | 113 | bdev_swap_init(), /* 3: swap pseudo-device */ |
5456a133 | 114 | bdev_ldisk_init(NSD,sd),/* 4: scsi disk */ |
a0422ac5 AF |
115 | bdev_notdef(), /* 5 */ |
116 | bdev_disk_init(NVN,vn), /* 6: vnode disk driver (swap to files) */ | |
117 | bdev_tape_init(NST,st), /* 7: scsi tape */ | |
118 | }; | |
119 | ||
120 | int nblkdev = sizeof (bdevsw) / sizeof (bdevsw[0]); | |
121 | ||
122 | /* cdevsw-specific types */ | |
123 | #define dev_type_read(n) int n __P((dev_t, struct uio *, int)) | |
124 | #define dev_type_write(n) int n __P((dev_t, struct uio *, int)) | |
125 | #define dev_type_stop(n) int n __P((struct tty *, int)) | |
126 | #define dev_type_reset(n) int n __P((int)) | |
127 | #define dev_type_select(n) int n __P((dev_t, int, struct proc *)) | |
128 | #define dev_type_map(n) int n __P(()) | |
129 | ||
130 | #define cdev_decl(n) \ | |
131 | dev_decl(n,open); dev_decl(n,close); dev_decl(n,read); \ | |
132 | dev_decl(n,write); dev_decl(n,ioctl); dev_decl(n,stop); \ | |
133 | dev_decl(n,reset); dev_decl(n,select); dev_decl(n,map); \ | |
134 | dev_decl(n,strategy); extern struct tty __CONCAT(n,_tty)[] | |
135 | ||
136 | #define dev_tty_init(c,n) (c > 0 ? __CONCAT(n,_tty) : 0) | |
137 | ||
138 | /* open, read, write, ioctl, strategy */ | |
139 | #define cdev_disk_init(c,n) { \ | |
140 | dev_init(c,n,open), (dev_type_close((*))) nullop, dev_init(c,n,read), \ | |
141 | dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ | |
142 | (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, \ | |
143 | dev_init(c,n,strategy) } | |
144 | ||
5456a133 AF |
145 | /* open, close, read, write, ioctl, strategy */ |
146 | #define cdev_ldisk_init(c,n) { \ | |
147 | dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ | |
148 | dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ | |
149 | (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, \ | |
150 | dev_init(c,n,strategy) } | |
151 | ||
a0422ac5 AF |
152 | /* open, close, read, write, ioctl, strategy */ |
153 | #define cdev_tape_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((*))) enodev, \ | |
156 | (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, \ | |
157 | dev_init(c,n,strategy) } | |
158 | ||
159 | /* open, close, read, write, ioctl, stop, tty */ | |
160 | #define cdev_tty_init(c,n) { \ | |
161 | dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ | |
162 | dev_init(c,n,write), dev_init(c,n,ioctl), dev_init(c,n,stop), \ | |
163 | (dev_type_reset((*))) nullop, dev_tty_init(c,n), ttselect, \ | |
164 | (dev_type_map((*))) enodev, 0 } | |
165 | ||
166 | #define cdev_notdef() { \ | |
167 | (dev_type_open((*))) enodev, (dev_type_close((*))) enodev, \ | |
168 | (dev_type_read((*))) enodev, (dev_type_write((*))) enodev, \ | |
169 | (dev_type_ioctl((*))) enodev, (dev_type_stop((*))) enodev, \ | |
170 | (dev_type_reset((*))) nullop, 0, seltrue, \ | |
171 | (dev_type_map((*))) enodev, 0 } | |
172 | ||
173 | cdev_decl(no); /* dummy declarations */ | |
174 | ||
175 | cdev_decl(cn); | |
176 | /* open, close, read, write, ioctl, select -- XXX should be a tty */ | |
177 | #define cdev_cn_init(c,n) { \ | |
178 | dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ | |
179 | dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) nullop, \ | |
180 | (dev_type_reset((*))) nullop, 0, dev_init(c,n,select), \ | |
181 | (dev_type_map((*))) enodev, 0 } | |
182 | ||
183 | cdev_decl(ctty); | |
184 | /* open, read, write, ioctl, select -- XXX should be a tty */ | |
185 | #define cdev_ctty_init(c,n) { \ | |
186 | dev_init(c,n,open), (dev_type_close((*))) nullop, dev_init(c,n,read), \ | |
187 | dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) nullop, \ | |
188 | (dev_type_reset((*))) nullop, 0, dev_init(c,n,select), \ | |
189 | (dev_type_map((*))) enodev, 0 } | |
190 | ||
191 | dev_type_read(mmrw); | |
192 | /* read/write */ | |
193 | #define cdev_mm_init(c,n) { \ | |
194 | (dev_type_open((*))) nullop, (dev_type_close((*))) nullop, mmrw, \ | |
195 | mmrw, (dev_type_ioctl((*))) enodev, (dev_type_stop((*))) nullop, \ | |
196 | (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, 0 } | |
197 | ||
198 | /* read, write, strategy */ | |
199 | #define cdev_swap_init(c,n) { \ | |
200 | (dev_type_open((*))) nullop, (dev_type_close((*))) nullop, rawread, \ | |
201 | rawwrite, (dev_type_ioctl((*))) enodev, (dev_type_stop((*))) enodev, \ | |
202 | (dev_type_reset((*))) nullop, 0, (dev_type_select((*))) enodev, \ | |
203 | (dev_type_map((*))) enodev, dev_init(c,n,strategy) } | |
204 | ||
205 | #include "pty.h" | |
206 | #define pts_tty pt_tty | |
207 | #define ptsioctl ptyioctl | |
208 | cdev_decl(pts); | |
209 | #define ptc_tty pt_tty | |
210 | #define ptcioctl ptyioctl | |
211 | cdev_decl(ptc); | |
212 | ||
213 | /* open, close, read, write, ioctl, tty, select */ | |
214 | #define cdev_ptc_init(c,n) { \ | |
215 | dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ | |
216 | dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) nullop, \ | |
217 | (dev_type_reset((*))) nullop, dev_tty_init(c,n), dev_init(c,n,select), \ | |
218 | (dev_type_map((*))) enodev, 0 } | |
219 | ||
220 | cdev_decl(log); | |
221 | /* open, close, read, ioctl, select -- XXX should be a generic device */ | |
222 | #define cdev_log_init(c,n) { \ | |
223 | dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ | |
224 | (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \ | |
225 | (dev_type_stop((*))) enodev, (dev_type_reset((*))) nullop, 0, \ | |
226 | dev_init(c,n,select), (dev_type_map((*))) enodev, 0 } | |
227 | ||
228 | cdev_decl(st); | |
229 | cdev_decl(sd); | |
230 | ||
a154dbec AF |
231 | cdev_decl(fb); |
232 | /* open, close, ioctl, mmap */ | |
233 | #define cdev_fb_init(c,n) { \ | |
234 | dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) nullop, \ | |
235 | (dev_type_write((*))) nullop, dev_init(c,n,ioctl), \ | |
236 | (dev_type_stop((*))) enodev, (dev_type_reset((*))) nullop, 0, \ | |
237 | dev_init(c,n,select), dev_init(c,n,map), 0 } | |
238 | ||
a0422ac5 AF |
239 | #include "sio.h" |
240 | cdev_decl(sio); | |
241 | ||
264d891a AF |
242 | #include "bmc.h" |
243 | cdev_decl(bmc); | |
244 | ||
a49126f5 AF |
245 | cdev_decl(kbd); |
246 | /* open, close, read, ioctl, select, map -- XXX should be a map device */ | |
247 | #define cdev_kbd_init(c,n) { \ | |
248 | dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ | |
249 | (dev_type_write((*))) nullop, dev_init(c,n,ioctl), \ | |
250 | (dev_type_stop((*))) enodev, (dev_type_reset((*))) nullop, 0, \ | |
251 | dev_init(c,n,select), (dev_type_map((*))) nullop, 0 } | |
252 | ||
a0422ac5 AF |
253 | cdev_decl(cd); |
254 | ||
a0422ac5 AF |
255 | cdev_decl(vn); |
256 | /* open, read, write, ioctl -- XXX should be a disk */ | |
257 | #define cdev_vn_init(c,n) { \ | |
258 | dev_init(c,n,open), (dev_type_close((*))) nullop, dev_init(c,n,read), \ | |
259 | dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ | |
260 | (dev_type_reset((*))) nullop, 0, seltrue, (dev_type_map((*))) enodev, \ | |
261 | 0 } | |
262 | ||
263 | dev_type_open(fdopen); | |
264 | /* open */ | |
265 | #define cdev_fd_init(c,n) { \ | |
266 | dev_init(c,n,open), (dev_type_close((*))) enodev, \ | |
267 | (dev_type_read((*))) enodev, (dev_type_write((*))) enodev, \ | |
268 | (dev_type_ioctl((*))) enodev, (dev_type_stop((*))) enodev, \ | |
269 | (dev_type_reset((*))) enodev, 0, (dev_type_select((*))) enodev, \ | |
270 | (dev_type_map((*))) enodev, 0 } | |
271 | ||
272 | #include "bpfilter.h" | |
273 | cdev_decl(bpf); | |
274 | /* open, close, read, write, ioctl, select -- XXX should be generic device */ | |
275 | #define cdev_bpf_init(c,n) { \ | |
276 | dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ | |
277 | dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ | |
278 | (dev_type_reset((*))) enodev, 0, dev_init(c,n,select), \ | |
279 | (dev_type_map((*))) enodev, 0 } | |
280 | ||
281 | struct cdevsw cdevsw[] = | |
282 | { | |
283 | cdev_cn_init(1,cn), /* 0: virtual console */ | |
284 | cdev_ctty_init(1,ctty), /* 1: controlling terminal */ | |
285 | cdev_mm_init(1,mm), /* 2: /dev/{null,mem,kmem,...} */ | |
286 | cdev_swap_init(1,sw), /* 3: /dev/drum (swap pseudo-device) */ | |
287 | cdev_tty_init(NPTY,pts), /* 4: pseudo-tty slave */ | |
288 | cdev_ptc_init(NPTY,ptc), /* 5: pseudo-tty master */ | |
289 | cdev_log_init(1,log), /* 6: /dev/klog */ | |
290 | cdev_notdef(), /* 7 */ | |
5456a133 | 291 | cdev_ldisk_init(NSD,sd), /* 8: scsi disk */ |
a154dbec AF |
292 | cdev_notdef(), /* 9 */ |
293 | cdev_fb_init(1,fb), /* 10: frame buffer */ | |
a0422ac5 AF |
294 | cdev_notdef(), /* 11 */ |
295 | cdev_tty_init(NSIO,sio), /* 12: built-in single-port serial */ | |
264d891a | 296 | cdev_tty_init(NBMC,bmc), /* 13: console terminal emulator */ |
a49126f5 | 297 | cdev_kbd_init(2,kbd), /* 14: kyeboard */ |
a0422ac5 AF |
298 | cdev_notdef(), /* 15 */ |
299 | cdev_notdef(), /* 16 */ | |
300 | cdev_notdef(), /* 17 */ | |
c4b4b65a | 301 | cdev_notdef(), /* 18 */ |
a0422ac5 AF |
302 | cdev_vn_init(NVN,vn), /* 19: vnode disk */ |
303 | cdev_tape_init(NST,st), /* 20: scsi tape */ | |
304 | cdev_fd_init(1,fd), /* 21: file descriptor pseudo-dev */ | |
305 | cdev_bpf_init(NBPFILTER,bpf), /* 22: berkeley packet filter */ | |
306 | }; | |
307 | ||
308 | int nchrdev = sizeof (cdevsw) / sizeof (cdevsw[0]); | |
309 | ||
310 | int mem_no = 2; /* major device number of memory special file */ | |
311 | ||
312 | /* | |
313 | * Swapdev is a fake device implemented | |
314 | * in sw.c used only internally to get to swstrategy. | |
315 | * It cannot be provided to the users, because the | |
316 | * swstrategy routine munches the b_dev and b_blkno entries | |
317 | * before calling the appropriate driver. This would horribly | |
318 | * confuse, e.g. the hashing routines. Instead, /dev/drum is | |
319 | * provided as a character (raw) device. | |
320 | */ | |
321 | dev_t swapdev = makedev(3, 0); | |
d8fbd58f AF |
322 | |
323 | /* | |
324 | * Routine that identifies /dev/mem and /dev/kmem. | |
325 | * | |
326 | * A minimal stub routine can always return 0. | |
327 | */ | |
328 | iskmemdev(dev) | |
329 | dev_t dev; | |
330 | { | |
331 | ||
332 | if (major(dev) == 2 && (minor(dev) == 0 || minor(dev) == 1)) | |
333 | return (1); | |
334 | return (0); | |
335 | } | |
336 | ||
337 | /* | |
338 | * Routine to determine if a device is a disk. | |
339 | * | |
340 | * A minimal stub routine can always return 0. | |
341 | */ | |
342 | isdisk(dev, type) | |
343 | dev_t dev; | |
344 | int type; | |
345 | { | |
346 | ||
347 | switch (major(dev)) { | |
348 | case 4: | |
349 | case 6: | |
350 | if (type == VBLK) | |
351 | return (1); | |
352 | return (0); | |
353 | case 8: | |
354 | case 19: | |
355 | if (type == VCHR) | |
356 | return (1); | |
357 | /* fall through */ | |
358 | default: | |
359 | return (0); | |
360 | } | |
361 | /* NOTREACHED */ | |
362 | } | |
363 | ||
364 | #define MAXDEV 21 | |
365 | static int chrtoblktbl[MAXDEV] = { | |
366 | /* VCHR */ /* VBLK */ | |
367 | /* 0 */ NODEV, | |
368 | /* 1 */ NODEV, | |
369 | /* 2 */ NODEV, | |
370 | /* 3 */ NODEV, | |
371 | /* 4 */ NODEV, | |
372 | /* 5 */ NODEV, | |
373 | /* 6 */ NODEV, | |
374 | /* 7 */ NODEV, | |
375 | /* 8 */ 4, | |
376 | /* 9 */ NODEV, | |
377 | /* 10 */ NODEV, | |
378 | /* 11 */ NODEV, | |
379 | /* 12 */ NODEV, | |
380 | /* 13 */ NODEV, | |
381 | /* 14 */ NODEV, | |
382 | /* 15 */ NODEV, | |
383 | /* 16 */ NODEV, | |
384 | /* 17 */ NODEV, | |
385 | /* 18 */ NODEV, | |
386 | /* 19 */ 6, | |
387 | /* 20 */ 7, | |
388 | }; | |
389 | /* | |
390 | * Routine to convert from character to block device number. | |
391 | * | |
392 | * A minimal stub routine can always return NODEV. | |
393 | */ | |
394 | chrtoblk(dev) | |
395 | dev_t dev; | |
396 | { | |
397 | int blkmaj; | |
398 | ||
399 | if (major(dev) >= MAXDEV || (blkmaj = chrtoblktbl[major(dev)]) == NODEV) | |
400 | return (NODEV); | |
401 | return (makedev(blkmaj, minor(dev))); | |
402 | } |