kern_conf.c revision 177858
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: head/sys/kern/kern_conf.c 177858 2008-04-02 11:11:58Z kib $");
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/module.h>
37#include <sys/malloc.h>
38#include <sys/conf.h>
39#include <sys/vnode.h>
40#include <sys/queue.h>
41#include <sys/poll.h>
42#include <sys/sx.h>
43#include <sys/ctype.h>
44#include <sys/tty.h>
45#include <sys/ucred.h>
46#include <sys/taskqueue.h>
47#include <machine/stdarg.h>
48
49#include <fs/devfs/devfs_int.h>
50
51static MALLOC_DEFINE(M_DEVT, "cdev", "cdev storage");
52
53struct mtx devmtx;
54static void destroy_devl(struct cdev *dev);
55static int destroy_dev_sched_cbl(struct cdev *dev,
56    void (*cb)(void *), void *arg);
57static struct cdev *make_dev_credv(int flags,
58    struct cdevsw *devsw, int minornr,
59    struct ucred *cr, uid_t uid, gid_t gid, int mode, const char *fmt,
60    va_list ap);
61
62static struct cdev_priv_list cdevp_free_list =
63    TAILQ_HEAD_INITIALIZER(cdevp_free_list);
64static SLIST_HEAD(free_cdevsw, cdevsw) cdevsw_gt_post_list =
65    SLIST_HEAD_INITIALIZER();
66
67void
68dev_lock(void)
69{
70
71	mtx_lock(&devmtx);
72}
73
74/*
75 * Free all the memory collected while the cdev mutex was
76 * locked. Since devmtx is after the system map mutex, free() cannot
77 * be called immediately and is postponed until cdev mutex can be
78 * dropped.
79 */
80static void
81dev_unlock_and_free(void)
82{
83	struct cdev_priv_list cdp_free;
84	struct free_cdevsw csw_free;
85	struct cdev_priv *cdp;
86	struct cdevsw *csw;
87
88	mtx_assert(&devmtx, MA_OWNED);
89
90	/*
91	 * Make the local copy of the list heads while the dev_mtx is
92	 * held. Free it later.
93	 */
94	TAILQ_INIT(&cdp_free);
95	TAILQ_CONCAT(&cdp_free, &cdevp_free_list, cdp_list);
96	csw_free = cdevsw_gt_post_list;
97	SLIST_INIT(&cdevsw_gt_post_list);
98
99	mtx_unlock(&devmtx);
100
101	while ((cdp = TAILQ_FIRST(&cdp_free)) != NULL) {
102		TAILQ_REMOVE(&cdp_free, cdp, cdp_list);
103		devfs_free(&cdp->cdp_c);
104	}
105	while ((csw = SLIST_FIRST(&csw_free)) != NULL) {
106		SLIST_REMOVE_HEAD(&csw_free, d_postfree_list);
107		free(csw, M_DEVT);
108	}
109}
110
111static void
112dev_free_devlocked(struct cdev *cdev)
113{
114	struct cdev_priv *cdp;
115
116	mtx_assert(&devmtx, MA_OWNED);
117	cdp = cdev->si_priv;
118	TAILQ_INSERT_HEAD(&cdevp_free_list, cdp, cdp_list);
119}
120
121static void
122cdevsw_free_devlocked(struct cdevsw *csw)
123{
124
125	mtx_assert(&devmtx, MA_OWNED);
126	SLIST_INSERT_HEAD(&cdevsw_gt_post_list, csw, d_postfree_list);
127}
128
129void
130dev_unlock(void)
131{
132
133	mtx_unlock(&devmtx);
134}
135
136void
137dev_ref(struct cdev *dev)
138{
139
140	mtx_assert(&devmtx, MA_NOTOWNED);
141	mtx_lock(&devmtx);
142	dev->si_refcount++;
143	mtx_unlock(&devmtx);
144}
145
146void
147dev_refl(struct cdev *dev)
148{
149
150	mtx_assert(&devmtx, MA_OWNED);
151	dev->si_refcount++;
152}
153
154void
155dev_rel(struct cdev *dev)
156{
157	int flag = 0;
158
159	mtx_assert(&devmtx, MA_NOTOWNED);
160	dev_lock();
161	dev->si_refcount--;
162	KASSERT(dev->si_refcount >= 0,
163	    ("dev_rel(%s) gave negative count", devtoname(dev)));
164#if 0
165	if (dev->si_usecount == 0 &&
166	    (dev->si_flags & SI_CHEAPCLONE) && (dev->si_flags & SI_NAMED))
167		;
168	else
169#endif
170	if (dev->si_devsw == NULL && dev->si_refcount == 0) {
171		LIST_REMOVE(dev, si_list);
172		flag = 1;
173	}
174	dev_unlock();
175	if (flag)
176		devfs_free(dev);
177}
178
179struct cdevsw *
180dev_refthread(struct cdev *dev)
181{
182	struct cdevsw *csw;
183	struct cdev_priv *cdp;
184
185	mtx_assert(&devmtx, MA_NOTOWNED);
186	dev_lock();
187	csw = dev->si_devsw;
188	if (csw != NULL) {
189		cdp = dev->si_priv;
190		if ((cdp->cdp_flags & CDP_SCHED_DTR) == 0)
191			dev->si_threadcount++;
192		else
193			csw = NULL;
194	}
195	dev_unlock();
196	return (csw);
197}
198
199struct cdevsw *
200devvn_refthread(struct vnode *vp, struct cdev **devp)
201{
202	struct cdevsw *csw;
203	struct cdev_priv *cdp;
204
205	mtx_assert(&devmtx, MA_NOTOWNED);
206	csw = NULL;
207	dev_lock();
208	*devp = vp->v_rdev;
209	if (*devp != NULL) {
210		cdp = (*devp)->si_priv;
211		if ((cdp->cdp_flags & CDP_SCHED_DTR) == 0) {
212			csw = (*devp)->si_devsw;
213			if (csw != NULL)
214				(*devp)->si_threadcount++;
215		}
216	}
217	dev_unlock();
218	return (csw);
219}
220
221void
222dev_relthread(struct cdev *dev)
223{
224
225	mtx_assert(&devmtx, MA_NOTOWNED);
226	dev_lock();
227	dev->si_threadcount--;
228	dev_unlock();
229}
230
231int
232nullop(void)
233{
234
235	return (0);
236}
237
238int
239eopnotsupp(void)
240{
241
242	return (EOPNOTSUPP);
243}
244
245static int
246enxio(void)
247{
248	return (ENXIO);
249}
250
251static int
252enodev(void)
253{
254	return (ENODEV);
255}
256
257/* Define a dead_cdevsw for use when devices leave unexpectedly. */
258
259#define dead_open	(d_open_t *)enxio
260#define dead_close	(d_close_t *)enxio
261#define dead_read	(d_read_t *)enxio
262#define dead_write	(d_write_t *)enxio
263#define dead_ioctl	(d_ioctl_t *)enxio
264#define dead_poll	(d_poll_t *)enodev
265#define dead_mmap	(d_mmap_t *)enodev
266
267static void
268dead_strategy(struct bio *bp)
269{
270
271	biofinish(bp, NULL, ENXIO);
272}
273
274#define dead_dump	(dumper_t *)enxio
275#define dead_kqfilter	(d_kqfilter_t *)enxio
276
277static struct cdevsw dead_cdevsw = {
278	.d_version =	D_VERSION,
279	.d_flags =	D_NEEDGIANT, /* XXX: does dead_strategy need this ? */
280	.d_open =	dead_open,
281	.d_close =	dead_close,
282	.d_read =	dead_read,
283	.d_write =	dead_write,
284	.d_ioctl =	dead_ioctl,
285	.d_poll =	dead_poll,
286	.d_mmap =	dead_mmap,
287	.d_strategy =	dead_strategy,
288	.d_name =	"dead",
289	.d_dump =	dead_dump,
290	.d_kqfilter =	dead_kqfilter
291};
292
293/* Default methods if driver does not specify method */
294
295#define null_open	(d_open_t *)nullop
296#define null_close	(d_close_t *)nullop
297#define no_read		(d_read_t *)enodev
298#define no_write	(d_write_t *)enodev
299#define no_ioctl	(d_ioctl_t *)enodev
300#define no_mmap		(d_mmap_t *)enodev
301#define no_kqfilter	(d_kqfilter_t *)enodev
302
303static void
304no_strategy(struct bio *bp)
305{
306
307	biofinish(bp, NULL, ENODEV);
308}
309
310static int
311no_poll(struct cdev *dev __unused, int events, struct thread *td __unused)
312{
313	/*
314	 * Return true for read/write.  If the user asked for something
315	 * special, return POLLNVAL, so that clients have a way of
316	 * determining reliably whether or not the extended
317	 * functionality is present without hard-coding knowledge
318	 * of specific filesystem implementations.
319	 * Stay in sync with vop_nopoll().
320	 */
321	if (events & ~POLLSTANDARD)
322		return (POLLNVAL);
323
324	return (events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
325}
326
327#define no_dump		(dumper_t *)enodev
328
329static int
330giant_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
331{
332	struct cdevsw *dsw;
333	int retval;
334
335	dsw = dev_refthread(dev);
336	if (dsw == NULL)
337		return (ENXIO);
338	mtx_lock(&Giant);
339	retval = dsw->d_gianttrick->d_open(dev, oflags, devtype, td);
340	mtx_unlock(&Giant);
341	dev_relthread(dev);
342	return (retval);
343}
344
345static int
346giant_fdopen(struct cdev *dev, int oflags, struct thread *td, struct file *fp)
347{
348	struct cdevsw *dsw;
349	int retval;
350
351	dsw = dev_refthread(dev);
352	if (dsw == NULL)
353		return (ENXIO);
354	mtx_lock(&Giant);
355	retval = dsw->d_gianttrick->d_fdopen(dev, oflags, td, fp);
356	mtx_unlock(&Giant);
357	dev_relthread(dev);
358	return (retval);
359}
360
361static int
362giant_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
363{
364	struct cdevsw *dsw;
365	int retval;
366
367	dsw = dev_refthread(dev);
368	if (dsw == NULL)
369		return (ENXIO);
370	mtx_lock(&Giant);
371	retval = dsw->d_gianttrick->d_close(dev, fflag, devtype, td);
372	mtx_unlock(&Giant);
373	dev_relthread(dev);
374	return (retval);
375}
376
377static void
378giant_strategy(struct bio *bp)
379{
380	struct cdevsw *dsw;
381	struct cdev *dev;
382
383	dev = bp->bio_dev;
384	dsw = dev_refthread(dev);
385	if (dsw == NULL) {
386		biofinish(bp, NULL, ENXIO);
387		return;
388	}
389	mtx_lock(&Giant);
390	dsw->d_gianttrick->d_strategy(bp);
391	mtx_unlock(&Giant);
392	dev_relthread(dev);
393}
394
395static int
396giant_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td)
397{
398	struct cdevsw *dsw;
399	int retval;
400
401	dsw = dev_refthread(dev);
402	if (dsw == NULL)
403		return (ENXIO);
404	mtx_lock(&Giant);
405	retval = dsw->d_gianttrick->d_ioctl(dev, cmd, data, fflag, td);
406	mtx_unlock(&Giant);
407	dev_relthread(dev);
408	return (retval);
409}
410
411static int
412giant_read(struct cdev *dev, struct uio *uio, int ioflag)
413{
414	struct cdevsw *dsw;
415	int retval;
416
417	dsw = dev_refthread(dev);
418	if (dsw == NULL)
419		return (ENXIO);
420	mtx_lock(&Giant);
421	retval = dsw->d_gianttrick->d_read(dev, uio, ioflag);
422	mtx_unlock(&Giant);
423	dev_relthread(dev);
424	return (retval);
425}
426
427static int
428giant_write(struct cdev *dev, struct uio *uio, int ioflag)
429{
430	struct cdevsw *dsw;
431	int retval;
432
433	dsw = dev_refthread(dev);
434	if (dsw == NULL)
435		return (ENXIO);
436	mtx_lock(&Giant);
437	retval = dsw->d_gianttrick->d_write(dev, uio, ioflag);
438	mtx_unlock(&Giant);
439	dev_relthread(dev);
440	return (retval);
441}
442
443static int
444giant_poll(struct cdev *dev, int events, struct thread *td)
445{
446	struct cdevsw *dsw;
447	int retval;
448
449	dsw = dev_refthread(dev);
450	if (dsw == NULL)
451		return (ENXIO);
452	mtx_lock(&Giant);
453	retval = dsw->d_gianttrick->d_poll(dev, events, td);
454	mtx_unlock(&Giant);
455	dev_relthread(dev);
456	return (retval);
457}
458
459static int
460giant_kqfilter(struct cdev *dev, struct knote *kn)
461{
462	struct cdevsw *dsw;
463	int retval;
464
465	dsw = dev_refthread(dev);
466	if (dsw == NULL)
467		return (ENXIO);
468	mtx_lock(&Giant);
469	retval = dsw->d_gianttrick->d_kqfilter(dev, kn);
470	mtx_unlock(&Giant);
471	dev_relthread(dev);
472	return (retval);
473}
474
475static int
476giant_mmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot)
477{
478	struct cdevsw *dsw;
479	int retval;
480
481	dsw = dev_refthread(dev);
482	if (dsw == NULL)
483		return (ENXIO);
484	mtx_lock(&Giant);
485	retval = dsw->d_gianttrick->d_mmap(dev, offset, paddr, nprot);
486	mtx_unlock(&Giant);
487	dev_relthread(dev);
488	return (retval);
489}
490
491
492/*
493 * struct cdev * and u_dev_t primitives
494 */
495
496int
497minor(struct cdev *x)
498{
499	if (x == NULL)
500		return NODEV;
501	return(x->si_drv0 & MAXMINOR);
502}
503
504int
505dev2unit(struct cdev *x)
506{
507
508	if (x == NULL)
509		return NODEV;
510	return (minor2unit(minor(x)));
511}
512
513u_int
514minor2unit(u_int _minor)
515{
516
517	KASSERT((_minor & ~MAXMINOR) == 0, ("Illegal minor %x", _minor));
518	return ((_minor & 0xff) | ((_minor >> 8) & 0xffff00));
519}
520
521int
522unit2minor(int unit)
523{
524
525	KASSERT(unit <= 0xffffff, ("Invalid unit (%d) in unit2minor", unit));
526	return ((unit & 0xff) | ((unit << 8) & ~0xffff));
527}
528
529static struct cdev *
530newdev(struct cdevsw *csw, int y, struct cdev *si)
531{
532	struct cdev *si2;
533	dev_t	udev;
534
535	mtx_assert(&devmtx, MA_OWNED);
536	udev = y;
537	LIST_FOREACH(si2, &csw->d_devs, si_list) {
538		if (si2->si_drv0 == udev) {
539			dev_free_devlocked(si);
540			return (si2);
541		}
542	}
543	si->si_drv0 = udev;
544	si->si_devsw = csw;
545	LIST_INSERT_HEAD(&csw->d_devs, si, si_list);
546	return (si);
547}
548
549int
550uminor(dev_t dev)
551{
552	return (dev & MAXMINOR);
553}
554
555int
556umajor(dev_t dev)
557{
558	return ((dev & ~MAXMINOR) >> 8);
559}
560
561static void
562fini_cdevsw(struct cdevsw *devsw)
563{
564	struct cdevsw *gt;
565
566	if (devsw->d_gianttrick != NULL) {
567		gt = devsw->d_gianttrick;
568		memcpy(devsw, gt, sizeof *devsw);
569		cdevsw_free_devlocked(gt);
570		devsw->d_gianttrick = NULL;
571	}
572	devsw->d_flags &= ~D_INIT;
573}
574
575static void
576prep_cdevsw(struct cdevsw *devsw)
577{
578	struct cdevsw *dsw2;
579
580	mtx_assert(&devmtx, MA_OWNED);
581	if (devsw->d_flags & D_INIT)
582		return;
583	if (devsw->d_flags & D_NEEDGIANT) {
584		dev_unlock();
585		dsw2 = malloc(sizeof *dsw2, M_DEVT, M_WAITOK);
586		dev_lock();
587	} else
588		dsw2 = NULL;
589	if (devsw->d_flags & D_INIT) {
590		if (dsw2 != NULL)
591			cdevsw_free_devlocked(dsw2);
592		return;
593	}
594
595	if (devsw->d_version != D_VERSION_01) {
596		printf(
597		    "WARNING: Device driver \"%s\" has wrong version %s\n",
598		    devsw->d_name == NULL ? "???" : devsw->d_name,
599		    "and is disabled.  Recompile KLD module.");
600		devsw->d_open = dead_open;
601		devsw->d_close = dead_close;
602		devsw->d_read = dead_read;
603		devsw->d_write = dead_write;
604		devsw->d_ioctl = dead_ioctl;
605		devsw->d_poll = dead_poll;
606		devsw->d_mmap = dead_mmap;
607		devsw->d_strategy = dead_strategy;
608		devsw->d_dump = dead_dump;
609		devsw->d_kqfilter = dead_kqfilter;
610	}
611
612	if (devsw->d_flags & D_TTY) {
613		if (devsw->d_ioctl == NULL)	devsw->d_ioctl = ttyioctl;
614		if (devsw->d_read == NULL)	devsw->d_read = ttyread;
615		if (devsw->d_write == NULL)	devsw->d_write = ttywrite;
616		if (devsw->d_kqfilter == NULL)	devsw->d_kqfilter = ttykqfilter;
617		if (devsw->d_poll == NULL)	devsw->d_poll = ttypoll;
618	}
619
620	if (devsw->d_flags & D_NEEDGIANT) {
621		if (devsw->d_gianttrick == NULL) {
622			memcpy(dsw2, devsw, sizeof *dsw2);
623			devsw->d_gianttrick = dsw2;
624			dsw2 = NULL;
625		}
626	}
627
628#define FIXUP(member, noop, giant) 				\
629	do {							\
630		if (devsw->member == NULL) {			\
631			devsw->member = noop;			\
632		} else if (devsw->d_flags & D_NEEDGIANT)	\
633			devsw->member = giant;			\
634		}						\
635	while (0)
636
637	FIXUP(d_open,		null_open,	giant_open);
638	FIXUP(d_fdopen,		NULL,		giant_fdopen);
639	FIXUP(d_close,		null_close,	giant_close);
640	FIXUP(d_read,		no_read,	giant_read);
641	FIXUP(d_write,		no_write,	giant_write);
642	FIXUP(d_ioctl,		no_ioctl,	giant_ioctl);
643	FIXUP(d_poll,		no_poll,	giant_poll);
644	FIXUP(d_mmap,		no_mmap,	giant_mmap);
645	FIXUP(d_strategy,	no_strategy,	giant_strategy);
646	FIXUP(d_kqfilter,	no_kqfilter,	giant_kqfilter);
647
648	if (devsw->d_dump == NULL)	devsw->d_dump = no_dump;
649
650	LIST_INIT(&devsw->d_devs);
651
652	devsw->d_flags |= D_INIT;
653
654	if (dsw2 != NULL)
655		cdevsw_free_devlocked(dsw2);
656}
657
658struct cdev *
659make_dev_credv(int flags, struct cdevsw *devsw, int minornr,
660    struct ucred *cr, uid_t uid,
661    gid_t gid, int mode, const char *fmt, va_list ap)
662{
663	struct cdev *dev;
664	int i;
665
666	KASSERT((minornr & ~MAXMINOR) == 0,
667	    ("Invalid minor (0x%x) in make_dev", minornr));
668
669	dev = devfs_alloc();
670	dev_lock();
671	prep_cdevsw(devsw);
672	dev = newdev(devsw, minornr, dev);
673	if (flags & MAKEDEV_REF)
674		dev_refl(dev);
675	if (dev->si_flags & SI_CHEAPCLONE &&
676	    dev->si_flags & SI_NAMED) {
677		/*
678		 * This is allowed as it removes races and generally
679		 * simplifies cloning devices.
680		 * XXX: still ??
681		 */
682		dev_unlock_and_free();
683		return (dev);
684	}
685	KASSERT(!(dev->si_flags & SI_NAMED),
686	    ("make_dev() by driver %s on pre-existing device (min=%x, name=%s)",
687	    devsw->d_name, minor(dev), devtoname(dev)));
688
689	i = vsnrprintf(dev->__si_namebuf, sizeof dev->__si_namebuf, 32, fmt, ap);
690	if (i > (sizeof dev->__si_namebuf - 1)) {
691		printf("WARNING: Device name truncated! (%s)\n",
692		    dev->__si_namebuf);
693	}
694
695	dev->si_flags |= SI_NAMED;
696#ifdef MAC
697	if (cr != NULL)
698		dev->si_cred = crhold(cr);
699	else
700#endif
701		dev->si_cred = NULL;
702	dev->si_uid = uid;
703	dev->si_gid = gid;
704	dev->si_mode = mode;
705
706	devfs_create(dev);
707	clean_unrhdrl(devfs_inos);
708	dev_unlock_and_free();
709	return (dev);
710}
711
712struct cdev *
713make_dev(struct cdevsw *devsw, int minornr, uid_t uid, gid_t gid, int mode,
714    const char *fmt, ...)
715{
716	struct cdev *dev;
717	va_list ap;
718
719	va_start(ap, fmt);
720	dev = make_dev_credv(0, devsw, minornr, NULL, uid, gid, mode, fmt, ap);
721	va_end(ap);
722	return (dev);
723}
724
725struct cdev *
726make_dev_cred(struct cdevsw *devsw, int minornr, struct ucred *cr, uid_t uid,
727    gid_t gid, int mode, const char *fmt, ...)
728{
729	struct cdev *dev;
730	va_list ap;
731
732	va_start(ap, fmt);
733	dev = make_dev_credv(0, devsw, minornr, cr, uid, gid, mode, fmt, ap);
734	va_end(ap);
735
736	return (dev);
737}
738
739struct cdev *
740make_dev_credf(int flags, struct cdevsw *devsw, int minornr,
741    struct ucred *cr, uid_t uid,
742    gid_t gid, int mode, const char *fmt, ...)
743{
744	struct cdev *dev;
745	va_list ap;
746
747	va_start(ap, fmt);
748	dev = make_dev_credv(flags, devsw, minornr, cr, uid, gid, mode,
749	    fmt, ap);
750	va_end(ap);
751
752	return (dev);
753}
754
755static void
756dev_dependsl(struct cdev *pdev, struct cdev *cdev)
757{
758
759	cdev->si_parent = pdev;
760	cdev->si_flags |= SI_CHILD;
761	LIST_INSERT_HEAD(&pdev->si_children, cdev, si_siblings);
762}
763
764
765void
766dev_depends(struct cdev *pdev, struct cdev *cdev)
767{
768
769	dev_lock();
770	dev_dependsl(pdev, cdev);
771	dev_unlock();
772}
773
774struct cdev *
775make_dev_alias(struct cdev *pdev, const char *fmt, ...)
776{
777	struct cdev *dev;
778	va_list ap;
779	int i;
780
781	dev = devfs_alloc();
782	dev_lock();
783	dev->si_flags |= SI_ALIAS;
784	dev->si_flags |= SI_NAMED;
785	va_start(ap, fmt);
786	i = vsnrprintf(dev->__si_namebuf, sizeof dev->__si_namebuf, 32, fmt, ap);
787	if (i > (sizeof dev->__si_namebuf - 1)) {
788		printf("WARNING: Device name truncated! (%s)\n",
789		    dev->__si_namebuf);
790	}
791	va_end(ap);
792
793	devfs_create(dev);
794	clean_unrhdrl(devfs_inos);
795	dev_unlock();
796	dev_depends(pdev, dev);
797	return (dev);
798}
799
800static void
801destroy_devl(struct cdev *dev)
802{
803	struct cdevsw *csw;
804
805	mtx_assert(&devmtx, MA_OWNED);
806	KASSERT(dev->si_flags & SI_NAMED,
807	    ("WARNING: Driver mistake: destroy_dev on %d\n", minor(dev)));
808
809	devfs_destroy(dev);
810
811	/* Remove name marking */
812	dev->si_flags &= ~SI_NAMED;
813
814	/* If we are a child, remove us from the parents list */
815	if (dev->si_flags & SI_CHILD) {
816		LIST_REMOVE(dev, si_siblings);
817		dev->si_flags &= ~SI_CHILD;
818	}
819
820	/* Kill our children */
821	while (!LIST_EMPTY(&dev->si_children))
822		destroy_devl(LIST_FIRST(&dev->si_children));
823
824	/* Remove from clone list */
825	if (dev->si_flags & SI_CLONELIST) {
826		LIST_REMOVE(dev, si_clone);
827		dev->si_flags &= ~SI_CLONELIST;
828	}
829
830	dev->si_refcount++;	/* Avoid race with dev_rel() */
831	csw = dev->si_devsw;
832	dev->si_devsw = NULL;	/* already NULL for SI_ALIAS */
833	while (csw != NULL && csw->d_purge != NULL && dev->si_threadcount) {
834		csw->d_purge(dev);
835		msleep(csw, &devmtx, PRIBIO, "devprg", hz/10);
836		if (dev->si_threadcount)
837			printf("Still %lu threads in %s\n",
838			    dev->si_threadcount, devtoname(dev));
839	}
840	while (dev->si_threadcount != 0) {
841		/* Use unique dummy wait ident */
842		msleep(&csw, &devmtx, PRIBIO, "devdrn", hz / 10);
843	}
844
845	dev->si_drv1 = 0;
846	dev->si_drv2 = 0;
847	bzero(&dev->__si_u, sizeof(dev->__si_u));
848
849	if (!(dev->si_flags & SI_ALIAS)) {
850		/* Remove from cdevsw list */
851		LIST_REMOVE(dev, si_list);
852
853		/* If cdevsw has no more struct cdev *'s, clean it */
854		if (LIST_EMPTY(&csw->d_devs)) {
855			fini_cdevsw(csw);
856			wakeup(&csw->d_devs);
857		}
858	}
859	dev->si_flags &= ~SI_ALIAS;
860	dev->si_refcount--;	/* Avoid race with dev_rel() */
861
862	if (dev->si_refcount > 0) {
863		LIST_INSERT_HEAD(&dead_cdevsw.d_devs, dev, si_list);
864	} else {
865		dev_free_devlocked(dev);
866	}
867}
868
869void
870destroy_dev(struct cdev *dev)
871{
872
873	dev_lock();
874	destroy_devl(dev);
875	dev_unlock_and_free();
876}
877
878const char *
879devtoname(struct cdev *dev)
880{
881	char *p;
882	struct cdevsw *csw;
883	int mynor;
884
885	if (dev->si_name[0] == '#' || dev->si_name[0] == '\0') {
886		p = dev->si_name;
887		csw = dev_refthread(dev);
888		if (csw != NULL) {
889			sprintf(p, "(%s)", csw->d_name);
890			dev_relthread(dev);
891		}
892		p += strlen(p);
893		mynor = minor(dev);
894		if (mynor < 0 || mynor > 255)
895			sprintf(p, "/%#x", (u_int)mynor);
896		else
897			sprintf(p, "/%d", mynor);
898	}
899	return (dev->si_name);
900}
901
902int
903dev_stdclone(char *name, char **namep, const char *stem, int *unit)
904{
905	int u, i;
906
907	i = strlen(stem);
908	if (bcmp(stem, name, i) != 0)
909		return (0);
910	if (!isdigit(name[i]))
911		return (0);
912	u = 0;
913	if (name[i] == '0' && isdigit(name[i+1]))
914		return (0);
915	while (isdigit(name[i])) {
916		u *= 10;
917		u += name[i++] - '0';
918	}
919	if (u > 0xffffff)
920		return (0);
921	*unit = u;
922	if (namep)
923		*namep = &name[i];
924	if (name[i])
925		return (2);
926	return (1);
927}
928
929/*
930 * Helper functions for cloning device drivers.
931 *
932 * The objective here is to make it unnecessary for the device drivers to
933 * use rman or similar to manage their unit number space.  Due to the way
934 * we do "on-demand" devices, using rman or other "private" methods
935 * will be very tricky to lock down properly once we lock down this file.
936 *
937 * Instead we give the drivers these routines which puts the struct cdev *'s
938 * that are to be managed on their own list, and gives the driver the ability
939 * to ask for the first free unit number or a given specified unit number.
940 *
941 * In addition these routines support paired devices (pty, nmdm and similar)
942 * by respecting a number of "flag" bits in the minor number.
943 *
944 */
945
946struct clonedevs {
947	LIST_HEAD(,cdev)	head;
948};
949
950void
951clone_setup(struct clonedevs **cdp)
952{
953
954	*cdp = malloc(sizeof **cdp, M_DEVBUF, M_WAITOK | M_ZERO);
955	LIST_INIT(&(*cdp)->head);
956}
957
958int
959clone_create(struct clonedevs **cdp, struct cdevsw *csw, int *up, struct cdev **dp, int extra)
960{
961	struct clonedevs *cd;
962	struct cdev *dev, *ndev, *dl, *de;
963	int unit, low, u;
964
965	KASSERT(*cdp != NULL,
966	    ("clone_setup() not called in driver \"%s\"", csw->d_name));
967	KASSERT(!(extra & CLONE_UNITMASK),
968	    ("Illegal extra bits (0x%x) in clone_create", extra));
969	KASSERT(*up <= CLONE_UNITMASK,
970	    ("Too high unit (0x%x) in clone_create", *up));
971
972
973	/*
974	 * Search the list for a lot of things in one go:
975	 *   A preexisting match is returned immediately.
976	 *   The lowest free unit number if we are passed -1, and the place
977	 *	 in the list where we should insert that new element.
978	 *   The place to insert a specified unit number, if applicable
979	 *       the end of the list.
980	 */
981	unit = *up;
982	ndev = devfs_alloc();
983	dev_lock();
984	prep_cdevsw(csw);
985	low = extra;
986	de = dl = NULL;
987	cd = *cdp;
988	LIST_FOREACH(dev, &cd->head, si_clone) {
989		KASSERT(dev->si_flags & SI_CLONELIST,
990		    ("Dev %p(%s) should be on clonelist", dev, dev->si_name));
991		u = dev2unit(dev);
992		if (u == (unit | extra)) {
993			*dp = dev;
994			dev_unlock();
995			devfs_free(ndev);
996			return (0);
997		}
998		if (unit == -1 && u == low) {
999			low++;
1000			de = dev;
1001			continue;
1002		} else if (u < (unit | extra)) {
1003			de = dev;
1004			continue;
1005		} else if (u > (unit | extra)) {
1006			dl = dev;
1007			break;
1008		}
1009	}
1010	if (unit == -1)
1011		unit = low & CLONE_UNITMASK;
1012	dev = newdev(csw, unit2minor(unit | extra), ndev);
1013	if (dev->si_flags & SI_CLONELIST) {
1014		printf("dev %p (%s) is on clonelist\n", dev, dev->si_name);
1015		printf("unit=%d, low=%d, extra=0x%x\n", unit, low, extra);
1016		LIST_FOREACH(dev, &cd->head, si_clone) {
1017			printf("\t%p %s\n", dev, dev->si_name);
1018		}
1019		panic("foo");
1020	}
1021	KASSERT(!(dev->si_flags & SI_CLONELIST),
1022	    ("Dev %p(%s) should not be on clonelist", dev, dev->si_name));
1023	if (dl != NULL)
1024		LIST_INSERT_BEFORE(dl, dev, si_clone);
1025	else if (de != NULL)
1026		LIST_INSERT_AFTER(de, dev, si_clone);
1027	else
1028		LIST_INSERT_HEAD(&cd->head, dev, si_clone);
1029	dev->si_flags |= SI_CLONELIST;
1030	*up = unit;
1031	dev_unlock_and_free();
1032	return (1);
1033}
1034
1035/*
1036 * Kill everything still on the list.  The driver should already have
1037 * disposed of any softc hung of the struct cdev *'s at this time.
1038 */
1039void
1040clone_cleanup(struct clonedevs **cdp)
1041{
1042	struct cdev *dev;
1043	struct cdev_priv *cp;
1044	struct clonedevs *cd;
1045
1046	cd = *cdp;
1047	if (cd == NULL)
1048		return;
1049	dev_lock();
1050	while (!LIST_EMPTY(&cd->head)) {
1051		dev = LIST_FIRST(&cd->head);
1052		LIST_REMOVE(dev, si_clone);
1053		KASSERT(dev->si_flags & SI_CLONELIST,
1054		    ("Dev %p(%s) should be on clonelist", dev, dev->si_name));
1055		dev->si_flags &= ~SI_CLONELIST;
1056		cp = dev->si_priv;
1057		if (!(cp->cdp_flags & CDP_SCHED_DTR)) {
1058			cp->cdp_flags |= CDP_SCHED_DTR;
1059			KASSERT(dev->si_flags & SI_NAMED,
1060				("Driver has goofed in cloning underways udev %x", dev->si_drv0));
1061			destroy_devl(dev);
1062		}
1063	}
1064	dev_unlock_and_free();
1065	free(cd, M_DEVBUF);
1066	*cdp = NULL;
1067}
1068
1069static TAILQ_HEAD(, cdev_priv) dev_ddtr =
1070	TAILQ_HEAD_INITIALIZER(dev_ddtr);
1071static struct task dev_dtr_task;
1072
1073static void
1074destroy_dev_tq(void *ctx, int pending)
1075{
1076	struct cdev_priv *cp;
1077	struct cdev *dev;
1078	void (*cb)(void *);
1079	void *cb_arg;
1080
1081	dev_lock();
1082	while (!TAILQ_EMPTY(&dev_ddtr)) {
1083		cp = TAILQ_FIRST(&dev_ddtr);
1084		dev = &cp->cdp_c;
1085		KASSERT(cp->cdp_flags & CDP_SCHED_DTR,
1086		    ("cdev %p in dev_destroy_tq without CDP_SCHED_DTR", cp));
1087		TAILQ_REMOVE(&dev_ddtr, cp, cdp_dtr_list);
1088		cb = cp->cdp_dtr_cb;
1089		cb_arg = cp->cdp_dtr_cb_arg;
1090		destroy_devl(dev);
1091		dev_unlock_and_free();
1092		dev_rel(dev);
1093		if (cb != NULL)
1094			cb(cb_arg);
1095		dev_lock();
1096	}
1097	dev_unlock();
1098}
1099
1100/*
1101 * devmtx shall be locked on entry. devmtx will be unlocked after
1102 * function return.
1103 */
1104static int
1105destroy_dev_sched_cbl(struct cdev *dev, void (*cb)(void *), void *arg)
1106{
1107	struct cdev_priv *cp;
1108
1109	mtx_assert(&devmtx, MA_OWNED);
1110	cp = dev->si_priv;
1111	if (cp->cdp_flags & CDP_SCHED_DTR) {
1112		dev_unlock();
1113		return (0);
1114	}
1115	dev_refl(dev);
1116	cp->cdp_flags |= CDP_SCHED_DTR;
1117	cp->cdp_dtr_cb = cb;
1118	cp->cdp_dtr_cb_arg = arg;
1119	TAILQ_INSERT_TAIL(&dev_ddtr, cp, cdp_dtr_list);
1120	dev_unlock();
1121	taskqueue_enqueue(taskqueue_swi_giant, &dev_dtr_task);
1122	return (1);
1123}
1124
1125int
1126destroy_dev_sched_cb(struct cdev *dev, void (*cb)(void *), void *arg)
1127{
1128	dev_lock();
1129	return (destroy_dev_sched_cbl(dev, cb, arg));
1130}
1131
1132int
1133destroy_dev_sched(struct cdev *dev)
1134{
1135	return (destroy_dev_sched_cb(dev, NULL, NULL));
1136}
1137
1138void
1139destroy_dev_drain(struct cdevsw *csw)
1140{
1141
1142	dev_lock();
1143	while (!LIST_EMPTY(&csw->d_devs)) {
1144		msleep(&csw->d_devs, &devmtx, PRIBIO, "devscd", hz/10);
1145	}
1146	dev_unlock();
1147}
1148
1149void
1150drain_dev_clone_events(void)
1151{
1152
1153	sx_xlock(&clone_drain_lock);
1154	sx_xunlock(&clone_drain_lock);
1155}
1156
1157static void
1158devdtr_init(void *dummy __unused)
1159{
1160
1161	TASK_INIT(&dev_dtr_task, 0, destroy_dev_tq, NULL);
1162}
1163
1164SYSINIT(devdtr, SI_SUB_DEVFS, SI_ORDER_SECOND, devdtr_init, NULL);
1165