xref: /netbsd/sys/sys/device.h (revision cfc732c2)
1 /* $NetBSD: device.h,v 1.186 2023/05/22 14:58:22 riastradh 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  * the same, but with a non-constant list so it can be modified
442  * for module bookkeeping
443  */
444 struct cfattachlkminit {
445 	const char *cfai_name;		/* driver name */
446 	struct cfattach **cfai_list;	/* list of attachments */
447 };
448 
449 /*
450  * Configuration printing functions, and their return codes.  The second
451  * argument is NULL if the device was configured; otherwise it is the name
452  * of the parent device.  The return value is ignored if the device was
453  * configured, so most functions can return UNCONF unconditionally.
454  */
455 typedef int (*cfprint_t)(void *, const char *);		/* XXX const char * */
456 #define	QUIET	0		/* print nothing */
457 #define	UNCONF	1		/* print " not configured\n" */
458 #define	UNSUPP	2		/* print " not supported\n" */
459 
460 /*
461  * Pseudo-device attach information (function + number of pseudo-devs).
462  */
463 struct pdevinit {
464 	void	(*pdev_attach)(int);
465 	int	pdev_count;
466 };
467 
468 /* This allows us to wildcard a device unit. */
469 #define	DVUNIT_ANY	-1
470 
471 #if defined(_KERNEL) || defined(_KMEMUSER) || defined(_STANDALONE)
472 /*
473  * Arguments passed to config_search() and config_found().
474  */
475 struct cfargs {
476 	uintptr_t	cfargs_version;	/* version field */
477 
478 	/* version 1 fields */
479 	cfsubmatch_t	submatch;	/* submatch function (direct config) */
480 	cfsearch_t	search;		/* search function (indirect config) */
481 	const char *	iattr;		/* interface attribute */
482 	const int *	locators;	/* locators array */
483 	devhandle_t	devhandle;	/* devhandle_t (by value) */
484 
485 	/* version 2 fields below here */
486 };
487 
488 #define	CFARGS_VERSION		1	/* current cfargs version */
489 
490 #define	CFARGS_NONE		NULL	/* no cfargs to pass */
491 
492 /*
493  * Construct a cfargs with this macro, like so:
494  *
495  *	CFARGS(.submatch = config_stdsubmatch,
496  *	       .devhandle = my_devhandle)
497  *
498  * You must supply at least one field.  If you don't need any, use the
499  * CFARGS_NONE macro.
500  */
501 #define	CFARGS(...)							\
502 	&((const struct cfargs){					\
503 		.cfargs_version = CFARGS_VERSION,			\
504 		__VA_ARGS__						\
505 	})
506 #endif /* _KERNEL || _KMEMUSER || _STANDALONE */
507 
508 #ifdef _KERNEL
509 
510 extern struct cfdriverlist allcfdrivers;/* list of all cfdrivers */
511 extern struct cftablelist allcftables;	/* list of all cfdata tables */
512 extern device_t booted_device;		/* the device we booted from */
513 extern const char *booted_method;	/* the method the device was found */
514 extern int booted_partition;		/* the partition on that device */
515 extern daddr_t booted_startblk;		/* or the start of a wedge */
516 extern uint64_t booted_nblks;		/* and the size of that wedge */
517 extern char *bootspec;			/* and the device/wedge name */
518 extern bool root_is_mounted;		/* true if root is mounted */
519 
520 struct vnode *opendisk(device_t);
521 int getdisksize(struct vnode *, uint64_t *, unsigned int *);
522 struct dkwedge_info;
523 int getdiskinfo(struct vnode *, struct dkwedge_info *);
524 
525 void	config_init(void);
526 int	config_init_component(struct cfdriver *const*,
527 			      const struct cfattachinit *, struct cfdata *);
528 int	config_fini_component(struct cfdriver *const*,
529 			      const struct cfattachinit *, struct cfdata *);
530 void	config_init_mi(void);
531 void	drvctl_init(void);
532 void	drvctl_fini(void);
533 extern	int (*devmon_insert_vec)(const char *, prop_dictionary_t);
534 
535 int	config_cfdriver_attach(struct cfdriver *);
536 int	config_cfdriver_detach(struct cfdriver *);
537 
538 int	config_cfattach_attach(const char *, struct cfattach *);
539 int	config_cfattach_detach(const char *, struct cfattach *);
540 
541 int	config_cfdata_attach(cfdata_t, int);
542 int	config_cfdata_detach(cfdata_t);
543 
544 struct cfdriver *config_cfdriver_lookup(const char *);
545 struct cfattach *config_cfattach_lookup(const char *, const char *);
546 const struct cfiattrdata *cfiattr_lookup(const char *, const struct cfdriver *);
547 
548 const char *cfdata_ifattr(const struct cfdata *);
549 
550 int	config_stdsubmatch(device_t, cfdata_t, const int *, void *);
551 cfdata_t config_search(device_t, void *, const struct cfargs *);
552 cfdata_t config_rootsearch(cfsubmatch_t, const char *, void *);
553 device_t config_found(device_t, void *, cfprint_t, const struct cfargs *);
554 device_t config_rootfound(const char *, void *);
555 device_t config_attach(device_t, cfdata_t, void *, cfprint_t,
556 	    const struct cfargs *);
557 device_t config_found_acquire(device_t, void *, cfprint_t,
558 	    const struct cfargs *);
559 device_t config_attach_acquire(device_t, cfdata_t, void *, cfprint_t,
560 	    const struct cfargs *);
561 int	config_match(device_t, cfdata_t, void *);
562 int	config_probe(device_t, cfdata_t, void *);
563 
564 bool	ifattr_match(const char *, const char *);
565 
566 device_t config_attach_pseudo(cfdata_t);
567 device_t config_attach_pseudo_acquire(cfdata_t, void *);
568 
569 int	config_detach(device_t, int);
570 int	config_detach_release(device_t, int);
571 int	config_detach_children(device_t, int flags);
572 void	config_detach_commit(device_t);
573 bool	config_detach_all(int);
574 int	config_deactivate(device_t);
575 void	config_defer(device_t, void (*)(device_t));
576 void	config_deferred(device_t);
577 void	config_interrupts(device_t, void (*)(device_t));
578 void	config_mountroot(device_t, void (*)(device_t));
579 void	config_pending_incr(device_t);
580 void	config_pending_decr(device_t);
581 void	config_create_interruptthreads(void);
582 void	config_create_mountrootthreads(void);
583 
584 int	config_finalize_register(device_t, int (*)(device_t));
585 void	config_finalize(void);
586 void	config_finalize_mountroot(void);
587 
588 void	config_twiddle_init(void);
589 void	config_twiddle_fn(void *);
590 
591 void	null_childdetached(device_t, device_t);
592 
593 device_t	device_lookup(cfdriver_t, int);
594 void		*device_lookup_private(cfdriver_t, int);
595 
596 device_t	device_lookup_acquire(cfdriver_t, int);
597 void		device_acquire(device_t);
598 void		device_release(device_t);
599 
600 void		device_register(device_t, void *);
601 void		device_register_post_config(device_t, void *);
602 
603 devclass_t	device_class(device_t);
604 cfdata_t	device_cfdata(device_t);
605 cfdriver_t	device_cfdriver(device_t);
606 cfattach_t	device_cfattach(device_t);
607 int		device_unit(device_t);
608 const char	*device_xname(device_t);
609 device_t	device_parent(device_t);
610 bool		device_is_active(device_t);
611 bool		device_activation(device_t, devact_level_t);
612 bool		device_is_enabled(device_t);
613 bool		device_has_power(device_t);
614 int		device_locator(device_t, u_int);
615 void		*device_private(device_t);
616 void		device_set_private(device_t, void *);
617 prop_dictionary_t device_properties(device_t);
618 void		device_set_handle(device_t, devhandle_t);
619 devhandle_t	device_handle(device_t);
620 
621 bool		devhandle_is_valid(devhandle_t);
622 devhandle_t	devhandle_invalid(void);
623 devhandle_type_t devhandle_type(devhandle_t);
624 int		devhandle_compare(devhandle_t, devhandle_t);
625 
626 device_call_t	devhandle_lookup_device_call(devhandle_t, const char *,
627 		    devhandle_t *);
628 void		devhandle_impl_inherit(struct devhandle_impl *,
629 		    const struct devhandle_impl *);
630 
631 device_t	deviter_first(deviter_t *, deviter_flags_t);
632 void		deviter_init(deviter_t *, deviter_flags_t);
633 device_t	deviter_next(deviter_t *);
634 void		deviter_release(deviter_t *);
635 
636 bool		device_active(device_t, devactive_t);
637 bool		device_active_register(device_t,
638 				       void (*)(device_t, devactive_t));
639 void		device_active_deregister(device_t,
640 				         void (*)(device_t, devactive_t));
641 
642 bool		device_is_a(device_t, const char *);
643 bool		device_attached_to_iattr(device_t, const char *);
644 
645 device_t	device_find_by_xname(const char *);
646 device_t	device_find_by_driver_unit(const char *, int);
647 
648 int		device_enumerate_children(device_t,
649 		    bool (*)(device_t, devhandle_t, void *), void *);
650 
651 int		device_compatible_match(const char **, int,
652 				const struct device_compatible_entry *);
653 int		device_compatible_pmatch(const char **, int,
654 				const struct device_compatible_entry *);
655 const struct device_compatible_entry *
656 		device_compatible_lookup(const char **, int,
657 				const struct device_compatible_entry *);
658 const struct device_compatible_entry *
659 		device_compatible_plookup(const char **, int,
660 				const struct device_compatible_entry *);
661 
662 int		device_compatible_match_strlist(const char *, size_t,
663 				const struct device_compatible_entry *);
664 int		device_compatible_pmatch_strlist(const char *, size_t,
665 				const struct device_compatible_entry *);
666 const struct device_compatible_entry *
667 		device_compatible_lookup_strlist(const char *, size_t,
668 				const struct device_compatible_entry *);
669 const struct device_compatible_entry *
670 		device_compatible_plookup_strlist(const char *, size_t,
671 				const struct device_compatible_entry *);
672 
673 int		device_compatible_match_id(uintptr_t const, uintptr_t const,
674 				const struct device_compatible_entry *);
675 const struct device_compatible_entry *
676 		device_compatible_lookup_id(uintptr_t const, uintptr_t const,
677 				const struct device_compatible_entry *);
678 
679 void		device_pmf_driver_child_register(device_t);
680 void		device_pmf_driver_set_child_register(device_t,
681 		    void (*)(device_t));
682 
683 void		*device_pmf_bus_private(device_t);
684 bool		device_pmf_bus_suspend(device_t, const pmf_qual_t *);
685 bool		device_pmf_bus_resume(device_t, const pmf_qual_t *);
686 bool		device_pmf_bus_shutdown(device_t, int);
687 
688 void		device_pmf_bus_register(device_t, void *,
689 		    bool (*)(device_t, const pmf_qual_t *),
690 		    bool (*)(device_t, const pmf_qual_t *),
691 		    bool (*)(device_t, int),
692 		    void (*)(device_t));
693 void		device_pmf_bus_deregister(device_t);
694 
695 device_t	shutdown_first(struct shutdown_state *);
696 device_t	shutdown_next(struct shutdown_state *);
697 
698 /*
699  * device calls --
700  *
701  * This provides a generic mechanism for invoking special methods on
702  * devices, often dependent on the device tree implementation used
703  * by the platform.
704  *
705  * While individual subsystems may define their own device calls,
706  * the ones prefixed with "device-" are reserved, and defined by
707  * the device autoconfiguration subsystem.  It is the responsibility
708  * of each device tree back end to implement these calls.
709  *
710  * We define a generic interface; individual device calls feature
711  * type checking of the argument structure.  The argument structures
712  * and the call binding data are automatically generated from device
713  * call interface descriptions by gendevcalls.awk.
714  */
715 struct device_call_generic {
716 	const char *name;
717 	void *args;
718 };
719 
720 int	device_call_generic(device_t, const struct device_call_generic *);
721 
722 #define	device_call(dev, call)						\
723 	device_call_generic((dev), &(call)->generic)
724 
725 #endif /* _KERNEL */
726 
727 #endif /* !_SYS_DEVICE_H_ */
728