FreeBSD/Linux Kernel Cross Reference
sys/sys/device.h
1 /* $NetBSD: device.h,v 1.112.6.2 2011/01/07 06:33:44 riz 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/evcnt.h>
81 #include <sys/queue.h>
82
83 typedef struct device *device_t;
84 #ifdef _KERNEL
85 #include <sys/pmf.h>
86 #endif
87
88 #include <prop/proplib.h>
89
90 /*
91 * Minimal device structures.
92 * Note that all ``system'' device types are listed here.
93 */
94 typedef enum devclass {
95 DV_DULL, /* generic, no special info */
96 DV_CPU, /* CPU (carries resource utilization) */
97 DV_DISK, /* disk drive (label, etc) */
98 DV_IFNET, /* network interface */
99 DV_TAPE, /* tape device */
100 DV_TTY, /* serial line interface (?) */
101 DV_AUDIODEV, /* audio device */
102 DV_DISPLAYDEV, /* display device */
103 DV_BUS /* bus device */
104 } devclass_t;
105
106 /*
107 * Actions for ca_activate.
108 */
109 typedef enum devact {
110 DVACT_ACTIVATE, /* activate the device */
111 DVACT_DEACTIVATE /* deactivate the device */
112 } devact_t;
113
114 typedef enum {
115 DVA_SYSTEM,
116 DVA_HARDWARE
117 } devactive_t;
118
119 typedef struct cfdata *cfdata_t;
120 typedef struct cfdriver *cfdriver_t;
121 typedef struct cfattach *cfattach_t;
122
123 struct device {
124 devclass_t dv_class; /* this device's classification */
125 TAILQ_ENTRY(device) dv_list; /* entry on list of all devices */
126 cfdata_t dv_cfdata; /* config data that found us
127 (NULL if pseudo-device) */
128 cfdriver_t dv_cfdriver; /* our cfdriver */
129 cfattach_t dv_cfattach; /* our cfattach */
130 int dv_unit; /* device unit number */
131 char dv_xname[16]; /* external name (name + unit) */
132 device_t dv_parent; /* pointer to parent device
133 (NULL if pseudo- or root node) */
134 int dv_depth; /* number of parents until root */
135 int dv_flags; /* misc. flags; see below */
136 void *dv_private; /* this device's private storage */
137 int *dv_locators; /* our actual locators (optional) */
138 prop_dictionary_t dv_properties;/* properties dictionary */
139
140 size_t dv_activity_count;
141 void (**dv_activity_handlers)(device_t, devactive_t);
142
143 bool (*dv_driver_suspend)(device_t PMF_FN_PROTO);
144 bool (*dv_driver_resume)(device_t PMF_FN_PROTO);
145 bool (*dv_driver_shutdown)(device_t, int);
146 bool (*dv_driver_child_register)(device_t);
147
148 void *dv_bus_private;
149 bool (*dv_bus_suspend)(device_t PMF_FN_PROTO);
150 bool (*dv_bus_resume)(device_t PMF_FN_PROTO);
151 bool (*dv_bus_shutdown)(device_t, int);
152 void (*dv_bus_deregister)(device_t);
153
154 void *dv_class_private;
155 bool (*dv_class_suspend)(device_t PMF_FN_PROTO);
156 bool (*dv_class_resume)(device_t PMF_FN_PROTO);
157 void (*dv_class_deregister)(device_t);
158
159 void *dv_pmf_private;
160 };
161
162 /* dv_flags */
163 #define DVF_ACTIVE 0x0001 /* device is activated */
164 #define DVF_PRIV_ALLOC 0x0002 /* device private storage != device */
165 #define DVF_POWER_HANDLERS 0x0004 /* device has suspend/resume support */
166 #define DVF_CLASS_SUSPENDED 0x0008 /* device class suspend was called */
167 #define DVF_DRIVER_SUSPENDED 0x0010 /* device driver suspend was called */
168 #define DVF_BUS_SUSPENDED 0x0020 /* device bus suspend was called */
169 #define DVF_SELF_SUSPENDED 0x0040 /* device suspended itself */
170
171 TAILQ_HEAD(devicelist, device);
172
173 enum deviter_flags {
174 DEVITER_F_RW = 0x1
175 , DEVITER_F_SHUTDOWN = 0x2
176 , DEVITER_F_LEAVES_FIRST = 0x4
177 , DEVITER_F_ROOT_FIRST = 0x8
178 };
179
180 typedef enum deviter_flags deviter_flags_t;
181
182 struct deviter {
183 device_t di_prev;
184 deviter_flags_t di_flags;
185 int di_curdepth;
186 int di_maxdepth;
187 };
188
189 typedef struct deviter deviter_t;
190
191 /*
192 * Description of a locator, as part of interface attribute definitions.
193 */
194 struct cflocdesc {
195 const char *cld_name;
196 const char *cld_defaultstr; /* NULL if no default */
197 int cld_default;
198 };
199
200 /*
201 * Description of an interface attribute, provided by potential
202 * parent device drivers, referred to by child device configuration data.
203 */
204 struct cfiattrdata {
205 const char *ci_name;
206 int ci_loclen;
207 const struct cflocdesc ci_locdesc[
208 #if defined(__GNUC__) && __GNUC__ <= 2
209 0
210 #endif
211 ];
212 };
213
214 /*
215 * Description of a configuration parent. Each device attachment attaches
216 * to an "interface attribute", which is given in this structure. The parent
217 * *must* carry this attribute. Optionally, an individual device instance
218 * may also specify a specific parent device instance.
219 */
220 struct cfparent {
221 const char *cfp_iattr; /* interface attribute */
222 const char *cfp_parent; /* optional specific parent */
223 int cfp_unit; /* optional specific unit
224 (-1 to wildcard) */
225 };
226
227 /*
228 * Configuration data (i.e., data placed in ioconf.c).
229 */
230 struct cfdata {
231 const char *cf_name; /* driver name */
232 const char *cf_atname; /* attachment name */
233 short cf_unit; /* unit number */
234 short cf_fstate; /* finding state (below) */
235 int *cf_loc; /* locators (machine dependent) */
236 int cf_flags; /* flags from config */
237 const struct cfparent *cf_pspec;/* parent specification */
238 };
239 #define FSTATE_NOTFOUND 0 /* has not been found */
240 #define FSTATE_FOUND 1 /* has been found */
241 #define FSTATE_STAR 2 /* duplicable */
242 #define FSTATE_DSTAR 3 /* has not been found, and disabled */
243 #define FSTATE_DNOTFOUND 4 /* duplicate, and disabled */
244
245 /*
246 * Multiple configuration data tables may be maintained. This structure
247 * provides the linkage.
248 */
249 struct cftable {
250 cfdata_t ct_cfdata; /* pointer to cfdata table */
251 TAILQ_ENTRY(cftable) ct_list; /* list linkage */
252 };
253 TAILQ_HEAD(cftablelist, cftable);
254
255 typedef int (*cfsubmatch_t)(device_t, cfdata_t, const int *, void *);
256
257 /*
258 * `configuration' attachment and driver (what the machine-independent
259 * autoconf uses). As devices are found, they are applied against all
260 * the potential matches. The one with the best match is taken, and a
261 * device structure (plus any other data desired) is allocated. Pointers
262 * to these are placed into an array of pointers. The array itself must
263 * be dynamic since devices can be found long after the machine is up
264 * and running.
265 *
266 * Devices can have multiple configuration attachments if they attach
267 * to different attributes (busses, or whatever), to allow specification
268 * of multiple match and attach functions. There is only one configuration
269 * driver per driver, so that things like unit numbers and the device
270 * structure array will be shared.
271 */
272 struct cfattach {
273 const char *ca_name; /* name of attachment */
274 LIST_ENTRY(cfattach) ca_list; /* link on cfdriver's list */
275 size_t ca_devsize; /* size of dev data (for malloc) */
276 int ca_flags; /* flags for driver allocation etc */
277 int (*ca_match)(device_t, cfdata_t, void *);
278 void (*ca_attach)(device_t, device_t, void *);
279 int (*ca_detach)(device_t, int);
280 int (*ca_activate)(device_t, devact_t);
281 /* technically, the next 2 belong into "struct cfdriver" */
282 int (*ca_rescan)(device_t, const char *,
283 const int *); /* scan for new children */
284 void (*ca_childdetached)(device_t, device_t);
285 };
286 LIST_HEAD(cfattachlist, cfattach);
287
288 #define CFATTACH_DECL2(name, ddsize, matfn, attfn, detfn, actfn, \
289 rescanfn, chdetfn) \
290 struct cfattach __CONCAT(name,_ca) = { \
291 .ca_name = ___STRING(name), \
292 .ca_devsize = ddsize, \
293 .ca_match = matfn, \
294 .ca_attach = attfn, \
295 .ca_detach = detfn, \
296 .ca_activate = actfn, \
297 .ca_rescan = rescanfn, \
298 .ca_childdetached = chdetfn, \
299 }
300
301 #define CFATTACH_DECL(name, ddsize, matfn, attfn, detfn, actfn) \
302 CFATTACH_DECL2(name, ddsize, matfn, attfn, detfn, actfn, NULL, NULL)
303
304 #define CFATTACH_DECL2_NEW(name, ddsize, matfn, attfn, detfn, actfn, \
305 rescanfn, chdetfn) \
306 struct cfattach __CONCAT(name,_ca) = { \
307 .ca_name = ___STRING(name), \
308 .ca_devsize = ddsize, \
309 .ca_flags = DVF_PRIV_ALLOC, \
310 .ca_match = matfn, \
311 .ca_attach = attfn, \
312 .ca_detach = detfn, \
313 .ca_activate = actfn, \
314 .ca_rescan = rescanfn, \
315 .ca_childdetached = chdetfn, \
316 }
317
318 #define CFATTACH_DECL_NEW(name, ddsize, matfn, attfn, detfn, actfn) \
319 CFATTACH_DECL2_NEW(name, ddsize, matfn, attfn, detfn, actfn, NULL, NULL)
320
321 /* Flags given to config_detach(), and the ca_detach function. */
322 #define DETACH_FORCE 0x01 /* force detachment; hardware gone */
323 #define DETACH_QUIET 0x02 /* don't print a notice */
324
325 struct cfdriver {
326 LIST_ENTRY(cfdriver) cd_list; /* link on allcfdrivers */
327 struct cfattachlist cd_attach; /* list of all attachments */
328 device_t *cd_devs; /* devices found */
329 const char *cd_name; /* device name */
330 enum devclass cd_class; /* device classification */
331 int cd_ndevs; /* size of cd_devs array */
332 const struct cfiattrdata * const *cd_attrs; /* attributes provided */
333 };
334 LIST_HEAD(cfdriverlist, cfdriver);
335
336 #define CFDRIVER_DECL(name, class, attrs) \
337 struct cfdriver __CONCAT(name,_cd) = { \
338 .cd_name = ___STRING(name), \
339 .cd_class = class, \
340 .cd_attrs = attrs, \
341 }
342
343 /*
344 * The cfattachinit is a data structure used to associate a list of
345 * cfattach's with cfdrivers as found in the static kernel configuration.
346 */
347 struct cfattachinit {
348 const char *cfai_name; /* driver name */
349 struct cfattach * const *cfai_list;/* list of attachments */
350 };
351 /*
352 * the same, but with a non-constant list so it can be modified
353 * for LKM bookkeeping
354 */
355 struct cfattachlkminit {
356 const char *cfai_name; /* driver name */
357 struct cfattach **cfai_list; /* list of attachments */
358 };
359
360 /*
361 * Configuration printing functions, and their return codes. The second
362 * argument is NULL if the device was configured; otherwise it is the name
363 * of the parent device. The return value is ignored if the device was
364 * configured, so most functions can return UNCONF unconditionally.
365 */
366 typedef int (*cfprint_t)(void *, const char *); /* XXX const char * */
367 #define QUIET 0 /* print nothing */
368 #define UNCONF 1 /* print " not configured\n" */
369 #define UNSUPP 2 /* print " not supported\n" */
370
371 /*
372 * Pseudo-device attach information (function + number of pseudo-devs).
373 */
374 struct pdevinit {
375 void (*pdev_attach)(int);
376 int pdev_count;
377 };
378
379 /* This allows us to wildcard a device unit. */
380 #define DVUNIT_ANY -1
381
382 #ifdef _KERNEL
383
384 extern struct cfdriverlist allcfdrivers;/* list of all cfdrivers */
385 extern struct devicelist alldevs; /* list of all devices */
386 extern struct cftablelist allcftables; /* list of all cfdata tables */
387 extern device_t booted_device; /* the device we booted from */
388 extern device_t booted_wedge; /* the wedge on that device */
389 extern int booted_partition; /* or the partition on that device */
390
391 struct vnode *opendisk(struct device *);
392 int getdisksize(struct vnode *, uint64_t *, unsigned *);
393 int config_handle_wedges(struct device *, int);
394
395 void config_init(void);
396 void drvctl_init(void);
397 void configure(void);
398 void configure2(void);
399
400 int config_cfdriver_attach(struct cfdriver *);
401 int config_cfdriver_detach(struct cfdriver *);
402
403 int config_cfattach_attach(const char *, struct cfattach *);
404 int config_cfattach_detach(const char *, struct cfattach *);
405
406 int config_cfdata_attach(cfdata_t, int);
407 int config_cfdata_detach(cfdata_t);
408
409 struct cfdriver *config_cfdriver_lookup(const char *);
410 struct cfattach *config_cfattach_lookup(const char *, const char *);
411 const struct cfiattrdata *cfiattr_lookup(const char *, const struct cfdriver *);
412
413 int config_stdsubmatch(device_t, cfdata_t, const int *, void *);
414 cfdata_t config_search_loc(cfsubmatch_t, device_t,
415 const char *, const int *, void *);
416 cfdata_t config_search_ia(cfsubmatch_t, device_t,
417 const char *, void *);
418 cfdata_t config_rootsearch(cfsubmatch_t, const char *, void *);
419 device_t config_found_sm_loc(device_t, const char *, const int *,
420 void *, cfprint_t, cfsubmatch_t);
421 device_t config_found_ia(device_t, const char *, void *, cfprint_t);
422 device_t config_found(device_t, void *, cfprint_t);
423 device_t config_rootfound(const char *, void *);
424 device_t config_attach_loc(device_t, cfdata_t, const int *, void *, cfprint_t);
425 device_t config_attach(device_t, cfdata_t, void *, cfprint_t);
426 int config_match(device_t, cfdata_t, void *);
427
428 device_t config_attach_pseudo(cfdata_t);
429
430 int config_detach(device_t, int);
431 int config_detach_children(device_t, int flags);
432 int config_activate(device_t);
433 int config_deactivate(device_t);
434 void config_defer(device_t, void (*)(device_t));
435 void config_deferred(device_t);
436 void config_interrupts(device_t, void (*)(device_t));
437 void config_pending_incr(void);
438 void config_pending_decr(void);
439
440 int config_finalize_register(device_t, int (*)(device_t));
441 void config_finalize(void);
442
443 device_t device_lookup(cfdriver_t, int);
444 void *device_lookup_private(cfdriver_t, int);
445 #ifdef __HAVE_DEVICE_REGISTER
446 void device_register(device_t, void *);
447 #endif
448
449 devclass_t device_class(device_t);
450 cfdata_t device_cfdata(device_t);
451 cfdriver_t device_cfdriver(device_t);
452 cfattach_t device_cfattach(device_t);
453 int device_unit(device_t);
454 const char *device_xname(device_t);
455 device_t device_parent(device_t);
456 bool device_is_active(device_t);
457 bool device_is_enabled(device_t);
458 bool device_has_power(device_t);
459 int device_locator(device_t, u_int);
460 void *device_private(device_t);
461 prop_dictionary_t device_properties(device_t);
462
463 device_t deviter_first(deviter_t *, deviter_flags_t);
464 void deviter_init(deviter_t *, deviter_flags_t);
465 device_t deviter_next(deviter_t *);
466 void deviter_release(deviter_t *);
467
468 bool device_active(device_t, devactive_t);
469 bool device_active_register(device_t,
470 void (*)(device_t, devactive_t));
471 void device_active_deregister(device_t,
472 void (*)(device_t, devactive_t));
473
474 bool device_is_a(device_t, const char *);
475
476 device_t device_find_by_xname(const char *);
477 device_t device_find_by_driver_unit(const char *, int);
478
479 bool device_pmf_is_registered(device_t);
480
481 bool device_pmf_driver_suspend(device_t PMF_FN_PROTO);
482 bool device_pmf_driver_resume(device_t PMF_FN_PROTO);
483 bool device_pmf_driver_shutdown(device_t, int);
484
485 bool device_pmf_driver_register(device_t,
486 bool (*)(device_t PMF_FN_PROTO),
487 bool (*)(device_t PMF_FN_PROTO),
488 bool (*)(device_t, int));
489 void device_pmf_driver_deregister(device_t);
490
491 bool device_pmf_driver_child_register(device_t);
492 void device_pmf_driver_set_child_register(device_t,
493 bool (*)(device_t));
494
495 void *device_pmf_bus_private(device_t);
496 bool device_pmf_bus_suspend(device_t PMF_FN_PROTO);
497 bool device_pmf_bus_resume(device_t PMF_FN_PROTO);
498 bool device_pmf_bus_shutdown(device_t, int);
499
500 void *device_pmf_private(device_t);
501 void device_pmf_unlock(device_t PMF_FN_PROTO);
502 bool device_pmf_lock(device_t PMF_FN_PROTO);
503
504 bool device_is_self_suspended(device_t);
505 void device_pmf_self_suspend(device_t PMF_FN_PROTO);
506 void device_pmf_self_resume(device_t PMF_FN_PROTO);
507 bool device_pmf_self_wait(device_t PMF_FN_PROTO);
508
509 void device_pmf_bus_register(device_t, void *,
510 bool (*)(device_t PMF_FN_PROTO),
511 bool (*)(device_t PMF_FN_PROTO),
512 bool (*)(device_t, int),
513 void (*)(device_t));
514 void device_pmf_bus_deregister(device_t);
515
516 void *device_pmf_class_private(device_t);
517 bool device_pmf_class_suspend(device_t PMF_FN_PROTO);
518 bool device_pmf_class_resume(device_t PMF_FN_PROTO);
519
520 void device_pmf_class_register(device_t, void *,
521 bool (*)(device_t PMF_FN_PROTO),
522 bool (*)(device_t PMF_FN_PROTO),
523 void (*)(device_t));
524 void device_pmf_class_deregister(device_t);
525
526 #endif /* _KERNEL */
527
528 #endif /* !_SYS_DEVICE_H_ */
Cache object: 17f6e25510544b7ae626a62ca23fdd77
|