kern_conf.c revision 29688
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.19 1997/09/14 02:52:12 peter 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
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 */
59int
60isdisk(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 */
107dev_t
108chrtoblk(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) \
125int 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
162ADDENTRY(bdevsw, nblkdev,bdevsw_ALLOCSTART)
163ADDENTRY(cdevsw, nchrdev,cdevsw_ALLOCSTART)
164
165/*
166 * Since the bdevsw struct for a disk contains all the informnation
167 * needed to create a cdevsw entry, these two routines do that, rather
168 * than specifying it by hand.
169 */
170
171void
172cdevsw_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
194void
195bdevsw_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) && bdevsw->d_flags != D_DISK) {
202	    printf("bdevsw_add_generic: adding D_DISK flag for device %d\n",
203		   bdev);
204	    bdevsw->d_flags = D_DISK;
205	}
206	cdevsw_make(bdevsw);
207	dev = makedev(cdev, 0);
208	cdevsw_add(&dev, bdevsw->d_cdev, NULL);
209	dev = makedev(bdev, 0);
210	bdevsw_add(&dev, bdevsw        , NULL);
211}
212