1 /* $NetBSD: device.h,v 1.149 2016/06/19 09:35:06 bouyer 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_garbage {
142 	device_t	*dg_devs;
143 	int		dg_ndevs;
144 };
145 
146 struct device {
147 	devclass_t	dv_class;	/* this device's classification */
148 	TAILQ_ENTRY(device) dv_list;	/* entry on list of all devices */
149 	cfdata_t	dv_cfdata;	/* config data that found us
150 					   (NULL if pseudo-device) */
151 	cfdriver_t	dv_cfdriver;	/* our cfdriver */
152 	cfattach_t	dv_cfattach;	/* our cfattach */
153 	int		dv_unit;	/* device unit number */
154 	char		dv_xname[16];	/* external name (name + unit) */
155 	device_t	dv_parent;	/* pointer to parent device
156 					   (NULL if pseudo- or root node) */
157 	int		dv_depth;	/* number of parents until root */
158 	int		dv_flags;	/* misc. flags; see below */
159 	void		*dv_private;	/* this device's private storage */
160 	int		*dv_locators;	/* our actual locators (optional) */
161 	prop_dictionary_t dv_properties;/* properties dictionary */
162 
163 	size_t		dv_activity_count;
164 	void		(**dv_activity_handlers)(device_t, devactive_t);
165 
166 	bool		(*dv_driver_suspend)(device_t, const pmf_qual_t *);
167 	bool		(*dv_driver_resume)(device_t, const pmf_qual_t *);
168 	bool		(*dv_driver_shutdown)(device_t, int);
169 	bool		(*dv_driver_child_register)(device_t);
170 
171 	void		*dv_bus_private;
172 	bool		(*dv_bus_suspend)(device_t, const pmf_qual_t *);
173 	bool		(*dv_bus_resume)(device_t, const pmf_qual_t *);
174 	bool		(*dv_bus_shutdown)(device_t, int);
175 	void		(*dv_bus_deregister)(device_t);
176 
177 	void		*dv_class_private;
178 	bool		(*dv_class_suspend)(device_t, const pmf_qual_t *);
179 	bool		(*dv_class_resume)(device_t, const pmf_qual_t *);
180 	void		(*dv_class_deregister)(device_t);
181 
182 	devgen_t		dv_add_gen,
183 				dv_del_gen;
184 
185 	struct device_lock	dv_lock;
186 	const device_suspensor_t
187 	    *dv_bus_suspensors[DEVICE_SUSPENSORS_MAX],
188 	    *dv_driver_suspensors[DEVICE_SUSPENSORS_MAX],
189 	    *dv_class_suspensors[DEVICE_SUSPENSORS_MAX];
190 	struct device_garbage dv_garbage;
191 };
192 
193 /* dv_flags */
194 #define	DVF_ACTIVE		0x0001	/* device is activated */
195 #define	DVF_PRIV_ALLOC		0x0002	/* device private storage != device */
196 #define	DVF_POWER_HANDLERS	0x0004	/* device has suspend/resume support */
197 #define	DVF_CLASS_SUSPENDED	0x0008	/* device class suspend was called */
198 #define	DVF_DRIVER_SUSPENDED	0x0010	/* device driver suspend was called */
199 #define	DVF_BUS_SUSPENDED	0x0020	/* device bus suspend was called */
200 #define	DVF_DETACH_SHUTDOWN	0x0080	/* device detaches safely at shutdown */
201 
202 TAILQ_HEAD(devicelist, device);
203 
204 enum deviter_flags {
205 	  DEVITER_F_RW =		0x1
206 	, DEVITER_F_SHUTDOWN =		0x2
207 	, DEVITER_F_LEAVES_FIRST =	0x4
208 	, DEVITER_F_ROOT_FIRST =	0x8
209 };
210 
211 typedef enum deviter_flags deviter_flags_t;
212 
213 struct deviter {
214 	device_t	di_prev;
215 	deviter_flags_t	di_flags;
216 	int		di_curdepth;
217 	int		di_maxdepth;
218 	devgen_t	di_gen;
219 };
220 
221 typedef struct deviter deviter_t;
222 
223 struct shutdown_state {
224 	bool initialized;
225 	deviter_t di;
226 };
227 #endif
228 
229 /*
230  * Description of a locator, as part of interface attribute definitions.
231  */
232 struct cflocdesc {
233 	const char *cld_name;
234 	const char *cld_defaultstr; /* NULL if no default */
235 	int cld_default;
236 };
237 
238 /*
239  * Description of an interface attribute, provided by potential
240  * parent device drivers, referred to by child device configuration data.
241  */
242 struct cfiattrdata {
243 	const char *ci_name;
244 	int ci_loclen;
245 	const struct cflocdesc ci_locdesc[
246 #if defined(__GNUC__) && __GNUC__ <= 2
247 		0
248 #endif
249 	];
250 };
251 
252 /*
253  * Description of a configuration parent.  Each device attachment attaches
254  * to an "interface attribute", which is given in this structure.  The parent
255  * *must* carry this attribute.  Optionally, an individual device instance
256  * may also specify a specific parent device instance.
257  */
258 struct cfparent {
259 	const char *cfp_iattr;		/* interface attribute */
260 	const char *cfp_parent;		/* optional specific parent */
261 	int cfp_unit;			/* optional specific unit
262 					   (DVUNIT_ANY to wildcard) */
263 };
264 
265 /*
266  * Configuration data (i.e., data placed in ioconf.c).
267  */
268 struct cfdata {
269 	const char *cf_name;		/* driver name */
270 	const char *cf_atname;		/* attachment name */
271 	short	cf_unit;		/* unit number */
272 	short	cf_fstate;		/* finding state (below) */
273 	int	*cf_loc;		/* locators (machine dependent) */
274 	int	cf_flags;		/* flags from config */
275 	const struct cfparent *cf_pspec;/* parent specification */
276 };
277 #define FSTATE_NOTFOUND		0	/* has not been found */
278 #define	FSTATE_FOUND		1	/* has been found */
279 #define	FSTATE_STAR		2	/* duplicable */
280 #define FSTATE_DSTAR		3	/* has not been found, and disabled */
281 #define FSTATE_DNOTFOUND	4	/* duplicate, and disabled */
282 
283 /*
284  * Multiple configuration data tables may be maintained.  This structure
285  * provides the linkage.
286  */
287 struct cftable {
288 	cfdata_t	ct_cfdata;	/* pointer to cfdata table */
289 	TAILQ_ENTRY(cftable) ct_list;	/* list linkage */
290 };
291 TAILQ_HEAD(cftablelist, cftable);
292 
293 typedef int (*cfsubmatch_t)(device_t, cfdata_t, const int *, void *);
294 
295 /*
296  * `configuration' attachment and driver (what the machine-independent
297  * autoconf uses).  As devices are found, they are applied against all
298  * the potential matches.  The one with the best match is taken, and a
299  * device structure (plus any other data desired) is allocated.  Pointers
300  * to these are placed into an array of pointers.  The array itself must
301  * be dynamic since devices can be found long after the machine is up
302  * and running.
303  *
304  * Devices can have multiple configuration attachments if they attach
305  * to different attributes (busses, or whatever), to allow specification
306  * of multiple match and attach functions.  There is only one configuration
307  * driver per driver, so that things like unit numbers and the device
308  * structure array will be shared.
309  */
310 struct cfattach {
311 	const char *ca_name;		/* name of attachment */
312 	LIST_ENTRY(cfattach) ca_list;	/* link on cfdriver's list */
313 	size_t	  ca_devsize;		/* size of dev data (for alloc) */
314 	int	  ca_flags;		/* flags for driver allocation etc */
315 	int	(*ca_match)(device_t, cfdata_t, void *);
316 	void	(*ca_attach)(device_t, device_t, void *);
317 	int	(*ca_detach)(device_t, int);
318 	int	(*ca_activate)(device_t, devact_t);
319 	/* technically, the next 2 belong into "struct cfdriver" */
320 	int	(*ca_rescan)(device_t, const char *,
321 			     const int *); /* scan for new children */
322 	void	(*ca_childdetached)(device_t, device_t);
323 };
324 LIST_HEAD(cfattachlist, cfattach);
325 
326 #define	CFATTACH_DECL3_NEW(name, ddsize, matfn, attfn, detfn, actfn, \
327 	rescanfn, chdetfn, __flags) \
328 struct cfattach __CONCAT(name,_ca) = {					\
329 	.ca_name		= ___STRING(name),			\
330 	.ca_devsize		= ddsize,				\
331 	.ca_flags		= (__flags) | DVF_PRIV_ALLOC,		\
332 	.ca_match 		= matfn,				\
333 	.ca_attach		= attfn,				\
334 	.ca_detach		= detfn,				\
335 	.ca_activate		= actfn,				\
336 	.ca_rescan		= rescanfn,				\
337 	.ca_childdetached	= chdetfn,				\
338 }
339 
340 #define	CFATTACH_DECL2_NEW(name, ddsize, matfn, attfn, detfn, actfn,	\
341 	rescanfn, chdetfn)						\
342 	CFATTACH_DECL3_NEW(name, ddsize, matfn, attfn, detfn, actfn,	\
343 	    rescanfn, chdetfn, 0)
344 
345 #define	CFATTACH_DECL_NEW(name, ddsize, matfn, attfn, detfn, actfn)	\
346 	CFATTACH_DECL2_NEW(name, ddsize, matfn, attfn, detfn, actfn, NULL, NULL)
347 
348 /* Flags given to config_detach(), and the ca_detach function. */
349 #define	DETACH_FORCE	0x01		/* force detachment; hardware gone */
350 #define	DETACH_QUIET	0x02		/* don't print a notice */
351 #define	DETACH_SHUTDOWN	0x04		/* detach because of system shutdown */
352 #define	DETACH_POWEROFF	0x08		/* going to power off; power down devices */
353 
354 struct cfdriver {
355 	LIST_ENTRY(cfdriver) cd_list;	/* link on allcfdrivers */
356 	struct cfattachlist cd_attach;	/* list of all attachments */
357 	device_t *cd_devs;		/* devices found */
358 	const char *cd_name;		/* device name */
359 	enum	devclass cd_class;	/* device classification */
360 	int	cd_ndevs;		/* size of cd_devs array */
361 	const struct cfiattrdata * const *cd_attrs; /* attributes provided */
362 };
363 LIST_HEAD(cfdriverlist, cfdriver);
364 
365 #define	CFDRIVER_DECL(name, class, attrs)				\
366 struct cfdriver __CONCAT(name,_cd) = {					\
367 	.cd_name		= ___STRING(name),			\
368 	.cd_class		= class,				\
369 	.cd_attrs		= attrs,				\
370 }
371 
372 /*
373  * The cfattachinit is a data structure used to associate a list of
374  * cfattach's with cfdrivers as found in the static kernel configuration.
375  */
376 struct cfattachinit {
377 	const char *cfai_name;		 /* driver name */
378 	struct cfattach * const *cfai_list;/* list of attachments */
379 };
380 /*
381  * the same, but with a non-constant list so it can be modified
382  * for module bookkeeping
383  */
384 struct cfattachlkminit {
385 	const char *cfai_name;		/* driver name */
386 	struct cfattach **cfai_list;	/* list of attachments */
387 };
388 
389 /*
390  * Configuration printing functions, and their return codes.  The second
391  * argument is NULL if the device was configured; otherwise it is the name
392  * of the parent device.  The return value is ignored if the device was
393  * configured, so most functions can return UNCONF unconditionally.
394  */
395 typedef int (*cfprint_t)(void *, const char *);		/* XXX const char * */
396 #define	QUIET	0		/* print nothing */
397 #define	UNCONF	1		/* print " not configured\n" */
398 #define	UNSUPP	2		/* print " not supported\n" */
399 
400 /*
401  * Pseudo-device attach information (function + number of pseudo-devs).
402  */
403 struct pdevinit {
404 	void	(*pdev_attach)(int);
405 	int	pdev_count;
406 };
407 
408 /* This allows us to wildcard a device unit. */
409 #define	DVUNIT_ANY	-1
410 
411 #ifdef _KERNEL
412 
413 extern struct cfdriverlist allcfdrivers;/* list of all cfdrivers */
414 extern struct cftablelist allcftables;	/* list of all cfdata tables */
415 extern device_t booted_device;		/* the device we booted from */
416 extern int booted_partition;		/* the partition on that device */
417 extern daddr_t booted_startblk;		/* or the start of a wedge */
418 extern uint64_t booted_nblks;		/* and the size of that wedge */
419 extern char *bootspec;			/* and the device/wedge name */
420 
421 struct vnode *opendisk(device_t);
422 int getdisksize(struct vnode *, uint64_t *, unsigned int *);
423 struct dkwedge_info;
424 int getdiskinfo(struct vnode *, struct dkwedge_info *);
425 
426 void	config_init(void);
427 int	config_init_component(struct cfdriver *const*,
428 			      const struct cfattachinit *, struct cfdata *);
429 int	config_fini_component(struct cfdriver *const*,
430 			      const struct cfattachinit *, struct cfdata *);
431 void	config_init_mi(void);
432 void	drvctl_init(void);
433 void	drvctl_fini(void);
434 
435 int	config_cfdriver_attach(struct cfdriver *);
436 int	config_cfdriver_detach(struct cfdriver *);
437 
438 int	config_cfattach_attach(const char *, struct cfattach *);
439 int	config_cfattach_detach(const char *, struct cfattach *);
440 
441 int	config_cfdata_attach(cfdata_t, int);
442 int	config_cfdata_detach(cfdata_t);
443 
444 struct cfdriver *config_cfdriver_lookup(const char *);
445 struct cfattach *config_cfattach_lookup(const char *, const char *);
446 const struct cfiattrdata *cfiattr_lookup(const char *, const struct cfdriver *);
447 
448 const char *cfdata_ifattr(const struct cfdata *);
449 
450 int	config_stdsubmatch(device_t, cfdata_t, const int *, void *);
451 cfdata_t config_search_loc(cfsubmatch_t, device_t,
452 				 const char *, const int *, void *);
453 cfdata_t config_search_ia(cfsubmatch_t, device_t,
454 				 const char *, void *);
455 cfdata_t config_rootsearch(cfsubmatch_t, const char *, void *);
456 device_t config_found_sm_loc(device_t, const char *, const int *,
457 			     void *, cfprint_t, cfsubmatch_t);
458 device_t config_found_ia(device_t, const char *, void *, cfprint_t);
459 device_t config_found(device_t, void *, cfprint_t);
460 device_t config_rootfound(const char *, void *);
461 device_t config_attach_loc(device_t, cfdata_t, const int *, void *, cfprint_t);
462 device_t config_attach(device_t, cfdata_t, void *, cfprint_t);
463 int	config_match(device_t, cfdata_t, void *);
464 
465 bool ifattr_match(const char *, const char *);
466 
467 device_t config_attach_pseudo(cfdata_t);
468 
469 int	config_detach(device_t, int);
470 int	config_detach_children(device_t, int flags);
471 bool	config_detach_all(int);
472 int	config_deactivate(device_t);
473 void	config_defer(device_t, void (*)(device_t));
474 void	config_deferred(device_t);
475 void	config_interrupts(device_t, void (*)(device_t));
476 void	config_mountroot(device_t, void (*)(device_t));
477 void	config_pending_incr(device_t);
478 void	config_pending_decr(device_t);
479 void	config_create_interruptthreads(void);
480 void	config_create_mountrootthreads(void);
481 
482 int	config_finalize_register(device_t, int (*)(device_t));
483 void	config_finalize(void);
484 void	config_finalize_mountroot(void);
485 
486 void	config_twiddle_init(void);
487 void	config_twiddle_fn(void *);
488 
489 void	null_childdetached(device_t, device_t);
490 
491 device_t	device_lookup(cfdriver_t, int);
492 void		*device_lookup_private(cfdriver_t, int);
493 void		device_register(device_t, void *);
494 void		device_register_post_config(device_t, void *);
495 
496 devclass_t	device_class(device_t);
497 cfdata_t	device_cfdata(device_t);
498 cfdriver_t	device_cfdriver(device_t);
499 cfattach_t	device_cfattach(device_t);
500 int		device_unit(device_t);
501 const char	*device_xname(device_t);
502 device_t	device_parent(device_t);
503 bool		device_is_active(device_t);
504 bool		device_activation(device_t, devact_level_t);
505 bool		device_is_enabled(device_t);
506 bool		device_has_power(device_t);
507 int		device_locator(device_t, u_int);
508 void		*device_private(device_t);
509 prop_dictionary_t device_properties(device_t);
510 
511 device_t	deviter_first(deviter_t *, deviter_flags_t);
512 void		deviter_init(deviter_t *, deviter_flags_t);
513 device_t	deviter_next(deviter_t *);
514 void		deviter_release(deviter_t *);
515 
516 bool		device_active(device_t, devactive_t);
517 bool		device_active_register(device_t,
518 				       void (*)(device_t, devactive_t));
519 void		device_active_deregister(device_t,
520 				         void (*)(device_t, devactive_t));
521 
522 bool		device_is_a(device_t, const char *);
523 
524 device_t	device_find_by_xname(const char *);
525 device_t	device_find_by_driver_unit(const char *, int);
526 
527 bool		device_pmf_is_registered(device_t);
528 
529 bool		device_pmf_driver_suspend(device_t, const pmf_qual_t *);
530 bool		device_pmf_driver_resume(device_t, const pmf_qual_t *);
531 bool		device_pmf_driver_shutdown(device_t, int);
532 
533 bool		device_pmf_driver_register(device_t,
534 		    bool (*)(device_t, const pmf_qual_t *),
535 		    bool (*)(device_t, const pmf_qual_t *),
536 		    bool (*)(device_t, int));
537 void		device_pmf_driver_deregister(device_t);
538 
539 bool		device_pmf_driver_child_register(device_t);
540 void		device_pmf_driver_set_child_register(device_t,
541 		    bool (*)(device_t));
542 
543 void		*device_pmf_bus_private(device_t);
544 bool		device_pmf_bus_suspend(device_t, const pmf_qual_t *);
545 bool		device_pmf_bus_resume(device_t, const pmf_qual_t *);
546 bool		device_pmf_bus_shutdown(device_t, int);
547 
548 device_lock_t	device_getlock(device_t);
549 void		device_pmf_unlock(device_t);
550 bool		device_pmf_lock(device_t);
551 
552 bool		device_is_self_suspended(device_t);
553 void		device_pmf_self_suspend(device_t, const pmf_qual_t *);
554 void		device_pmf_self_resume(device_t, const pmf_qual_t *);
555 bool		device_pmf_self_wait(device_t, const pmf_qual_t *);
556 
557 void		device_pmf_bus_register(device_t, void *,
558 		    bool (*)(device_t, const pmf_qual_t *),
559 		    bool (*)(device_t, const pmf_qual_t *),
560 		    bool (*)(device_t, int),
561 		    void (*)(device_t));
562 void		device_pmf_bus_deregister(device_t);
563 
564 void		*device_pmf_class_private(device_t);
565 bool		device_pmf_class_suspend(device_t, const pmf_qual_t *);
566 bool		device_pmf_class_resume(device_t, const pmf_qual_t *);
567 
568 void		device_pmf_class_register(device_t, void *,
569 		    bool (*)(device_t, const pmf_qual_t *),
570 		    bool (*)(device_t, const pmf_qual_t *),
571 		    void (*)(device_t));
572 void		device_pmf_class_deregister(device_t);
573 
574 device_t	shutdown_first(struct shutdown_state *);
575 device_t	shutdown_next(struct shutdown_state *);
576 #endif /* _KERNEL */
577 
578 #endif /* !_SYS_DEVICE_H_ */
579