xref: /freebsd/sys/kern/kern_conf.c (revision 0de89efe5c443f213c7ea28773ef2dc6cf3af2ed)
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.21 1997/09/21 22:20:12 julian 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 
46 struct bdevsw 	*bdevsw[NUMBDEV];
47 int	nblkdev = NUMBDEV;
48 struct cdevsw 	*cdevsw[NUMCDEV];
49 int	nchrdev = NUMCDEV;
50 
51 
52 
53 /*
54  * Routine to determine if a device is a disk.
55  *
56  * KLUDGE XXX add flags to cdevsw entries for disks XXX
57  * A minimal stub routine can always return 0.
58  */
59 int
60 isdisk(dev, type)
61 	dev_t dev;
62 	int type;
63 {
64 
65 	switch (major(dev)) {
66 	case 15:		/* VBLK: vn, VCHR: cd */
67 		return (1);
68 	case 0:			/* wd */
69 	case 2:			/* fd */
70 	case 4:			/* sd */
71 	case 6:			/* cd */
72 	case 7:			/* mcd */
73 	case 16:		/* scd */
74 	case 17:		/* matcd */
75 	case 18:		/* ata */
76 	case 19:		/* wcd */
77 	case 20:		/* od */
78 	case 22:		/* gd */
79 		if (type == VBLK)
80 			return (1);
81 		return (0);
82 	case 3:			/* wd */
83 	case 9:			/* fd */
84 	case 13:		/* sd */
85 	case 29:		/* mcd */
86 	case 43:		/* vn */
87 	case 45:		/* scd */
88 	case 46:		/* matcd */
89 	case 69:		/* wcd */
90 	case 70:		/* od */
91 	case 78:		/* gd */
92 		if (type == VCHR)
93 			return (1);
94 		/* fall through */
95 	default:
96 		return (0);
97 	}
98 	/* NOTREACHED */
99 }
100 
101 
102 /*
103  * Routine to convert from character to block device number.
104  *
105  * A minimal stub routine can always return NODEV.
106  */
107 dev_t
108 chrtoblk(dev_t dev)
109 {
110 	struct bdevsw *bd;
111 	struct cdevsw *cd;
112 
113 	if(cd = cdevsw[major(dev)]) {
114           if ( (bd = cd->d_bdev) )
115 	    return(makedev(bd->d_maj,minor(dev)));
116 	}
117 	return(NODEV);
118 }
119 
120 /*
121  * (re)place an entry in the bdevsw or cdevsw table
122  * return the slot used in major(*descrip)
123  */
124 #define ADDENTRY(TTYPE,NXXXDEV,ALLOCSTART) \
125 int TTYPE##_add(dev_t *descrip,						\
126 		struct TTYPE *newentry,					\
127 		struct TTYPE **oldentry)				\
128 {									\
129 	int i ;								\
130 	if ( (int)*descrip == NODEV) {	/* auto (0 is valid) */		\
131 		/*							\
132 		 * Search the table looking for a slot...		\
133 		 */							\
134 		for (i = ALLOCSTART; i < NXXXDEV; i++)			\
135 			if (TTYPE[i] == NULL)				\
136 				break;		/* found one! */	\
137 		/* out of allocable slots? */				\
138 		if (i >= NXXXDEV) {					\
139 			return ENFILE;					\
140 		}							\
141 	} else {				/* assign */		\
142 		i = major(*descrip);					\
143 		if (i < 0 || i >= NXXXDEV) {				\
144 			return EINVAL;					\
145 		}							\
146 	}								\
147 									\
148 	/* maybe save old */						\
149         if (oldentry) {							\
150 		*oldentry = TTYPE[i];					\
151 	}								\
152 	if (newentry)							\
153 		newentry->d_maj = i;					\
154 	/* replace with new */						\
155 	TTYPE[i] = newentry;						\
156 									\
157 	/* done!  let them know where we put it */			\
158 	*descrip = makedev(i,0);					\
159 	return 0;							\
160 } \
161 
162 ADDENTRY(bdevsw, nblkdev,bdevsw_ALLOCSTART)
163 ADDENTRY(cdevsw, nchrdev,cdevsw_ALLOCSTART)
164 
165 /*
166  * Since the bdevsw struct for a disk contains all the information
167  * needed to create a cdevsw entry, these two routines do that, rather
168  * than specifying it by hand.
169  */
170 
171 void
172 cdevsw_make(struct bdevsw *from)
173 {
174 	struct cdevsw *to = from->d_cdev;
175 
176 	if (!to)
177 		panic("No target cdevsw in bdevsw");
178 	to->d_open = from->d_open;
179 	to->d_close = from->d_close;
180 	to->d_read = rawread;
181 	to->d_write = rawwrite;
182 	to->d_ioctl = from->d_ioctl;
183 	to->d_stop = nostop;
184 	to->d_reset = nullreset;
185 	to->d_devtotty = nodevtotty;
186 	to->d_poll = seltrue;
187 	to->d_mmap = nommap;
188 	to->d_strategy = from->d_strategy;
189 	to->d_name = from->d_name;
190 	to->d_bdev = from;
191 	to->d_maj = -1;
192 }
193 
194 void
195 bdevsw_add_generic(int bdev, int cdev, struct bdevsw *bdevsw)
196 {
197 	dev_t dev;
198 	/*
199 	 * XXX hack alert.
200 	 */
201 	if (isdisk(makedev(bdev, 0), VBLK) &&
202 	    (bdevsw->d_flags & D_TYPEMASK) != D_DISK) {
203 	    printf("bdevsw_add_generic: adding D_DISK flag for device %d\n",
204 		   bdev);
205 	    bdevsw->d_flags &= ~D_TYPEMASK;
206 	    bdevsw->d_flags |= D_DISK;
207 	}
208 	cdevsw_make(bdevsw);
209 	dev = makedev(cdev, 0);
210 	cdevsw_add(&dev, bdevsw->d_cdev, NULL);
211 	dev = makedev(bdev, 0);
212 	bdevsw_add(&dev, bdevsw        , NULL);
213 }
214