2 * Copyright (c) 1999-2002 Poul-Henning Kamp
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
30 #include <sys/param.h>
31 #include <sys/kernel.h>
32 #include <sys/systm.h>
36 #include <sys/mutex.h>
37 #include <sys/module.h>
38 #include <sys/malloc.h>
40 #include <sys/vnode.h>
41 #include <sys/queue.h>
44 #include <sys/ctype.h>
45 #include <sys/ucred.h>
46 #include <sys/taskqueue.h>
47 #include <machine/stdarg.h>
49 #include <fs/devfs/devfs_int.h>
51 static MALLOC_DEFINE(M_DEVT
, "cdev", "cdev storage");
54 static void destroy_devl(struct cdev
*dev
);
55 static int destroy_dev_sched_cbl(struct cdev
*dev
,
56 void (*cb
)(void *), void *arg
);
57 static 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
,
62 static struct cdev_priv_list cdevp_free_list
=
63 TAILQ_HEAD_INITIALIZER(cdevp_free_list
);
64 static SLIST_HEAD(free_cdevsw
, cdevsw
) cdevsw_gt_post_list
=
65 SLIST_HEAD_INITIALIZER();
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
81 dev_unlock_and_free(void)
83 struct cdev_priv_list cdp_free
;
84 struct free_cdevsw csw_free
;
85 struct cdev_priv
*cdp
;
88 mtx_assert(&devmtx
, MA_OWNED
);
91 * Make the local copy of the list heads while the dev_mtx is
92 * held. Free it later.
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
);
101 while ((cdp
= TAILQ_FIRST(&cdp_free
)) != NULL
) {
102 TAILQ_REMOVE(&cdp_free
, cdp
, cdp_list
);
103 devfs_free(&cdp
->cdp_c
);
105 while ((csw
= SLIST_FIRST(&csw_free
)) != NULL
) {
106 SLIST_REMOVE_HEAD(&csw_free
, d_postfree_list
);
112 dev_free_devlocked(struct cdev
*cdev
)
114 struct cdev_priv
*cdp
;
116 mtx_assert(&devmtx
, MA_OWNED
);
117 cdp
= cdev2priv(cdev
);
118 TAILQ_INSERT_HEAD(&cdevp_free_list
, cdp
, cdp_list
);
122 cdevsw_free_devlocked(struct cdevsw
*csw
)
125 mtx_assert(&devmtx
, MA_OWNED
);
126 SLIST_INSERT_HEAD(&cdevsw_gt_post_list
, csw
, d_postfree_list
);
137 dev_ref(struct cdev
*dev
)
140 mtx_assert(&devmtx
, MA_NOTOWNED
);
147 dev_refl(struct cdev
*dev
)
150 mtx_assert(&devmtx
, MA_OWNED
);
155 dev_rel(struct cdev
*dev
)
159 mtx_assert(&devmtx
, MA_NOTOWNED
);
162 KASSERT(dev
->si_refcount
>= 0,
163 ("dev_rel(%s) gave negative count", devtoname(dev
)));
165 if (dev
->si_usecount
== 0 &&
166 (dev
->si_flags
& SI_CHEAPCLONE
) && (dev
->si_flags
& SI_NAMED
))
170 if (dev
->si_devsw
== NULL
&& dev
->si_refcount
== 0) {
171 LIST_REMOVE(dev
, si_list
);
180 dev_refthread(struct cdev
*dev
)
183 struct cdev_priv
*cdp
;
185 mtx_assert(&devmtx
, MA_NOTOWNED
);
189 cdp
= cdev2priv(dev
);
190 if ((cdp
->cdp_flags
& CDP_SCHED_DTR
) == 0)
191 dev
->si_threadcount
++;
200 devvn_refthread(struct vnode
*vp
, struct cdev
**devp
)
203 struct cdev_priv
*cdp
;
205 mtx_assert(&devmtx
, MA_NOTOWNED
);
210 cdp
= cdev2priv(*devp
);
211 if ((cdp
->cdp_flags
& CDP_SCHED_DTR
) == 0) {
212 csw
= (*devp
)->si_devsw
;
214 (*devp
)->si_threadcount
++;
222 dev_relthread(struct cdev
*dev
)
225 mtx_assert(&devmtx
, MA_NOTOWNED
);
227 KASSERT(dev
->si_threadcount
> 0,
228 ("%s threadcount is wrong", dev
->si_name
));
229 dev
->si_threadcount
--;
259 /* Define a dead_cdevsw for use when devices leave unexpectedly. */
261 #define dead_open (d_open_t *)enxio
262 #define dead_close (d_close_t *)enxio
263 #define dead_read (d_read_t *)enxio
264 #define dead_write (d_write_t *)enxio
265 #define dead_ioctl (d_ioctl_t *)enxio
266 #define dead_poll (d_poll_t *)enodev
267 #define dead_mmap (d_mmap_t *)enodev
270 dead_strategy(struct bio
*bp
)
273 biofinish(bp
, NULL
, ENXIO
);
276 #define dead_dump (dumper_t *)enxio
277 #define dead_kqfilter (d_kqfilter_t *)enxio
279 static struct cdevsw dead_cdevsw
= {
280 .d_version
= D_VERSION
,
281 .d_flags
= D_NEEDGIANT
, /* XXX: does dead_strategy need this ? */
283 .d_close
= dead_close
,
285 .d_write
= dead_write
,
286 .d_ioctl
= dead_ioctl
,
289 .d_strategy
= dead_strategy
,
292 .d_kqfilter
= dead_kqfilter
295 /* Default methods if driver does not specify method */
297 #define null_open (d_open_t *)nullop
298 #define null_close (d_close_t *)nullop
299 #define no_read (d_read_t *)enodev
300 #define no_write (d_write_t *)enodev
301 #define no_ioctl (d_ioctl_t *)enodev
302 #define no_mmap (d_mmap_t *)enodev
303 #define no_kqfilter (d_kqfilter_t *)enodev
306 no_strategy(struct bio
*bp
)
309 biofinish(bp
, NULL
, ENODEV
);
313 no_poll(struct cdev
*dev __unused
, int events
, struct thread
*td __unused
)
316 * Return true for read/write. If the user asked for something
317 * special, return POLLNVAL, so that clients have a way of
318 * determining reliably whether or not the extended
319 * functionality is present without hard-coding knowledge
320 * of specific filesystem implementations.
321 * Stay in sync with vop_nopoll().
323 if (events
& ~POLLSTANDARD
)
326 return (events
& (POLLIN
| POLLOUT
| POLLRDNORM
| POLLWRNORM
));
329 #define no_dump (dumper_t *)enodev
332 giant_open(struct cdev
*dev
, int oflags
, int devtype
, struct thread
*td
)
337 dsw
= dev_refthread(dev
);
341 retval
= dsw
->d_gianttrick
->d_open(dev
, oflags
, devtype
, td
);
348 giant_fdopen(struct cdev
*dev
, int oflags
, struct thread
*td
, struct file
*fp
)
353 dsw
= dev_refthread(dev
);
357 retval
= dsw
->d_gianttrick
->d_fdopen(dev
, oflags
, td
, fp
);
364 giant_close(struct cdev
*dev
, int fflag
, int devtype
, struct thread
*td
)
369 dsw
= dev_refthread(dev
);
373 retval
= dsw
->d_gianttrick
->d_close(dev
, fflag
, devtype
, td
);
380 giant_strategy(struct bio
*bp
)
386 dsw
= dev_refthread(dev
);
388 biofinish(bp
, NULL
, ENXIO
);
392 dsw
->d_gianttrick
->d_strategy(bp
);
398 giant_ioctl(struct cdev
*dev
, u_long cmd
, caddr_t data
, int fflag
, struct thread
*td
)
403 dsw
= dev_refthread(dev
);
407 retval
= dsw
->d_gianttrick
->d_ioctl(dev
, cmd
, data
, fflag
, td
);
414 giant_read(struct cdev
*dev
, struct uio
*uio
, int ioflag
)
419 dsw
= dev_refthread(dev
);
423 retval
= dsw
->d_gianttrick
->d_read(dev
, uio
, ioflag
);
430 giant_write(struct cdev
*dev
, struct uio
*uio
, int ioflag
)
435 dsw
= dev_refthread(dev
);
439 retval
= dsw
->d_gianttrick
->d_write(dev
, uio
, ioflag
);
446 giant_poll(struct cdev
*dev
, int events
, struct thread
*td
)
451 dsw
= dev_refthread(dev
);
455 retval
= dsw
->d_gianttrick
->d_poll(dev
, events
, td
);
462 giant_kqfilter(struct cdev
*dev
, struct knote
*kn
)
467 dsw
= dev_refthread(dev
);
471 retval
= dsw
->d_gianttrick
->d_kqfilter(dev
, kn
);
478 giant_mmap(struct cdev
*dev
, vm_offset_t offset
, vm_paddr_t
*paddr
, int nprot
)
483 dsw
= dev_refthread(dev
);
487 retval
= dsw
->d_gianttrick
->d_mmap(dev
, offset
, paddr
, nprot
);
495 notify(struct cdev
*dev
, const char *ev
)
497 static const char prefix
[] = "cdev=";
503 namelen
= strlen(dev
->si_name
);
504 data
= malloc(namelen
+ sizeof(prefix
), M_TEMP
, M_WAITOK
);
505 memcpy(data
, prefix
, sizeof(prefix
) - 1);
506 memcpy(data
+ sizeof(prefix
) - 1, dev
->si_name
, namelen
+ 1);
507 devctl_notify("DEVFS", "CDEV", ev
, data
);
512 notify_create(struct cdev
*dev
)
515 notify(dev
, "CREATE");
519 notify_destroy(struct cdev
*dev
)
522 notify(dev
, "DESTROY");
526 newdev(struct cdevsw
*csw
, int y
, struct cdev
*si
)
531 mtx_assert(&devmtx
, MA_OWNED
);
533 if (csw
->d_flags
& D_NEEDMINOR
) {
534 /* We may want to return an existing device */
535 LIST_FOREACH(si2
, &csw
->d_devs
, si_list
) {
536 if (si2
->si_drv0
== udev
) {
537 dev_free_devlocked(si
);
544 LIST_INSERT_HEAD(&csw
->d_devs
, si
, si_list
);
548 #define UMINORMASK 0xffff00ffU
553 return (dev
& UMINORMASK
);
559 return ((dev
& ~UMINORMASK
) >> 8);
563 fini_cdevsw(struct cdevsw
*devsw
)
567 if (devsw
->d_gianttrick
!= NULL
) {
568 gt
= devsw
->d_gianttrick
;
569 memcpy(devsw
, gt
, sizeof *devsw
);
570 cdevsw_free_devlocked(gt
);
571 devsw
->d_gianttrick
= NULL
;
573 devsw
->d_flags
&= ~D_INIT
;
577 prep_cdevsw(struct cdevsw
*devsw
)
581 mtx_assert(&devmtx
, MA_OWNED
);
582 if (devsw
->d_flags
& D_INIT
)
584 if (devsw
->d_flags
& D_NEEDGIANT
) {
586 dsw2
= malloc(sizeof *dsw2
, M_DEVT
, M_WAITOK
);
590 if (devsw
->d_flags
& D_INIT
) {
592 cdevsw_free_devlocked(dsw2
);
596 if (devsw
->d_version
!= D_VERSION_01
) {
598 "WARNING: Device driver \"%s\" has wrong version %s\n",
599 devsw
->d_name
== NULL
? "???" : devsw
->d_name
,
600 "and is disabled. Recompile KLD module.");
601 devsw
->d_open
= dead_open
;
602 devsw
->d_close
= dead_close
;
603 devsw
->d_read
= dead_read
;
604 devsw
->d_write
= dead_write
;
605 devsw
->d_ioctl
= dead_ioctl
;
606 devsw
->d_poll
= dead_poll
;
607 devsw
->d_mmap
= dead_mmap
;
608 devsw
->d_strategy
= dead_strategy
;
609 devsw
->d_dump
= dead_dump
;
610 devsw
->d_kqfilter
= dead_kqfilter
;
613 if (devsw
->d_flags
& D_NEEDGIANT
) {
614 if (devsw
->d_gianttrick
== NULL
) {
615 memcpy(dsw2
, devsw
, sizeof *dsw2
);
616 devsw
->d_gianttrick
= dsw2
;
621 #define FIXUP(member, noop, giant) \
623 if (devsw->member == NULL) { \
624 devsw->member = noop; \
625 } else if (devsw->d_flags & D_NEEDGIANT) \
626 devsw->member = giant; \
630 FIXUP(d_open
, null_open
, giant_open
);
631 FIXUP(d_fdopen
, NULL
, giant_fdopen
);
632 FIXUP(d_close
, null_close
, giant_close
);
633 FIXUP(d_read
, no_read
, giant_read
);
634 FIXUP(d_write
, no_write
, giant_write
);
635 FIXUP(d_ioctl
, no_ioctl
, giant_ioctl
);
636 FIXUP(d_poll
, no_poll
, giant_poll
);
637 FIXUP(d_mmap
, no_mmap
, giant_mmap
);
638 FIXUP(d_strategy
, no_strategy
, giant_strategy
);
639 FIXUP(d_kqfilter
, no_kqfilter
, giant_kqfilter
);
641 if (devsw
->d_dump
== NULL
) devsw
->d_dump
= no_dump
;
643 LIST_INIT(&devsw
->d_devs
);
645 devsw
->d_flags
|= D_INIT
;
648 cdevsw_free_devlocked(dsw2
);
652 make_dev_credv(int flags
, struct cdevsw
*devsw
, int minornr
,
653 struct ucred
*cr
, uid_t uid
,
654 gid_t gid
, int mode
, const char *fmt
, va_list ap
)
662 dev
= newdev(devsw
, minornr
, dev
);
663 if (flags
& MAKEDEV_REF
)
665 if (dev
->si_flags
& SI_CHEAPCLONE
&&
666 dev
->si_flags
& SI_NAMED
) {
668 * This is allowed as it removes races and generally
669 * simplifies cloning devices.
672 dev_unlock_and_free();
675 KASSERT(!(dev
->si_flags
& SI_NAMED
),
676 ("make_dev() by driver %s on pre-existing device (min=%x, name=%s)",
677 devsw
->d_name
, minor(dev
), devtoname(dev
)));
679 i
= vsnrprintf(dev
->__si_namebuf
, sizeof dev
->__si_namebuf
, 32, fmt
, ap
);
680 if (i
> (sizeof dev
->__si_namebuf
- 1)) {
681 printf("WARNING: Device name truncated! (%s)\n",
685 dev
->si_flags
|= SI_NAMED
;
687 dev
->si_cred
= crhold(cr
);
695 clean_unrhdrl(devfs_inos
);
696 dev_unlock_and_free();
704 make_dev(struct cdevsw
*devsw
, int minornr
, uid_t uid
, gid_t gid
, int mode
,
705 const char *fmt
, ...)
711 dev
= make_dev_credv(0, devsw
, minornr
, NULL
, uid
, gid
, mode
, fmt
, ap
);
717 make_dev_cred(struct cdevsw
*devsw
, int minornr
, struct ucred
*cr
, uid_t uid
,
718 gid_t gid
, int mode
, const char *fmt
, ...)
724 dev
= make_dev_credv(0, devsw
, minornr
, cr
, uid
, gid
, mode
, fmt
, ap
);
731 make_dev_credf(int flags
, struct cdevsw
*devsw
, int minornr
,
732 struct ucred
*cr
, uid_t uid
,
733 gid_t gid
, int mode
, const char *fmt
, ...)
739 dev
= make_dev_credv(flags
, devsw
, minornr
, cr
, uid
, gid
, mode
,
747 dev_dependsl(struct cdev
*pdev
, struct cdev
*cdev
)
750 cdev
->si_parent
= pdev
;
751 cdev
->si_flags
|= SI_CHILD
;
752 LIST_INSERT_HEAD(&pdev
->si_children
, cdev
, si_siblings
);
757 dev_depends(struct cdev
*pdev
, struct cdev
*cdev
)
761 dev_dependsl(pdev
, cdev
);
766 make_dev_alias(struct cdev
*pdev
, const char *fmt
, ...)
772 KASSERT(pdev
!= NULL
, ("NULL pdev"));
775 dev
->si_flags
|= SI_ALIAS
;
776 dev
->si_flags
|= SI_NAMED
;
778 i
= vsnrprintf(dev
->__si_namebuf
, sizeof dev
->__si_namebuf
, 32, fmt
, ap
);
779 if (i
> (sizeof dev
->__si_namebuf
- 1)) {
780 printf("WARNING: Device name truncated! (%s)\n",
786 dev_dependsl(pdev
, dev
);
787 clean_unrhdrl(devfs_inos
);
796 destroy_devl(struct cdev
*dev
)
799 struct cdev_privdata
*p
, *p1
;
801 mtx_assert(&devmtx
, MA_OWNED
);
802 KASSERT(dev
->si_flags
& SI_NAMED
,
803 ("WARNING: Driver mistake: destroy_dev on %d\n", minor(dev
)));
807 /* Remove name marking */
808 dev
->si_flags
&= ~SI_NAMED
;
810 /* If we are a child, remove us from the parents list */
811 if (dev
->si_flags
& SI_CHILD
) {
812 LIST_REMOVE(dev
, si_siblings
);
813 dev
->si_flags
&= ~SI_CHILD
;
816 /* Kill our children */
817 while (!LIST_EMPTY(&dev
->si_children
))
818 destroy_devl(LIST_FIRST(&dev
->si_children
));
820 /* Remove from clone list */
821 if (dev
->si_flags
& SI_CLONELIST
) {
822 LIST_REMOVE(dev
, si_clone
);
823 dev
->si_flags
&= ~SI_CLONELIST
;
826 dev
->si_refcount
++; /* Avoid race with dev_rel() */
828 dev
->si_devsw
= NULL
; /* already NULL for SI_ALIAS */
829 while (csw
!= NULL
&& csw
->d_purge
!= NULL
&& dev
->si_threadcount
) {
831 msleep(csw
, &devmtx
, PRIBIO
, "devprg", hz
/10);
832 if (dev
->si_threadcount
)
833 printf("Still %lu threads in %s\n",
834 dev
->si_threadcount
, devtoname(dev
));
836 while (dev
->si_threadcount
!= 0) {
837 /* Use unique dummy wait ident */
838 msleep(&csw
, &devmtx
, PRIBIO
, "devdrn", hz
/ 10);
843 mtx_lock(&cdevpriv_mtx
);
844 LIST_FOREACH_SAFE(p
, &cdev2priv(dev
)->cdp_fdpriv
, cdpd_list
, p1
) {
845 devfs_destroy_cdevpriv(p
);
846 mtx_lock(&cdevpriv_mtx
);
848 mtx_unlock(&cdevpriv_mtx
);
853 bzero(&dev
->__si_u
, sizeof(dev
->__si_u
));
855 if (!(dev
->si_flags
& SI_ALIAS
)) {
856 /* Remove from cdevsw list */
857 LIST_REMOVE(dev
, si_list
);
859 /* If cdevsw has no more struct cdev *'s, clean it */
860 if (LIST_EMPTY(&csw
->d_devs
)) {
862 wakeup(&csw
->d_devs
);
865 dev
->si_flags
&= ~SI_ALIAS
;
866 dev
->si_refcount
--; /* Avoid race with dev_rel() */
868 if (dev
->si_refcount
> 0) {
869 LIST_INSERT_HEAD(&dead_cdevsw
.d_devs
, dev
, si_list
);
871 dev_free_devlocked(dev
);
876 destroy_dev(struct cdev
*dev
)
881 dev_unlock_and_free();
885 devtoname(struct cdev
*dev
)
891 if (dev
->si_name
[0] == '#' || dev
->si_name
[0] == '\0') {
893 csw
= dev_refthread(dev
);
895 sprintf(p
, "(%s)", csw
->d_name
);
900 if (mynor
< 0 || mynor
> 255)
901 sprintf(p
, "/%#x", (u_int
)mynor
);
903 sprintf(p
, "/%d", mynor
);
905 return (dev
->si_name
);
909 dev_stdclone(char *name
, char **namep
, const char *stem
, int *unit
)
914 if (bcmp(stem
, name
, i
) != 0)
916 if (!isdigit(name
[i
]))
919 if (name
[i
] == '0' && isdigit(name
[i
+1]))
921 while (isdigit(name
[i
])) {
923 u
+= name
[i
++] - '0';
936 * Helper functions for cloning device drivers.
938 * The objective here is to make it unnecessary for the device drivers to
939 * use rman or similar to manage their unit number space. Due to the way
940 * we do "on-demand" devices, using rman or other "private" methods
941 * will be very tricky to lock down properly once we lock down this file.
943 * Instead we give the drivers these routines which puts the struct cdev *'s
944 * that are to be managed on their own list, and gives the driver the ability
945 * to ask for the first free unit number or a given specified unit number.
947 * In addition these routines support paired devices (pty, nmdm and similar)
948 * by respecting a number of "flag" bits in the minor number.
953 LIST_HEAD(,cdev
) head
;
957 clone_setup(struct clonedevs
**cdp
)
960 *cdp
= malloc(sizeof **cdp
, M_DEVBUF
, M_WAITOK
| M_ZERO
);
961 LIST_INIT(&(*cdp
)->head
);
965 clone_create(struct clonedevs
**cdp
, struct cdevsw
*csw
, int *up
, struct cdev
**dp
, int extra
)
967 struct clonedevs
*cd
;
968 struct cdev
*dev
, *ndev
, *dl
, *de
;
971 KASSERT(*cdp
!= NULL
,
972 ("clone_setup() not called in driver \"%s\"", csw
->d_name
));
973 KASSERT(!(extra
& CLONE_UNITMASK
),
974 ("Illegal extra bits (0x%x) in clone_create", extra
));
975 KASSERT(*up
<= CLONE_UNITMASK
,
976 ("Too high unit (0x%x) in clone_create", *up
));
977 KASSERT(csw
->d_flags
& D_NEEDMINOR
,
978 ("clone_create() on cdevsw without minor numbers"));
982 * Search the list for a lot of things in one go:
983 * A preexisting match is returned immediately.
984 * The lowest free unit number if we are passed -1, and the place
985 * in the list where we should insert that new element.
986 * The place to insert a specified unit number, if applicable
987 * the end of the list.
990 ndev
= devfs_alloc();
996 LIST_FOREACH(dev
, &cd
->head
, si_clone
) {
997 KASSERT(dev
->si_flags
& SI_CLONELIST
,
998 ("Dev %p(%s) should be on clonelist", dev
, dev
->si_name
));
1000 if (u
== (unit
| extra
)) {
1006 if (unit
== -1 && u
== low
) {
1010 } else if (u
< (unit
| extra
)) {
1013 } else if (u
> (unit
| extra
)) {
1019 unit
= low
& CLONE_UNITMASK
;
1020 dev
= newdev(csw
, unit2minor(unit
| extra
), ndev
);
1021 if (dev
->si_flags
& SI_CLONELIST
) {
1022 printf("dev %p (%s) is on clonelist\n", dev
, dev
->si_name
);
1023 printf("unit=%d, low=%d, extra=0x%x\n", unit
, low
, extra
);
1024 LIST_FOREACH(dev
, &cd
->head
, si_clone
) {
1025 printf("\t%p %s\n", dev
, dev
->si_name
);
1029 KASSERT(!(dev
->si_flags
& SI_CLONELIST
),
1030 ("Dev %p(%s) should not be on clonelist", dev
, dev
->si_name
));
1032 LIST_INSERT_BEFORE(dl
, dev
, si_clone
);
1033 else if (de
!= NULL
)
1034 LIST_INSERT_AFTER(de
, dev
, si_clone
);
1036 LIST_INSERT_HEAD(&cd
->head
, dev
, si_clone
);
1037 dev
->si_flags
|= SI_CLONELIST
;
1039 dev_unlock_and_free();
1044 * Kill everything still on the list. The driver should already have
1045 * disposed of any softc hung of the struct cdev *'s at this time.
1048 clone_cleanup(struct clonedevs
**cdp
)
1051 struct cdev_priv
*cp
;
1052 struct clonedevs
*cd
;
1058 while (!LIST_EMPTY(&cd
->head
)) {
1059 dev
= LIST_FIRST(&cd
->head
);
1060 LIST_REMOVE(dev
, si_clone
);
1061 KASSERT(dev
->si_flags
& SI_CLONELIST
,
1062 ("Dev %p(%s) should be on clonelist", dev
, dev
->si_name
));
1063 dev
->si_flags
&= ~SI_CLONELIST
;
1064 cp
= cdev2priv(dev
);
1065 if (!(cp
->cdp_flags
& CDP_SCHED_DTR
)) {
1066 cp
->cdp_flags
|= CDP_SCHED_DTR
;
1067 KASSERT(dev
->si_flags
& SI_NAMED
,
1068 ("Driver has goofed in cloning underways udev %x", dev
->si_drv0
));
1072 dev_unlock_and_free();
1077 static TAILQ_HEAD(, cdev_priv
) dev_ddtr
=
1078 TAILQ_HEAD_INITIALIZER(dev_ddtr
);
1079 static struct task dev_dtr_task
;
1082 destroy_dev_tq(void *ctx
, int pending
)
1084 struct cdev_priv
*cp
;
1090 while (!TAILQ_EMPTY(&dev_ddtr
)) {
1091 cp
= TAILQ_FIRST(&dev_ddtr
);
1093 KASSERT(cp
->cdp_flags
& CDP_SCHED_DTR
,
1094 ("cdev %p in dev_destroy_tq without CDP_SCHED_DTR", cp
));
1095 TAILQ_REMOVE(&dev_ddtr
, cp
, cdp_dtr_list
);
1096 cb
= cp
->cdp_dtr_cb
;
1097 cb_arg
= cp
->cdp_dtr_cb_arg
;
1099 dev_unlock_and_free();
1109 * devmtx shall be locked on entry. devmtx will be unlocked after
1113 destroy_dev_sched_cbl(struct cdev
*dev
, void (*cb
)(void *), void *arg
)
1115 struct cdev_priv
*cp
;
1117 mtx_assert(&devmtx
, MA_OWNED
);
1118 cp
= cdev2priv(dev
);
1119 if (cp
->cdp_flags
& CDP_SCHED_DTR
) {
1124 cp
->cdp_flags
|= CDP_SCHED_DTR
;
1125 cp
->cdp_dtr_cb
= cb
;
1126 cp
->cdp_dtr_cb_arg
= arg
;
1127 TAILQ_INSERT_TAIL(&dev_ddtr
, cp
, cdp_dtr_list
);
1129 taskqueue_enqueue(taskqueue_swi_giant
, &dev_dtr_task
);
1134 destroy_dev_sched_cb(struct cdev
*dev
, void (*cb
)(void *), void *arg
)
1137 return (destroy_dev_sched_cbl(dev
, cb
, arg
));
1141 destroy_dev_sched(struct cdev
*dev
)
1143 return (destroy_dev_sched_cb(dev
, NULL
, NULL
));
1147 destroy_dev_drain(struct cdevsw
*csw
)
1151 while (!LIST_EMPTY(&csw
->d_devs
)) {
1152 msleep(&csw
->d_devs
, &devmtx
, PRIBIO
, "devscd", hz
/10);
1158 drain_dev_clone_events(void)
1161 sx_xlock(&clone_drain_lock
);
1162 sx_xunlock(&clone_drain_lock
);
1166 devdtr_init(void *dummy __unused
)
1169 TASK_INIT(&dev_dtr_task
, 0, destroy_dev_tq
, NULL
);
1172 SYSINIT(devdtr
, SI_SUB_DEVFS
, SI_ORDER_SECOND
, devdtr_init
, NULL
);