xref: /freebsd/sys/kern/kern_conf.c (revision 3193579b66fd7067f898dbc54bdea81a0e6f9bd0)
1 /*-
2  * Copyright (c) 1999-2002 Poul-Henning Kamp
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 #include <sys/param.h>
31 #include <sys/kernel.h>
32 #include <sys/systm.h>
33 #include <sys/bio.h>
34 #include <sys/lock.h>
35 #include <sys/mutex.h>
36 #include <sys/sysctl.h>
37 #include <sys/module.h>
38 #include <sys/malloc.h>
39 #include <sys/conf.h>
40 #include <sys/vnode.h>
41 #include <sys/queue.h>
42 #include <sys/poll.h>
43 #include <sys/ctype.h>
44 #include <machine/stdarg.h>
45 
46 static MALLOC_DEFINE(M_DEVT, "dev_t", "dev_t storage");
47 
48 /* Built at compile time from sys/conf/majors */
49 extern unsigned char reserved_majors[256];
50 
51 /*
52  * This is the number of hash-buckets.  Experiements with 'real-life'
53  * udev_t's show that a prime halfway between two powers of two works
54  * best.
55  */
56 #define DEVT_HASH 83
57 
58 /* The number of dev_t's we can create before malloc(9) kick in.  */
59 #define DEVT_STASH 50
60 
61 static struct cdev devt_stash[DEVT_STASH];
62 
63 static LIST_HEAD(, cdev) dev_hash[DEVT_HASH];
64 
65 static LIST_HEAD(, cdev) dev_free;
66 
67 static int ready_for_devs;
68 
69 static int free_devt;
70 SYSCTL_INT(_debug, OID_AUTO, free_devt, CTLFLAG_RW, &free_devt, 0, "");
71 
72 int
73 nullop(void)
74 {
75 
76 	return (0);
77 }
78 
79 int
80 eopnotsupp(void)
81 {
82 
83 	return (EOPNOTSUPP);
84 }
85 
86 static int
87 enxio(void)
88 {
89 	return (ENXIO);
90 }
91 
92 static int
93 enodev(void)
94 {
95 	return (ENODEV);
96 }
97 
98 /* Define a dead_cdevsw for use when devices leave unexpectedly. */
99 
100 #define dead_open	(d_open_t *)enxio
101 #define dead_close	(d_close_t *)enxio
102 #define dead_read	(d_read_t *)enxio
103 #define dead_write	(d_write_t *)enxio
104 #define dead_ioctl	(d_ioctl_t *)enxio
105 #define dead_poll	(d_poll_t *)enodev
106 #define dead_mmap	(d_mmap_t *)enodev
107 
108 static void
109 dead_strategy(struct bio *bp)
110 {
111 
112 	biofinish(bp, NULL, ENXIO);
113 }
114 
115 #define dead_dump	(dumper_t *)enxio
116 #define dead_kqfilter	(d_kqfilter_t *)enxio
117 
118 static struct cdevsw dead_cdevsw = {
119 	.d_open =	dead_open,
120 	.d_close =	dead_close,
121 	.d_read =	dead_read,
122 	.d_write =	dead_write,
123 	.d_ioctl =	dead_ioctl,
124 	.d_poll =	dead_poll,
125 	.d_mmap =	dead_mmap,
126 	.d_strategy =	dead_strategy,
127 	.d_name =	"dead",
128 	.d_maj =	255,
129 	.d_dump =	dead_dump,
130 	.d_kqfilter =	dead_kqfilter
131 };
132 
133 /* Default methods if driver does not specify method */
134 
135 #define null_open	(d_open_t *)nullop
136 #define null_close	(d_close_t *)nullop
137 #define no_read		(d_read_t *)enodev
138 #define no_write	(d_write_t *)enodev
139 #define no_ioctl	(d_ioctl_t *)enodev
140 #define no_mmap		(d_mmap_t *)enodev
141 
142 static int
143 no_kqfilter(dev_t dev __unused, struct knote *kn __unused)
144 {
145 
146 	return (1);
147 }
148 
149 static void
150 no_strategy(struct bio *bp)
151 {
152 
153 	biofinish(bp, NULL, ENODEV);
154 }
155 
156 static int
157 no_poll(dev_t dev __unused, int events, struct thread *td __unused)
158 {
159 	/*
160 	 * Return true for read/write.  If the user asked for something
161 	 * special, return POLLNVAL, so that clients have a way of
162 	 * determining reliably whether or not the extended
163 	 * functionality is present without hard-coding knowledge
164 	 * of specific filesystem implementations.
165 	 * Stay in sync with vop_nopoll().
166 	 */
167 	if (events & ~POLLSTANDARD)
168 		return (POLLNVAL);
169 
170 	return (events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
171 }
172 
173 #define no_dump		(dumper_t *)enodev
174 
175 struct cdevsw *
176 devsw(dev_t dev)
177 {
178 	if (dev->si_devsw)
179 		return (dev->si_devsw);
180 	return (&dead_cdevsw);
181 }
182 
183 /*
184  * dev_t and u_dev_t primitives
185  */
186 
187 int
188 major(dev_t x)
189 {
190 	if (x == NODEV)
191 		return NOUDEV;
192 	return((x->si_udev >> 8) & 0xff);
193 }
194 
195 int
196 minor(dev_t x)
197 {
198 	if (x == NODEV)
199 		return NOUDEV;
200 	return(x->si_udev & 0xffff00ff);
201 }
202 
203 int
204 dev2unit(dev_t x)
205 {
206 	int i;
207 
208 	if (x == NODEV)
209 		return NOUDEV;
210 	i = minor(x);
211 	return ((i & 0xff) | (i >> 8));
212 }
213 
214 int
215 unit2minor(int unit)
216 {
217 
218 	KASSERT(unit <= 0xffffff, ("Invalid unit (%d) in unit2minor", unit));
219 	return ((unit & 0xff) | ((unit << 8) & ~0xffff));
220 }
221 
222 static dev_t
223 allocdev(void)
224 {
225 	static int stashed;
226 	struct cdev *si;
227 
228 	if (LIST_FIRST(&dev_free)) {
229 		si = LIST_FIRST(&dev_free);
230 		LIST_REMOVE(si, si_hash);
231 	} else if (stashed >= DEVT_STASH) {
232 		MALLOC(si, struct cdev *, sizeof(*si), M_DEVT,
233 		    M_USE_RESERVE | M_ZERO | M_WAITOK);
234 	} else {
235 		si = devt_stash + stashed++;
236 		bzero(si, sizeof *si);
237 		si->si_flags |= SI_STASHED;
238 	}
239 	si->__si_namebuf[0] = '\0';
240 	si->si_name = si->__si_namebuf;
241 	LIST_INIT(&si->si_children);
242 	TAILQ_INIT(&si->si_snapshots);
243 	return (si);
244 }
245 
246 dev_t
247 makedev(int x, int y)
248 {
249 	struct cdev *si;
250 	udev_t	udev;
251 	int hash;
252 
253 	if (x == umajor(NOUDEV) && y == uminor(NOUDEV))
254 		panic("makedev of NOUDEV");
255 	udev = (x << 8) | y;
256 	hash = udev % DEVT_HASH;
257 	LIST_FOREACH(si, &dev_hash[hash], si_hash) {
258 		if (si->si_udev == udev)
259 			return (si);
260 	}
261 	si = allocdev();
262 	si->si_udev = udev;
263 	LIST_INSERT_HEAD(&dev_hash[hash], si, si_hash);
264         return (si);
265 }
266 
267 void
268 freedev(dev_t dev)
269 {
270 
271 	if (!free_devt)
272 		return;
273 	if (SLIST_FIRST(&dev->si_hlist))
274 		return;
275 	if (dev->si_devsw || dev->si_drv1 || dev->si_drv2)
276 		return;
277 	LIST_REMOVE(dev, si_hash);
278 	if (dev->si_flags & SI_STASHED) {
279 		bzero(dev, sizeof(*dev));
280 		dev->si_flags |= SI_STASHED;
281 		LIST_INSERT_HEAD(&dev_free, dev, si_hash);
282 	} else {
283 		FREE(dev, M_DEVT);
284 	}
285 }
286 
287 udev_t
288 dev2udev(dev_t x)
289 {
290 	if (x == NODEV)
291 		return NOUDEV;
292 	return (x->si_udev);
293 }
294 
295 dev_t
296 udev2dev(udev_t x, int b)
297 {
298 
299 	if (x == NOUDEV)
300 		return (NODEV);
301 	switch (b) {
302 		case 0:
303 			return makedev(umajor(x), uminor(x));
304 		case 1:
305 			return (NODEV);
306 		default:
307 			Debugger("udev2dev(...,X)");
308 			return NODEV;
309 	}
310 }
311 
312 int
313 uminor(udev_t dev)
314 {
315 	return(dev & 0xffff00ff);
316 }
317 
318 int
319 umajor(udev_t dev)
320 {
321 	return((dev & 0xff00) >> 8);
322 }
323 
324 udev_t
325 makeudev(int x, int y)
326 {
327         return ((x << 8) | y);
328 }
329 
330 dev_t
331 make_dev(struct cdevsw *devsw, int minor, uid_t uid, gid_t gid, int perms, const char *fmt, ...)
332 {
333 	dev_t	dev;
334 	va_list ap;
335 	int i;
336 
337 	KASSERT((minor & ~0xffff00ff) == 0,
338 	    ("Invalid minor (0x%x) in make_dev", minor));
339 
340 	if (devsw->d_open == NULL)	devsw->d_open = null_open;
341 	if (devsw->d_close == NULL)	devsw->d_close = null_close;
342 	if (devsw->d_read == NULL)	devsw->d_read = no_read;
343 	if (devsw->d_write == NULL)	devsw->d_write = no_write;
344 	if (devsw->d_ioctl == NULL)	devsw->d_ioctl = no_ioctl;
345 	if (devsw->d_poll == NULL)	devsw->d_poll = no_poll;
346 	if (devsw->d_mmap == NULL)	devsw->d_mmap = no_mmap;
347 	if (devsw->d_strategy == NULL)	devsw->d_strategy = no_strategy;
348 	if (devsw->d_dump == NULL)	devsw->d_dump = no_dump;
349 	if (devsw->d_kqfilter == NULL)	devsw->d_kqfilter = no_kqfilter;
350 
351 	if (devsw->d_maj == MAJOR_AUTO) {
352 		for (i = NUMCDEVSW - 1; i > 0; i--)
353 			if (reserved_majors[i] != i)
354 				break;
355 		KASSERT(i > 0, ("Out of major numbers (%s)", devsw->d_name));
356 		devsw->d_maj = i;
357 		reserved_majors[i] = i;
358 	} else {
359 		if (devsw->d_maj == 256)	/* XXX: tty_cons.c is magic */
360 			devsw->d_maj = 0;
361 		KASSERT(devsw->d_maj >= 0 && devsw->d_maj < 256,
362 		    ("Invalid major (%d) in make_dev", devsw->d_maj));
363 		if (reserved_majors[devsw->d_maj] != devsw->d_maj) {
364 			printf("WARNING: driver \"%s\" used %s %d\n",
365 			    devsw->d_name, "unreserved major device number",
366 			    devsw->d_maj);
367 			reserved_majors[devsw->d_maj] = devsw->d_maj;
368 		}
369 	}
370 
371 	if (!ready_for_devs) {
372 		printf("WARNING: Driver mistake: make_dev(%s) called before SI_SUB_DRIVERS\n",
373 		       fmt);
374 		/* XXX panic here once drivers are cleaned up */
375 	}
376 
377 	dev = makedev(devsw->d_maj, minor);
378 	if (dev->si_flags & SI_CHEAPCLONE &&
379 	    dev->si_flags & SI_NAMED &&
380 	    dev->si_devsw == devsw) {
381 		/*
382 		 * This is allowed as it removes races and generally
383 		 * simplifies cloning devices.
384 		 */
385 		return (dev);
386 	}
387 	if (dev->si_flags & SI_NAMED) {
388 		printf( "WARNING: Driver mistake: repeat make_dev(\"%s\")\n",
389 		    dev->si_name);
390 		panic("don't do that");
391 	}
392 	va_start(ap, fmt);
393 	i = vsnrprintf(dev->__si_namebuf, sizeof dev->__si_namebuf, 32, fmt, ap);
394 	if (i > (sizeof dev->__si_namebuf - 1)) {
395 		printf("WARNING: Device name truncated! (%s)",
396 		    dev->__si_namebuf);
397 	}
398 	va_end(ap);
399 	dev->si_devsw = devsw;
400 	dev->si_uid = uid;
401 	dev->si_gid = gid;
402 	dev->si_mode = perms;
403 	dev->si_flags |= SI_NAMED;
404 
405 	devfs_create(dev);
406 	return (dev);
407 }
408 
409 int
410 dev_named(dev_t pdev, const char *name)
411 {
412 	dev_t cdev;
413 
414 	if (strcmp(devtoname(pdev), name) == 0)
415 		return (1);
416 	LIST_FOREACH(cdev, &pdev->si_children, si_siblings)
417 		if (strcmp(devtoname(cdev), name) == 0)
418 			return (1);
419 	return (0);
420 }
421 
422 void
423 dev_depends(dev_t pdev, dev_t cdev)
424 {
425 
426 	cdev->si_parent = pdev;
427 	cdev->si_flags |= SI_CHILD;
428 	LIST_INSERT_HEAD(&pdev->si_children, cdev, si_siblings);
429 }
430 
431 dev_t
432 make_dev_alias(dev_t pdev, const char *fmt, ...)
433 {
434 	dev_t	dev;
435 	va_list ap;
436 	int i;
437 
438 	dev = allocdev();
439 	dev->si_flags |= SI_ALIAS;
440 	dev->si_flags |= SI_NAMED;
441 	dev_depends(pdev, dev);
442 	va_start(ap, fmt);
443 	i = vsnrprintf(dev->__si_namebuf, sizeof dev->__si_namebuf, 32, fmt, ap);
444 	if (i > (sizeof dev->__si_namebuf - 1)) {
445 		printf("WARNING: Device name truncated! (%s)",
446 		    dev->__si_namebuf);
447 	}
448 	va_end(ap);
449 
450 	devfs_create(dev);
451 	return (dev);
452 }
453 
454 void
455 destroy_dev(dev_t dev)
456 {
457 
458 	if (!(dev->si_flags & SI_NAMED)) {
459 		printf( "WARNING: Driver mistake: destroy_dev on %d/%d\n",
460 		    major(dev), minor(dev));
461 		panic("don't do that");
462 	}
463 
464 	devfs_destroy(dev);
465 	if (dev->si_flags & SI_CHILD) {
466 		LIST_REMOVE(dev, si_siblings);
467 		dev->si_flags &= ~SI_CHILD;
468 	}
469 	while (!LIST_EMPTY(&dev->si_children))
470 		destroy_dev(LIST_FIRST(&dev->si_children));
471 	dev->si_drv1 = 0;
472 	dev->si_drv2 = 0;
473 	dev->si_devsw = 0;
474 	bzero(&dev->__si_u, sizeof(dev->__si_u));
475 	dev->si_flags &= ~SI_NAMED;
476 	dev->si_flags &= ~SI_ALIAS;
477 	freedev(dev);
478 }
479 
480 const char *
481 devtoname(dev_t dev)
482 {
483 	char *p;
484 	int mynor;
485 
486 	if (dev->si_name[0] == '#' || dev->si_name[0] == '\0') {
487 		p = dev->si_name;
488 		if (devsw(dev))
489 			sprintf(p, "#%s/", devsw(dev)->d_name);
490 		else
491 			sprintf(p, "#%d/", major(dev));
492 		p += strlen(p);
493 		mynor = minor(dev);
494 		if (mynor < 0 || mynor > 255)
495 			sprintf(p, "%#x", (u_int)mynor);
496 		else
497 			sprintf(p, "%d", mynor);
498 	}
499 	return (dev->si_name);
500 }
501 
502 int
503 dev_stdclone(char *name, char **namep, const char *stem, int *unit)
504 {
505 	int u, i;
506 
507 	i = strlen(stem);
508 	if (bcmp(stem, name, i) != 0)
509 		return (0);
510 	if (!isdigit(name[i]))
511 		return (0);
512 	u = 0;
513 	if (name[i] == '0' && isdigit(name[i+1]))
514 		return (0);
515 	while (isdigit(name[i])) {
516 		u *= 10;
517 		u += name[i++] - '0';
518 	}
519 	if (u > 0xffffff)
520 		return (0);
521 	*unit = u;
522 	if (namep)
523 		*namep = &name[i];
524 	if (name[i])
525 		return (2);
526 	return (1);
527 }
528 
529 /*
530  * Helper sysctl for devname(3).  We're given a {u}dev_t and return
531  * the name, if any, registered by the device driver.
532  */
533 static int
534 sysctl_devname(SYSCTL_HANDLER_ARGS)
535 {
536 	int error;
537 	udev_t ud;
538 	dev_t dev;
539 
540 	error = SYSCTL_IN(req, &ud, sizeof (ud));
541 	if (error)
542 		return (error);
543 	if (ud == NOUDEV)
544 		return(EINVAL);
545 	dev = makedev(umajor(ud), uminor(ud));
546 	if (dev->si_name[0] == '\0')
547 		error = ENOENT;
548 	else
549 		error = SYSCTL_OUT(req, dev->si_name, strlen(dev->si_name) + 1);
550 	freedev(dev);
551 	return (error);
552 }
553 
554 SYSCTL_PROC(_kern, OID_AUTO, devname, CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_ANYBODY,
555 	NULL, 0, sysctl_devname, "", "devname(3) handler");
556 
557 /*
558  * Set ready_for_devs; prior to this point, device creation is not allowed.
559  */
560 static void
561 dev_set_ready(void *junk)
562 {
563 	ready_for_devs = 1;
564 }
565 
566 SYSINIT(dev_ready, SI_SUB_DEVFS, SI_ORDER_FIRST, dev_set_ready, NULL);
567