xref: /freebsd/sys/kern/kern_conf.c (revision ca9ac06c99bfd0150b85d4d83c396ce6237c0e05)
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 <sys/tty.h>
45 #include <machine/stdarg.h>
46 
47 static MALLOC_DEFINE(M_DEVT, "cdev", "cdev storage");
48 
49 /* Built at compile time from sys/conf/majors */
50 extern unsigned char reserved_majors[256];
51 
52 /*
53  * This is the number of hash-buckets.  Experiments with 'real-life'
54  * dev_t's show that a prime halfway between two powers of two works
55  * best.
56  */
57 #define DEVT_HASH 83
58 
59 static LIST_HEAD(, cdev) dev_hash[DEVT_HASH];
60 
61 static struct mtx devmtx;
62 static void freedev(struct cdev *dev);
63 static struct cdev *newdev(int x, int y, struct cdev *);
64 static void destroy_devl(struct cdev *dev);
65 
66 void
67 dev_lock(void)
68 {
69 	if (!mtx_initialized(&devmtx))
70 		mtx_init(&devmtx, "cdev", NULL, MTX_DEF);
71 	mtx_lock(&devmtx);
72 }
73 
74 void
75 dev_unlock(void)
76 {
77 
78 	mtx_unlock(&devmtx);
79 }
80 
81 void
82 dev_ref(struct cdev *dev)
83 {
84 
85 	mtx_assert(&devmtx, MA_OWNED);
86 	dev->si_refcount++;
87 }
88 
89 void
90 dev_rel(struct cdev *dev)
91 {
92 	int flag = 0;
93 
94 	mtx_assert(&devmtx, MA_NOTOWNED);
95 	dev_lock();
96 	dev->si_refcount--;
97 	KASSERT(dev->si_refcount >= 0,
98 	    ("dev_rel(%s) gave negative count", devtoname(dev)));
99 	if (dev->si_usecount == 0 &&
100 	    (dev->si_flags & SI_CHEAPCLONE) && (dev->si_flags & SI_NAMED))
101 	if (dev->si_devsw == NULL && dev->si_refcount == 0) {
102 		LIST_REMOVE(dev, si_list);
103 		flag = 1;
104 	}
105 	dev_unlock();
106 	if (flag)
107 		freedev(dev);
108 }
109 
110 struct cdevsw *
111 dev_refthread(struct cdev *dev)
112 {
113 	struct cdevsw *csw;
114 
115 	mtx_assert(&devmtx, MA_NOTOWNED);
116 	dev_lock();
117 	csw = dev->si_devsw;
118 	if (csw != NULL)
119 		dev->si_threadcount++;
120 	dev_unlock();
121 	return (csw);
122 }
123 
124 void
125 dev_relthread(struct cdev *dev)
126 {
127 
128 	mtx_assert(&devmtx, MA_NOTOWNED);
129 	dev_lock();
130 	dev->si_threadcount--;
131 	dev_unlock();
132 }
133 
134 int
135 nullop(void)
136 {
137 
138 	return (0);
139 }
140 
141 int
142 eopnotsupp(void)
143 {
144 
145 	return (EOPNOTSUPP);
146 }
147 
148 static int
149 enxio(void)
150 {
151 	return (ENXIO);
152 }
153 
154 static int
155 enodev(void)
156 {
157 	return (ENODEV);
158 }
159 
160 /* Define a dead_cdevsw for use when devices leave unexpectedly. */
161 
162 #define dead_open	(d_open_t *)enxio
163 #define dead_close	(d_close_t *)enxio
164 #define dead_read	(d_read_t *)enxio
165 #define dead_write	(d_write_t *)enxio
166 #define dead_ioctl	(d_ioctl_t *)enxio
167 #define dead_poll	(d_poll_t *)enodev
168 #define dead_mmap	(d_mmap_t *)enodev
169 
170 static void
171 dead_strategy(struct bio *bp)
172 {
173 
174 	biofinish(bp, NULL, ENXIO);
175 }
176 
177 #define dead_dump	(dumper_t *)enxio
178 #define dead_kqfilter	(d_kqfilter_t *)enxio
179 
180 static struct cdevsw dead_cdevsw = {
181 	.d_version =	D_VERSION,
182 	.d_flags =	D_NEEDGIANT, /* XXX: does dead_strategy need this ? */
183 	.d_open =	dead_open,
184 	.d_close =	dead_close,
185 	.d_read =	dead_read,
186 	.d_write =	dead_write,
187 	.d_ioctl =	dead_ioctl,
188 	.d_poll =	dead_poll,
189 	.d_mmap =	dead_mmap,
190 	.d_strategy =	dead_strategy,
191 	.d_name =	"dead",
192 	.d_maj =	255,
193 	.d_dump =	dead_dump,
194 	.d_kqfilter =	dead_kqfilter
195 };
196 
197 /* Default methods if driver does not specify method */
198 
199 #define null_open	(d_open_t *)nullop
200 #define null_close	(d_close_t *)nullop
201 #define no_read		(d_read_t *)enodev
202 #define no_write	(d_write_t *)enodev
203 #define no_ioctl	(d_ioctl_t *)enodev
204 #define no_mmap		(d_mmap_t *)enodev
205 #define no_kqfilter	(d_kqfilter_t *)enodev
206 
207 static void
208 no_strategy(struct bio *bp)
209 {
210 
211 	biofinish(bp, NULL, ENODEV);
212 }
213 
214 static int
215 no_poll(struct cdev *dev __unused, int events, struct thread *td __unused)
216 {
217 	/*
218 	 * Return true for read/write.  If the user asked for something
219 	 * special, return POLLNVAL, so that clients have a way of
220 	 * determining reliably whether or not the extended
221 	 * functionality is present without hard-coding knowledge
222 	 * of specific filesystem implementations.
223 	 * Stay in sync with vop_nopoll().
224 	 */
225 	if (events & ~POLLSTANDARD)
226 		return (POLLNVAL);
227 
228 	return (events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
229 }
230 
231 #define no_dump		(dumper_t *)enodev
232 
233 /*
234  * struct cdev * and u_dev_t primitives
235  */
236 
237 int
238 major(struct cdev *x)
239 {
240 	if (x == NULL)
241 		return NODEV;
242 	return((x->si_drv0 >> 8) & 0xff);
243 }
244 
245 int
246 minor(struct cdev *x)
247 {
248 	if (x == NULL)
249 		return NODEV;
250 	return(x->si_drv0 & MAXMINOR);
251 }
252 
253 int
254 dev2unit(struct cdev *x)
255 {
256 
257 	if (x == NULL)
258 		return NODEV;
259 	return (minor2unit(minor(x)));
260 }
261 
262 u_int
263 minor2unit(u_int _minor)
264 {
265 
266 	KASSERT((_minor & ~MAXMINOR) == 0, ("Illegal minor %x", _minor));
267 	return ((_minor & 0xff) | ((_minor >> 8) & 0xffff00));
268 }
269 
270 int
271 unit2minor(int unit)
272 {
273 
274 	KASSERT(unit <= 0xffffff, ("Invalid unit (%d) in unit2minor", unit));
275 	return ((unit & 0xff) | ((unit << 8) & ~0xffff));
276 }
277 
278 static struct cdev *
279 allocdev(void)
280 {
281 	struct cdev *si;
282 
283 	si = malloc(sizeof *si, M_DEVT, M_USE_RESERVE | M_ZERO | M_WAITOK);
284 	si->si_name = si->__si_namebuf;
285 	LIST_INIT(&si->si_children);
286 	LIST_INIT(&si->si_alist);
287 	return (si);
288 }
289 
290 static struct cdev *
291 newdev(int x, int y, struct cdev *si)
292 {
293 	struct cdev *si2;
294 	dev_t	udev;
295 	int hash;
296 
297 	mtx_assert(&devmtx, MA_OWNED);
298 	if (x == umajor(NODEV) && y == uminor(NODEV))
299 		panic("newdev of NODEV");
300 	udev = (x << 8) | y;
301 	hash = udev % DEVT_HASH;
302 	LIST_FOREACH(si2, &dev_hash[hash], si_hash) {
303 		if (si2->si_drv0 == udev) {
304 			freedev(si);
305 			return (si2);
306 		}
307 	}
308 	si->si_drv0 = udev;
309 	LIST_INSERT_HEAD(&dev_hash[hash], si, si_hash);
310 	return (si);
311 }
312 
313 static void
314 freedev(struct cdev *dev)
315 {
316 
317 	free(dev, M_DEVT);
318 }
319 
320 int
321 uminor(dev_t dev)
322 {
323 	return (dev & MAXMINOR);
324 }
325 
326 int
327 umajor(dev_t dev)
328 {
329 	return ((dev & ~MAXMINOR) >> 8);
330 }
331 
332 static void
333 find_major(struct cdevsw *devsw)
334 {
335 	int i;
336 
337 	if (devsw->d_maj != 0) {
338 		printf("NOTICE: Ignoring d_maj hint from driver \"%s\", %s",
339 		    devsw->d_name, "driver should be updated/fixed\n");
340 		devsw->d_maj = 0;
341 	}
342 	for (i = NUMCDEVSW - 1; i > 0; i--)
343 		if (reserved_majors[i] != i)
344 			break;
345 	KASSERT(i > 0, ("Out of major numbers (%s)", devsw->d_name));
346 	devsw->d_maj = i;
347 	reserved_majors[i] = i;
348 	devsw->d_flags |= D_ALLOCMAJ;
349 }
350 
351 static void
352 fini_cdevsw(struct cdevsw *devsw)
353 {
354 	if (devsw->d_flags & D_ALLOCMAJ) {
355 		reserved_majors[devsw->d_maj] = 0;
356 		devsw->d_maj = 0;
357 		devsw->d_flags &= ~D_ALLOCMAJ;
358 	}
359 	devsw->d_flags &= ~D_INIT;
360 }
361 
362 static void
363 prep_cdevsw(struct cdevsw *devsw)
364 {
365 
366 	dev_lock();
367 
368 	if (devsw->d_version != D_VERSION_01) {
369 		printf(
370 		    "WARNING: Device driver \"%s\" has wrong version %s\n",
371 		    devsw->d_name, "and is disabled.  Recompile KLD module.");
372 		devsw->d_open = dead_open;
373 		devsw->d_close = dead_close;
374 		devsw->d_read = dead_read;
375 		devsw->d_write = dead_write;
376 		devsw->d_ioctl = dead_ioctl;
377 		devsw->d_poll = dead_poll;
378 		devsw->d_mmap = dead_mmap;
379 		devsw->d_strategy = dead_strategy;
380 		devsw->d_dump = dead_dump;
381 		devsw->d_kqfilter = dead_kqfilter;
382 	}
383 
384 	if (devsw->d_flags & D_TTY) {
385 		if (devsw->d_ioctl == NULL)	devsw->d_ioctl = ttyioctl;
386 		if (devsw->d_read == NULL)	devsw->d_read = ttyread;
387 		if (devsw->d_write == NULL)	devsw->d_write = ttywrite;
388 		if (devsw->d_kqfilter == NULL)	devsw->d_kqfilter = ttykqfilter;
389 		if (devsw->d_poll == NULL)	devsw->d_poll = ttypoll;
390 	}
391 
392 	if (devsw->d_open == NULL)	devsw->d_open = null_open;
393 	if (devsw->d_close == NULL)	devsw->d_close = null_close;
394 	if (devsw->d_read == NULL)	devsw->d_read = no_read;
395 	if (devsw->d_write == NULL)	devsw->d_write = no_write;
396 	if (devsw->d_ioctl == NULL)	devsw->d_ioctl = no_ioctl;
397 	if (devsw->d_poll == NULL)	devsw->d_poll = no_poll;
398 	if (devsw->d_mmap == NULL)	devsw->d_mmap = no_mmap;
399 	if (devsw->d_strategy == NULL)	devsw->d_strategy = no_strategy;
400 	if (devsw->d_dump == NULL)	devsw->d_dump = no_dump;
401 	if (devsw->d_kqfilter == NULL)	devsw->d_kqfilter = no_kqfilter;
402 
403 	LIST_INIT(&devsw->d_devs);
404 
405 	devsw->d_flags |= D_INIT;
406 
407 	if (!(devsw->d_flags & D_ALLOCMAJ))
408 		find_major(devsw);
409 	dev_unlock();
410 }
411 
412 struct cdev *
413 make_dev(struct cdevsw *devsw, int minornr, uid_t uid, gid_t gid, int perms, const char *fmt, ...)
414 {
415 	struct cdev *dev;
416 	va_list ap;
417 	int i;
418 
419 	KASSERT((minornr & ~MAXMINOR) == 0,
420 	    ("Invalid minor (0x%x) in make_dev", minornr));
421 
422 	if (!(devsw->d_flags & D_INIT)) {
423 		prep_cdevsw(devsw);
424 		if (devsw->d_uid == 0)
425 			devsw->d_uid = uid;
426 		if (devsw->d_gid == 0)
427 			devsw->d_gid = gid;
428 		if (devsw->d_mode == 0)
429 			devsw->d_mode = perms;
430 	}
431 	dev = allocdev();
432 	dev_lock();
433 	dev = newdev(devsw->d_maj, minornr, dev);
434 	if (dev->si_flags & SI_CHEAPCLONE &&
435 	    dev->si_flags & SI_NAMED &&
436 	    dev->si_devsw == devsw) {
437 		/*
438 		 * This is allowed as it removes races and generally
439 		 * simplifies cloning devices.
440 		 * XXX: still ??
441 		 */
442 		dev_unlock();
443 		return (dev);
444 	}
445 	KASSERT(!(dev->si_flags & SI_NAMED),
446 	    ("make_dev() by driver %s on pre-existing device (maj=%d, min=%x, name=%s)",
447 	    devsw->d_name, major(dev), minor(dev), devtoname(dev)));
448 
449 	va_start(ap, fmt);
450 	i = vsnrprintf(dev->__si_namebuf, sizeof dev->__si_namebuf, 32, fmt, ap);
451 	if (i > (sizeof dev->__si_namebuf - 1)) {
452 		printf("WARNING: Device name truncated! (%s)\n",
453 		    dev->__si_namebuf);
454 	}
455 	va_end(ap);
456 
457 	dev->si_devsw = devsw;
458 	dev->si_flags |= SI_NAMED;
459 
460 	LIST_INSERT_HEAD(&devsw->d_devs, dev, si_list);
461 	devfs_create(dev);
462 	dev_unlock();
463 	return (dev);
464 }
465 
466 int
467 dev_named(struct cdev *pdev, const char *name)
468 {
469 	struct cdev *cdev;
470 
471 	if (strcmp(devtoname(pdev), name) == 0)
472 		return (1);
473 	LIST_FOREACH(cdev, &pdev->si_children, si_siblings)
474 		if (strcmp(devtoname(cdev), name) == 0)
475 			return (1);
476 	return (0);
477 }
478 
479 void
480 dev_depends(struct cdev *pdev, struct cdev *cdev)
481 {
482 
483 	dev_lock();
484 	cdev->si_parent = pdev;
485 	cdev->si_flags |= SI_CHILD;
486 	LIST_INSERT_HEAD(&pdev->si_children, cdev, si_siblings);
487 	dev_unlock();
488 }
489 
490 struct cdev *
491 make_dev_alias(struct cdev *pdev, const char *fmt, ...)
492 {
493 	struct cdev *dev;
494 	va_list ap;
495 	int i;
496 
497 	dev = allocdev();
498 	dev_lock();
499 	dev->si_flags |= SI_ALIAS;
500 	dev->si_flags |= SI_NAMED;
501 	va_start(ap, fmt);
502 	i = vsnrprintf(dev->__si_namebuf, sizeof dev->__si_namebuf, 32, fmt, ap);
503 	if (i > (sizeof dev->__si_namebuf - 1)) {
504 		printf("WARNING: Device name truncated! (%s)\n",
505 		    dev->__si_namebuf);
506 	}
507 	va_end(ap);
508 
509 	devfs_create(dev);
510 	dev_unlock();
511 	dev_depends(pdev, dev);
512 	return (dev);
513 }
514 
515 static void
516 destroy_devl(struct cdev *dev)
517 {
518 	struct cdevsw *csw;
519 
520 	mtx_assert(&devmtx, MA_OWNED);
521 	KASSERT(dev->si_flags & SI_NAMED,
522 	    ("WARNING: Driver mistake: destroy_dev on %d/%d\n",
523 	    major(dev), minor(dev)));
524 
525 	devfs_destroy(dev);
526 
527 	/* Remove name marking */
528 	dev->si_flags &= ~SI_NAMED;
529 
530 	/* If we are a child, remove us from the parents list */
531 	if (dev->si_flags & SI_CHILD) {
532 		LIST_REMOVE(dev, si_siblings);
533 		dev->si_flags &= ~SI_CHILD;
534 	}
535 
536 	/* Kill our children */
537 	while (!LIST_EMPTY(&dev->si_children))
538 		destroy_devl(LIST_FIRST(&dev->si_children));
539 
540 	/* Remove from clone list */
541 	if (dev->si_flags & SI_CLONELIST) {
542 		LIST_REMOVE(dev, si_clone);
543 		dev->si_flags &= ~SI_CLONELIST;
544 	}
545 
546 	csw = dev->si_devsw;
547 	dev->si_devsw = NULL;	/* already NULL for SI_ALIAS */
548 	while (csw != NULL && csw->d_purge != NULL && dev->si_threadcount) {
549 		printf("Purging %lu threads from %s\n",
550 		    dev->si_threadcount, devtoname(dev));
551 		csw->d_purge(dev);
552 		msleep(csw, &devmtx, PRIBIO, "devprg", hz/10);
553 	}
554 	if (csw != NULL && csw->d_purge != NULL)
555 		printf("All threads purged from %s\n", devtoname(dev));
556 
557 	dev->si_drv1 = 0;
558 	dev->si_drv2 = 0;
559 	bzero(&dev->__si_u, sizeof(dev->__si_u));
560 
561 	if (!(dev->si_flags & SI_ALIAS)) {
562 		/* Remove from cdevsw list */
563 		LIST_REMOVE(dev, si_list);
564 
565 		/* If cdevsw has no struct cdev *'s, clean it */
566 		if (LIST_EMPTY(&csw->d_devs))
567 			fini_cdevsw(csw);
568 
569 		LIST_REMOVE(dev, si_hash);
570 	}
571 	dev->si_flags &= ~SI_ALIAS;
572 
573 	if (dev->si_refcount > 0) {
574 		LIST_INSERT_HEAD(&dead_cdevsw.d_devs, dev, si_list);
575 	} else {
576 		freedev(dev);
577 	}
578 }
579 
580 void
581 destroy_dev(struct cdev *dev)
582 {
583 
584 	dev_lock();
585 	destroy_devl(dev);
586 	dev_unlock();
587 }
588 
589 const char *
590 devtoname(struct cdev *dev)
591 {
592 	char *p;
593 	struct cdevsw *csw;
594 	int mynor;
595 
596 	if (dev->si_name[0] == '#' || dev->si_name[0] == '\0') {
597 		p = dev->si_name;
598 		sprintf(p, "#%d", major(dev));
599 		p += strlen(p);
600 		csw = dev_refthread(dev);
601 		if (csw != NULL) {
602 			sprintf(p, "(%s)", csw->d_name);
603 			dev_relthread(dev);
604 		}
605 		p += strlen(p);
606 		mynor = minor(dev);
607 		if (mynor < 0 || mynor > 255)
608 			sprintf(p, "/%#x", (u_int)mynor);
609 		else
610 			sprintf(p, "/%d", mynor);
611 	}
612 	return (dev->si_name);
613 }
614 
615 int
616 dev_stdclone(char *name, char **namep, const char *stem, int *unit)
617 {
618 	int u, i;
619 
620 	i = strlen(stem);
621 	if (bcmp(stem, name, i) != 0)
622 		return (0);
623 	if (!isdigit(name[i]))
624 		return (0);
625 	u = 0;
626 	if (name[i] == '0' && isdigit(name[i+1]))
627 		return (0);
628 	while (isdigit(name[i])) {
629 		u *= 10;
630 		u += name[i++] - '0';
631 	}
632 	if (u > 0xffffff)
633 		return (0);
634 	*unit = u;
635 	if (namep)
636 		*namep = &name[i];
637 	if (name[i])
638 		return (2);
639 	return (1);
640 }
641 
642 /*
643  * Helper functions for cloning device drivers.
644  *
645  * The objective here is to make it unnecessary for the device drivers to
646  * use rman or similar to manage their unit number space.  Due to the way
647  * we do "on-demand" devices, using rman or other "private" methods
648  * will be very tricky to lock down properly once we lock down this file.
649  *
650  * Instead we give the drivers these routines which puts the struct cdev *'s
651  * that are to be managed on their own list, and gives the driver the ability
652  * to ask for the first free unit number or a given specified unit number.
653  *
654  * In addition these routines support paired devices (pty, nmdm and similar)
655  * by respecting a number of "flag" bits in the minor number.
656  *
657  */
658 
659 struct clonedevs {
660 	LIST_HEAD(,cdev)	head;
661 };
662 
663 void
664 clone_setup(struct clonedevs **cdp)
665 {
666 
667 	*cdp = malloc(sizeof **cdp, M_DEVBUF, M_WAITOK | M_ZERO);
668 	LIST_INIT(&(*cdp)->head);
669 }
670 
671 int
672 clone_create(struct clonedevs **cdp, struct cdevsw *csw, int *up, struct cdev **dp, u_int extra)
673 {
674 	struct clonedevs *cd;
675 	struct cdev *dev, *ndev, *dl, *de;
676 	int unit, low, u;
677 
678 	KASSERT(*cdp != NULL,
679 	    ("clone_setup() not called in driver \"%s\"", csw->d_name));
680 	KASSERT(!(extra & CLONE_UNITMASK),
681 	    ("Illegal extra bits (0x%x) in clone_create", extra));
682 	KASSERT(*up <= CLONE_UNITMASK,
683 	    ("Too high unit (0x%x) in clone_create", *up));
684 
685 	if (!(csw->d_flags & D_INIT))
686 		prep_cdevsw(csw);
687 
688 	/*
689 	 * Search the list for a lot of things in one go:
690 	 *   A preexisting match is returned immediately.
691 	 *   The lowest free unit number if we are passed -1, and the place
692 	 *	 in the list where we should insert that new element.
693 	 *   The place to insert a specified unit number, if applicable
694 	 *       the end of the list.
695 	 */
696 	unit = *up;
697 	ndev = allocdev();
698 	dev_lock();
699 	low = extra;
700 	de = dl = NULL;
701 	cd = *cdp;
702 	LIST_FOREACH(dev, &cd->head, si_clone) {
703 		KASSERT(dev->si_flags & SI_CLONELIST,
704 		    ("Dev %p(%s) should be on clonelist", dev, dev->si_name));
705 		u = dev2unit(dev);
706 		if (u == (unit | extra)) {
707 			*dp = dev;
708 			freedev(ndev);
709 			dev_unlock();
710 			return (0);
711 		}
712 		if (unit == -1 && u == low) {
713 			low++;
714 			de = dev;
715 			continue;
716 		}
717 		if (u > (unit | extra)) {
718 			dl = dev;
719 			break;
720 		}
721 	}
722 	if (unit == -1)
723 		unit = low & CLONE_UNITMASK;
724 	dev = newdev(csw->d_maj, unit2minor(unit | extra), ndev);
725 	if (dev->si_flags & SI_CLONELIST) {
726 		printf("dev %p (%s) is on clonelist\n", dev, dev->si_name);
727 		printf("unit=%d\n", unit);
728 		LIST_FOREACH(dev, &cd->head, si_clone) {
729 			printf("\t%p %s\n", dev, dev->si_name);
730 		}
731 		panic("foo");
732 	}
733 	KASSERT(!(dev->si_flags & SI_CLONELIST),
734 	    ("Dev %p(%s) should not be on clonelist", dev, dev->si_name));
735 	if (dl != NULL)
736 		LIST_INSERT_BEFORE(dl, dev, si_clone);
737 	else if (de != NULL)
738 		LIST_INSERT_AFTER(de, dev, si_clone);
739 	else
740 		LIST_INSERT_HEAD(&cd->head, dev, si_clone);
741 	dev->si_flags |= SI_CLONELIST;
742 	*up = unit;
743 	dev_unlock();
744 	return (1);
745 }
746 
747 /*
748  * Kill everything still on the list.  The driver should already have
749  * disposed of any softc hung of the struct cdev *'s at this time.
750  */
751 void
752 clone_cleanup(struct clonedevs **cdp)
753 {
754 	struct cdev *dev, *tdev;
755 	struct clonedevs *cd;
756 
757 	cd = *cdp;
758 	if (cd == NULL)
759 		return;
760 	dev_lock();
761 	LIST_FOREACH_SAFE(dev, &cd->head, si_clone, tdev) {
762 		KASSERT(dev->si_flags & SI_CLONELIST,
763 		    ("Dev %p(%s) should be on clonelist", dev, dev->si_name));
764 		KASSERT(dev->si_flags & SI_NAMED,
765 		    ("Driver has goofed in cloning underways udev %x", dev->si_drv0));
766 		destroy_devl(dev);
767 	}
768 	dev_unlock();
769 	free(cd, M_DEVBUF);
770 	*cdp = NULL;
771 }
772