kern_conf.c revision 31352
1/*-
2 * Parts Copyright (c) 1995 Terrence R. Lambert
3 * Copyright (c) 1995 Julian R. Elischer
4 * All rights reserved.
5 *
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 Terrence R. Lambert.
17 * 4. The name Terrence R. Lambert may not be used to endorse or promote
18 *    products derived from this software without specific prior written
19 *    permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY Julian R. Elischer ``AS IS'' AND ANY
22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE TERRENCE R. LAMBERT BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * $Id: kern_conf.c,v 1.22 1997/09/27 13:39:03 kato Exp $
34 */
35
36#include <sys/param.h>
37#include <sys/systm.h>
38#include <sys/conf.h>
39#include <sys/vnode.h>
40
41#define NUMBDEV 128
42#define NUMCDEV 256
43#define bdevsw_ALLOCSTART	(NUMBDEV/2)
44#define cdevsw_ALLOCSTART	(NUMCDEV/2)
45
46struct bdevsw 	*bdevsw[NUMBDEV];
47int	nblkdev = NUMBDEV;
48struct cdevsw 	*cdevsw[NUMCDEV];
49int	nchrdev = NUMCDEV;
50
51static void	cdevsw_make __P((struct bdevsw *from));
52static int	isdisk __P((dev_t dev, int type));
53
54/*
55 * Routine to determine if a device is a disk.
56 *
57 * KLUDGE XXX add flags to cdevsw entries for disks XXX
58 * A minimal stub routine can always return 0.
59 */
60static int
61isdisk(dev, type)
62	dev_t dev;
63	int type;
64{
65
66	switch (major(dev)) {
67	case 15:		/* VBLK: vn, VCHR: cd */
68		return (1);
69	case 0:			/* wd */
70	case 2:			/* fd */
71	case 4:			/* sd */
72	case 6:			/* cd */
73	case 7:			/* mcd */
74	case 16:		/* scd */
75	case 17:		/* matcd */
76	case 18:		/* ata */
77	case 19:		/* wcd */
78	case 20:		/* od */
79	case 22:		/* gd */
80		if (type == VBLK)
81			return (1);
82		return (0);
83	case 3:			/* wd */
84	case 9:			/* fd */
85	case 13:		/* sd */
86	case 29:		/* mcd */
87	case 43:		/* vn */
88	case 45:		/* scd */
89	case 46:		/* matcd */
90	case 69:		/* wcd */
91	case 70:		/* od */
92	case 78:		/* gd */
93		if (type == VCHR)
94			return (1);
95		/* fall through */
96	default:
97		return (0);
98	}
99	/* NOTREACHED */
100}
101
102
103/*
104 * Routine to convert from character to block device number.
105 *
106 * A minimal stub routine can always return NODEV.
107 */
108dev_t
109chrtoblk(dev_t dev)
110{
111	struct bdevsw *bd;
112	struct cdevsw *cd;
113
114	if(cd = cdevsw[major(dev)]) {
115          if ( (bd = cd->d_bdev) )
116	    return(makedev(bd->d_maj,minor(dev)));
117	}
118	return(NODEV);
119}
120
121/*
122 * (re)place an entry in the bdevsw or cdevsw table
123 * return the slot used in major(*descrip)
124 */
125#define ADDENTRY(TTYPE,NXXXDEV,ALLOCSTART) \
126int TTYPE##_add(dev_t *descrip,						\
127		struct TTYPE *newentry,					\
128		struct TTYPE **oldentry)				\
129{									\
130	int i ;								\
131	if ( (int)*descrip == NODEV) {	/* auto (0 is valid) */		\
132		/*							\
133		 * Search the table looking for a slot...		\
134		 */							\
135		for (i = ALLOCSTART; i < NXXXDEV; i++)			\
136			if (TTYPE[i] == NULL)				\
137				break;		/* found one! */	\
138		/* out of allocable slots? */				\
139		if (i >= NXXXDEV) {					\
140			return ENFILE;					\
141		}							\
142	} else {				/* assign */		\
143		i = major(*descrip);					\
144		if (i < 0 || i >= NXXXDEV) {				\
145			return EINVAL;					\
146		}							\
147	}								\
148									\
149	/* maybe save old */						\
150        if (oldentry) {							\
151		*oldentry = TTYPE[i];					\
152	}								\
153	if (newentry)							\
154		newentry->d_maj = i;					\
155	/* replace with new */						\
156	TTYPE[i] = newentry;						\
157									\
158	/* done!  let them know where we put it */			\
159	*descrip = makedev(i,0);					\
160	return 0;							\
161} \
162
163ADDENTRY(bdevsw, nblkdev,bdevsw_ALLOCSTART)
164ADDENTRY(cdevsw, nchrdev,cdevsw_ALLOCSTART)
165
166/*
167 * Since the bdevsw struct for a disk contains all the information
168 * needed to create a cdevsw entry, these two routines do that, rather
169 * than specifying it by hand.
170 */
171
172static void
173cdevsw_make(struct bdevsw *from)
174{
175	struct cdevsw *to = from->d_cdev;
176
177	if (!to)
178		panic("No target cdevsw in bdevsw");
179	to->d_open = from->d_open;
180	to->d_close = from->d_close;
181	to->d_read = rawread;
182	to->d_write = rawwrite;
183	to->d_ioctl = from->d_ioctl;
184	to->d_stop = nostop;
185	to->d_reset = nullreset;
186	to->d_devtotty = nodevtotty;
187	to->d_poll = seltrue;
188	to->d_mmap = nommap;
189	to->d_strategy = from->d_strategy;
190	to->d_name = from->d_name;
191	to->d_bdev = from;
192	to->d_maj = -1;
193}
194
195void
196bdevsw_add_generic(int bdev, int cdev, struct bdevsw *bdevsw)
197{
198	dev_t dev;
199	/*
200	 * XXX hack alert.
201	 */
202	if (isdisk(makedev(bdev, 0), VBLK) &&
203	    (bdevsw->d_flags & D_TYPEMASK) != D_DISK) {
204	    printf("bdevsw_add_generic: adding D_DISK flag for device %d\n",
205		   bdev);
206	    bdevsw->d_flags &= ~D_TYPEMASK;
207	    bdevsw->d_flags |= D_DISK;
208	}
209	cdevsw_make(bdevsw);
210	dev = makedev(cdev, 0);
211	cdevsw_add(&dev, bdevsw->d_cdev, NULL);
212	dev = makedev(bdev, 0);
213	bdevsw_add(&dev, bdevsw        , NULL);
214}
215