xref: /freebsd/sys/kern/kern_conf.c (revision e627b39baccd1ec9129690167cf5e6d860509655)
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.10 1996/07/23 21:52:06 phk Exp $
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 		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 		if (type == VCHR)
92 			return (1);
93 		/* fall through */
94 	default:
95 		return (0);
96 	}
97 	/* NOTREACHED */
98 }
99 
100 
101 /*
102  * Routine to convert from character to block device number.
103  *
104  * A minimal stub routine can always return NODEV.
105  */
106 dev_t
107 chrtoblk(dev_t dev)
108 {
109 	struct bdevsw *bd;
110 	struct cdevsw *cd;
111 
112 	if(cd = cdevsw[major(dev)]) {
113           if ( (bd = cd->d_bdev) )
114 	    return(makedev(bd->d_maj,minor(dev)));
115 	}
116 	return(NODEV);
117 }
118 
119 /*
120  * (re)place an entry in the bdevsw or cdevsw table
121  * return the slot used in major(*descrip)
122  */
123 #define ADDENTRY(TTYPE,NXXXDEV,ALLOCSTART) \
124 int TTYPE##_add(dev_t *descrip,						\
125 		struct TTYPE *newentry,					\
126 		struct TTYPE **oldentry)				\
127 {									\
128 	int i ;								\
129 	if ( (int)*descrip == NODEV) {	/* auto (0 is valid) */		\
130 		/*							\
131 		 * Search the table looking for a slot...		\
132 		 */							\
133 		for (i = ALLOCSTART; i < NXXXDEV; i++)				\
134 			if (TTYPE[i] == NULL)				\
135 				break;		/* found one! */	\
136 		/* out of allocable slots? */				\
137 		if (i >= NXXXDEV) {					\
138 			return ENFILE;					\
139 		}							\
140 	} else {				/* assign */		\
141 		i = major(*descrip);					\
142 		if (i < 0 || i >= NXXXDEV) {				\
143 			return EINVAL;					\
144 		}							\
145 	}								\
146 									\
147 	/* maybe save old */						\
148         if (oldentry) {							\
149 		*oldentry = TTYPE[i];					\
150 	}								\
151 	newentry->d_maj = i;						\
152 	/* replace with new */						\
153 	TTYPE[i] = newentry;						\
154 									\
155 	/* done!  let them know where we put it */			\
156 	*descrip = makedev(i,0);					\
157 	return 0;							\
158 } \
159 
160 ADDENTRY(bdevsw, nblkdev,bdevsw_ALLOCSTART)
161 ADDENTRY(cdevsw, nchrdev,cdevsw_ALLOCSTART)
162 
163 /* Maybe the author might indicate what the f*@# tehis is for? */
164 
165 void
166 cdevsw_make(struct bdevsw *from)
167 {
168 	struct cdevsw *to = from->d_cdev;
169 
170 	if (!to)
171 		panic("No target cdevsw in bdevsw");
172 	to->d_open = from->d_open;
173 	to->d_close = from->d_close;
174 	to->d_read = rawread;
175 	to->d_write = rawwrite;
176 	to->d_ioctl = from->d_ioctl;
177 	to->d_stop = nostop;
178 	to->d_reset = nullreset;
179 	to->d_devtotty = nodevtotty;
180 	to->d_select = seltrue;
181 	to->d_mmap = nommap;
182 	to->d_strategy = from->d_strategy;
183 	to->d_name = from->d_name;
184 	to->d_bdev = from;
185 	to->d_maj = -1;
186 }
187 
188 void
189 bdevsw_add_generic(int bdev, int cdev, struct bdevsw *bdevsw)
190 {
191 	dev_t dev;
192 	cdevsw_make(bdevsw);
193 	dev = makedev(cdev, 0);
194 	cdevsw_add(&dev, bdevsw->d_cdev, NULL);
195 	dev = makedev(bdev, 0);
196 	bdevsw_add(&dev, bdevsw        , NULL);
197 }
198