1 /* $NetBSD: device.h,v 1.129 2010/01/07 22:39:52 dyoung Exp $ */
4 * Copyright (c) 1996, 2000 Christopher G. Demetriou
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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.
34 * --(license Id: LICENSE.proto,v 1.1 2000/06/13 21:40:26 cgd Exp )--
38 * Copyright (c) 1992, 1993
39 * The Regents of the University of California. All rights reserved.
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.
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.
50 * Redistribution and use in source and binary forms, with or without
51 * modification, are permitted provided that the following conditions
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.
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
74 * @(#)device.h 8.2 (Berkeley) 2/17/94
77 #ifndef _SYS_DEVICE_H_
78 #define _SYS_DEVICE_H_
80 #include <sys/device_if.h>
81 #include <sys/evcnt.h>
82 #include <sys/queue.h>
85 #include <sys/mutex.h>
86 #include <sys/condvar.h>
90 #include <prop/proplib.h>
93 * Minimal device structures.
94 * Note that all ``system'' device types are listed here.
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 */
110 * Actions for ca_activate.
112 typedef enum devact
{
113 DVACT_DEACTIVATE
/* deactivate the device */
121 typedef struct cfdata
*cfdata_t
;
122 typedef struct cfdriver
*cfdriver_t
;
123 typedef struct cfattach
*cfattach_t
;
134 struct device_suspensor
{
135 const struct device_suspensor
*ds_delegator
;
139 #define DEVICE_SUSPENSORS_MAX 16
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 */
158 size_t dv_activity_count
;
159 void (**dv_activity_handlers
)(device_t
, devactive_t
);
161 bool (*dv_driver_suspend
)(device_t PMF_FN_PROTO
);
162 bool (*dv_driver_resume
)(device_t PMF_FN_PROTO
);
163 bool (*dv_driver_shutdown
)(device_t
, int);
164 bool (*dv_driver_child_register
)(device_t
);
166 void *dv_bus_private
;
167 bool (*dv_bus_suspend
)(device_t PMF_FN_PROTO
);
168 bool (*dv_bus_resume
)(device_t PMF_FN_PROTO
);
169 bool (*dv_bus_shutdown
)(device_t
, int);
170 void (*dv_bus_deregister
)(device_t
);
172 void *dv_class_private
;
173 bool (*dv_class_suspend
)(device_t PMF_FN_PROTO
);
174 bool (*dv_class_resume
)(device_t PMF_FN_PROTO
);
175 void (*dv_class_deregister
)(device_t
);
180 struct device_lock dv_lock
;
181 device_suspensor_t dv_bus_suspensors
[DEVICE_SUSPENSORS_MAX
];
182 device_suspensor_t dv_driver_suspensors
[DEVICE_SUSPENSORS_MAX
];
183 device_suspensor_t dv_class_suspensors
[DEVICE_SUSPENSORS_MAX
];
184 struct device_garbage
{
191 #define DVF_ACTIVE 0x0001 /* device is activated */
192 #define DVF_PRIV_ALLOC 0x0002 /* device private storage != device */
193 #define DVF_POWER_HANDLERS 0x0004 /* device has suspend/resume support */
194 #define DVF_CLASS_SUSPENDED 0x0008 /* device class suspend was called */
195 #define DVF_DRIVER_SUSPENDED 0x0010 /* device driver suspend was called */
196 #define DVF_BUS_SUSPENDED 0x0020 /* device bus suspend was called */
197 #define DVF_DETACH_SHUTDOWN 0x0080 /* device detaches safely at shutdown */
199 TAILQ_HEAD(devicelist
, device
);
203 , DEVITER_F_SHUTDOWN
= 0x2
204 , DEVITER_F_LEAVES_FIRST
= 0x4
205 , DEVITER_F_ROOT_FIRST
= 0x8
208 typedef enum deviter_flags deviter_flags_t
;
212 deviter_flags_t di_flags
;
218 typedef struct deviter deviter_t
;
220 struct shutdown_state
{
227 * Description of a locator, as part of interface attribute definitions.
230 const char *cld_name
;
231 const char *cld_defaultstr
; /* NULL if no default */
236 * Description of an interface attribute, provided by potential
237 * parent device drivers, referred to by child device configuration data.
242 const struct cflocdesc ci_locdesc
[
243 #if defined(__GNUC__) && __GNUC__ <= 2
250 * Description of a configuration parent. Each device attachment attaches
251 * to an "interface attribute", which is given in this structure. The parent
252 * *must* carry this attribute. Optionally, an individual device instance
253 * may also specify a specific parent device instance.
256 const char *cfp_iattr
; /* interface attribute */
257 const char *cfp_parent
; /* optional specific parent */
258 int cfp_unit
; /* optional specific unit
259 (DVUNIT_ANY to wildcard) */
263 * Configuration data (i.e., data placed in ioconf.c).
266 const char *cf_name
; /* driver name */
267 const char *cf_atname
; /* attachment name */
268 short cf_unit
; /* unit number */
269 short cf_fstate
; /* finding state (below) */
270 int *cf_loc
; /* locators (machine dependent) */
271 int cf_flags
; /* flags from config */
272 const struct cfparent
*cf_pspec
;/* parent specification */
274 #define FSTATE_NOTFOUND 0 /* has not been found */
275 #define FSTATE_FOUND 1 /* has been found */
276 #define FSTATE_STAR 2 /* duplicable */
277 #define FSTATE_DSTAR 3 /* has not been found, and disabled */
278 #define FSTATE_DNOTFOUND 4 /* duplicate, and disabled */
281 * Multiple configuration data tables may be maintained. This structure
282 * provides the linkage.
285 cfdata_t ct_cfdata
; /* pointer to cfdata table */
286 TAILQ_ENTRY(cftable
) ct_list
; /* list linkage */
288 TAILQ_HEAD(cftablelist
, cftable
);
290 typedef int (*cfsubmatch_t
)(device_t
, cfdata_t
, const int *, void *);
293 * `configuration' attachment and driver (what the machine-independent
294 * autoconf uses). As devices are found, they are applied against all
295 * the potential matches. The one with the best match is taken, and a
296 * device structure (plus any other data desired) is allocated. Pointers
297 * to these are placed into an array of pointers. The array itself must
298 * be dynamic since devices can be found long after the machine is up
301 * Devices can have multiple configuration attachments if they attach
302 * to different attributes (busses, or whatever), to allow specification
303 * of multiple match and attach functions. There is only one configuration
304 * driver per driver, so that things like unit numbers and the device
305 * structure array will be shared.
308 const char *ca_name
; /* name of attachment */
309 LIST_ENTRY(cfattach
) ca_list
; /* link on cfdriver's list */
310 size_t ca_devsize
; /* size of dev data (for malloc) */
311 int ca_flags
; /* flags for driver allocation etc */
312 int (*ca_match
)(device_t
, cfdata_t
, void *);
313 void (*ca_attach
)(device_t
, device_t
, void *);
314 int (*ca_detach
)(device_t
, int);
315 int (*ca_activate
)(device_t
, devact_t
);
316 /* technically, the next 2 belong into "struct cfdriver" */
317 int (*ca_rescan
)(device_t
, const char *,
318 const int *); /* scan for new children */
319 void (*ca_childdetached
)(device_t
, device_t
);
321 LIST_HEAD(cfattachlist
, cfattach
);
323 #define CFATTACH_DECL(name, ddsize, matfn, attfn, detfn, actfn) \
324 struct cfattach __CONCAT(name,_ca) = { \
325 .ca_name = ___STRING(name), \
326 .ca_devsize = ddsize, \
329 .ca_attach = attfn, \
330 .ca_detach = detfn, \
331 .ca_activate = actfn, \
333 .ca_childdetached = NULL, \
336 #define CFATTACH_DECL3_NEW(name, ddsize, matfn, attfn, detfn, actfn, \
337 rescanfn, chdetfn, __flags) \
338 struct cfattach __CONCAT(name,_ca) = { \
339 .ca_name = ___STRING(name), \
340 .ca_devsize = ddsize, \
341 .ca_flags = (__flags) | DVF_PRIV_ALLOC, \
343 .ca_attach = attfn, \
344 .ca_detach = detfn, \
345 .ca_activate = actfn, \
346 .ca_rescan = rescanfn, \
347 .ca_childdetached = chdetfn, \
350 #define CFATTACH_DECL2_NEW(name, ddsize, matfn, attfn, detfn, actfn, \
352 CFATTACH_DECL3_NEW(name, ddsize, matfn, attfn, detfn, actfn, \
353 rescanfn, chdetfn, 0)
355 #define CFATTACH_DECL_NEW(name, ddsize, matfn, attfn, detfn, actfn) \
356 CFATTACH_DECL2_NEW(name, ddsize, matfn, attfn, detfn, actfn, NULL, NULL)
358 /* Flags given to config_detach(), and the ca_detach function. */
359 #define DETACH_FORCE 0x01 /* force detachment; hardware gone */
360 #define DETACH_QUIET 0x02 /* don't print a notice */
361 #define DETACH_SHUTDOWN 0x04 /* detach because of system shutdown */
364 LIST_ENTRY(cfdriver
) cd_list
; /* link on allcfdrivers */
365 struct cfattachlist cd_attach
; /* list of all attachments */
366 device_t
*cd_devs
; /* devices found */
367 const char *cd_name
; /* device name */
368 enum devclass cd_class
; /* device classification */
369 int cd_ndevs
; /* size of cd_devs array */
370 const struct cfiattrdata
* const *cd_attrs
; /* attributes provided */
372 LIST_HEAD(cfdriverlist
, cfdriver
);
374 #define CFDRIVER_DECL(name, class, attrs) \
375 struct cfdriver __CONCAT(name,_cd) = { \
376 .cd_name = ___STRING(name), \
382 * The cfattachinit is a data structure used to associate a list of
383 * cfattach's with cfdrivers as found in the static kernel configuration.
385 struct cfattachinit
{
386 const char *cfai_name
; /* driver name */
387 struct cfattach
* const *cfai_list
;/* list of attachments */
390 * the same, but with a non-constant list so it can be modified
391 * for module bookkeeping
393 struct cfattachlkminit
{
394 const char *cfai_name
; /* driver name */
395 struct cfattach
**cfai_list
; /* list of attachments */
399 * Configuration printing functions, and their return codes. The second
400 * argument is NULL if the device was configured; otherwise it is the name
401 * of the parent device. The return value is ignored if the device was
402 * configured, so most functions can return UNCONF unconditionally.
404 typedef int (*cfprint_t
)(void *, const char *); /* XXX const char * */
405 #define QUIET 0 /* print nothing */
406 #define UNCONF 1 /* print " not configured\n" */
407 #define UNSUPP 2 /* print " not supported\n" */
410 * Pseudo-device attach information (function + number of pseudo-devs).
413 void (*pdev_attach
)(int);
417 /* This allows us to wildcard a device unit. */
418 #define DVUNIT_ANY -1
422 extern struct cfdriverlist allcfdrivers
;/* list of all cfdrivers */
423 extern struct cftablelist allcftables
; /* list of all cfdata tables */
424 extern device_t booted_device
; /* the device we booted from */
425 extern device_t booted_wedge
; /* the wedge on that device */
426 extern int booted_partition
; /* or the partition on that device */
428 struct vnode
*opendisk(struct device
*);
429 int config_handle_wedges(struct device
*, int);
431 void config_init(void);
432 void config_init_mi(void);
433 void drvctl_init(void);
435 int config_cfdriver_attach(struct cfdriver
*);
436 int config_cfdriver_detach(struct cfdriver
*);
438 int config_cfattach_attach(const char *, struct cfattach
*);
439 int config_cfattach_detach(const char *, struct cfattach
*);
441 int config_cfdata_attach(cfdata_t
, int);
442 int config_cfdata_detach(cfdata_t
);
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
*);
448 int config_stdsubmatch(device_t
, cfdata_t
, const int *, void *);
449 cfdata_t
config_search_loc(cfsubmatch_t
, device_t
,
450 const char *, const int *, void *);
451 cfdata_t
config_search_ia(cfsubmatch_t
, device_t
,
452 const char *, void *);
453 cfdata_t
config_rootsearch(cfsubmatch_t
, const char *, void *);
454 device_t
config_found_sm_loc(device_t
, const char *, const int *,
455 void *, cfprint_t
, cfsubmatch_t
);
456 device_t
config_found_ia(device_t
, const char *, void *, cfprint_t
);
457 device_t
config_found(device_t
, void *, cfprint_t
);
458 device_t
config_rootfound(const char *, void *);
459 device_t
config_attach_loc(device_t
, cfdata_t
, const int *, void *, cfprint_t
);
460 device_t
config_attach(device_t
, cfdata_t
, void *, cfprint_t
);
461 int config_match(device_t
, cfdata_t
, void *);
463 bool ifattr_match(const char *, const char *);
465 device_t
config_attach_pseudo(cfdata_t
);
467 int config_detach(device_t
, int);
468 int config_detach_children(device_t
, int flags
);
469 bool config_detach_all(int);
470 int config_deactivate(device_t
);
471 void config_defer(device_t
, void (*)(device_t
));
472 void config_deferred(device_t
);
473 void config_interrupts(device_t
, void (*)(device_t
));
474 void config_pending_incr(void);
475 void config_pending_decr(void);
476 void config_create_interruptthreads(void);
478 int config_finalize_register(device_t
, int (*)(device_t
));
479 void config_finalize(void);
481 void config_twiddle_init(void);
482 void config_twiddle_fn(void *);
484 void null_childdetached(device_t
, device_t
);
486 device_t
device_lookup(cfdriver_t
, int);
487 void *device_lookup_private(cfdriver_t
, int);
488 #ifdef __HAVE_DEVICE_REGISTER
489 void device_register(device_t
, void *);
492 devclass_t
device_class(device_t
);
493 cfdata_t
device_cfdata(device_t
);
494 cfdriver_t
device_cfdriver(device_t
);
495 cfattach_t
device_cfattach(device_t
);
496 int device_unit(device_t
);
497 const char *device_xname(device_t
);
498 device_t
device_parent(device_t
);
499 bool device_is_active(device_t
);
500 bool device_activation(device_t
, devact_level_t
);
501 bool device_is_enabled(device_t
);
502 bool device_has_power(device_t
);
503 int device_locator(device_t
, u_int
);
504 void *device_private(device_t
);
505 prop_dictionary_t
device_properties(device_t
);
507 device_t
deviter_first(deviter_t
*, deviter_flags_t
);
508 void deviter_init(deviter_t
*, deviter_flags_t
);
509 device_t
deviter_next(deviter_t
*);
510 void deviter_release(deviter_t
*);
512 bool device_active(device_t
, devactive_t
);
513 bool device_active_register(device_t
,
514 void (*)(device_t
, devactive_t
));
515 void device_active_deregister(device_t
,
516 void (*)(device_t
, devactive_t
));
518 bool device_is_a(device_t
, const char *);
520 device_t
device_find_by_xname(const char *);
521 device_t
device_find_by_driver_unit(const char *, int);
523 bool device_pmf_is_registered(device_t
);
525 bool device_pmf_driver_suspend(device_t PMF_FN_PROTO
);
526 bool device_pmf_driver_resume(device_t PMF_FN_PROTO
);
527 bool device_pmf_driver_shutdown(device_t
, int);
529 bool device_pmf_driver_register(device_t
,
530 bool (*)(device_t PMF_FN_PROTO
),
531 bool (*)(device_t PMF_FN_PROTO
),
532 bool (*)(device_t
, int));
533 void device_pmf_driver_deregister(device_t
);
535 bool device_pmf_driver_child_register(device_t
);
536 void device_pmf_driver_set_child_register(device_t
,
539 void *device_pmf_bus_private(device_t
);
540 bool device_pmf_bus_suspend(device_t PMF_FN_PROTO
);
541 bool device_pmf_bus_resume(device_t PMF_FN_PROTO
);
542 bool device_pmf_bus_shutdown(device_t
, int);
544 device_lock_t
device_getlock(device_t
);
545 void device_pmf_unlock(device_t
);
546 bool device_pmf_lock(device_t
);
548 bool device_is_self_suspended(device_t
);
549 void device_pmf_self_suspend(device_t PMF_FN_PROTO
);
550 void device_pmf_self_resume(device_t PMF_FN_PROTO
);
551 bool device_pmf_self_wait(device_t PMF_FN_PROTO
);
553 void device_pmf_bus_register(device_t
, void *,
554 bool (*)(device_t PMF_FN_PROTO
),
555 bool (*)(device_t PMF_FN_PROTO
),
556 bool (*)(device_t
, int),
558 void device_pmf_bus_deregister(device_t
);
560 void *device_pmf_class_private(device_t
);
561 bool device_pmf_class_suspend(device_t PMF_FN_PROTO
);
562 bool device_pmf_class_resume(device_t PMF_FN_PROTO
);
564 void device_pmf_class_register(device_t
, void *,
565 bool (*)(device_t PMF_FN_PROTO
),
566 bool (*)(device_t PMF_FN_PROTO
),
568 void device_pmf_class_deregister(device_t
);
570 device_t
shutdown_first(struct shutdown_state
*);
571 device_t
shutdown_next(struct shutdown_state
*);
574 #endif /* !_SYS_DEVICE_H_ */