1 /* $NetBSD: device.h,v 1.190 2025/03/19 20:47:49 jakllsch Exp $ */
2 
3 /*
4  * Copyright (c) 2021 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
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  *
16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /*
30  * Copyright (c) 1996, 2000 Christopher G. Demetriou
31  * All rights reserved.
32  *
33  * Redistribution and use in source and binary forms, with or without
34  * modification, are permitted provided that the following conditions
35  * are met:
36  * 1. Redistributions of source code must retain the above copyright
37  *    notice, this list of conditions and the following disclaimer.
38  * 2. Redistributions in binary form must reproduce the above copyright
39  *    notice, this list of conditions and the following disclaimer in the
40  *    documentation and/or other materials provided with the distribution.
41  * 3. All advertising materials mentioning features or use of this software
42  *    must display the following acknowledgement:
43  *          This product includes software developed for the
44  *          NetBSD Project.  See http://www.NetBSD.org/ for
45  *          information about NetBSD.
46  * 4. The name of the author may not be used to endorse or promote products
47  *    derived from this software without specific prior written permission.
48  *
49  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
50  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
51  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
52  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
53  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
54  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
55  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
56  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
57  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
58  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59  *
60  * --(license Id: LICENSE.proto,v 1.1 2000/06/13 21:40:26 cgd Exp )--
61  */
62 
63 /*
64  * Copyright (c) 1992, 1993
65  *        The Regents of the University of California.  All rights reserved.
66  *
67  * This software was developed by the Computer Systems Engineering group
68  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
69  * contributed to Berkeley.
70  *
71  * All advertising materials mentioning features or use of this software
72  * must display the following acknowledgement:
73  *        This product includes software developed by the University of
74  *        California, Lawrence Berkeley Laboratories.
75  *
76  * Redistribution and use in source and binary forms, with or without
77  * modification, are permitted provided that the following conditions
78  * are met:
79  * 1. Redistributions of source code must retain the above copyright
80  *    notice, this list of conditions and the following disclaimer.
81  * 2. Redistributions in binary form must reproduce the above copyright
82  *    notice, this list of conditions and the following disclaimer in the
83  *    documentation and/or other materials provided with the distribution.
84  * 3. Neither the name of the University nor the names of its contributors
85  *    may be used to endorse or promote products derived from this software
86  *    without specific prior written permission.
87  *
88  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
89  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
90  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
91  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
92  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
93  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
94  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
95  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
96  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
97  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
98  * SUCH DAMAGE.
99  *
100  *        @(#)device.h        8.2 (Berkeley) 2/17/94
101  */
102 
103 #ifndef _SYS_DEVICE_H_
104 #define   _SYS_DEVICE_H_
105 
106 #include <sys/device_if.h>
107 #include <sys/evcnt.h>
108 #include <sys/queue.h>
109 
110 #if defined(_KERNEL) || defined(_KMEMUSER)
111 #include <sys/mutex.h>
112 #include <sys/condvar.h>
113 #include <sys/pmf.h>
114 #endif
115 
116 #include <prop/proplib.h>
117 
118 /*
119  * Minimal device structures.
120  * Note that all ``system'' device types are listed here.
121  */
122 typedef enum devclass {
123           DV_DULL,            /* generic, no special info */
124           DV_CPU,                       /* CPU (carries resource utilization) */
125           DV_DISK,            /* disk drive (label, etc) */
126           DV_IFNET,           /* network interface */
127           DV_TAPE,            /* tape device */
128           DV_TTY,                       /* serial line interface (?) */
129           DV_AUDIODEV,                  /* audio device */
130           DV_DISPLAYDEV,                /* display device */
131           DV_BUS,                       /* bus device */
132           DV_VIRTUAL,                   /* unbacked virtual device */
133 } devclass_t;
134 
135 /*
136  * Actions for ca_activate.
137  */
138 typedef enum devact {
139           DVACT_DEACTIVATE    /* deactivate the device */
140 } devact_t;
141 
142 typedef enum {
143           DVA_SYSTEM,
144           DVA_HARDWARE
145 } devactive_t;
146 
147 typedef struct cfdata *cfdata_t;
148 typedef struct cfdriver *cfdriver_t;
149 typedef struct cfattach *cfattach_t;
150 
151 #if defined(_KERNEL) || defined(_KMEMUSER) || defined(_STANDALONE)
152 /*
153  * devhandle_t --
154  *
155  *        This is an abstraction of the device handles used by ACPI,
156  *        OpenFirmware, and others, to support device enumeration and
157  *        device tree linkage.  A devhandle_t can be safely passed
158  *        by value.
159  */
160 struct devhandle {
161           const struct devhandle_impl * impl;
162           union {
163                     /*
164                      * Storage for the device handle.  Which storage field
165                      * is used is at the sole discretion of the type
166                      * implementation.
167                      */
168                     void *                        pointer;
169                     const void *                  const_pointer;
170                     uintptr_t           uintptr;
171                     intptr_t            integer;
172           };
173 };
174 typedef struct devhandle devhandle_t;
175 #endif
176 
177 #if defined(_KERNEL) || defined(_KMEMUSER)
178 struct device_compatible_entry {
179           union {
180                     const char *compat;
181                     uintptr_t id;
182           };
183           union {
184                     const void *data;
185                     uintptr_t value;
186           };
187 };
188 
189 #define   DEVICE_COMPAT_EOL   { .compat = NULL }
190 
191 struct device_suspensor {
192           const device_suspensor_t      *ds_delegator;
193           char                                    ds_name[32];
194 };
195 
196 struct device_garbage {
197           device_t  *dg_devs;
198           int                 dg_ndevs;
199 };
200 
201 
202 typedef enum {
203           /* Used to represent invalid states. */
204           DEVHANDLE_TYPE_INVALID                  =         0,
205 
206           /* ACPI */
207           DEVHANDLE_TYPE_ACPI           =         0x41435049,         /* 'ACPI' */
208 
209           /* OpenFirmware, FDT */
210           DEVHANDLE_TYPE_OF             =         0x4f504657,         /* 'OPFW' */
211 
212           /* Sun OpenBoot */
213           DEVHANDLE_TYPE_OPENBOOT                 =         0x4f504254,         /* 'OPBT' */
214 
215           /* Private (opaque data) */
216           DEVHANDLE_TYPE_PRIVATE                  =         0x50525654,         /* 'PRVT' */
217 
218           /* Max value. */
219           DEVHANDLE_TYPE_MAX            =         0xffffffff
220 } devhandle_type_t;
221 
222 /* Device method call function signature. */
223 typedef int (*device_call_t)(device_t, devhandle_t, void *);
224 
225 struct device_call_descriptor {
226           const char *name;
227           device_call_t call;
228 };
229 
230 #define   _DEVICE_CALL_REGISTER(_g_, _c_)                                                 \
231           __link_set_add_rodata(_g_, __CONCAT(_c_,_descriptor));
232 #define   DEVICE_CALL_REGISTER(_g_, _n_, _c_)                                   \
233 static const struct device_call_descriptor __CONCAT(_c_,_descriptor) = {\
234           .name = (_n_), .call = (_c_)                                          \
235 };                                                                                        \
236 _DEVICE_CALL_REGISTER(_g_, _c_)
237 
238 struct devhandle_impl {
239           devhandle_type_t              type;
240           const struct devhandle_impl * super;
241           device_call_t                           (*lookup_device_call)(devhandle_t,
242                                                       const char *, devhandle_t *);
243 };
244 
245 /* Max size of a device external name (including terminating NUL) */
246 #define   DEVICE_XNAME_SIZE   16
247 
248 struct device;
249 
250 /*
251  * struct cfattach::ca_flags (must not overlap with device_impl.h
252  * struct device::dv_flags for now)
253  */
254 #define   DVF_PRIV_ALLOC                0x0002    /* device private storage != device */
255 #define   DVF_DETACH_SHUTDOWN 0x0080    /* device detaches safely at shutdown */
256 
257 #ifdef _KERNEL
258 TAILQ_HEAD(devicelist, device);
259 #endif
260 
261 enum deviter_flags {
262             DEVITER_F_RW =              0x1
263           , DEVITER_F_SHUTDOWN =                  0x2
264           , DEVITER_F_LEAVES_FIRST =    0x4
265           , DEVITER_F_ROOT_FIRST =      0x8
266 };
267 
268 typedef enum deviter_flags deviter_flags_t;
269 
270 struct deviter {
271           device_t  di_prev;
272           deviter_flags_t     di_flags;
273           int                 di_curdepth;
274           int                 di_maxdepth;
275           devgen_t  di_gen;
276 };
277 
278 typedef struct deviter deviter_t;
279 
280 struct shutdown_state {
281           bool initialized;
282           deviter_t di;
283 };
284 #endif
285 
286 /*
287  * Description of a locator, as part of interface attribute definitions.
288  */
289 struct cflocdesc {
290           const char *cld_name;
291           const char *cld_defaultstr; /* NULL if no default */
292           int cld_default;
293 };
294 
295 /*
296  * Description of an interface attribute, provided by potential
297  * parent device drivers, referred to by child device configuration data.
298  */
299 struct cfiattrdata {
300           const char *ci_name;
301           int ci_loclen;
302           const struct cflocdesc ci_locdesc[
303 #if defined(__GNUC__) && __GNUC__ <= 2
304                     0
305 #endif
306           ];
307 };
308 
309 /*
310  * Description of a configuration parent.  Each device attachment attaches
311  * to an "interface attribute", which is given in this structure.  The parent
312  * *must* carry this attribute.  Optionally, an individual device instance
313  * may also specify a specific parent device instance.
314  */
315 struct cfparent {
316           const char *cfp_iattr;                  /* interface attribute */
317           const char *cfp_parent;                 /* optional specific parent */
318           int cfp_unit;                           /* optional specific unit
319                                                      (DVUNIT_ANY to wildcard) */
320 };
321 
322 /*
323  * Configuration data (i.e., data placed in ioconf.c).
324  */
325 struct cfdata {
326           const char *cf_name;                    /* driver name */
327           const char *cf_atname;                  /* attachment name */
328           unsigned int cf_unit:24;      /* unit number */
329           unsigned char cf_fstate;      /* finding state (below) */
330           int       *cf_loc;            /* locators (machine dependent) */
331           int       cf_flags;           /* flags from config */
332           const struct cfparent *cf_pspec;/* parent specification */
333 };
334 #define FSTATE_NOTFOUND                 0         /* has not been found */
335 #define   FSTATE_FOUND                  1         /* has been found */
336 #define   FSTATE_STAR                   2         /* duplicable */
337 #define FSTATE_DSTAR                    3         /* has not been found, and disabled */
338 #define FSTATE_DNOTFOUND      4         /* duplicate, and disabled */
339 
340 /*
341  * Multiple configuration data tables may be maintained.  This structure
342  * provides the linkage.
343  */
344 struct cftable {
345           cfdata_t  ct_cfdata;          /* pointer to cfdata table */
346           TAILQ_ENTRY(cftable) ct_list; /* list linkage */
347 };
348 #ifdef _KERNEL
349 TAILQ_HEAD(cftablelist, cftable);
350 #endif
351 
352 typedef int (*cfsubmatch_t)(device_t, cfdata_t, const int *, void *);
353 typedef int (*cfsearch_t)(device_t, cfdata_t, const int *, void *);
354 
355 /*
356  * `configuration' attachment and driver (what the machine-independent
357  * autoconf uses).  As devices are found, they are applied against all
358  * the potential matches.  The one with the best match is taken, and a
359  * device structure (plus any other data desired) is allocated.  Pointers
360  * to these are placed into an array of pointers.  The array itself must
361  * be dynamic since devices can be found long after the machine is up
362  * and running.
363  *
364  * Devices can have multiple configuration attachments if they attach
365  * to different attributes (busses, or whatever), to allow specification
366  * of multiple match and attach functions.  There is only one configuration
367  * driver per driver, so that things like unit numbers and the device
368  * structure array will be shared.
369  */
370 struct cfattach {
371           const char *ca_name;                    /* name of attachment */
372           LIST_ENTRY(cfattach) ca_list; /* link on cfdriver's list */
373           size_t      ca_devsize;                 /* size of dev data (for alloc) */
374           int         ca_flags;                   /* flags for driver allocation etc */
375           int       (*ca_match)(device_t, cfdata_t, void *);
376           void      (*ca_attach)(device_t, device_t, void *);
377           int       (*ca_detach)(device_t, int);
378           int       (*ca_activate)(device_t, devact_t);
379           /* technically, the next 2 belong into "struct cfdriver" */
380           int       (*ca_rescan)(device_t, const char *,
381                                    const int *); /* scan for new children */
382           void      (*ca_childdetached)(device_t, device_t);
383 };
384 LIST_HEAD(cfattachlist, cfattach);
385 
386 #define   CFATTACH_DECL3_NEW(name, ddsize, matfn, attfn, detfn, actfn, \
387           rescanfn, chdetfn, __flags) \
388 struct cfattach __CONCAT(name,_ca) = {                                          \
389           .ca_name            = ___STRING(name),                      \
390           .ca_devsize                   = ddsize,                               \
391           .ca_flags           = (__flags) | DVF_PRIV_ALLOC,           \
392           .ca_match                     = matfn,                                \
393           .ca_attach                    = attfn,                                \
394           .ca_detach                    = detfn,                                \
395           .ca_activate                  = actfn,                                \
396           .ca_rescan                    = rescanfn,                                       \
397           .ca_childdetached   = chdetfn,                                        \
398 }
399 
400 #define   CFATTACH_DECL2_NEW(name, ddsize, matfn, attfn, detfn, actfn,          \
401           rescanfn, chdetfn)                                                    \
402           CFATTACH_DECL3_NEW(name, ddsize, matfn, attfn, detfn, actfn,          \
403               rescanfn, chdetfn, 0)
404 
405 #define   CFATTACH_DECL_NEW(name, ddsize, matfn, attfn, detfn, actfn) \
406           CFATTACH_DECL2_NEW(name, ddsize, matfn, attfn, detfn, actfn, NULL, NULL)
407 
408 /* Flags given to config_detach(), and the ca_detach function. */
409 #define   DETACH_FORCE        0x01                /* force detachment; hardware gone */
410 #define   DETACH_QUIET        0x02                /* don't print a notice */
411 #define   DETACH_SHUTDOWN     0x04                /* detach because of system shutdown */
412 #define   DETACH_POWEROFF     0x08                /* going to power off; power down devices */
413 
414 struct cfdriver {
415           LIST_ENTRY(cfdriver) cd_list; /* link on allcfdrivers */
416           struct cfattachlist cd_attach;          /* list of all attachments */
417           device_t *cd_devs;            /* devices found */
418           const char *cd_name;                    /* device name */
419           enum      devclass cd_class;  /* device classification */
420           int       cd_ndevs;           /* size of cd_devs array */
421           const struct cfiattrdata * const *cd_attrs; /* attributes provided */
422 };
423 LIST_HEAD(cfdriverlist, cfdriver);
424 
425 #define   CFDRIVER_DECL(name, class, attrs)                                     \
426 struct cfdriver __CONCAT(name,_cd) = {                                          \
427           .cd_name            = ___STRING(name),                      \
428           .cd_class           = class,                                \
429           .cd_attrs           = attrs,                                \
430 }
431 
432 /*
433  * The cfattachinit is a data structure used to associate a list of
434  * cfattach's with cfdrivers as found in the static kernel configuration.
435  */
436 struct cfattachinit {
437           const char *cfai_name;                   /* driver name */
438           struct cfattach * const *cfai_list;/* list of attachments */
439 };
440 
441 /*
442  * Configuration printing functions, and their return codes.  The second
443  * argument is NULL if the device was configured; otherwise it is the name
444  * of the parent device.  The return value is ignored if the device was
445  * configured, so most functions can return UNCONF unconditionally.
446  */
447 typedef int (*cfprint_t)(void *, const char *);             /* XXX const char * */
448 #define   QUIET     0                   /* print nothing */
449 #define   UNCONF    1                   /* print " not configured\n" */
450 #define   UNSUPP    2                   /* print " not supported\n" */
451 
452 /*
453  * Pseudo-device attach information (function + number of pseudo-devs).
454  */
455 struct pdevinit {
456           void      (*pdev_attach)(int);
457           int       pdev_count;
458 };
459 
460 /* This allows us to wildcard a device unit. */
461 #define   DVUNIT_ANY          -1
462 
463 #if defined(_KERNEL) || defined(_KMEMUSER) || defined(_STANDALONE)
464 /*
465  * Arguments passed to config_search() and config_found().
466  */
467 struct cfargs {
468           uintptr_t cfargs_version;     /* version field */
469 
470           /* version 1 fields */
471           cfsubmatch_t        submatch; /* submatch function (direct config) */
472           cfsearch_t          search;             /* search function (indirect config) */
473           const char *        iattr;              /* interface attribute */
474           const int *         locators; /* locators array */
475           devhandle_t         devhandle;          /* devhandle_t (by value) */
476 
477           /* version 2 fields below here */
478 };
479 
480 #define   CFARGS_VERSION                1         /* current cfargs version */
481 
482 #define   CFARGS_NONE                   NULL      /* no cfargs to pass */
483 
484 /*
485  * Construct a cfargs with this macro, like so:
486  *
487  *        CFARGS(.submatch = config_stdsubmatch,
488  *               .devhandle = my_devhandle)
489  *
490  * You must supply at least one field.  If you don't need any, use the
491  * CFARGS_NONE macro.
492  */
493 #define   CFARGS(...)                                                                     \
494           &((const struct cfargs){                                              \
495                     .cfargs_version = CFARGS_VERSION,                           \
496                     __VA_ARGS__                                                           \
497           })
498 #endif /* _KERNEL || _KMEMUSER || _STANDALONE */
499 
500 #ifdef _KERNEL
501 
502 extern struct cfdriverlist allcfdrivers;/* list of all cfdrivers */
503 extern struct cftablelist allcftables;  /* list of all cfdata tables */
504 extern device_t booted_device;                    /* the device we booted from */
505 extern const char *booted_method;       /* the method the device was found */
506 extern int booted_partition;            /* the partition on that device */
507 extern daddr_t booted_startblk;                   /* or the start of a wedge */
508 extern uint64_t booted_nblks;           /* and the size of that wedge */
509 extern char *bootspec;                            /* and the device/wedge name */
510 extern bool root_is_mounted;            /* true if root is mounted */
511 
512 struct vnode *opendisk(device_t);
513 int getdisksize(struct vnode *, uint64_t *, unsigned int *);
514 struct dkwedge_info;
515 int getdiskinfo(struct vnode *, struct dkwedge_info *);
516 
517 void      config_init(void);
518 int       config_init_component(struct cfdriver *const*,
519                                     const struct cfattachinit *, struct cfdata *);
520 int       config_fini_component(struct cfdriver *const*,
521                                     const struct cfattachinit *, struct cfdata *);
522 void      config_init_mi(void);
523 void      drvctl_init(void);
524 void      drvctl_fini(void);
525 extern    int (*devmon_insert_vec)(const char *, prop_dictionary_t);
526 
527 int       config_cfdriver_attach(struct cfdriver *);
528 int       config_cfdriver_detach(struct cfdriver *);
529 
530 int       config_cfattach_attach(const char *, struct cfattach *);
531 int       config_cfattach_detach(const char *, struct cfattach *);
532 
533 int       config_cfdata_attach(cfdata_t, int);
534 int       config_cfdata_detach(cfdata_t);
535 
536 struct cfdriver *config_cfdriver_lookup(const char *);
537 struct cfattach *config_cfattach_lookup(const char *, const char *);
538 const struct cfiattrdata *cfiattr_lookup(const char *, const struct cfdriver *);
539 
540 const char *cfdata_ifattr(const struct cfdata *);
541 
542 int       config_stdsubmatch(device_t, cfdata_t, const int *, void *);
543 cfdata_t config_search(device_t, void *, const struct cfargs *);
544 cfdata_t config_rootsearch(cfsubmatch_t, const char *, void *);
545 device_t config_found(device_t, void *, cfprint_t, const struct cfargs *);
546 device_t config_rootfound(const char *, void *);
547 device_t config_attach(device_t, cfdata_t, void *, cfprint_t,
548               const struct cfargs *);
549 device_t config_found_acquire(device_t, void *, cfprint_t,
550               const struct cfargs *);
551 device_t config_attach_acquire(device_t, cfdata_t, void *, cfprint_t,
552               const struct cfargs *);
553 int       config_match(device_t, cfdata_t, void *);
554 int       config_probe(device_t, cfdata_t, void *);
555 
556 bool      ifattr_match(const char *, const char *);
557 
558 device_t config_attach_pseudo(cfdata_t);
559 device_t config_attach_pseudo_acquire(cfdata_t, void *);
560 
561 int       config_detach(device_t, int);
562 int       config_detach_release(device_t, int);
563 int       config_detach_children(device_t, int flags);
564 void      config_detach_commit(device_t);
565 bool      config_detach_all(int);
566 int       config_deactivate(device_t);
567 void      config_defer(device_t, void (*)(device_t));
568 void      config_deferred(device_t);
569 void      config_interrupts(device_t, void (*)(device_t));
570 void      config_mountroot(device_t, void (*)(device_t));
571 void      config_pending_incr(device_t);
572 void      config_pending_decr(device_t);
573 void      config_create_interruptthreads(void);
574 void      config_create_mountrootthreads(void);
575 
576 int       config_finalize_register(device_t, int (*)(device_t));
577 void      config_finalize(void);
578 void      config_finalize_mountroot(void);
579 
580 void      config_twiddle_init(void);
581 void      config_twiddle_fn(void *);
582 
583 void      null_childdetached(device_t, device_t);
584 
585 device_t  device_lookup(cfdriver_t, int);
586 void                *device_lookup_private(cfdriver_t, int);
587 
588 device_t  device_lookup_acquire(cfdriver_t, int);
589 void                device_acquire(device_t);
590 void                device_release(device_t);
591 
592 void                device_register(device_t, void *);
593 void                device_register_post_config(device_t, void *);
594 
595 devclass_t          device_class(device_t);
596 cfdata_t  device_cfdata(device_t);
597 cfdriver_t          device_cfdriver(device_t);
598 cfattach_t          device_cfattach(device_t);
599 int                 device_unit(device_t);
600 const char          *device_xname(device_t);
601 device_t  device_parent(device_t);
602 bool                device_is_active(device_t);
603 bool                device_activation(device_t, devact_level_t);
604 bool                device_is_enabled(device_t);
605 bool                device_has_power(device_t);
606 int                 device_locator(device_t, u_int);
607 void                *device_private(device_t);
608 void                device_set_private(device_t, void *);
609 prop_dictionary_t device_properties(device_t);
610 void                device_set_handle(device_t, devhandle_t);
611 devhandle_t         device_handle(device_t);
612 
613 bool                devhandle_is_valid(devhandle_t);
614 devhandle_t         devhandle_invalid(void);
615 devhandle_type_t devhandle_type(devhandle_t);
616 int                 devhandle_compare(devhandle_t, devhandle_t);
617 devhandle_t         devhandle_subclass(devhandle_t, struct devhandle_impl *,
618                         device_call_t (*)(devhandle_t, const char *,
619                                               devhandle_t *));
620 
621 device_call_t       devhandle_lookup_device_call(devhandle_t, const char *,
622                         devhandle_t *);
623 void                devhandle_impl_subclass(struct devhandle_impl *,
624                         const struct devhandle_impl *,
625                         device_call_t (*)(devhandle_t, const char *,
626                                               devhandle_t *));
627 
628 device_t  deviter_first(deviter_t *, deviter_flags_t);
629 void                deviter_init(deviter_t *, deviter_flags_t);
630 device_t  deviter_next(deviter_t *);
631 void                deviter_release(deviter_t *);
632 
633 bool                device_active(device_t, devactive_t);
634 bool                device_active_register(device_t,
635                                                void (*)(device_t, devactive_t));
636 void                device_active_deregister(device_t,
637                                                  void (*)(device_t, devactive_t));
638 
639 bool                device_is_a(device_t, const char *);
640 bool                device_attached_to_iattr(device_t, const char *);
641 
642 device_t  device_find_by_xname(const char *);
643 device_t  device_find_by_driver_unit(const char *, int);
644 
645 int                 device_enumerate_children(device_t,
646                         bool (*)(device_t, devhandle_t, void *), void *);
647 
648 int                 device_compatible_match(const char **, int,
649                                         const struct device_compatible_entry *);
650 int                 device_compatible_pmatch(const char **, int,
651                                         const struct device_compatible_entry *);
652 const struct device_compatible_entry *
653                     device_compatible_lookup(const char **, int,
654                                         const struct device_compatible_entry *);
655 const struct device_compatible_entry *
656                     device_compatible_plookup(const char **, int,
657                                         const struct device_compatible_entry *);
658 
659 int                 device_compatible_match_strlist(const char *, size_t,
660                                         const struct device_compatible_entry *);
661 int                 device_compatible_pmatch_strlist(const char *, size_t,
662                                         const struct device_compatible_entry *);
663 const struct device_compatible_entry *
664                     device_compatible_lookup_strlist(const char *, size_t,
665                                         const struct device_compatible_entry *);
666 const struct device_compatible_entry *
667                     device_compatible_plookup_strlist(const char *, size_t,
668                                         const struct device_compatible_entry *);
669 
670 int                 device_compatible_match_id(uintptr_t const, uintptr_t const,
671                                         const struct device_compatible_entry *);
672 const struct device_compatible_entry *
673                     device_compatible_lookup_id(uintptr_t const, uintptr_t const,
674                                         const struct device_compatible_entry *);
675 
676 void                device_pmf_driver_child_register(device_t);
677 void                device_pmf_driver_set_child_register(device_t,
678                         void (*)(device_t));
679 
680 void                *device_pmf_bus_private(device_t);
681 bool                device_pmf_bus_suspend(device_t, const pmf_qual_t *);
682 bool                device_pmf_bus_resume(device_t, const pmf_qual_t *);
683 bool                device_pmf_bus_shutdown(device_t, int);
684 
685 void                device_pmf_bus_register(device_t, void *,
686                         bool (*)(device_t, const pmf_qual_t *),
687                         bool (*)(device_t, const pmf_qual_t *),
688                         bool (*)(device_t, int),
689                         void (*)(device_t));
690 void                device_pmf_bus_deregister(device_t);
691 
692 device_t  shutdown_first(struct shutdown_state *);
693 device_t  shutdown_next(struct shutdown_state *);
694 
695 /*
696  * device calls --
697  *
698  * This provides a generic mechanism for invoking special methods on
699  * devices, often dependent on the device tree implementation used
700  * by the platform.
701  *
702  * While individual subsystems may define their own device calls,
703  * the ones prefixed with "device-" are reserved, and defined by
704  * the device autoconfiguration subsystem.  It is the responsibility
705  * of each device tree back end to implement these calls.
706  *
707  * We define a generic interface; individual device calls feature
708  * type checking of the argument structure.  The argument structures
709  * and the call binding data are automatically generated from device
710  * call interface descriptions by gendevcalls.awk.
711  */
712 struct device_call_generic {
713           const char *name;
714           void *args;
715 };
716 
717 int                 device_call_generic(device_t, devhandle_t,
718                         const struct device_call_generic *);
719 
720 #define   device_call(dev, call)                                                          \
721           device_call_generic((dev), device_handle(dev), &(call)->generic)
722 #define   devhandle_call(handle, call)                                          \
723           device_call_generic(NULL, (handle), &(call)->generic)
724 
725 #endif /* _KERNEL */
726 
727 #endif /* !_SYS_DEVICE_H_ */
728