1 /* $NetBSD: subr_autoconf.c,v 1.194 2010/01/08 12:07:08 rmind Exp $ */
4 * Copyright (c) 1996, 2000 Christopher G. Demetriou
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed for the
18 * NetBSD Project. See http://www.NetBSD.org/ for
19 * information about NetBSD.
20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * --(license Id: LICENSE.proto,v 1.1 2000/06/13 21:40:26 cgd Exp )--
38 * Copyright (c) 1992, 1993
39 * The Regents of the University of California. All rights reserved.
41 * This software was developed by the Computer Systems Engineering group
42 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
43 * contributed to Berkeley.
45 * All advertising materials mentioning features or use of this software
46 * must display the following acknowledgement:
47 * This product includes software developed by the University of
48 * California, Lawrence Berkeley Laboratories.
50 * Redistribution and use in source and binary forms, with or without
51 * modification, are permitted provided that the following conditions
53 * 1. Redistributions of source code must retain the above copyright
54 * notice, this list of conditions and the following disclaimer.
55 * 2. Redistributions in binary form must reproduce the above copyright
56 * notice, this list of conditions and the following disclaimer in the
57 * documentation and/or other materials provided with the distribution.
58 * 3. Neither the name of the University nor the names of its contributors
59 * may be used to endorse or promote products derived from this software
60 * without specific prior written permission.
62 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
63 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
64 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
65 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
66 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
67 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
68 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
69 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
70 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
71 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74 * from: Header: subr_autoconf.c,v 1.12 93/02/01 19:31:48 torek Exp (LBL)
76 * @(#)subr_autoconf.c 8.3 (Berkeley) 5/17/94
79 #include <sys/cdefs.h>
80 __KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.194 2010/01/08 12:07:08 rmind Exp $");
86 #include <sys/param.h>
87 #include <sys/device.h>
88 #include <sys/disklabel.h>
90 #include <sys/kauth.h>
91 #include <sys/malloc.h>
93 #include <sys/systm.h>
94 #include <sys/kernel.h>
95 #include <sys/errno.h>
97 #include <sys/reboot.h>
98 #include <sys/kthread.h>
100 #include <sys/dirent.h>
101 #include <sys/vnode.h>
102 #include <sys/mount.h>
103 #include <sys/namei.h>
104 #include <sys/unistd.h>
105 #include <sys/fcntl.h>
106 #include <sys/lockf.h>
107 #include <sys/callout.h>
108 #include <sys/devmon.h>
110 #include <sys/sysctl.h>
112 #include <sys/disk.h>
114 #include <machine/limits.h>
116 #if defined(__i386__) && defined(_KERNEL_OPT)
117 #include "opt_splash.h"
118 #if defined(SPLASHSCREEN) && defined(SPLASHSCREEN_PROGRESS)
119 #include <dev/splash/splash.h>
120 extern struct splash_progress
*splash_progress_state
;
125 * Autoconfiguration subroutines.
129 * ioconf.c exports exactly two names: cfdata and cfroots. All system
130 * devices and drivers are found via these tables.
132 extern struct cfdata cfdata
[];
133 extern const short cfroots
[];
136 * List of all cfdriver structures. We use this to detect duplicates
137 * when other cfdrivers are loaded.
139 struct cfdriverlist allcfdrivers
= LIST_HEAD_INITIALIZER(&allcfdrivers
);
140 extern struct cfdriver
* const cfdriver_list_initial
[];
143 * Initial list of cfattach's.
145 extern const struct cfattachinit cfattachinit
[];
148 * List of cfdata tables. We always have one such list -- the one
149 * built statically when the kernel was configured.
151 struct cftablelist allcftables
= TAILQ_HEAD_INITIALIZER(allcftables
);
152 static struct cftable initcftable
;
154 #define ROOT ((device_t)NULL)
158 struct device
*parent
;
161 struct cfdata
*match
;
165 static char *number(char *, int);
166 static void mapply(struct matchinfo
*, cfdata_t
);
167 static device_t
config_devalloc(const device_t
, const cfdata_t
, const int *);
168 static void config_devdelete(device_t
);
169 static void config_devunlink(device_t
, struct devicelist
*);
170 static void config_makeroom(int, struct cfdriver
*);
171 static void config_devlink(device_t
);
172 static void config_alldevs_unlock(int);
173 static int config_alldevs_lock(void);
174 static void config_alldevs_unlock_gc(int);
175 static void pmflock_debug(device_t
, const char *, int);
177 static device_t
deviter_next1(deviter_t
*);
178 static void deviter_reinit(deviter_t
*);
180 struct deferred_config
{
181 TAILQ_ENTRY(deferred_config
) dc_queue
;
183 void (*dc_func
)(device_t
);
186 TAILQ_HEAD(deferred_config_head
, deferred_config
);
188 struct deferred_config_head deferred_config_queue
=
189 TAILQ_HEAD_INITIALIZER(deferred_config_queue
);
190 struct deferred_config_head interrupt_config_queue
=
191 TAILQ_HEAD_INITIALIZER(interrupt_config_queue
);
192 int interrupt_config_threads
= 8;
194 static void config_process_deferred(struct deferred_config_head
*, device_t
);
196 /* Hooks to finalize configuration once all real devices have been found. */
197 struct finalize_hook
{
198 TAILQ_ENTRY(finalize_hook
) f_list
;
199 int (*f_func
)(device_t
);
202 static TAILQ_HEAD(, finalize_hook
) config_finalize_list
=
203 TAILQ_HEAD_INITIALIZER(config_finalize_list
);
204 static int config_finalize_done
;
206 /* list of all devices */
207 static struct devicelist alldevs
= TAILQ_HEAD_INITIALIZER(alldevs
);
208 static struct devicelist devs_gclist
= TAILQ_HEAD_INITIALIZER(devs_gclist
);
209 static kmutex_t alldevs_mtx
;
210 static volatile bool alldevs_garbage
= false;
211 static volatile devgen_t alldevs_gen
= 1;
212 static volatile int alldevs_nread
= 0;
213 static volatile int alldevs_nwrite
= 0;
215 static int config_pending
; /* semaphore for mountroot */
216 static kmutex_t config_misc_lock
;
217 static kcondvar_t config_misc_cv
;
219 static int detachall
= 0;
221 #define STREQ(s1, s2) \
222 (*(s1) == *(s2) && strcmp((s1), (s2)) == 0)
224 static bool config_initialized
= false; /* config_init() has been called. */
226 static int config_do_twiddle
;
227 static callout_t config_twiddle_ch
;
229 static void sysctl_detach_setup(struct sysctllog
**);
232 * Initialize the autoconfiguration data structures. Normally this
233 * is done by configure(), but some platforms need to do this very
234 * early (to e.g. initialize the console).
239 const struct cfattachinit
*cfai
;
242 KASSERT(config_initialized
== false);
244 mutex_init(&alldevs_mtx
, MUTEX_DEFAULT
, IPL_HIGH
);
246 mutex_init(&config_misc_lock
, MUTEX_DEFAULT
, IPL_NONE
);
247 cv_init(&config_misc_cv
, "cfgmisc");
249 callout_init(&config_twiddle_ch
, CALLOUT_MPSAFE
);
251 /* allcfdrivers is statically initialized. */
252 for (i
= 0; cfdriver_list_initial
[i
] != NULL
; i
++) {
253 if (config_cfdriver_attach(cfdriver_list_initial
[i
]) != 0)
254 panic("configure: duplicate `%s' drivers",
255 cfdriver_list_initial
[i
]->cd_name
);
258 for (cfai
= &cfattachinit
[0]; cfai
->cfai_name
!= NULL
; cfai
++) {
259 for (j
= 0; cfai
->cfai_list
[j
] != NULL
; j
++) {
260 if (config_cfattach_attach(cfai
->cfai_name
,
261 cfai
->cfai_list
[j
]) != 0)
262 panic("configure: duplicate `%s' attachment "
264 cfai
->cfai_list
[j
]->ca_name
,
269 initcftable
.ct_cfdata
= cfdata
;
270 TAILQ_INSERT_TAIL(&allcftables
, &initcftable
, ct_list
);
272 config_initialized
= true;
279 if (!config_initialized
)
282 sysctl_detach_setup(NULL
);
286 config_deferred(device_t dev
)
288 config_process_deferred(&deferred_config_queue
, dev
);
289 config_process_deferred(&interrupt_config_queue
, dev
);
293 config_interrupts_thread(void *cookie
)
295 struct deferred_config
*dc
;
297 while ((dc
= TAILQ_FIRST(&interrupt_config_queue
)) != NULL
) {
298 TAILQ_REMOVE(&interrupt_config_queue
, dc
, dc_queue
);
299 (*dc
->dc_func
)(dc
->dc_dev
);
300 kmem_free(dc
, sizeof(*dc
));
301 config_pending_decr();
307 config_create_interruptthreads()
311 for (i
= 0; i
< interrupt_config_threads
; i
++) {
312 (void)kthread_create(PRI_NONE
, 0, NULL
,
313 config_interrupts_thread
, NULL
, NULL
, "config");
318 * Announce device attach/detach to userland listeners.
321 devmon_report_device(device_t dev
, bool isattach
)
324 prop_dictionary_t ev
;
327 device_t pdev
= device_parent(dev
);
329 ev
= prop_dictionary_create();
333 what
= (isattach
? "device-attach" : "device-detach");
334 parent
= (pdev
== NULL
? "root" : device_xname(pdev
));
335 if (!prop_dictionary_set_cstring(ev
, "device", device_xname(dev
)) ||
336 !prop_dictionary_set_cstring(ev
, "parent", parent
)) {
337 prop_object_release(ev
);
341 devmon_insert(what
, ev
);
346 * Add a cfdriver to the system.
349 config_cfdriver_attach(struct cfdriver
*cd
)
351 struct cfdriver
*lcd
;
353 /* Make sure this driver isn't already in the system. */
354 LIST_FOREACH(lcd
, &allcfdrivers
, cd_list
) {
355 if (STREQ(lcd
->cd_name
, cd
->cd_name
))
359 LIST_INIT(&cd
->cd_attach
);
360 LIST_INSERT_HEAD(&allcfdrivers
, cd
, cd_list
);
366 * Remove a cfdriver from the system.
369 config_cfdriver_detach(struct cfdriver
*cd
)
373 s
= config_alldevs_lock();
374 /* Make sure there are no active instances. */
375 for (i
= 0; i
< cd
->cd_ndevs
; i
++) {
376 if (cd
->cd_devs
[i
] != NULL
) {
381 config_alldevs_unlock_gc(s
);
386 /* ...and no attachments loaded. */
387 if (LIST_EMPTY(&cd
->cd_attach
) == 0)
390 LIST_REMOVE(cd
, cd_list
);
392 KASSERT(cd
->cd_devs
== NULL
);
398 * Look up a cfdriver by name.
401 config_cfdriver_lookup(const char *name
)
405 LIST_FOREACH(cd
, &allcfdrivers
, cd_list
) {
406 if (STREQ(cd
->cd_name
, name
))
414 * Add a cfattach to the specified driver.
417 config_cfattach_attach(const char *driver
, struct cfattach
*ca
)
419 struct cfattach
*lca
;
422 cd
= config_cfdriver_lookup(driver
);
426 /* Make sure this attachment isn't already on this driver. */
427 LIST_FOREACH(lca
, &cd
->cd_attach
, ca_list
) {
428 if (STREQ(lca
->ca_name
, ca
->ca_name
))
432 LIST_INSERT_HEAD(&cd
->cd_attach
, ca
, ca_list
);
438 * Remove a cfattach from the specified driver.
441 config_cfattach_detach(const char *driver
, struct cfattach
*ca
)
447 cd
= config_cfdriver_lookup(driver
);
451 s
= config_alldevs_lock();
452 /* Make sure there are no active instances. */
453 for (i
= 0; i
< cd
->cd_ndevs
; i
++) {
454 if ((dev
= cd
->cd_devs
[i
]) == NULL
)
456 if (dev
->dv_cfattach
== ca
) {
461 config_alldevs_unlock_gc(s
);
466 LIST_REMOVE(ca
, ca_list
);
472 * Look up a cfattach by name.
474 static struct cfattach
*
475 config_cfattach_lookup_cd(struct cfdriver
*cd
, const char *atname
)
479 LIST_FOREACH(ca
, &cd
->cd_attach
, ca_list
) {
480 if (STREQ(ca
->ca_name
, atname
))
488 * Look up a cfattach by driver/attachment name.
491 config_cfattach_lookup(const char *name
, const char *atname
)
495 cd
= config_cfdriver_lookup(name
);
499 return config_cfattach_lookup_cd(cd
, atname
);
503 * Apply the matching function and choose the best. This is used
504 * a few times and we want to keep the code small.
507 mapply(struct matchinfo
*m
, cfdata_t cf
)
512 pri
= (*m
->fn
)(m
->parent
, cf
, m
->locs
, m
->aux
);
514 pri
= config_match(m
->parent
, cf
, m
->aux
);
523 config_stdsubmatch(device_t parent
, cfdata_t cf
, const int *locs
, void *aux
)
525 const struct cfiattrdata
*ci
;
526 const struct cflocdesc
*cl
;
529 ci
= cfiattr_lookup(cf
->cf_pspec
->cfp_iattr
, parent
->dv_cfdriver
);
531 nlocs
= ci
->ci_loclen
;
532 KASSERT(!nlocs
|| locs
);
533 for (i
= 0; i
< nlocs
; i
++) {
534 cl
= &ci
->ci_locdesc
[i
];
535 /* !cld_defaultstr means no default value */
536 if ((!(cl
->cld_defaultstr
)
537 || (cf
->cf_loc
[i
] != cl
->cld_default
))
538 && cf
->cf_loc
[i
] != locs
[i
])
542 return config_match(parent
, cf
, aux
);
546 * Helper function: check whether the driver supports the interface attribute
547 * and return its descriptor structure.
549 static const struct cfiattrdata
*
550 cfdriver_get_iattr(const struct cfdriver
*cd
, const char *ia
)
552 const struct cfiattrdata
* const *cpp
;
554 if (cd
->cd_attrs
== NULL
)
557 for (cpp
= cd
->cd_attrs
; *cpp
; cpp
++) {
558 if (STREQ((*cpp
)->ci_name
, ia
)) {
567 * Lookup an interface attribute description by name.
568 * If the driver is given, consider only its supported attributes.
570 const struct cfiattrdata
*
571 cfiattr_lookup(const char *name
, const struct cfdriver
*cd
)
573 const struct cfdriver
*d
;
574 const struct cfiattrdata
*ia
;
577 return cfdriver_get_iattr(cd
, name
);
579 LIST_FOREACH(d
, &allcfdrivers
, cd_list
) {
580 ia
= cfdriver_get_iattr(d
, name
);
588 * Determine if `parent' is a potential parent for a device spec based
592 cfparent_match(const device_t parent
, const struct cfparent
*cfp
)
594 struct cfdriver
*pcd
;
596 /* We don't match root nodes here. */
600 pcd
= parent
->dv_cfdriver
;
601 KASSERT(pcd
!= NULL
);
604 * First, ensure this parent has the correct interface
607 if (!cfdriver_get_iattr(pcd
, cfp
->cfp_iattr
))
611 * If no specific parent device instance was specified (i.e.
612 * we're attaching to the attribute only), we're done!
614 if (cfp
->cfp_parent
== NULL
)
618 * Check the parent device's name.
620 if (STREQ(pcd
->cd_name
, cfp
->cfp_parent
) == 0)
621 return 0; /* not the same parent */
624 * Make sure the unit number matches.
626 if (cfp
->cfp_unit
== DVUNIT_ANY
|| /* wildcard */
627 cfp
->cfp_unit
== parent
->dv_unit
)
630 /* Unit numbers don't match. */
635 * Helper for config_cfdata_attach(): check all devices whether it could be
636 * parent any attachment in the config data table passed, and rescan.
639 rescan_with_cfdata(const struct cfdata
*cf
)
642 const struct cfdata
*cf1
;
647 * "alldevs" is likely longer than a modules's cfdata, so make it
650 for (d
= deviter_first(&di
, 0); d
!= NULL
; d
= deviter_next(&di
)) {
652 if (!(d
->dv_cfattach
->ca_rescan
))
655 for (cf1
= cf
; cf1
->cf_name
; cf1
++) {
657 if (!cfparent_match(d
, cf1
->cf_pspec
))
660 (*d
->dv_cfattach
->ca_rescan
)(d
,
661 cf1
->cf_pspec
->cfp_iattr
, cf1
->cf_loc
);
664 deviter_release(&di
);
668 * Attach a supplemental config data table and rescan potential
669 * parent devices if required.
672 config_cfdata_attach(cfdata_t cf
, int scannow
)
676 ct
= kmem_alloc(sizeof(*ct
), KM_SLEEP
);
678 TAILQ_INSERT_TAIL(&allcftables
, ct
, ct_list
);
681 rescan_with_cfdata(cf
);
687 * Helper for config_cfdata_detach: check whether a device is
688 * found through any attachment in the config data table.
691 dev_in_cfdata(const struct device
*d
, const struct cfdata
*cf
)
693 const struct cfdata
*cf1
;
695 for (cf1
= cf
; cf1
->cf_name
; cf1
++)
696 if (d
->dv_cfdata
== cf1
)
703 * Detach a supplemental config data table. Detach all devices found
704 * through that table (and thus keeping references to it) before.
707 config_cfdata_detach(cfdata_t cf
)
714 for (d
= deviter_first(&di
, DEVITER_F_RW
); d
!= NULL
;
715 d
= deviter_next(&di
)) {
716 if (!dev_in_cfdata(d
, cf
))
718 if ((error
= config_detach(d
, 0)) != 0)
721 deviter_release(&di
);
723 aprint_error_dev(d
, "unable to detach instance\n");
727 TAILQ_FOREACH(ct
, &allcftables
, ct_list
) {
728 if (ct
->ct_cfdata
== cf
) {
729 TAILQ_REMOVE(&allcftables
, ct
, ct_list
);
730 kmem_free(ct
, sizeof(*ct
));
735 /* not found -- shouldn't happen */
740 * Invoke the "match" routine for a cfdata entry on behalf of
741 * an external caller, usually a "submatch" routine.
744 config_match(device_t parent
, cfdata_t cf
, void *aux
)
748 ca
= config_cfattach_lookup(cf
->cf_name
, cf
->cf_atname
);
750 /* No attachment for this entry, oh well. */
754 return (*ca
->ca_match
)(parent
, cf
, aux
);
758 * Iterate over all potential children of some device, calling the given
759 * function (default being the child's match function) for each one.
760 * Nonzero returns are matches; the highest value returned is considered
761 * the best match. Return the `found child' if we got a match, or NULL
762 * otherwise. The `aux' pointer is simply passed on through.
764 * Note that this function is designed so that it can be used to apply
765 * an arbitrary function to all potential children (its return value
769 config_search_loc(cfsubmatch_t fn
, device_t parent
,
770 const char *ifattr
, const int *locs
, void *aux
)
776 KASSERT(config_initialized
);
777 KASSERT(!ifattr
|| cfdriver_get_iattr(parent
->dv_cfdriver
, ifattr
));
786 TAILQ_FOREACH(ct
, &allcftables
, ct_list
) {
787 for (cf
= ct
->ct_cfdata
; cf
->cf_name
; cf
++) {
789 /* We don't match root nodes here. */
794 * Skip cf if no longer eligible, otherwise scan
795 * through parents for one matching `parent', and
796 * try match function.
798 if (cf
->cf_fstate
== FSTATE_FOUND
)
800 if (cf
->cf_fstate
== FSTATE_DNOTFOUND
||
801 cf
->cf_fstate
== FSTATE_DSTAR
)
805 * If an interface attribute was specified,
806 * consider only children which attach to
809 if (ifattr
&& !STREQ(ifattr
, cf
->cf_pspec
->cfp_iattr
))
812 if (cfparent_match(parent
, cf
->cf_pspec
))
820 config_search_ia(cfsubmatch_t fn
, device_t parent
, const char *ifattr
,
824 return config_search_loc(fn
, parent
, ifattr
, NULL
, aux
);
828 * Find the given root device.
829 * This is much like config_search, but there is no parent.
830 * Don't bother with multiple cfdata tables; the root node
831 * must always be in the initial table.
834 config_rootsearch(cfsubmatch_t fn
, const char *rootname
, void *aux
)
847 * Look at root entries for matching name. We do not bother
848 * with found-state here since only one root should ever be
849 * searched (and it must be done first).
851 for (p
= cfroots
; *p
>= 0; p
++) {
853 if (strcmp(cf
->cf_name
, rootname
) == 0)
859 static const char * const msgs
[3] = { "", " not configured\n", " unsupported\n" };
862 * The given `aux' argument describes a device that has been found
863 * on the given parent, but not necessarily configured. Locate the
864 * configuration data for that device (using the submatch function
865 * provided, or using candidates' cd_match configuration driver
866 * functions) and attach it, and return true. If the device was
867 * not configured, call the given `print' function and return 0.
870 config_found_sm_loc(device_t parent
,
871 const char *ifattr
, const int *locs
, void *aux
,
872 cfprint_t print
, cfsubmatch_t submatch
)
876 #if defined(SPLASHSCREEN) && defined(SPLASHSCREEN_PROGRESS)
877 if (splash_progress_state
)
878 splash_progress_update(splash_progress_state
);
881 if ((cf
= config_search_loc(submatch
, parent
, ifattr
, locs
, aux
)))
882 return(config_attach_loc(parent
, cf
, locs
, aux
, print
));
884 if (config_do_twiddle
&& cold
)
886 aprint_normal("%s", msgs
[(*print
)(aux
, device_xname(parent
))]);
889 #if defined(SPLASHSCREEN) && defined(SPLASHSCREEN_PROGRESS)
890 if (splash_progress_state
)
891 splash_progress_update(splash_progress_state
);
898 config_found_ia(device_t parent
, const char *ifattr
, void *aux
,
902 return config_found_sm_loc(parent
, ifattr
, NULL
, aux
, print
, NULL
);
906 config_found(device_t parent
, void *aux
, cfprint_t print
)
909 return config_found_sm_loc(parent
, NULL
, NULL
, aux
, print
, NULL
);
913 * As above, but for root devices.
916 config_rootfound(const char *rootname
, void *aux
)
920 if ((cf
= config_rootsearch((cfsubmatch_t
)NULL
, rootname
, aux
)) != NULL
)
921 return config_attach(ROOT
, cf
, aux
, (cfprint_t
)NULL
);
922 aprint_error("root device %s not configured\n", rootname
);
926 /* just like sprintf(buf, "%d") except that it works from the end */
928 number(char *ep
, int n
)
933 *--ep
= (n
% 10) + '0';
941 * Expand the size of the cd_devs array if necessary.
943 * The caller must hold alldevs_mtx. config_makeroom() may release and
944 * re-acquire alldevs_mtx, so callers should re-check conditions such
945 * as alldevs_nwrite == 0 and alldevs_nread == 0 when config_makeroom()
949 config_makeroom(int n
, struct cfdriver
*cd
)
956 for (new = MAX(4, cd
->cd_ndevs
); new <= n
; new += new)
959 while (n
>= cd
->cd_ndevs
) {
961 * Need to expand the array.
966 /* Release alldevs_mtx around allocation, which may
969 mutex_exit(&alldevs_mtx
);
970 nsp
= kmem_alloc(sizeof(device_t
[new]), KM_SLEEP
);
972 panic("%s: could not expand cd_devs", __func__
);
973 mutex_enter(&alldevs_mtx
);
975 /* If another thread moved the array while we did
976 * not hold alldevs_mtx, try again.
978 if (cd
->cd_devs
!= osp
) {
979 kmem_free(nsp
, sizeof(device_t
[new]));
983 memset(nsp
+ old
, 0, sizeof(device_t
[new - old
]));
985 memcpy(nsp
, cd
->cd_devs
, sizeof(device_t
[old
]));
990 kmem_free(osp
, sizeof(device_t
[old
]));
996 * Put dev into the devices list.
999 config_devlink(device_t dev
)
1003 s
= config_alldevs_lock();
1005 KASSERT(device_cfdriver(dev
)->cd_devs
[dev
->dv_unit
] == dev
);
1007 dev
->dv_add_gen
= alldevs_gen
;
1008 /* It is safe to add a device to the tail of the list while
1009 * readers and writers are in the list.
1011 TAILQ_INSERT_TAIL(&alldevs
, dev
, dv_list
);
1012 config_alldevs_unlock(s
);
1016 config_devfree(device_t dev
)
1018 int priv
= (dev
->dv_flags
& DVF_PRIV_ALLOC
);
1020 if (dev
->dv_cfattach
->ca_devsize
> 0)
1021 kmem_free(dev
->dv_private
, dev
->dv_cfattach
->ca_devsize
);
1023 kmem_free(dev
, sizeof(*dev
));
1027 * config_devunlink: unlink the device and put into the garbage list.
1029 * => caller must hold alldevs_mtx.
1032 config_devunlink(device_t dev
, struct devicelist
*garbage
)
1034 struct device_garbage
*dg
= &dev
->dv_garbage
;
1035 cfdriver_t cd
= device_cfdriver(dev
);
1038 KASSERT(mutex_owned(&alldevs_mtx
));
1040 /* Unlink from device list. Link to garbage list. */
1041 TAILQ_REMOVE(&alldevs
, dev
, dv_list
);
1042 TAILQ_INSERT_TAIL(garbage
, dev
, dv_list
);
1044 /* Remove from cfdriver's array. */
1045 cd
->cd_devs
[dev
->dv_unit
] = NULL
;
1048 * If the device now has no units in use, unlink its softc array.
1050 for (i
= 0; i
< cd
->cd_ndevs
; i
++) {
1051 if (cd
->cd_devs
[i
] != NULL
)
1054 /* Nothing found. Unlink, now. Deallocate, later. */
1055 if (i
== cd
->cd_ndevs
) {
1056 dg
->dg_ndevs
= cd
->cd_ndevs
;
1057 dg
->dg_devs
= cd
->cd_devs
;
1064 config_devdelete(device_t dev
)
1066 struct device_garbage
*dg
= &dev
->dv_garbage
;
1067 device_lock_t dvl
= device_getlock(dev
);
1069 if (dg
->dg_devs
!= NULL
)
1070 kmem_free(dg
->dg_devs
, sizeof(device_t
[dg
->dg_ndevs
]));
1072 cv_destroy(&dvl
->dvl_cv
);
1073 mutex_destroy(&dvl
->dvl_mtx
);
1075 KASSERT(dev
->dv_properties
!= NULL
);
1076 prop_object_release(dev
->dv_properties
);
1078 KASSERT(dev
->dv_activity_handlers
== NULL
);
1080 if (dev
->dv_locators
) {
1081 size_t amount
= *--dev
->dv_locators
;
1082 kmem_free(dev
->dv_locators
, amount
);
1084 config_devfree(dev
);
1088 config_unit_nextfree(cfdriver_t cd
, cfdata_t cf
)
1092 if (cf
->cf_fstate
== FSTATE_STAR
) {
1093 for (unit
= cf
->cf_unit
; unit
< cd
->cd_ndevs
; unit
++)
1094 if (cd
->cd_devs
[unit
] == NULL
)
1097 * unit is now the unit of the first NULL device pointer,
1098 * or max(cd->cd_ndevs,cf->cf_unit).
1102 if (unit
< cd
->cd_ndevs
&& cd
->cd_devs
[unit
] != NULL
)
1109 config_unit_alloc(device_t dev
, cfdriver_t cd
, cfdata_t cf
)
1113 s
= config_alldevs_lock();
1115 unit
= config_unit_nextfree(cd
, cf
);
1118 if (unit
< cd
->cd_ndevs
) {
1119 cd
->cd_devs
[unit
] = dev
;
1120 dev
->dv_unit
= unit
;
1123 config_makeroom(unit
, cd
);
1125 config_alldevs_unlock_gc(s
);
1131 config_devalloc(const device_t parent
, const cfdata_t cf
, const int *locs
)
1135 size_t lname
, lunit
;
1141 const struct cfiattrdata
*ia
;
1144 cd
= config_cfdriver_lookup(cf
->cf_name
);
1148 ca
= config_cfattach_lookup_cd(cd
, cf
->cf_atname
);
1152 if ((ca
->ca_flags
& DVF_PRIV_ALLOC
) == 0 &&
1153 ca
->ca_devsize
< sizeof(struct device
))
1154 panic("config_devalloc: %s", cf
->cf_atname
);
1156 /* get memory for all device vars */
1157 KASSERT((ca
->ca_flags
& DVF_PRIV_ALLOC
) || ca
->ca_devsize
>= sizeof(struct device
));
1158 if (ca
->ca_devsize
> 0) {
1159 dev_private
= kmem_zalloc(ca
->ca_devsize
, KM_SLEEP
);
1160 if (dev_private
== NULL
)
1161 panic("config_devalloc: memory allocation for device softc failed");
1163 KASSERT(ca
->ca_flags
& DVF_PRIV_ALLOC
);
1167 if ((ca
->ca_flags
& DVF_PRIV_ALLOC
) != 0) {
1168 dev
= kmem_zalloc(sizeof(*dev
), KM_SLEEP
);
1173 panic("config_devalloc: memory allocation for device_t failed");
1175 myunit
= config_unit_alloc(dev
, cd
, cf
);
1177 config_devfree(dev
);
1181 /* compute length of name and decimal expansion of unit number */
1182 lname
= strlen(cd
->cd_name
);
1183 xunit
= number(&num
[sizeof(num
)], myunit
);
1184 lunit
= &num
[sizeof(num
)] - xunit
;
1185 if (lname
+ lunit
> sizeof(dev
->dv_xname
))
1186 panic("config_devalloc: device name too long");
1188 dvl
= device_getlock(dev
);
1190 mutex_init(&dvl
->dvl_mtx
, MUTEX_DEFAULT
, IPL_NONE
);
1191 cv_init(&dvl
->dvl_cv
, "pmfsusp");
1193 dev
->dv_class
= cd
->cd_class
;
1194 dev
->dv_cfdata
= cf
;
1195 dev
->dv_cfdriver
= cd
;
1196 dev
->dv_cfattach
= ca
;
1197 dev
->dv_activity_count
= 0;
1198 dev
->dv_activity_handlers
= NULL
;
1199 dev
->dv_private
= dev_private
;
1200 memcpy(dev
->dv_xname
, cd
->cd_name
, lname
);
1201 memcpy(dev
->dv_xname
+ lname
, xunit
, lunit
);
1202 dev
->dv_parent
= parent
;
1204 dev
->dv_depth
= parent
->dv_depth
+ 1;
1207 dev
->dv_flags
= DVF_ACTIVE
; /* always initially active */
1208 dev
->dv_flags
|= ca
->ca_flags
; /* inherit flags from class */
1210 KASSERT(parent
); /* no locators at root */
1211 ia
= cfiattr_lookup(cf
->cf_pspec
->cfp_iattr
,
1212 parent
->dv_cfdriver
);
1214 kmem_alloc(sizeof(int [ia
->ci_loclen
+ 1]), KM_SLEEP
);
1215 *dev
->dv_locators
++ = sizeof(int [ia
->ci_loclen
+ 1]);
1216 memcpy(dev
->dv_locators
, locs
, sizeof(int [ia
->ci_loclen
]));
1218 dev
->dv_properties
= prop_dictionary_create();
1219 KASSERT(dev
->dv_properties
!= NULL
);
1221 prop_dictionary_set_cstring_nocopy(dev
->dv_properties
,
1222 "device-driver", dev
->dv_cfdriver
->cd_name
);
1223 prop_dictionary_set_uint16(dev
->dv_properties
,
1224 "device-unit", dev
->dv_unit
);
1230 * Attach a found device.
1233 config_attach_loc(device_t parent
, cfdata_t cf
,
1234 const int *locs
, void *aux
, cfprint_t print
)
1238 const char *drvname
;
1240 #if defined(SPLASHSCREEN) && defined(SPLASHSCREEN_PROGRESS)
1241 if (splash_progress_state
)
1242 splash_progress_update(splash_progress_state
);
1245 dev
= config_devalloc(parent
, cf
, locs
);
1247 panic("config_attach: allocation of device softc failed");
1249 /* XXX redundant - see below? */
1250 if (cf
->cf_fstate
!= FSTATE_STAR
) {
1251 KASSERT(cf
->cf_fstate
== FSTATE_NOTFOUND
);
1252 cf
->cf_fstate
= FSTATE_FOUND
;
1255 config_devlink(dev
);
1257 if (config_do_twiddle
&& cold
)
1260 aprint_naive("Found ");
1262 * We want the next two printfs for normal, verbose, and quiet,
1263 * but not silent (in which case, we're twiddling, instead).
1265 if (parent
== ROOT
) {
1266 aprint_naive("%s (root)", device_xname(dev
));
1267 aprint_normal("%s (root)", device_xname(dev
));
1269 aprint_naive("%s at %s", device_xname(dev
), device_xname(parent
));
1270 aprint_normal("%s at %s", device_xname(dev
), device_xname(parent
));
1272 (void) (*print
)(aux
, NULL
);
1276 * Before attaching, clobber any unfound devices that are
1277 * otherwise identical.
1278 * XXX code above is redundant?
1280 drvname
= dev
->dv_cfdriver
->cd_name
;
1281 TAILQ_FOREACH(ct
, &allcftables
, ct_list
) {
1282 for (cf
= ct
->ct_cfdata
; cf
->cf_name
; cf
++) {
1283 if (STREQ(cf
->cf_name
, drvname
) &&
1284 cf
->cf_unit
== dev
->dv_unit
) {
1285 if (cf
->cf_fstate
== FSTATE_NOTFOUND
)
1286 cf
->cf_fstate
= FSTATE_FOUND
;
1290 #ifdef __HAVE_DEVICE_REGISTER
1291 device_register(dev
, aux
);
1294 /* Let userland know */
1295 devmon_report_device(dev
, true);
1297 #if defined(SPLASHSCREEN) && defined(SPLASHSCREEN_PROGRESS)
1298 if (splash_progress_state
)
1299 splash_progress_update(splash_progress_state
);
1301 (*dev
->dv_cfattach
->ca_attach
)(parent
, dev
, aux
);
1302 #if defined(SPLASHSCREEN) && defined(SPLASHSCREEN_PROGRESS)
1303 if (splash_progress_state
)
1304 splash_progress_update(splash_progress_state
);
1307 if (!device_pmf_is_registered(dev
))
1308 aprint_debug_dev(dev
, "WARNING: power management not supported\n");
1310 config_process_deferred(&deferred_config_queue
, dev
);
1315 config_attach(device_t parent
, cfdata_t cf
, void *aux
, cfprint_t print
)
1318 return config_attach_loc(parent
, cf
, NULL
, aux
, print
);
1322 * As above, but for pseudo-devices. Pseudo-devices attached in this
1323 * way are silently inserted into the device tree, and their children
1326 * Note that because pseudo-devices are attached silently, any information
1327 * the attach routine wishes to print should be prefixed with the device
1328 * name by the attach routine.
1331 config_attach_pseudo(cfdata_t cf
)
1335 dev
= config_devalloc(ROOT
, cf
, NULL
);
1339 /* XXX mark busy in cfdata */
1341 if (cf
->cf_fstate
!= FSTATE_STAR
) {
1342 KASSERT(cf
->cf_fstate
== FSTATE_NOTFOUND
);
1343 cf
->cf_fstate
= FSTATE_FOUND
;
1346 config_devlink(dev
);
1348 #if 0 /* XXXJRT not yet */
1349 #ifdef __HAVE_DEVICE_REGISTER
1350 device_register(dev
, NULL
); /* like a root node */
1353 (*dev
->dv_cfattach
->ca_attach
)(ROOT
, dev
, NULL
);
1354 config_process_deferred(&deferred_config_queue
, dev
);
1359 * Detach a device. Optionally forced (e.g. because of hardware
1360 * removal) and quiet. Returns zero if successful, non-zero
1361 * (an error code) otherwise.
1363 * Note that this code wants to be run from a process context, so
1364 * that the detach can sleep to allow processes which have a device
1365 * open to run and unwind their stacks.
1368 config_detach(device_t dev
, int flags
)
1372 const struct cfattach
*ca
;
1373 struct cfdriver
*cd
;
1380 cf
= dev
->dv_cfdata
;
1381 if (cf
!= NULL
&& cf
->cf_fstate
!= FSTATE_FOUND
&&
1382 cf
->cf_fstate
!= FSTATE_STAR
)
1383 panic("config_detach: %s: bad device fstate %d",
1384 device_xname(dev
), cf
? cf
->cf_fstate
: -1);
1386 cd
= dev
->dv_cfdriver
;
1387 KASSERT(cd
!= NULL
);
1389 ca
= dev
->dv_cfattach
;
1390 KASSERT(ca
!= NULL
);
1392 s
= config_alldevs_lock();
1393 if (dev
->dv_del_gen
!= 0) {
1394 config_alldevs_unlock(s
);
1396 printf("%s: %s is already detached\n", __func__
,
1398 #endif /* DIAGNOSTIC */
1402 config_alldevs_unlock(s
);
1405 (flags
& (DETACH_SHUTDOWN
|DETACH_FORCE
)) == DETACH_SHUTDOWN
&&
1406 (dev
->dv_flags
& DVF_DETACH_SHUTDOWN
) == 0) {
1408 } else if (ca
->ca_detach
!= NULL
) {
1409 rv
= (*ca
->ca_detach
)(dev
, flags
);
1414 * If it was not possible to detach the device, then we either
1415 * panic() (for the forced but failed case), or return an error.
1417 * If it was possible to detach the device, ensure that the
1418 * device is deactivated.
1421 dev
->dv_flags
&= ~DVF_ACTIVE
;
1422 else if ((flags
& DETACH_FORCE
) == 0)
1425 panic("config_detach: forced detach of %s failed (%d)",
1426 device_xname(dev
), rv
);
1430 * The device has now been successfully detached.
1433 /* Let userland know */
1434 devmon_report_device(dev
, false);
1438 * Sanity: If you're successfully detached, you should have no
1439 * children. (Note that because children must be attached
1440 * after parents, we only need to search the latter part of
1443 for (d
= TAILQ_NEXT(dev
, dv_list
); d
!= NULL
;
1444 d
= TAILQ_NEXT(d
, dv_list
)) {
1445 if (d
->dv_parent
== dev
&& d
->dv_del_gen
== 0) {
1446 printf("config_detach: detached device %s"
1447 " has children %s\n", device_xname(dev
), device_xname(d
));
1448 panic("config_detach");
1453 /* notify the parent that the child is gone */
1454 if (dev
->dv_parent
) {
1455 device_t p
= dev
->dv_parent
;
1456 if (p
->dv_cfattach
->ca_childdetached
)
1457 (*p
->dv_cfattach
->ca_childdetached
)(p
, dev
);
1461 * Mark cfdata to show that the unit can be reused, if possible.
1463 TAILQ_FOREACH(ct
, &allcftables
, ct_list
) {
1464 for (cf
= ct
->ct_cfdata
; cf
->cf_name
; cf
++) {
1465 if (STREQ(cf
->cf_name
, cd
->cd_name
)) {
1466 if (cf
->cf_fstate
== FSTATE_FOUND
&&
1467 cf
->cf_unit
== dev
->dv_unit
)
1468 cf
->cf_fstate
= FSTATE_NOTFOUND
;
1473 if (dev
->dv_cfdata
!= NULL
&& (flags
& DETACH_QUIET
) == 0)
1474 aprint_normal_dev(dev
, "detached\n");
1477 s
= config_alldevs_lock();
1478 KASSERT(alldevs_nwrite
!= 0);
1480 if (rv
== 0 && dev
->dv_del_gen
== 0) {
1481 dev
->dv_del_gen
= alldevs_gen
;
1482 alldevs_garbage
= true;
1484 config_alldevs_unlock_gc(s
);
1490 config_detach_children(device_t parent
, int flags
)
1496 for (dv
= deviter_first(&di
, DEVITER_F_RW
); dv
!= NULL
;
1497 dv
= deviter_next(&di
)) {
1498 if (device_parent(dv
) != parent
)
1500 if ((error
= config_detach(dv
, flags
)) != 0)
1503 deviter_release(&di
);
1508 shutdown_first(struct shutdown_state
*s
)
1510 if (!s
->initialized
) {
1511 deviter_init(&s
->di
, DEVITER_F_SHUTDOWN
|DEVITER_F_LEAVES_FIRST
);
1512 s
->initialized
= true;
1514 return shutdown_next(s
);
1518 shutdown_next(struct shutdown_state
*s
)
1522 while ((dv
= deviter_next(&s
->di
)) != NULL
&& !device_is_active(dv
))
1526 s
->initialized
= false;
1532 config_detach_all(int how
)
1534 static struct shutdown_state s
;
1536 bool progress
= false;
1538 if ((how
& RB_NOSYNC
) != 0)
1541 for (curdev
= shutdown_first(&s
); curdev
!= NULL
;
1542 curdev
= shutdown_next(&s
)) {
1543 aprint_debug(" detaching %s, ", device_xname(curdev
));
1544 if (config_detach(curdev
, DETACH_SHUTDOWN
) == 0) {
1546 aprint_debug("success.");
1548 aprint_debug("failed.");
1554 device_is_ancestor_of(device_t ancestor
, device_t descendant
)
1558 for (dv
= descendant
; dv
!= NULL
; dv
= device_parent(dv
)) {
1559 if (device_parent(dv
) == ancestor
)
1566 config_deactivate(device_t dev
)
1569 const struct cfattach
*ca
;
1570 device_t descendant
;
1571 int s
, rv
= 0, oflags
;
1573 for (descendant
= deviter_first(&di
, DEVITER_F_ROOT_FIRST
);
1575 descendant
= deviter_next(&di
)) {
1576 if (dev
!= descendant
&&
1577 !device_is_ancestor_of(dev
, descendant
))
1580 if ((descendant
->dv_flags
& DVF_ACTIVE
) == 0)
1583 ca
= descendant
->dv_cfattach
;
1584 oflags
= descendant
->dv_flags
;
1586 descendant
->dv_flags
&= ~DVF_ACTIVE
;
1587 if (ca
->ca_activate
== NULL
)
1590 rv
= (*ca
->ca_activate
)(descendant
, DVACT_DEACTIVATE
);
1593 descendant
->dv_flags
= oflags
;
1595 deviter_release(&di
);
1600 * Defer the configuration of the specified device until all
1601 * of its parent's devices have been attached.
1604 config_defer(device_t dev
, void (*func
)(device_t
))
1606 struct deferred_config
*dc
;
1608 if (dev
->dv_parent
== NULL
)
1609 panic("config_defer: can't defer config of a root device");
1612 TAILQ_FOREACH(dc
, &deferred_config_queue
, dc_queue
) {
1613 if (dc
->dc_dev
== dev
)
1614 panic("config_defer: deferred twice");
1618 dc
= kmem_alloc(sizeof(*dc
), KM_SLEEP
);
1620 panic("config_defer: unable to allocate callback");
1624 TAILQ_INSERT_TAIL(&deferred_config_queue
, dc
, dc_queue
);
1625 config_pending_incr();
1629 * Defer some autoconfiguration for a device until after interrupts
1633 config_interrupts(device_t dev
, void (*func
)(device_t
))
1635 struct deferred_config
*dc
;
1638 * If interrupts are enabled, callback now.
1646 TAILQ_FOREACH(dc
, &interrupt_config_queue
, dc_queue
) {
1647 if (dc
->dc_dev
== dev
)
1648 panic("config_interrupts: deferred twice");
1652 dc
= kmem_alloc(sizeof(*dc
), KM_SLEEP
);
1654 panic("config_interrupts: unable to allocate callback");
1658 TAILQ_INSERT_TAIL(&interrupt_config_queue
, dc
, dc_queue
);
1659 config_pending_incr();
1663 * Process a deferred configuration queue.
1666 config_process_deferred(struct deferred_config_head
*queue
,
1669 struct deferred_config
*dc
, *ndc
;
1671 for (dc
= TAILQ_FIRST(queue
); dc
!= NULL
; dc
= ndc
) {
1672 ndc
= TAILQ_NEXT(dc
, dc_queue
);
1673 if (parent
== NULL
|| dc
->dc_dev
->dv_parent
== parent
) {
1674 TAILQ_REMOVE(queue
, dc
, dc_queue
);
1675 (*dc
->dc_func
)(dc
->dc_dev
);
1676 kmem_free(dc
, sizeof(*dc
));
1677 config_pending_decr();
1683 * Manipulate the config_pending semaphore.
1686 config_pending_incr(void)
1689 mutex_enter(&config_misc_lock
);
1691 mutex_exit(&config_misc_lock
);
1695 config_pending_decr(void)
1699 if (config_pending
== 0)
1700 panic("config_pending_decr: config_pending == 0");
1702 mutex_enter(&config_misc_lock
);
1704 if (config_pending
== 0)
1705 cv_broadcast(&config_misc_cv
);
1706 mutex_exit(&config_misc_lock
);
1710 * Register a "finalization" routine. Finalization routines are
1711 * called iteratively once all real devices have been found during
1712 * autoconfiguration, for as long as any one finalizer has done
1716 config_finalize_register(device_t dev
, int (*fn
)(device_t
))
1718 struct finalize_hook
*f
;
1721 * If finalization has already been done, invoke the
1722 * callback function now.
1724 if (config_finalize_done
) {
1725 while ((*fn
)(dev
) != 0)
1729 /* Ensure this isn't already on the list. */
1730 TAILQ_FOREACH(f
, &config_finalize_list
, f_list
) {
1731 if (f
->f_func
== fn
&& f
->f_dev
== dev
)
1735 f
= kmem_alloc(sizeof(*f
), KM_SLEEP
);
1738 TAILQ_INSERT_TAIL(&config_finalize_list
, f
, f_list
);
1744 config_finalize(void)
1746 struct finalize_hook
*f
;
1747 struct pdevinit
*pdev
;
1748 extern struct pdevinit pdevinit
[];
1752 * Now that device driver threads have been created, wait for
1753 * them to finish any deferred autoconfiguration.
1755 mutex_enter(&config_misc_lock
);
1756 while (config_pending
!= 0)
1757 cv_wait(&config_misc_cv
, &config_misc_lock
);
1758 mutex_exit(&config_misc_lock
);
1760 KERNEL_LOCK(1, NULL
);
1762 /* Attach pseudo-devices. */
1763 for (pdev
= pdevinit
; pdev
->pdev_attach
!= NULL
; pdev
++)
1764 (*pdev
->pdev_attach
)(pdev
->pdev_count
);
1766 /* Run the hooks until none of them does any work. */
1769 TAILQ_FOREACH(f
, &config_finalize_list
, f_list
)
1770 rv
|= (*f
->f_func
)(f
->f_dev
);
1773 config_finalize_done
= 1;
1775 /* Now free all the hooks. */
1776 while ((f
= TAILQ_FIRST(&config_finalize_list
)) != NULL
) {
1777 TAILQ_REMOVE(&config_finalize_list
, f
, f_list
);
1778 kmem_free(f
, sizeof(*f
));
1781 KERNEL_UNLOCK_ONE(NULL
);
1783 errcnt
= aprint_get_error_count();
1784 if ((boothowto
& (AB_QUIET
|AB_SILENT
)) != 0 &&
1785 (boothowto
& AB_VERBOSE
) == 0) {
1786 mutex_enter(&config_misc_lock
);
1787 if (config_do_twiddle
) {
1788 config_do_twiddle
= 0;
1789 printf_nolog(" done.\n");
1791 mutex_exit(&config_misc_lock
);
1793 printf("WARNING: %d error%s while detecting hardware; "
1794 "check system log.\n", errcnt
,
1795 errcnt
== 1 ? "" : "s");
1801 config_twiddle_init()
1804 if ((boothowto
& (AB_SILENT
|AB_VERBOSE
)) == AB_SILENT
) {
1805 config_do_twiddle
= 1;
1807 callout_setfunc(&config_twiddle_ch
, config_twiddle_fn
, NULL
);
1811 config_twiddle_fn(void *cookie
)
1814 mutex_enter(&config_misc_lock
);
1815 if (config_do_twiddle
) {
1817 callout_schedule(&config_twiddle_ch
, mstohz(100));
1819 mutex_exit(&config_misc_lock
);
1823 config_alldevs_lock(void)
1829 mutex_enter(&alldevs_mtx
);
1831 KASSERT(TAILQ_EMPTY(&devs_gclist
));
1832 while (alldevs_nwrite
== 0 && alldevs_nread
== 0 && alldevs_garbage
) {
1833 TAILQ_FOREACH(dv
, &alldevs
, dv_list
)
1834 if (dv
->dv_del_gen
!= 0)
1837 alldevs_garbage
= false;
1840 config_devunlink(dv
, &devs_gclist
);
1846 config_alldevs_unlock(int s
)
1849 mutex_exit(&alldevs_mtx
);
1854 * config_alldevs_unlock_gc: unlock and free garbage collected entries.
1857 config_alldevs_unlock_gc(int s
)
1859 struct devicelist gclist
= TAILQ_HEAD_INITIALIZER(gclist
);
1862 KASSERT(mutex_owned(&alldevs_mtx
));
1863 TAILQ_CONCAT(&gclist
, &devs_gclist
, dv_list
);
1864 KASSERT(TAILQ_EMPTY(&devs_gclist
));
1865 config_alldevs_unlock(s
);
1867 while ((dv
= TAILQ_FIRST(&gclist
)) != NULL
) {
1868 TAILQ_REMOVE(&gclist
, dv
, dv_list
);
1869 config_devdelete(dv
);
1876 * Look up a device instance for a given driver.
1879 device_lookup(cfdriver_t cd
, int unit
)
1884 s
= config_alldevs_lock();
1885 KASSERT(mutex_owned(&alldevs_mtx
));
1886 if (unit
< 0 || unit
>= cd
->cd_ndevs
)
1888 else if ((dv
= cd
->cd_devs
[unit
]) != NULL
&& dv
->dv_del_gen
!= 0)
1890 config_alldevs_unlock(s
);
1896 * device_lookup_private:
1898 * Look up a softc instance for a given driver.
1901 device_lookup_private(cfdriver_t cd
, int unit
)
1905 if ((dv
= device_lookup(cd
, unit
)) == NULL
)
1908 return dv
->dv_private
;
1912 * Accessor functions for the device_t type.
1915 device_class(device_t dev
)
1918 return dev
->dv_class
;
1922 device_cfdata(device_t dev
)
1925 return dev
->dv_cfdata
;
1929 device_cfdriver(device_t dev
)
1932 return dev
->dv_cfdriver
;
1936 device_cfattach(device_t dev
)
1939 return dev
->dv_cfattach
;
1943 device_unit(device_t dev
)
1946 return dev
->dv_unit
;
1950 device_xname(device_t dev
)
1953 return dev
->dv_xname
;
1957 device_parent(device_t dev
)
1960 return dev
->dv_parent
;
1964 device_activation(device_t dev
, devact_level_t level
)
1968 active_flags
= DVF_ACTIVE
;
1970 case DEVACT_LEVEL_FULL
:
1971 active_flags
|= DVF_CLASS_SUSPENDED
;
1973 case DEVACT_LEVEL_DRIVER
:
1974 active_flags
|= DVF_DRIVER_SUSPENDED
;
1976 case DEVACT_LEVEL_BUS
:
1977 active_flags
|= DVF_BUS_SUSPENDED
;
1981 return (dev
->dv_flags
& active_flags
) == DVF_ACTIVE
;
1985 device_is_active(device_t dev
)
1989 active_flags
= DVF_ACTIVE
;
1990 active_flags
|= DVF_CLASS_SUSPENDED
;
1991 active_flags
|= DVF_DRIVER_SUSPENDED
;
1992 active_flags
|= DVF_BUS_SUSPENDED
;
1994 return (dev
->dv_flags
& active_flags
) == DVF_ACTIVE
;
1998 device_is_enabled(device_t dev
)
2000 return (dev
->dv_flags
& DVF_ACTIVE
) == DVF_ACTIVE
;
2004 device_has_power(device_t dev
)
2008 active_flags
= DVF_ACTIVE
| DVF_BUS_SUSPENDED
;
2010 return (dev
->dv_flags
& active_flags
) == DVF_ACTIVE
;
2014 device_locator(device_t dev
, u_int locnum
)
2017 KASSERT(dev
->dv_locators
!= NULL
);
2018 return dev
->dv_locators
[locnum
];
2022 device_private(device_t dev
)
2026 * The reason why device_private(NULL) is allowed is to simplify the
2027 * work of a lot of userspace request handlers (i.e., c/bdev
2028 * handlers) which grab cfdriver_t->cd_units[n].
2029 * It avoids having them test for it to be NULL and only then calling
2032 return dev
== NULL
? NULL
: dev
->dv_private
;
2036 device_properties(device_t dev
)
2039 return dev
->dv_properties
;
2045 * Returns true if the device is an instance of the specified
2049 device_is_a(device_t dev
, const char *dname
)
2052 return strcmp(dev
->dv_cfdriver
->cd_name
, dname
) == 0;
2056 * device_find_by_xname:
2058 * Returns the device of the given name or NULL if it doesn't exist.
2061 device_find_by_xname(const char *name
)
2066 for (dv
= deviter_first(&di
, 0); dv
!= NULL
; dv
= deviter_next(&di
)) {
2067 if (strcmp(device_xname(dv
), name
) == 0)
2070 deviter_release(&di
);
2076 * device_find_by_driver_unit:
2078 * Returns the device of the given driver name and unit or
2079 * NULL if it doesn't exist.
2082 device_find_by_driver_unit(const char *name
, int unit
)
2084 struct cfdriver
*cd
;
2086 if ((cd
= config_cfdriver_lookup(name
)) == NULL
)
2088 return device_lookup(cd
, unit
);
2092 * Power management related functions.
2096 device_pmf_is_registered(device_t dev
)
2098 return (dev
->dv_flags
& DVF_POWER_HANDLERS
) != 0;
2102 device_pmf_driver_suspend(device_t dev
, pmf_qual_t qual
)
2104 if ((dev
->dv_flags
& DVF_DRIVER_SUSPENDED
) != 0)
2106 if ((dev
->dv_flags
& DVF_CLASS_SUSPENDED
) == 0)
2108 if (pmf_qual_depth(qual
) <= DEVACT_LEVEL_DRIVER
&&
2109 dev
->dv_driver_suspend
!= NULL
&&
2110 !(*dev
->dv_driver_suspend
)(dev
, qual
))
2113 dev
->dv_flags
|= DVF_DRIVER_SUSPENDED
;
2118 device_pmf_driver_resume(device_t dev
, pmf_qual_t qual
)
2120 if ((dev
->dv_flags
& DVF_DRIVER_SUSPENDED
) == 0)
2122 if ((dev
->dv_flags
& DVF_BUS_SUSPENDED
) != 0)
2124 if (pmf_qual_depth(qual
) <= DEVACT_LEVEL_DRIVER
&&
2125 dev
->dv_driver_resume
!= NULL
&&
2126 !(*dev
->dv_driver_resume
)(dev
, qual
))
2129 dev
->dv_flags
&= ~DVF_DRIVER_SUSPENDED
;
2134 device_pmf_driver_shutdown(device_t dev
, int how
)
2137 if (*dev
->dv_driver_shutdown
!= NULL
&&
2138 !(*dev
->dv_driver_shutdown
)(dev
, how
))
2144 device_pmf_driver_register(device_t dev
,
2145 bool (*suspend
)(device_t
, pmf_qual_t
),
2146 bool (*resume
)(device_t
, pmf_qual_t
),
2147 bool (*shutdown
)(device_t
, int))
2149 dev
->dv_driver_suspend
= suspend
;
2150 dev
->dv_driver_resume
= resume
;
2151 dev
->dv_driver_shutdown
= shutdown
;
2152 dev
->dv_flags
|= DVF_POWER_HANDLERS
;
2159 if (curlwp
->l_name
!= NULL
)
2160 return curlwp
->l_name
;
2162 return curlwp
->l_proc
->p_comm
;
2166 device_pmf_driver_deregister(device_t dev
)
2168 device_lock_t dvl
= device_getlock(dev
);
2170 dev
->dv_driver_suspend
= NULL
;
2171 dev
->dv_driver_resume
= NULL
;
2173 mutex_enter(&dvl
->dvl_mtx
);
2174 dev
->dv_flags
&= ~DVF_POWER_HANDLERS
;
2175 while (dvl
->dvl_nlock
> 0 || dvl
->dvl_nwait
> 0) {
2176 /* Wake a thread that waits for the lock. That
2177 * thread will fail to acquire the lock, and then
2178 * it will wake the next thread that waits for the
2179 * lock, or else it will wake us.
2181 cv_signal(&dvl
->dvl_cv
);
2182 pmflock_debug(dev
, __func__
, __LINE__
);
2183 cv_wait(&dvl
->dvl_cv
, &dvl
->dvl_mtx
);
2184 pmflock_debug(dev
, __func__
, __LINE__
);
2186 mutex_exit(&dvl
->dvl_mtx
);
2190 device_pmf_driver_child_register(device_t dev
)
2192 device_t parent
= device_parent(dev
);
2194 if (parent
== NULL
|| parent
->dv_driver_child_register
== NULL
)
2196 return (*parent
->dv_driver_child_register
)(dev
);
2200 device_pmf_driver_set_child_register(device_t dev
,
2201 bool (*child_register
)(device_t
))
2203 dev
->dv_driver_child_register
= child_register
;
2207 pmflock_debug(device_t dev
, const char *func
, int line
)
2209 device_lock_t dvl
= device_getlock(dev
);
2211 aprint_debug_dev(dev
, "%s.%d, %s dvl_nlock %d dvl_nwait %d dv_flags %x\n",
2212 func
, line
, curlwp_name(), dvl
->dvl_nlock
, dvl
->dvl_nwait
,
2217 device_pmf_lock1(device_t dev
)
2219 device_lock_t dvl
= device_getlock(dev
);
2221 while (device_pmf_is_registered(dev
) &&
2222 dvl
->dvl_nlock
> 0 && dvl
->dvl_holder
!= curlwp
) {
2224 pmflock_debug(dev
, __func__
, __LINE__
);
2225 cv_wait(&dvl
->dvl_cv
, &dvl
->dvl_mtx
);
2226 pmflock_debug(dev
, __func__
, __LINE__
);
2229 if (!device_pmf_is_registered(dev
)) {
2230 pmflock_debug(dev
, __func__
, __LINE__
);
2231 /* We could not acquire the lock, but some other thread may
2232 * wait for it, also. Wake that thread.
2234 cv_signal(&dvl
->dvl_cv
);
2238 dvl
->dvl_holder
= curlwp
;
2239 pmflock_debug(dev
, __func__
, __LINE__
);
2244 device_pmf_lock(device_t dev
)
2247 device_lock_t dvl
= device_getlock(dev
);
2249 mutex_enter(&dvl
->dvl_mtx
);
2250 rc
= device_pmf_lock1(dev
);
2251 mutex_exit(&dvl
->dvl_mtx
);
2257 device_pmf_unlock(device_t dev
)
2259 device_lock_t dvl
= device_getlock(dev
);
2261 KASSERT(dvl
->dvl_nlock
> 0);
2262 mutex_enter(&dvl
->dvl_mtx
);
2263 if (--dvl
->dvl_nlock
== 0)
2264 dvl
->dvl_holder
= NULL
;
2265 cv_signal(&dvl
->dvl_cv
);
2266 pmflock_debug(dev
, __func__
, __LINE__
);
2267 mutex_exit(&dvl
->dvl_mtx
);
2271 device_getlock(device_t dev
)
2273 return &dev
->dv_lock
;
2277 device_pmf_bus_private(device_t dev
)
2279 return dev
->dv_bus_private
;
2283 device_pmf_bus_suspend(device_t dev
, pmf_qual_t qual
)
2285 if ((dev
->dv_flags
& DVF_BUS_SUSPENDED
) != 0)
2287 if ((dev
->dv_flags
& DVF_CLASS_SUSPENDED
) == 0 ||
2288 (dev
->dv_flags
& DVF_DRIVER_SUSPENDED
) == 0)
2290 if (pmf_qual_depth(qual
) <= DEVACT_LEVEL_BUS
&&
2291 dev
->dv_bus_suspend
!= NULL
&&
2292 !(*dev
->dv_bus_suspend
)(dev
, qual
))
2295 dev
->dv_flags
|= DVF_BUS_SUSPENDED
;
2300 device_pmf_bus_resume(device_t dev
, pmf_qual_t qual
)
2302 if ((dev
->dv_flags
& DVF_BUS_SUSPENDED
) == 0)
2304 if (pmf_qual_depth(qual
) <= DEVACT_LEVEL_BUS
&&
2305 dev
->dv_bus_resume
!= NULL
&&
2306 !(*dev
->dv_bus_resume
)(dev
, qual
))
2309 dev
->dv_flags
&= ~DVF_BUS_SUSPENDED
;
2314 device_pmf_bus_shutdown(device_t dev
, int how
)
2317 if (*dev
->dv_bus_shutdown
!= NULL
&&
2318 !(*dev
->dv_bus_shutdown
)(dev
, how
))
2324 device_pmf_bus_register(device_t dev
, void *priv
,
2325 bool (*suspend
)(device_t
, pmf_qual_t
),
2326 bool (*resume
)(device_t
, pmf_qual_t
),
2327 bool (*shutdown
)(device_t
, int), void (*deregister
)(device_t
))
2329 dev
->dv_bus_private
= priv
;
2330 dev
->dv_bus_resume
= resume
;
2331 dev
->dv_bus_suspend
= suspend
;
2332 dev
->dv_bus_shutdown
= shutdown
;
2333 dev
->dv_bus_deregister
= deregister
;
2337 device_pmf_bus_deregister(device_t dev
)
2339 if (dev
->dv_bus_deregister
== NULL
)
2341 (*dev
->dv_bus_deregister
)(dev
);
2342 dev
->dv_bus_private
= NULL
;
2343 dev
->dv_bus_suspend
= NULL
;
2344 dev
->dv_bus_resume
= NULL
;
2345 dev
->dv_bus_deregister
= NULL
;
2349 device_pmf_class_private(device_t dev
)
2351 return dev
->dv_class_private
;
2355 device_pmf_class_suspend(device_t dev
, pmf_qual_t qual
)
2357 if ((dev
->dv_flags
& DVF_CLASS_SUSPENDED
) != 0)
2359 if (pmf_qual_depth(qual
) <= DEVACT_LEVEL_CLASS
&&
2360 dev
->dv_class_suspend
!= NULL
&&
2361 !(*dev
->dv_class_suspend
)(dev
, qual
))
2364 dev
->dv_flags
|= DVF_CLASS_SUSPENDED
;
2369 device_pmf_class_resume(device_t dev
, pmf_qual_t qual
)
2371 if ((dev
->dv_flags
& DVF_CLASS_SUSPENDED
) == 0)
2373 if ((dev
->dv_flags
& DVF_BUS_SUSPENDED
) != 0 ||
2374 (dev
->dv_flags
& DVF_DRIVER_SUSPENDED
) != 0)
2376 if (pmf_qual_depth(qual
) <= DEVACT_LEVEL_CLASS
&&
2377 dev
->dv_class_resume
!= NULL
&&
2378 !(*dev
->dv_class_resume
)(dev
, qual
))
2381 dev
->dv_flags
&= ~DVF_CLASS_SUSPENDED
;
2386 device_pmf_class_register(device_t dev
, void *priv
,
2387 bool (*suspend
)(device_t
, pmf_qual_t
),
2388 bool (*resume
)(device_t
, pmf_qual_t
),
2389 void (*deregister
)(device_t
))
2391 dev
->dv_class_private
= priv
;
2392 dev
->dv_class_suspend
= suspend
;
2393 dev
->dv_class_resume
= resume
;
2394 dev
->dv_class_deregister
= deregister
;
2398 device_pmf_class_deregister(device_t dev
)
2400 if (dev
->dv_class_deregister
== NULL
)
2402 (*dev
->dv_class_deregister
)(dev
);
2403 dev
->dv_class_private
= NULL
;
2404 dev
->dv_class_suspend
= NULL
;
2405 dev
->dv_class_resume
= NULL
;
2406 dev
->dv_class_deregister
= NULL
;
2410 device_active(device_t dev
, devactive_t type
)
2414 if (dev
->dv_activity_count
== 0)
2417 for (i
= 0; i
< dev
->dv_activity_count
; ++i
) {
2418 if (dev
->dv_activity_handlers
[i
] == NULL
)
2420 (*dev
->dv_activity_handlers
[i
])(dev
, type
);
2427 device_active_register(device_t dev
, void (*handler
)(device_t
, devactive_t
))
2429 void (**new_handlers
)(device_t
, devactive_t
);
2430 void (**old_handlers
)(device_t
, devactive_t
);
2431 size_t i
, old_size
, new_size
;
2434 old_handlers
= dev
->dv_activity_handlers
;
2435 old_size
= dev
->dv_activity_count
;
2437 for (i
= 0; i
< old_size
; ++i
) {
2438 KASSERT(old_handlers
[i
] != handler
);
2439 if (old_handlers
[i
] == NULL
) {
2440 old_handlers
[i
] = handler
;
2445 new_size
= old_size
+ 4;
2446 new_handlers
= kmem_alloc(sizeof(void *[new_size
]), KM_SLEEP
);
2448 memcpy(new_handlers
, old_handlers
, sizeof(void *[old_size
]));
2449 new_handlers
[old_size
] = handler
;
2450 memset(new_handlers
+ old_size
+ 1, 0,
2451 sizeof(int [new_size
- (old_size
+1)]));
2454 dev
->dv_activity_count
= new_size
;
2455 dev
->dv_activity_handlers
= new_handlers
;
2458 if (old_handlers
!= NULL
)
2459 kmem_free(old_handlers
, sizeof(void * [old_size
]));
2465 device_active_deregister(device_t dev
, void (*handler
)(device_t
, devactive_t
))
2467 void (**old_handlers
)(device_t
, devactive_t
);
2471 old_handlers
= dev
->dv_activity_handlers
;
2472 old_size
= dev
->dv_activity_count
;
2474 for (i
= 0; i
< old_size
; ++i
) {
2475 if (old_handlers
[i
] == handler
)
2477 if (old_handlers
[i
] == NULL
)
2478 return; /* XXX panic? */
2482 return; /* XXX panic? */
2484 for (; i
< old_size
- 1; ++i
) {
2485 if ((old_handlers
[i
] = old_handlers
[i
+ 1]) != NULL
)
2490 dev
->dv_activity_count
= 0;
2491 dev
->dv_activity_handlers
= NULL
;
2493 kmem_free(old_handlers
, sizeof(void *[old_size
]));
2497 old_handlers
[i
] = NULL
;
2500 /* Return true iff the device_t `dev' exists at generation `gen'. */
2502 device_exists_at(device_t dv
, devgen_t gen
)
2504 return (dv
->dv_del_gen
== 0 || dv
->dv_del_gen
> gen
) &&
2505 dv
->dv_add_gen
<= gen
;
2509 deviter_visits(const deviter_t
*di
, device_t dv
)
2511 return device_exists_at(dv
, di
->di_gen
);
2517 * deviter_t: a device iterator. Holds state for a "walk" visiting
2518 * each device_t's in the device tree.
2520 * deviter_init(di, flags): initialize the device iterator `di'
2521 * to "walk" the device tree. deviter_next(di) will return
2522 * the first device_t in the device tree, or NULL if there are
2525 * `flags' is one or more of DEVITER_F_RW, indicating that the
2526 * caller intends to modify the device tree by calling
2527 * config_detach(9) on devices in the order that the iterator
2528 * returns them; DEVITER_F_ROOT_FIRST, asking for the devices
2529 * nearest the "root" of the device tree to be returned, first;
2530 * DEVITER_F_LEAVES_FIRST, asking for the devices furthest from
2531 * the root of the device tree, first; and DEVITER_F_SHUTDOWN,
2532 * indicating both that deviter_init() should not respect any
2533 * locks on the device tree, and that deviter_next(di) may run
2534 * in more than one LWP before the walk has finished.
2536 * Only one DEVITER_F_RW iterator may be in the device tree at
2539 * DEVITER_F_SHUTDOWN implies DEVITER_F_RW.
2541 * Results are undefined if the flags DEVITER_F_ROOT_FIRST and
2542 * DEVITER_F_LEAVES_FIRST are used in combination.
2544 * deviter_first(di, flags): initialize the device iterator `di'
2545 * and return the first device_t in the device tree, or NULL
2546 * if there are no devices. The statement
2548 * dv = deviter_first(di);
2553 * dv = deviter_next(di);
2555 * deviter_next(di): return the next device_t in the device tree,
2556 * or NULL if there are no more devices. deviter_next(di)
2557 * is undefined if `di' was not initialized with deviter_init() or
2560 * deviter_release(di): stops iteration (subsequent calls to
2561 * deviter_next() will return NULL), releases any locks and
2562 * resources held by the device iterator.
2564 * Device iteration does not return device_t's in any particular
2565 * order. An iterator will never return the same device_t twice.
2566 * Device iteration is guaranteed to complete---i.e., if deviter_next(di)
2567 * is called repeatedly on the same `di', it will eventually return
2568 * NULL. It is ok to attach/detach devices during device iteration.
2571 deviter_init(deviter_t
*di
, deviter_flags_t flags
)
2576 memset(di
, 0, sizeof(*di
));
2578 s
= config_alldevs_lock();
2579 if ((flags
& DEVITER_F_SHUTDOWN
) != 0)
2580 flags
|= DEVITER_F_RW
;
2582 if ((flags
& DEVITER_F_RW
) != 0)
2586 di
->di_gen
= alldevs_gen
++;
2587 config_alldevs_unlock(s
);
2589 di
->di_flags
= flags
;
2591 switch (di
->di_flags
& (DEVITER_F_LEAVES_FIRST
|DEVITER_F_ROOT_FIRST
)) {
2592 case DEVITER_F_LEAVES_FIRST
:
2593 TAILQ_FOREACH(dv
, &alldevs
, dv_list
) {
2594 if (!deviter_visits(di
, dv
))
2596 di
->di_curdepth
= MAX(di
->di_curdepth
, dv
->dv_depth
);
2599 case DEVITER_F_ROOT_FIRST
:
2600 TAILQ_FOREACH(dv
, &alldevs
, dv_list
) {
2601 if (!deviter_visits(di
, dv
))
2603 di
->di_maxdepth
= MAX(di
->di_maxdepth
, dv
->dv_depth
);
2614 deviter_reinit(deviter_t
*di
)
2616 if ((di
->di_flags
& DEVITER_F_RW
) != 0)
2617 di
->di_prev
= TAILQ_LAST(&alldevs
, devicelist
);
2619 di
->di_prev
= TAILQ_FIRST(&alldevs
);
2623 deviter_first(deviter_t
*di
, deviter_flags_t flags
)
2625 deviter_init(di
, flags
);
2626 return deviter_next(di
);
2630 deviter_next2(deviter_t
*di
)
2639 if ((di
->di_flags
& DEVITER_F_RW
) != 0)
2640 di
->di_prev
= TAILQ_PREV(dv
, devicelist
, dv_list
);
2642 di
->di_prev
= TAILQ_NEXT(dv
, dv_list
);
2648 deviter_next1(deviter_t
*di
)
2653 dv
= deviter_next2(di
);
2654 } while (dv
!= NULL
&& !deviter_visits(di
, dv
));
2660 deviter_next(deviter_t
*di
)
2664 switch (di
->di_flags
& (DEVITER_F_LEAVES_FIRST
|DEVITER_F_ROOT_FIRST
)) {
2666 return deviter_next1(di
);
2667 case DEVITER_F_LEAVES_FIRST
:
2668 while (di
->di_curdepth
>= 0) {
2669 if ((dv
= deviter_next1(di
)) == NULL
) {
2672 } else if (dv
->dv_depth
== di
->di_curdepth
)
2676 case DEVITER_F_ROOT_FIRST
:
2677 while (di
->di_curdepth
<= di
->di_maxdepth
) {
2678 if ((dv
= deviter_next1(di
)) == NULL
) {
2681 } else if (dv
->dv_depth
== di
->di_curdepth
)
2691 deviter_release(deviter_t
*di
)
2693 bool rw
= (di
->di_flags
& DEVITER_F_RW
) != 0;
2696 s
= config_alldevs_lock();
2701 /* XXX wake a garbage-collection thread */
2702 config_alldevs_unlock(s
);
2706 ifattr_match(const char *snull
, const char *t
)
2708 return (snull
== NULL
) || strcmp(snull
, t
) == 0;
2712 null_childdetached(device_t self
, device_t child
)
2718 sysctl_detach_setup(struct sysctllog
**clog
)
2720 const struct sysctlnode
*node
= NULL
;
2722 sysctl_createv(clog
, 0, NULL
, &node
,
2724 CTLTYPE_NODE
, "kern", NULL
,
2731 sysctl_createv(clog
, 0, &node
, NULL
,
2732 CTLFLAG_PERMANENT
| CTLFLAG_READWRITE
,
2733 CTLTYPE_INT
, "detachall",
2734 SYSCTL_DESCR("Detach all devices at shutdown"),
2735 NULL
, 0, &detachall
, 0,
2736 CTL_CREATE
, CTL_EOL
);