Home | History | Annotate | Line # | Download | only in sys
      1 /* $NetBSD: device.h,v 1.194 2026/05/26 14:50:52 simonb 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 #define	SYSDFLT_DEVICE_CALL_REGISTER(_n_, _c_)				\
    239 	DEVICE_CALL_REGISTER(sysdflt_device_calls, _n_, _c_)
    240 
    241 struct devhandle_impl {
    242 	devhandle_type_t		type;
    243 	const struct devhandle_impl *	super;
    244 	device_call_t			(*lookup_device_call)(devhandle_t,
    245 					    const char *, devhandle_t *);
    246 };
    247 
    248 /* Max size of a device external name (including terminating NUL) */
    249 #define	DEVICE_XNAME_SIZE	16
    250 
    251 struct device;
    252 
    253 /*
    254  * struct cfattach::ca_flags (must not overlap with device_impl.h
    255  * struct device::dv_flags for now)
    256  */
    257 #define	DVF_PRIV_ALLOC		0x0002	/* device private storage != device */
    258 #define	DVF_DETACH_SHUTDOWN	0x0080	/* device detaches safely at shutdown */
    259 #define	DVF_NO_PARTITIONS	0x0100	/* (disk) device doesn't have partitions */
    260 
    261 #ifdef _KERNEL
    262 TAILQ_HEAD(devicelist, device);
    263 #endif
    264 
    265 enum deviter_flags {
    266 	  DEVITER_F_RW =		0x1
    267 	, DEVITER_F_SHUTDOWN =		0x2
    268 	, DEVITER_F_LEAVES_FIRST =	0x4
    269 	, DEVITER_F_ROOT_FIRST =	0x8
    270 };
    271 
    272 typedef enum deviter_flags deviter_flags_t;
    273 
    274 struct deviter {
    275 	device_t	di_prev;
    276 	deviter_flags_t	di_flags;
    277 	int		di_curdepth;
    278 	int		di_maxdepth;
    279 	devgen_t	di_gen;
    280 };
    281 
    282 typedef struct deviter deviter_t;
    283 
    284 struct shutdown_state {
    285 	bool initialized;
    286 	deviter_t di;
    287 };
    288 #endif
    289 
    290 /*
    291  * Description of a locator, as part of interface attribute definitions.
    292  */
    293 struct cflocdesc {
    294 	const char *cld_name;
    295 	const char *cld_defaultstr; /* NULL if no default */
    296 	int cld_default;
    297 };
    298 
    299 /*
    300  * Description of an interface attribute, provided by potential
    301  * parent device drivers, referred to by child device configuration data.
    302  */
    303 struct cfiattrdata {
    304 	const char *ci_name;
    305 	int ci_loclen;
    306 	const struct cflocdesc ci_locdesc[
    307 #if defined(__GNUC__) && __GNUC__ <= 2
    308 		0
    309 #endif
    310 	];
    311 };
    312 
    313 /*
    314  * Description of a configuration parent.  Each device attachment attaches
    315  * to an "interface attribute", which is given in this structure.  The parent
    316  * *must* carry this attribute.  Optionally, an individual device instance
    317  * may also specify a specific parent device instance.
    318  */
    319 struct cfparent {
    320 	const char *cfp_iattr;		/* interface attribute */
    321 	const char *cfp_parent;		/* optional specific parent */
    322 	int cfp_unit;			/* optional specific unit
    323 					   (DVUNIT_ANY to wildcard) */
    324 };
    325 
    326 /*
    327  * Configuration data (i.e., data placed in ioconf.c).
    328  */
    329 struct cfdata {
    330 	const char *cf_name;		/* driver name */
    331 	const char *cf_atname;		/* attachment name */
    332 	unsigned int cf_unit:24;	/* unit number */
    333 	unsigned char cf_fstate;	/* finding state (below) */
    334 	int	*cf_loc;		/* locators (machine dependent) */
    335 	int	cf_flags;		/* flags from config */
    336 	const struct cfparent *cf_pspec;/* parent specification */
    337 };
    338 #define FSTATE_NOTFOUND		0	/* has not been found */
    339 #define	FSTATE_FOUND		1	/* has been found */
    340 #define	FSTATE_STAR		2	/* duplicable */
    341 #define FSTATE_DSTAR		3	/* has not been found, and disabled */
    342 #define FSTATE_DNOTFOUND	4	/* duplicate, and disabled */
    343 
    344 /*
    345  * Multiple configuration data tables may be maintained.  This structure
    346  * provides the linkage.
    347  */
    348 struct cftable {
    349 	cfdata_t	ct_cfdata;	/* pointer to cfdata table */
    350 	TAILQ_ENTRY(cftable) ct_list;	/* list linkage */
    351 };
    352 #ifdef _KERNEL
    353 TAILQ_HEAD(cftablelist, cftable);
    354 #endif
    355 
    356 typedef int (*cfsubmatch_t)(device_t, cfdata_t, const int *, void *);
    357 typedef int (*cfsearch_t)(device_t, cfdata_t, const int *, void *);
    358 
    359 /*
    360  * `configuration' attachment and driver (what the machine-independent
    361  * autoconf uses).  As devices are found, they are applied against all
    362  * the potential matches.  The one with the best match is taken, and a
    363  * device structure (plus any other data desired) is allocated.  Pointers
    364  * to these are placed into an array of pointers.  The array itself must
    365  * be dynamic since devices can be found long after the machine is up
    366  * and running.
    367  *
    368  * Devices can have multiple configuration attachments if they attach
    369  * to different attributes (busses, or whatever), to allow specification
    370  * of multiple match and attach functions.  There is only one configuration
    371  * driver per driver, so that things like unit numbers and the device
    372  * structure array will be shared.
    373  */
    374 struct cfattach {
    375 	const char *ca_name;		/* name of attachment */
    376 	LIST_ENTRY(cfattach) ca_list;	/* link on cfdriver's list */
    377 	size_t	  ca_devsize;		/* size of dev data (for alloc) */
    378 	int	  ca_flags;		/* flags for driver allocation etc */
    379 	int	(*ca_match)(device_t, cfdata_t, void *);
    380 	void	(*ca_attach)(device_t, device_t, void *);
    381 	int	(*ca_detach)(device_t, int);
    382 	int	(*ca_activate)(device_t, devact_t);
    383 	/* technically, the next 2 belong into "struct cfdriver" */
    384 	int	(*ca_rescan)(device_t, const char *,
    385 			     const int *); /* scan for new children */
    386 	void	(*ca_childdetached)(device_t, device_t);
    387 };
    388 LIST_HEAD(cfattachlist, cfattach);
    389 
    390 #define	CFATTACH_DECL3_NEW(name, ddsize, matfn, attfn, detfn, actfn, \
    391 	rescanfn, chdetfn, __flags) \
    392 struct cfattach __CONCAT(name,_ca) = {					\
    393 	.ca_name		= ___STRING(name),			\
    394 	.ca_devsize		= ddsize,				\
    395 	.ca_flags		= (__flags) | DVF_PRIV_ALLOC,		\
    396 	.ca_match 		= matfn,				\
    397 	.ca_attach		= attfn,				\
    398 	.ca_detach		= detfn,				\
    399 	.ca_activate		= actfn,				\
    400 	.ca_rescan		= rescanfn,				\
    401 	.ca_childdetached	= chdetfn,				\
    402 }
    403 
    404 #define	CFATTACH_DECL2_NEW(name, ddsize, matfn, attfn, detfn, actfn,	\
    405 	rescanfn, chdetfn)						\
    406 	CFATTACH_DECL3_NEW(name, ddsize, matfn, attfn, detfn, actfn,	\
    407 	    rescanfn, chdetfn, 0)
    408 
    409 #define	CFATTACH_DECL_NEW(name, ddsize, matfn, attfn, detfn, actfn)	\
    410 	CFATTACH_DECL2_NEW(name, ddsize, matfn, attfn, detfn, actfn, NULL, NULL)
    411 
    412 /* Flags given to config_detach(), and the ca_detach function. */
    413 #define	DETACH_FORCE	0x01		/* force detachment; hardware gone */
    414 #define	DETACH_QUIET	0x02		/* don't print a notice */
    415 #define	DETACH_SHUTDOWN	0x04		/* detach because of system shutdown */
    416 #define	DETACH_POWEROFF	0x08		/* going to power off; power down devices */
    417 
    418 struct cfdriver {
    419 	LIST_ENTRY(cfdriver) cd_list;	/* link on allcfdrivers */
    420 	struct cfattachlist cd_attach;	/* list of all attachments */
    421 	device_t *cd_devs;		/* devices found */
    422 	const char *cd_name;		/* device name */
    423 	enum	devclass cd_class;	/* device classification */
    424 	int	cd_ndevs;		/* size of cd_devs array */
    425 	const struct cfiattrdata * const *cd_attrs; /* attributes provided */
    426 };
    427 LIST_HEAD(cfdriverlist, cfdriver);
    428 
    429 #define	CFDRIVER_DECL(name, class, attrs)				\
    430 struct cfdriver __CONCAT(name,_cd) = {					\
    431 	.cd_name		= ___STRING(name),			\
    432 	.cd_class		= class,				\
    433 	.cd_attrs		= attrs,				\
    434 }
    435 
    436 /*
    437  * The cfattachiattr associates a cfattach (which normally does not
    438  * carry interface attribute information) with a cfiattrdata (because
    439  * in very rare cases, it may need to).
    440  */
    441 struct cfattachiattr {
    442 	LIST_ENTRY(cfattachiattr) cfia_list;  /* entry on global list */
    443 	struct cfattach *cfia_attach;         /* ptr to cfattach */
    444 	const struct cfiattrdata *cfia_iattr; /* associated iattr data */
    445 };
    446 
    447 /*
    448  * The cfattachinit is a data structure used to associate a list of
    449  * cfattach's with cfdrivers as found in the static kernel configuration.
    450  */
    451 struct cfattachinit {
    452 	const char *cfai_name;             /* driver name */
    453 	struct cfattach * const *cfai_list;/* list of attachments */
    454 	                                   /* associated iattrs (if any */
    455 	struct cfattachiattr * const *cfai_iattrs;
    456 };
    457 
    458 /*
    459  * Configuration printing functions, and their return codes.  The second
    460  * argument is NULL if the device was configured; otherwise it is the name
    461  * of the parent device.  The return value is ignored if the device was
    462  * configured, so most functions can return UNCONF unconditionally.
    463  */
    464 typedef int (*cfprint_t)(void *, const char *);		/* XXX const char * */
    465 #define	QUIET	0		/* print nothing */
    466 #define	UNCONF	1		/* print " not configured\n" */
    467 #define	UNSUPP	2		/* print " not supported\n" */
    468 
    469 /*
    470  * Pseudo-device attach information (function + number of pseudo-devs).
    471  */
    472 struct pdevinit {
    473 	void	(*pdev_attach)(int);
    474 	int	pdev_count;
    475 };
    476 
    477 /* This allows us to wildcard a device unit. */
    478 #define	DVUNIT_ANY	-1
    479 
    480 #if defined(_KERNEL) || defined(_KMEMUSER) || defined(_STANDALONE)
    481 /*
    482  * Arguments passed to config_search() and config_found().
    483  */
    484 struct cfargs {
    485 	uintptr_t	cfargs_version;	/* version field */
    486 
    487 	/* version 1 fields */
    488 	cfsubmatch_t	submatch;	/* submatch function (direct config) */
    489 	cfsearch_t	search;		/* search function (indirect config) */
    490 	const char *	iattr;		/* interface attribute */
    491 	const int *	locators;	/* locators array */
    492 	devhandle_t	devhandle;	/* devhandle_t (by value) */
    493 
    494 	/* version 2 fields below here */
    495 };
    496 
    497 #define	CFARGS_VERSION		1	/* current cfargs version */
    498 
    499 #define	CFARGS_NONE		NULL	/* no cfargs to pass */
    500 
    501 /*
    502  * Construct a cfargs with this macro, like so:
    503  *
    504  *	CFARGS(.submatch = config_stdsubmatch,
    505  *	       .devhandle = my_devhandle)
    506  *
    507  * You must supply at least one field.  If you don't need any, use the
    508  * CFARGS_NONE macro.
    509  */
    510 #define	CFARGS(...)							\
    511 	&((const struct cfargs){					\
    512 		.cfargs_version = CFARGS_VERSION,			\
    513 		__VA_ARGS__						\
    514 	})
    515 #endif /* _KERNEL || _KMEMUSER || _STANDALONE */
    516 
    517 #ifdef _KERNEL
    518 
    519 extern struct cfdriverlist allcfdrivers;/* list of all cfdrivers */
    520 extern struct cftablelist allcftables;	/* list of all cfdata tables */
    521 extern device_t booted_device;		/* the device we booted from */
    522 extern const char *booted_method;	/* the method the device was found */
    523 extern int booted_partition;		/* the partition on that device */
    524 extern daddr_t booted_startblk;		/* or the start of a wedge */
    525 extern uint64_t booted_nblks;		/* and the size of that wedge */
    526 extern char *bootspec;			/* and the device/wedge name */
    527 extern bool root_is_mounted;		/* true if root is mounted */
    528 
    529 struct vnode *opendisk(device_t);
    530 int getdisksize(struct vnode *, uint64_t *, unsigned int *);
    531 struct dkwedge_info;
    532 int getdiskinfo(struct vnode *, struct dkwedge_info *);
    533 
    534 void	config_init(void);
    535 int	config_init_component(struct cfdriver *const*,
    536 			      const struct cfattachinit *, struct cfdata *);
    537 int	config_fini_component(struct cfdriver *const*,
    538 			      const struct cfattachinit *, struct cfdata *);
    539 void	config_init_mi(void);
    540 void	drvctl_init(void);
    541 void	drvctl_fini(void);
    542 extern	int (*devmon_insert_vec)(const char *, prop_dictionary_t);
    543 
    544 int	config_cfdriver_attach(struct cfdriver *);
    545 int	config_cfdriver_detach(struct cfdriver *);
    546 
    547 int	config_cfattach_attach(const char *, struct cfattach *);
    548 int	config_cfattach_detach(const char *, struct cfattach *);
    549 
    550 int	config_cfdata_attach(cfdata_t, int);
    551 int	config_cfdata_detach(cfdata_t);
    552 
    553 struct cfdriver *config_cfdriver_lookup(const char *);
    554 struct cfattach *config_cfattach_lookup(const char *, const char *);
    555 const struct cfiattrdata *cfiattr_lookup(const char *, const struct cfdriver *,
    556 					 const struct cfattach *);
    557 
    558 const char *cfdata_ifattr(const struct cfdata *);
    559 
    560 int	config_stdsubmatch(device_t, cfdata_t, const int *, void *);
    561 cfdata_t config_search(device_t, void *, const struct cfargs *);
    562 cfdata_t config_rootsearch(cfsubmatch_t, const char *, void *);
    563 device_t config_found(device_t, void *, cfprint_t, const struct cfargs *);
    564 device_t config_rootfound(const char *, void *);
    565 device_t config_attach(device_t, cfdata_t, void *, cfprint_t,
    566 	    const struct cfargs *);
    567 device_t config_found_acquire(device_t, void *, cfprint_t,
    568 	    const struct cfargs *);
    569 device_t config_attach_acquire(device_t, cfdata_t, void *, cfprint_t,
    570 	    const struct cfargs *);
    571 int	config_match(device_t, cfdata_t, void *);
    572 int	config_probe(device_t, cfdata_t, void *);
    573 
    574 bool	ifattr_match(const char *, const char *);
    575 
    576 device_t config_attach_pseudo(cfdata_t);
    577 device_t config_attach_pseudo_acquire(cfdata_t, void *);
    578 
    579 int	config_detach(device_t, int);
    580 int	config_detach_release(device_t, int);
    581 int	config_detach_children(device_t, int flags);
    582 void	config_detach_commit(device_t);
    583 bool	config_detach_all(int);
    584 int	config_deactivate(device_t);
    585 void	config_defer(device_t, void (*)(device_t));
    586 void	config_deferred(device_t);
    587 void	config_interrupts(device_t, void (*)(device_t));
    588 void	config_mountroot(device_t, void (*)(device_t));
    589 void	config_pending_incr(device_t);
    590 void	config_pending_decr(device_t);
    591 void	config_create_interruptthreads(void);
    592 void	config_create_mountrootthreads(void);
    593 
    594 int	config_finalize_register(device_t, int (*)(device_t));
    595 void	config_finalize(void);
    596 void	config_finalize_mountroot(void);
    597 
    598 void	config_twiddle_init(void);
    599 void	config_twiddle_fn(void *);
    600 
    601 void	null_childdetached(device_t, device_t);
    602 
    603 device_t	device_lookup(cfdriver_t, int);
    604 void		*device_lookup_private(cfdriver_t, int);
    605 
    606 device_t	device_lookup_acquire(cfdriver_t, int);
    607 void		device_acquire(device_t);
    608 void		device_release(device_t);
    609 
    610 void		device_register(device_t, void *);
    611 void		device_register_post_config(device_t, void *);
    612 
    613 devclass_t	device_class(device_t);
    614 cfdata_t	device_cfdata(device_t);
    615 cfdriver_t	device_cfdriver(device_t);
    616 cfattach_t	device_cfattach(device_t);
    617 int		device_unit(device_t);
    618 const char	*device_xname(device_t);
    619 device_t	device_parent(device_t);
    620 bool		device_is_active(device_t);
    621 bool		device_activation(device_t, devact_level_t);
    622 bool		device_is_enabled(device_t);
    623 bool		device_has_partitions(device_t);
    624 bool		device_has_power(device_t);
    625 int		device_locator(device_t, u_int);
    626 void		*device_private(device_t);
    627 void		device_set_private(device_t, void *);
    628 prop_dictionary_t device_properties(device_t);
    629 void		device_set_handle(device_t, devhandle_t);
    630 devhandle_t	device_handle(device_t);
    631 
    632 bool		devhandle_is_valid(devhandle_t);
    633 devhandle_t	devhandle_invalid(void);
    634 devhandle_type_t devhandle_type(devhandle_t);
    635 int		devhandle_compare(devhandle_t, devhandle_t);
    636 devhandle_t	devhandle_subclass(devhandle_t, struct devhandle_impl *,
    637 		    device_call_t (*)(devhandle_t, const char *,
    638 				      devhandle_t *));
    639 
    640 device_call_t	devhandle_lookup_device_call(devhandle_t, const char *,
    641 		    devhandle_t *);
    642 void		devhandle_impl_subclass(struct devhandle_impl *,
    643 		    const struct devhandle_impl *,
    644 		    device_call_t (*)(devhandle_t, const char *,
    645 				      devhandle_t *));
    646 
    647 device_t	deviter_first(deviter_t *, deviter_flags_t);
    648 void		deviter_init(deviter_t *, deviter_flags_t);
    649 device_t	deviter_next(deviter_t *);
    650 void		deviter_release(deviter_t *);
    651 
    652 bool		device_active(device_t, devactive_t);
    653 bool		device_active_register(device_t,
    654 				       void (*)(device_t, devactive_t));
    655 void		device_active_deregister(device_t,
    656 				         void (*)(device_t, devactive_t));
    657 
    658 bool		device_is_a(device_t, const char *);
    659 bool		device_attached_to_iattr(device_t, const char *);
    660 
    661 device_t	device_find_by_xname(const char *);
    662 device_t	device_find_by_driver_unit(const char *, int);
    663 
    664 int		device_enumerate_children(device_t,
    665 		    bool (*)(device_t, devhandle_t, void *), void *);
    666 
    667 int		device_compatible_match(const char **, int,
    668 				const struct device_compatible_entry *);
    669 int		device_compatible_pmatch(const char **, int,
    670 				const struct device_compatible_entry *);
    671 const struct device_compatible_entry *
    672 		device_compatible_lookup(const char **, int,
    673 				const struct device_compatible_entry *);
    674 const struct device_compatible_entry *
    675 		device_compatible_plookup(const char **, int,
    676 				const struct device_compatible_entry *);
    677 
    678 int		device_compatible_match_strlist(const char *, size_t,
    679 				const struct device_compatible_entry *);
    680 int		device_compatible_pmatch_strlist(const char *, size_t,
    681 				const struct device_compatible_entry *);
    682 const struct device_compatible_entry *
    683 		device_compatible_lookup_strlist(const char *, size_t,
    684 				const struct device_compatible_entry *);
    685 const struct device_compatible_entry *
    686 		device_compatible_plookup_strlist(const char *, size_t,
    687 				const struct device_compatible_entry *);
    688 
    689 int		device_compatible_match_id(uintptr_t const, uintptr_t const,
    690 				const struct device_compatible_entry *);
    691 const struct device_compatible_entry *
    692 		device_compatible_lookup_id(uintptr_t const, uintptr_t const,
    693 				const struct device_compatible_entry *);
    694 
    695 void		device_pmf_driver_child_register(device_t);
    696 void		device_pmf_driver_set_child_register(device_t,
    697 		    void (*)(device_t));
    698 
    699 void		*device_pmf_bus_private(device_t);
    700 bool		device_pmf_bus_suspend(device_t, const pmf_qual_t *);
    701 bool		device_pmf_bus_resume(device_t, const pmf_qual_t *);
    702 bool		device_pmf_bus_shutdown(device_t, int);
    703 
    704 void		device_pmf_bus_register(device_t, void *,
    705 		    bool (*)(device_t, const pmf_qual_t *),
    706 		    bool (*)(device_t, const pmf_qual_t *),
    707 		    bool (*)(device_t, int),
    708 		    void (*)(device_t));
    709 void		device_pmf_bus_deregister(device_t);
    710 
    711 device_t	shutdown_first(struct shutdown_state *);
    712 device_t	shutdown_next(struct shutdown_state *);
    713 
    714 /*
    715  * device calls --
    716  *
    717  * This provides a generic mechanism for invoking special methods on
    718  * devices, often dependent on the device tree implementation used
    719  * by the platform.
    720  *
    721  * While individual subsystems may define their own device calls,
    722  * the ones prefixed with "device-" are reserved, and defined by
    723  * the device autoconfiguration subsystem.  It is the responsibility
    724  * of each device tree back end to implement these calls.
    725  *
    726  * We define a generic interface; individual device calls feature
    727  * type checking of the argument structure.  The argument structures
    728  * and the call binding data are automatically generated from device
    729  * call interface descriptions by gendevcalls.awk.
    730  */
    731 struct device_call_generic {
    732 	const char *name;
    733 	void *args;
    734 };
    735 
    736 int		device_call_generic(device_t, devhandle_t,
    737 		    const struct device_call_generic *);
    738 
    739 #define	device_call(dev, call)						\
    740 	device_call_generic((dev), device_handle(dev), &(call)->generic)
    741 #define	devhandle_call(handle, call)					\
    742 	device_call_generic(NULL, (handle), &(call)->generic)
    743 
    744 /*
    745  * Device property infrastructure.
    746  */
    747 bool		device_hasprop(device_t, const char *);
    748 ssize_t		device_getproplen(device_t, const char *);
    749 int		device_getpropencoding(device_t, const char *);
    750 prop_type_t	device_getproptype(device_t, const char *);
    751 
    752 ssize_t		device_getprop_data(device_t, const char *, void *, size_t);
    753 ssize_t		device_getprop_string(device_t, const char *, char *, size_t);
    754 bool		device_getprop_bool(device_t, const char *);
    755 
    756 void *		device_getprop_data_alloc(device_t, const char *, size_t *);
    757 char *		device_getprop_string_alloc(device_t, const char *, size_t *);
    758 
    759 bool		device_getprop_int(device_t, const char *, int *);
    760 bool		device_getprop_uint(device_t, const char *, unsigned int *);
    761 bool		device_getprop_int32(device_t, const char *, int32_t *);
    762 bool		device_getprop_uint32(device_t, const char *, uint32_t *);
    763 bool		device_getprop_int64(device_t, const char *, int64_t *);
    764 bool		device_getprop_uint64(device_t, const char *, uint64_t *);
    765 
    766 int		device_getprop_int_default(device_t, const char *, int);
    767 unsigned int	device_getprop_uint_default(device_t, const char *,
    768 		    unsigned int);
    769 int32_t		device_getprop_int32_default(device_t, const char *, int32_t);
    770 uint32_t	device_getprop_uint32_default(device_t, const char *, uint32_t);
    771 int64_t		device_getprop_int64_default(device_t, const char *, int64_t);
    772 uint64_t	device_getprop_uint64_default(device_t, const char *, uint64_t);
    773 
    774 bool		device_setprop_data(device_t, const char *, const void *,
    775 		    size_t);
    776 bool		device_setprop_string(device_t, const char *, const char *);
    777 bool		device_setprop_bool(device_t, const char *, bool);
    778 
    779 bool		device_setprop_int(device_t, const char *, int);
    780 bool		device_setprop_uint(device_t, const char *, unsigned int);
    781 bool		device_setprop_int32(device_t, const char *, int32_t);
    782 bool		device_setprop_uint32(device_t, const char *, uint32_t);
    783 bool		device_setprop_int64(device_t, const char *, int64_t);
    784 bool		device_setprop_uint64(device_t, const char *, uint64_t);
    785 
    786 void		device_delprop(device_t, const char *);
    787 
    788 #endif /* _KERNEL */
    789 
    790 #endif /* !_SYS_DEVICE_H_ */
    791