xref: /freebsd/sys/kern/kern_conf.c (revision 3e0f6b97b257a96f7275e4442204263e44b16686)
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  * $FreeBSD$
34  */
35 
36 #include <sys/param.h>
37 #include <sys/types.h>
38 #include <sys/systm.h>
39 #include <sys/conf.h>
40 #include <sys/vnode.h>
41 
42 #define NUMBDEV 128
43 #define NUMCDEV 256
44 #define bdevsw_ALLOCSTART	(NUMBDEV/2)
45 #define cdevsw_ALLOCSTART	(NUMCDEV/2)
46 
47 struct bdevsw 	*bdevsw[NUMBDEV];
48 int	nblkdev = NUMBDEV;
49 struct cdevsw 	*cdevsw[NUMCDEV];
50 int	nchrdev = NUMCDEV;
51 
52 
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  */
60 int
61 isdisk(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  */
108 dev_t
109 chrtoblk(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) \
126 int 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 
163 ADDENTRY(bdevsw, nblkdev,bdevsw_ALLOCSTART)
164 ADDENTRY(cdevsw, nchrdev,cdevsw_ALLOCSTART)
165 
166 /* Maybe the author might indicate what the f*@# tehis is for? */
167 
168 void
169 cdevsw_make(struct bdevsw *from)
170 {
171 	struct cdevsw *to = from->d_cdev;
172 
173 	if (!to)
174 		panic("No target cdevsw in bdevsw");
175 	to->d_open = from->d_open;
176 	to->d_close = from->d_close;
177 	to->d_read = rawread;
178 	to->d_write = rawwrite;
179 	to->d_ioctl = from->d_ioctl;
180 	to->d_stop = nostop;
181 	to->d_reset = nullreset;
182 	to->d_devtotty = nodevtotty;
183 	to->d_select = seltrue;
184 	to->d_mmap = nommap;
185 	to->d_strategy = from->d_strategy;
186 	to->d_name = from->d_name;
187 	to->d_bdev = from;
188 	to->d_maj = -1;
189 }
190 
191 void
192 bdevsw_add_generic(int bdev, int cdev, struct bdevsw *bdevsw)
193 {
194 	dev_t dev;
195 	/*
196 	 * XXX hack alert.
197 	 */
198 	if (isdisk(makedev(bdev, 0), VBLK) && bdevsw->d_flags != D_DISK) {
199 	    printf("bdevsw_add_generic: adding D_DISK flag for device %d\n",
200 		   bdev);
201 	    bdevsw->d_flags = D_DISK;
202 	}
203 	cdevsw_make(bdevsw);
204 	dev = makedev(cdev, 0);
205 	cdevsw_add(&dev, bdevsw->d_cdev, NULL);
206 	dev = makedev(bdev, 0);
207 	bdevsw_add(&dev, bdevsw        , NULL);
208 }
209