xref: /minix/sys/sys/device.h (revision 6c8f7fc3)
1 /* $NetBSD: device.h,v 1.142 2012/07/07 16:15:21 tsutsui Exp $ */
2 
3 /*
4  * Copyright (c) 1996, 2000 Christopher G. Demetriou
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  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *          This product includes software developed for the
18  *          NetBSD Project.  See http://www.NetBSD.org/ for
19  *          information about NetBSD.
20  * 4. The name of the author may not be used to endorse or promote products
21  *    derived from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  * --(license Id: LICENSE.proto,v 1.1 2000/06/13 21:40:26 cgd Exp )--
35  */
36 
37 /*
38  * Copyright (c) 1992, 1993
39  *	The Regents of the University of California.  All rights reserved.
40  *
41  * This software was developed by the Computer Systems Engineering group
42  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
43  * contributed to Berkeley.
44  *
45  * All advertising materials mentioning features or use of this software
46  * must display the following acknowledgement:
47  *	This product includes software developed by the University of
48  *	California, Lawrence Berkeley Laboratories.
49  *
50  * Redistribution and use in source and binary forms, with or without
51  * modification, are permitted provided that the following conditions
52  * are met:
53  * 1. Redistributions of source code must retain the above copyright
54  *    notice, this list of conditions and the following disclaimer.
55  * 2. Redistributions in binary form must reproduce the above copyright
56  *    notice, this list of conditions and the following disclaimer in the
57  *    documentation and/or other materials provided with the distribution.
58  * 3. Neither the name of the University nor the names of its contributors
59  *    may be used to endorse or promote products derived from this software
60  *    without specific prior written permission.
61  *
62  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
63  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
64  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
65  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
66  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
67  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
68  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
69  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
70  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
71  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
72  * SUCH DAMAGE.
73  *
74  *	@(#)device.h	8.2 (Berkeley) 2/17/94
75  */
76 
77 #ifndef _SYS_DEVICE_H_
78 #define	_SYS_DEVICE_H_
79 
80 #include <sys/device_if.h>
81 #include <sys/evcnt.h>
82 #include <sys/queue.h>
83 
84 #ifdef _KERNEL
85 #include <sys/mutex.h>
86 #include <sys/condvar.h>
87 #include <sys/pmf.h>
88 #endif
89 
90 #include <prop/proplib.h>
91 
92 /*
93  * Minimal device structures.
94  * Note that all ``system'' device types are listed here.
95  */
96 typedef enum devclass {
97 	DV_DULL,		/* generic, no special info */
98 	DV_CPU,			/* CPU (carries resource utilization) */
99 	DV_DISK,		/* disk drive (label, etc) */
100 	DV_IFNET,		/* network interface */
101 	DV_TAPE,		/* tape device */
102 	DV_TTY,			/* serial line interface (?) */
103 	DV_AUDIODEV,		/* audio device */
104 	DV_DISPLAYDEV,		/* display device */
105 	DV_BUS,			/* bus device */
106 	DV_VIRTUAL,		/* unbacked virtual device */
107 } devclass_t;
108 
109 /*
110  * Actions for ca_activate.
111  */
112 typedef enum devact {
113 	DVACT_DEACTIVATE	/* deactivate the device */
114 } devact_t;
115 
116 typedef enum {
117 	DVA_SYSTEM,
118 	DVA_HARDWARE
119 } devactive_t;
120 
121 typedef struct cfdata *cfdata_t;
122 typedef struct cfdriver *cfdriver_t;
123 typedef struct cfattach *cfattach_t;
124 
125 #ifdef _KERNEL
126 struct device_lock {
127 	int		dvl_nwait;
128 	int		dvl_nlock;
129 	lwp_t		*dvl_holder;
130 	kmutex_t	dvl_mtx;
131 	kcondvar_t	dvl_cv;
132 };
133 
134 struct device_suspensor {
135 	const device_suspensor_t	*ds_delegator;
136 	char				ds_name[32];
137 };
138 
139 #define	DEVICE_SUSPENSORS_MAX	16
140 
141 struct device {
142 	devclass_t	dv_class;	/* this device's classification */
143 	TAILQ_ENTRY(device) dv_list;	/* entry on list of all devices */
144 	cfdata_t	dv_cfdata;	/* config data that found us
145 					   (NULL if pseudo-device) */
146 	cfdriver_t	dv_cfdriver;	/* our cfdriver */
147 	cfattach_t	dv_cfattach;	/* our cfattach */
148 	int		dv_unit;	/* device unit number */
149 	char		dv_xname[16];	/* external name (name + unit) */
150 	device_t	dv_parent;	/* pointer to parent device
151 					   (NULL if pseudo- or root node) */
152 	int		dv_depth;	/* number of parents until root */
153 	int		dv_flags;	/* misc. flags; see below */
154 	void		*dv_private;	/* this device's private storage */
155 	int		*dv_locators;	/* our actual locators (optional) */
156 	prop_dictionary_t dv_properties;/* properties dictionary */
157 
158 	size_t		dv_activity_count;
159 	void		(**dv_activity_handlers)(device_t, devactive_t);
160 
161 	bool		(*dv_driver_suspend)(device_t, const pmf_qual_t *);
162 	bool		(*dv_driver_resume)(device_t, const pmf_qual_t *);
163 	bool		(*dv_driver_shutdown)(device_t, int);
164 	bool		(*dv_driver_child_register)(device_t);
165 
166 	void		*dv_bus_private;
167 	bool		(*dv_bus_suspend)(device_t, const pmf_qual_t *);
168 	bool		(*dv_bus_resume)(device_t, const pmf_qual_t *);
169 	bool		(*dv_bus_shutdown)(device_t, int);
170 	void		(*dv_bus_deregister)(device_t);
171 
172 	void		*dv_class_private;
173 	bool		(*dv_class_suspend)(device_t, const pmf_qual_t *);
174 	bool		(*dv_class_resume)(device_t, const pmf_qual_t *);
175 	void		(*dv_class_deregister)(device_t);
176 
177 	devgen_t		dv_add_gen,
178 				dv_del_gen;
179 
180 	struct device_lock	dv_lock;
181 	const device_suspensor_t
182 	    *dv_bus_suspensors[DEVICE_SUSPENSORS_MAX],
183 	    *dv_driver_suspensors[DEVICE_SUSPENSORS_MAX],
184 	    *dv_class_suspensors[DEVICE_SUSPENSORS_MAX];
185 	struct device_garbage {
186 		device_t	*dg_devs;
187 		int		dg_ndevs;
188 	} dv_garbage;
189 };
190 
191 /* dv_flags */
192 #define	DVF_ACTIVE		0x0001	/* device is activated */
193 #define	DVF_PRIV_ALLOC		0x0002	/* device private storage != device */
194 #define	DVF_POWER_HANDLERS	0x0004	/* device has suspend/resume support */
195 #define	DVF_CLASS_SUSPENDED	0x0008	/* device class suspend was called */
196 #define	DVF_DRIVER_SUSPENDED	0x0010	/* device driver suspend was called */
197 #define	DVF_BUS_SUSPENDED	0x0020	/* device bus suspend was called */
198 #define	DVF_DETACH_SHUTDOWN	0x0080	/* device detaches safely at shutdown */
199 
200 TAILQ_HEAD(devicelist, device);
201 
202 enum deviter_flags {
203 	  DEVITER_F_RW =		0x1
204 	, DEVITER_F_SHUTDOWN =		0x2
205 	, DEVITER_F_LEAVES_FIRST =	0x4
206 	, DEVITER_F_ROOT_FIRST =	0x8
207 };
208 
209 typedef enum deviter_flags deviter_flags_t;
210 
211 struct deviter {
212 	device_t	di_prev;
213 	deviter_flags_t	di_flags;
214 	int		di_curdepth;
215 	int		di_maxdepth;
216 	devgen_t	di_gen;
217 };
218 
219 typedef struct deviter deviter_t;
220 
221 struct shutdown_state {
222 	bool initialized;
223 	deviter_t di;
224 };
225 #endif
226 
227 /*
228  * Description of a locator, as part of interface attribute definitions.
229  */
230 struct cflocdesc {
231 	const char *cld_name;
232 	const char *cld_defaultstr; /* NULL if no default */
233 	int cld_default;
234 };
235 
236 /*
237  * Description of an interface attribute, provided by potential
238  * parent device drivers, referred to by child device configuration data.
239  */
240 struct cfiattrdata {
241 	const char *ci_name;
242 	int ci_loclen;
243 	const struct cflocdesc ci_locdesc[
244 #if defined(__GNUC__) && __GNUC__ <= 2
245 		0
246 #endif
247 	];
248 };
249 
250 /*
251  * Description of a configuration parent.  Each device attachment attaches
252  * to an "interface attribute", which is given in this structure.  The parent
253  * *must* carry this attribute.  Optionally, an individual device instance
254  * may also specify a specific parent device instance.
255  */
256 struct cfparent {
257 	const char *cfp_iattr;		/* interface attribute */
258 	const char *cfp_parent;		/* optional specific parent */
259 	int cfp_unit;			/* optional specific unit
260 					   (DVUNIT_ANY to wildcard) */
261 };
262 
263 /*
264  * Configuration data (i.e., data placed in ioconf.c).
265  */
266 struct cfdata {
267 	const char *cf_name;		/* driver name */
268 	const char *cf_atname;		/* attachment name */
269 	short	cf_unit;		/* unit number */
270 	short	cf_fstate;		/* finding state (below) */
271 	int	*cf_loc;		/* locators (machine dependent) */
272 	int	cf_flags;		/* flags from config */
273 	const struct cfparent *cf_pspec;/* parent specification */
274 };
275 #define FSTATE_NOTFOUND		0	/* has not been found */
276 #define	FSTATE_FOUND		1	/* has been found */
277 #define	FSTATE_STAR		2	/* duplicable */
278 #define FSTATE_DSTAR		3	/* has not been found, and disabled */
279 #define FSTATE_DNOTFOUND	4	/* duplicate, and disabled */
280 
281 /*
282  * Multiple configuration data tables may be maintained.  This structure
283  * provides the linkage.
284  */
285 struct cftable {
286 	cfdata_t	ct_cfdata;	/* pointer to cfdata table */
287 	TAILQ_ENTRY(cftable) ct_list;	/* list linkage */
288 };
289 TAILQ_HEAD(cftablelist, cftable);
290 
291 typedef int (*cfsubmatch_t)(device_t, cfdata_t, const int *, void *);
292 
293 /*
294  * `configuration' attachment and driver (what the machine-independent
295  * autoconf uses).  As devices are found, they are applied against all
296  * the potential matches.  The one with the best match is taken, and a
297  * device structure (plus any other data desired) is allocated.  Pointers
298  * to these are placed into an array of pointers.  The array itself must
299  * be dynamic since devices can be found long after the machine is up
300  * and running.
301  *
302  * Devices can have multiple configuration attachments if they attach
303  * to different attributes (busses, or whatever), to allow specification
304  * of multiple match and attach functions.  There is only one configuration
305  * driver per driver, so that things like unit numbers and the device
306  * structure array will be shared.
307  */
308 struct cfattach {
309 	const char *ca_name;		/* name of attachment */
310 	LIST_ENTRY(cfattach) ca_list;	/* link on cfdriver's list */
311 	size_t	  ca_devsize;		/* size of dev data (for alloc) */
312 	int	  ca_flags;		/* flags for driver allocation etc */
313 	int	(*ca_match)(device_t, cfdata_t, void *);
314 	void	(*ca_attach)(device_t, device_t, void *);
315 	int	(*ca_detach)(device_t, int);
316 	int	(*ca_activate)(device_t, devact_t);
317 	/* technically, the next 2 belong into "struct cfdriver" */
318 	int	(*ca_rescan)(device_t, const char *,
319 			     const int *); /* scan for new children */
320 	void	(*ca_childdetached)(device_t, device_t);
321 };
322 LIST_HEAD(cfattachlist, cfattach);
323 
324 #define	CFATTACH_DECL(name, ddsize, matfn, attfn, detfn, actfn) \
325 struct cfattach __CONCAT(name,_ca) = {					\
326 	.ca_name		= ___STRING(name),			\
327 	.ca_devsize		= ddsize,				\
328 	.ca_flags		= 0,					\
329 	.ca_match 		= matfn,				\
330 	.ca_attach		= attfn,				\
331 	.ca_detach		= detfn,				\
332 	.ca_activate		= actfn,				\
333 	.ca_rescan		= NULL,					\
334 	.ca_childdetached	= NULL,					\
335 }
336 
337 #define	CFATTACH_DECL3_NEW(name, ddsize, matfn, attfn, detfn, actfn, \
338 	rescanfn, chdetfn, __flags) \
339 struct cfattach __CONCAT(name,_ca) = {					\
340 	.ca_name		= ___STRING(name),			\
341 	.ca_devsize		= ddsize,				\
342 	.ca_flags		= (__flags) | DVF_PRIV_ALLOC,		\
343 	.ca_match 		= matfn,				\
344 	.ca_attach		= attfn,				\
345 	.ca_detach		= detfn,				\
346 	.ca_activate		= actfn,				\
347 	.ca_rescan		= rescanfn,				\
348 	.ca_childdetached	= chdetfn,				\
349 }
350 
351 #define	CFATTACH_DECL2_NEW(name, ddsize, matfn, attfn, detfn, actfn,	\
352 	rescanfn, chdetfn)						\
353 	CFATTACH_DECL3_NEW(name, ddsize, matfn, attfn, detfn, actfn,	\
354 	    rescanfn, chdetfn, 0)
355 
356 #define	CFATTACH_DECL_NEW(name, ddsize, matfn, attfn, detfn, actfn)	\
357 	CFATTACH_DECL2_NEW(name, ddsize, matfn, attfn, detfn, actfn, NULL, NULL)
358 
359 /* Flags given to config_detach(), and the ca_detach function. */
360 #define	DETACH_FORCE	0x01		/* force detachment; hardware gone */
361 #define	DETACH_QUIET	0x02		/* don't print a notice */
362 #define	DETACH_SHUTDOWN	0x04		/* detach because of system shutdown */
363 
364 struct cfdriver {
365 	LIST_ENTRY(cfdriver) cd_list;	/* link on allcfdrivers */
366 	struct cfattachlist cd_attach;	/* list of all attachments */
367 	device_t *cd_devs;		/* devices found */
368 	const char *cd_name;		/* device name */
369 	enum	devclass cd_class;	/* device classification */
370 	int	cd_ndevs;		/* size of cd_devs array */
371 	const struct cfiattrdata * const *cd_attrs; /* attributes provided */
372 };
373 LIST_HEAD(cfdriverlist, cfdriver);
374 
375 #define	CFDRIVER_DECL(name, class, attrs)				\
376 struct cfdriver __CONCAT(name,_cd) = {					\
377 	.cd_name		= ___STRING(name),			\
378 	.cd_class		= class,				\
379 	.cd_attrs		= attrs,				\
380 }
381 
382 /*
383  * The cfattachinit is a data structure used to associate a list of
384  * cfattach's with cfdrivers as found in the static kernel configuration.
385  */
386 struct cfattachinit {
387 	const char *cfai_name;		 /* driver name */
388 	struct cfattach * const *cfai_list;/* list of attachments */
389 };
390 /*
391  * the same, but with a non-constant list so it can be modified
392  * for module bookkeeping
393  */
394 struct cfattachlkminit {
395 	const char *cfai_name;		/* driver name */
396 	struct cfattach **cfai_list;	/* list of attachments */
397 };
398 
399 /*
400  * Configuration printing functions, and their return codes.  The second
401  * argument is NULL if the device was configured; otherwise it is the name
402  * of the parent device.  The return value is ignored if the device was
403  * configured, so most functions can return UNCONF unconditionally.
404  */
405 typedef int (*cfprint_t)(void *, const char *);		/* XXX const char * */
406 #define	QUIET	0		/* print nothing */
407 #define	UNCONF	1		/* print " not configured\n" */
408 #define	UNSUPP	2		/* print " not supported\n" */
409 
410 /*
411  * Pseudo-device attach information (function + number of pseudo-devs).
412  */
413 struct pdevinit {
414 	void	(*pdev_attach)(int);
415 	int	pdev_count;
416 };
417 
418 /* This allows us to wildcard a device unit. */
419 #define	DVUNIT_ANY	-1
420 
421 #ifdef _KERNEL
422 
423 extern struct cfdriverlist allcfdrivers;/* list of all cfdrivers */
424 extern struct cftablelist allcftables;	/* list of all cfdata tables */
425 extern device_t booted_device;		/* the device we booted from */
426 extern int booted_partition;		/* the partition on that device */
427 extern daddr_t booted_startblk;		/* or the start of a wedge */
428 extern uint64_t booted_nblks;		/* and the size of that wedge */
429 
430 struct vnode *opendisk(struct device *);
431 int getdisksize(struct vnode *, uint64_t *, unsigned int *);
432 struct dkwedge_info;
433 int getdiskinfo(struct vnode *, struct dkwedge_info *);
434 
435 void	config_init(void);
436 int	config_init_component(struct cfdriver *const*,
437 			      const struct cfattachinit *, struct cfdata *);
438 int	config_fini_component(struct cfdriver *const*,
439 			      const struct cfattachinit *, struct cfdata *);
440 void	config_init_mi(void);
441 void	drvctl_init(void);
442 
443 int	config_cfdriver_attach(struct cfdriver *);
444 int	config_cfdriver_detach(struct cfdriver *);
445 
446 int	config_cfattach_attach(const char *, struct cfattach *);
447 int	config_cfattach_detach(const char *, struct cfattach *);
448 
449 int	config_cfdata_attach(cfdata_t, int);
450 int	config_cfdata_detach(cfdata_t);
451 
452 struct cfdriver *config_cfdriver_lookup(const char *);
453 struct cfattach *config_cfattach_lookup(const char *, const char *);
454 const struct cfiattrdata *cfiattr_lookup(const char *, const struct cfdriver *);
455 
456 const char *cfdata_ifattr(const struct cfdata *);
457 
458 int	config_stdsubmatch(device_t, cfdata_t, const int *, void *);
459 cfdata_t config_search_loc(cfsubmatch_t, device_t,
460 				 const char *, const int *, void *);
461 cfdata_t config_search_ia(cfsubmatch_t, device_t,
462 				 const char *, void *);
463 cfdata_t config_rootsearch(cfsubmatch_t, const char *, void *);
464 device_t config_found_sm_loc(device_t, const char *, const int *,
465 			     void *, cfprint_t, cfsubmatch_t);
466 device_t config_found_ia(device_t, const char *, void *, cfprint_t);
467 device_t config_found(device_t, void *, cfprint_t);
468 device_t config_rootfound(const char *, void *);
469 device_t config_attach_loc(device_t, cfdata_t, const int *, void *, cfprint_t);
470 device_t config_attach(device_t, cfdata_t, void *, cfprint_t);
471 int	config_match(device_t, cfdata_t, void *);
472 
473 bool ifattr_match(const char *, const char *);
474 
475 device_t config_attach_pseudo(cfdata_t);
476 
477 int	config_detach(device_t, int);
478 int	config_detach_children(device_t, int flags);
479 bool	config_detach_all(int);
480 int	config_deactivate(device_t);
481 void	config_defer(device_t, void (*)(device_t));
482 void	config_deferred(device_t);
483 void	config_interrupts(device_t, void (*)(device_t));
484 void	config_mountroot(device_t, void (*)(device_t));
485 void	config_pending_incr(void);
486 void	config_pending_decr(void);
487 void	config_create_interruptthreads(void);
488 void	config_create_mountrootthreads(void);
489 
490 int	config_finalize_register(device_t, int (*)(device_t));
491 void	config_finalize(void);
492 
493 void	config_twiddle_init(void);
494 void	config_twiddle_fn(void *);
495 
496 void	null_childdetached(device_t, device_t);
497 
498 device_t	device_lookup(cfdriver_t, int);
499 void		*device_lookup_private(cfdriver_t, int);
500 void		device_register(device_t, void *);
501 void		device_register_post_config(device_t, void *);
502 
503 devclass_t	device_class(device_t);
504 cfdata_t	device_cfdata(device_t);
505 cfdriver_t	device_cfdriver(device_t);
506 cfattach_t	device_cfattach(device_t);
507 int		device_unit(device_t);
508 const char	*device_xname(device_t);
509 device_t	device_parent(device_t);
510 bool		device_is_active(device_t);
511 bool		device_activation(device_t, devact_level_t);
512 bool		device_is_enabled(device_t);
513 bool		device_has_power(device_t);
514 int		device_locator(device_t, u_int);
515 void		*device_private(device_t);
516 prop_dictionary_t device_properties(device_t);
517 
518 device_t	deviter_first(deviter_t *, deviter_flags_t);
519 void		deviter_init(deviter_t *, deviter_flags_t);
520 device_t	deviter_next(deviter_t *);
521 void		deviter_release(deviter_t *);
522 
523 bool		device_active(device_t, devactive_t);
524 bool		device_active_register(device_t,
525 				       void (*)(device_t, devactive_t));
526 void		device_active_deregister(device_t,
527 				         void (*)(device_t, devactive_t));
528 
529 bool		device_is_a(device_t, const char *);
530 
531 device_t	device_find_by_xname(const char *);
532 device_t	device_find_by_driver_unit(const char *, int);
533 
534 bool		device_pmf_is_registered(device_t);
535 
536 bool		device_pmf_driver_suspend(device_t, const pmf_qual_t *);
537 bool		device_pmf_driver_resume(device_t, const pmf_qual_t *);
538 bool		device_pmf_driver_shutdown(device_t, int);
539 
540 bool		device_pmf_driver_register(device_t,
541 		    bool (*)(device_t, const pmf_qual_t *),
542 		    bool (*)(device_t, const pmf_qual_t *),
543 		    bool (*)(device_t, int));
544 void		device_pmf_driver_deregister(device_t);
545 
546 bool		device_pmf_driver_child_register(device_t);
547 void		device_pmf_driver_set_child_register(device_t,
548 		    bool (*)(device_t));
549 
550 void		*device_pmf_bus_private(device_t);
551 bool		device_pmf_bus_suspend(device_t, const pmf_qual_t *);
552 bool		device_pmf_bus_resume(device_t, const pmf_qual_t *);
553 bool		device_pmf_bus_shutdown(device_t, int);
554 
555 device_lock_t	device_getlock(device_t);
556 void		device_pmf_unlock(device_t);
557 bool		device_pmf_lock(device_t);
558 
559 bool		device_is_self_suspended(device_t);
560 void		device_pmf_self_suspend(device_t, const pmf_qual_t *);
561 void		device_pmf_self_resume(device_t, const pmf_qual_t *);
562 bool		device_pmf_self_wait(device_t, const pmf_qual_t *);
563 
564 void		device_pmf_bus_register(device_t, void *,
565 		    bool (*)(device_t, const pmf_qual_t *),
566 		    bool (*)(device_t, const pmf_qual_t *),
567 		    bool (*)(device_t, int),
568 		    void (*)(device_t));
569 void		device_pmf_bus_deregister(device_t);
570 
571 void		*device_pmf_class_private(device_t);
572 bool		device_pmf_class_suspend(device_t, const pmf_qual_t *);
573 bool		device_pmf_class_resume(device_t, const pmf_qual_t *);
574 
575 void		device_pmf_class_register(device_t, void *,
576 		    bool (*)(device_t, const pmf_qual_t *),
577 		    bool (*)(device_t, const pmf_qual_t *),
578 		    void (*)(device_t));
579 void		device_pmf_class_deregister(device_t);
580 
581 device_t	shutdown_first(struct shutdown_state *);
582 device_t	shutdown_next(struct shutdown_state *);
583 #endif /* _KERNEL */
584 
585 #endif /* !_SYS_DEVICE_H_ */
586