FreeBSD/Linux Kernel Cross Reference
sys/sys/device.h
1 /* $NetBSD: device.h,v 1.73 2005/02/26 22:25:34 perry 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/properties.h>
81 #include <sys/queue.h>
82
83 /*
84 * Minimal device structures.
85 * Note that all ``system'' device types are listed here.
86 */
87 enum devclass {
88 DV_DULL, /* generic, no special info */
89 DV_CPU, /* CPU (carries resource utilization) */
90 DV_DISK, /* disk drive (label, etc) */
91 DV_IFNET, /* network interface */
92 DV_TAPE, /* tape device */
93 DV_TTY /* serial line interface (?) */
94 };
95
96 /*
97 * Actions for ca_activate.
98 */
99 enum devact {
100 DVACT_ACTIVATE, /* activate the device */
101 DVACT_DEACTIVATE /* deactivate the device */
102 };
103
104 struct device {
105 enum devclass dv_class; /* this device's classification */
106 TAILQ_ENTRY(device) dv_list; /* entry on list of all devices */
107 struct cfdata *dv_cfdata; /* config data that found us
108 (NULL if pseudo-device) */
109 struct cfdriver *dv_cfdriver; /* our cfdriver */
110 struct cfattach *dv_cfattach; /* our cfattach */
111 int dv_unit; /* device unit number */
112 char dv_xname[16]; /* external name (name + unit) */
113 struct device *dv_parent; /* pointer to parent device
114 (NULL if pesudo- or root node) */
115 int dv_flags; /* misc. flags; see below */
116 int *dv_locators; /* our actual locators (optional) */
117 };
118
119 /* dv_flags */
120 #define DVF_ACTIVE 0x0001 /* device is activated */
121
122 TAILQ_HEAD(devicelist, device);
123
124 /*
125 * `event' counters (use zero or more per device instance, as needed)
126 */
127
128 struct evcnt {
129 u_int64_t ev_count; /* how many have occurred */
130 TAILQ_ENTRY(evcnt) ev_list; /* entry on list of all counters */
131 unsigned char ev_type; /* counter type; see below */
132 unsigned char ev_grouplen; /* 'group' len, excluding NUL */
133 unsigned char ev_namelen; /* 'name' len, excluding NUL */
134 char ev_pad1; /* reserved (for now); 0 */
135 const struct evcnt *ev_parent; /* parent, for hierarchical ctrs */
136 const char *ev_group; /* name of group */
137 const char *ev_name; /* name of specific event */
138 };
139 TAILQ_HEAD(evcntlist, evcnt);
140
141 /* maximum group/name lengths, including trailing NUL */
142 #define EVCNT_STRING_MAX 256
143
144 /* ev_type values */
145 #define EVCNT_TYPE_MISC 0 /* miscellaneous; catch all */
146 #define EVCNT_TYPE_INTR 1 /* interrupt; count with vmstat -i */
147 #define EVCNT_TYPE_TRAP 2 /* processor trap/execption */
148
149 /*
150 * initializer for an event count structure. the lengths are initted and
151 * it is added to the evcnt list at attach time.
152 */
153 #define EVCNT_INITIALIZER(type, parent, group, name) \
154 { \
155 0, /* ev_count */ \
156 { 0 }, /* ev_list */ \
157 type, /* ev_type */ \
158 0, /* ev_grouplen */ \
159 0, /* ev_namelen */ \
160 0, /* ev_pad1 */ \
161 parent, /* ev_parent */ \
162 group, /* ev_group */ \
163 name, /* ev_name */ \
164 }
165
166 /*
167 * Attach a static event counter. This uses a link set to do the work.
168 * NOTE: "ev" should not be a pointer to the object, but rather a direct
169 * reference to the object itself.
170 */
171 #define EVCNT_ATTACH_STATIC(ev) __link_set_add_data(evcnts, ev)
172 #define EVCNT_ATTACH_STATIC2(ev, n) __link_set_add_data2(evcnts, ev, n)
173
174 /*
175 * Description of a configuration parent. Each device attachment attaches
176 * to an "interface attribute", which is given in this structure. The parent
177 * *must* carry this attribute. Optionally, an individual device instance
178 * may also specify a specific parent device instance.
179 */
180 struct cfparent {
181 const char *cfp_iattr; /* interface attribute */
182 const char *cfp_parent; /* optional specific parent */
183 int cfp_unit; /* optional specific unit
184 (-1 to wildcard) */
185 };
186
187 /*
188 * Configuration data (i.e., data placed in ioconf.c).
189 */
190 struct cfdata {
191 const char *cf_name; /* driver name */
192 const char *cf_atname; /* attachment name */
193 short cf_unit; /* unit number */
194 short cf_fstate; /* finding state (below) */
195 int *cf_loc; /* locators (machine dependent) */
196 int cf_flags; /* flags from config */
197 const struct cfparent *cf_pspec;/* parent specification */
198 const char * const *cf_locnames;/* locator names (machine dependent) */
199 };
200 #define FSTATE_NOTFOUND 0 /* has not been found */
201 #define FSTATE_FOUND 1 /* has been found */
202 #define FSTATE_STAR 2 /* duplicable */
203 #define FSTATE_DSTAR 3 /* has not been found, and disabled */
204 #define FSTATE_DNOTFOUND 4 /* duplicate, and disabled */
205
206 /*
207 * Multiple configuration data tables may be maintained. This structure
208 * provides the linkage.
209 */
210 struct cftable {
211 struct cfdata *ct_cfdata; /* pointer to cfdata table */
212 TAILQ_ENTRY(cftable) ct_list; /* list linkage */
213 };
214 TAILQ_HEAD(cftablelist, cftable);
215
216 typedef int (*cfmatch_t)(struct device *, struct cfdata *, void *);
217
218 /*
219 * XXX the "locdesc_t" is unnecessary; the len is known to "config" and
220 * should be made available through cfdata->cf_pspec->cfp_iattr.
221 * So just an "int *" should do it.
222 */
223 typedef struct {
224 int len;
225 int locs[1];
226 } locdesc_t;
227 typedef int (*cfmatch_loc_t)(struct device *, struct cfdata *,
228 const locdesc_t *, void *);
229
230 /*
231 * `configuration' attachment and driver (what the machine-independent
232 * autoconf uses). As devices are found, they are applied against all
233 * the potential matches. The one with the best match is taken, and a
234 * device structure (plus any other data desired) is allocated. Pointers
235 * to these are placed into an array of pointers. The array itself must
236 * be dynamic since devices can be found long after the machine is up
237 * and running.
238 *
239 * Devices can have multiple configuration attachments if they attach
240 * to different attributes (busses, or whatever), to allow specification
241 * of multiple match and attach functions. There is only one configuration
242 * driver per driver, so that things like unit numbers and the device
243 * structure array will be shared.
244 */
245 struct cfattach {
246 const char *ca_name; /* name of attachment */
247 LIST_ENTRY(cfattach) ca_list; /* link on cfdriver's list */
248 size_t ca_devsize; /* size of dev data (for malloc) */
249 cfmatch_t ca_match; /* returns a match level */
250 void (*ca_attach)(struct device *, struct device *, void *);
251 int (*ca_detach)(struct device *, int);
252 int (*ca_activate)(struct device *, enum devact);
253 /* technically, the next 2 belong into "struct cfdriver" */
254 int (*ca_rescan)(struct device *, const char *,
255 const int *); /* scan for new children */
256 void (*ca_childdetached)(struct device *, struct device *);
257 };
258 LIST_HEAD(cfattachlist, cfattach);
259
260 #define CFATTACH_DECL(name, ddsize, matfn, attfn, detfn, actfn) \
261 struct cfattach __CONCAT(name,_ca) = { \
262 ___STRING(name), { 0 }, ddsize, matfn, attfn, detfn, actfn, 0, 0 \
263 }
264
265 #define CFATTACH_DECL2(name, ddsize, matfn, attfn, detfn, actfn, \
266 rescanfn, chdetfn) \
267 struct cfattach __CONCAT(name,_ca) = { \
268 ___STRING(name), { 0 }, ddsize, matfn, attfn, detfn, actfn, \
269 rescanfn, chdetfn \
270 }
271
272 /* Flags given to config_detach(), and the ca_detach function. */
273 #define DETACH_FORCE 0x01 /* force detachment; hardware gone */
274 #define DETACH_QUIET 0x02 /* don't print a notice */
275
276 struct cfdriver {
277 LIST_ENTRY(cfdriver) cd_list; /* link on allcfdrivers */
278 struct cfattachlist cd_attach; /* list of all attachments */
279 void **cd_devs; /* devices found */
280 const char *cd_name; /* device name */
281 enum devclass cd_class; /* device classification */
282 int cd_ndevs; /* size of cd_devs array */
283 const char * const *cd_attrs; /* attributes for this device */
284 };
285 LIST_HEAD(cfdriverlist, cfdriver);
286
287 #define CFDRIVER_DECL(name, class, attrs) \
288 struct cfdriver __CONCAT(name,_cd) = { \
289 { 0 }, { 0 }, NULL, ___STRING(name), class, 0, attrs \
290 }
291
292 /*
293 * The cfattachinit is a data structure used to associate a list of
294 * cfattach's with cfdrivers as found in the static kernel configuration.
295 */
296 struct cfattachinit {
297 const char *cfai_name; /* driver name */
298 struct cfattach * const *cfai_list;/* list of attachments */
299 };
300 /*
301 * the same, but with a non-constant list so it can be modified
302 * for LKM bookkeeping
303 */
304 struct cfattachlkminit {
305 const char *cfai_name; /* driver name */
306 struct cfattach **cfai_list; /* list of attachments */
307 };
308
309 /*
310 * Configuration printing functions, and their return codes. The second
311 * argument is NULL if the device was configured; otherwise it is the name
312 * of the parent device. The return value is ignored if the device was
313 * configured, so most functions can return UNCONF unconditionally.
314 */
315 typedef int (*cfprint_t)(void *, const char *); /* XXX const char * */
316 #define QUIET 0 /* print nothing */
317 #define UNCONF 1 /* print " not configured\n" */
318 #define UNSUPP 2 /* print " not supported\n" */
319
320 /*
321 * Pseudo-device attach information (function + number of pseudo-devs).
322 */
323 struct pdevinit {
324 void (*pdev_attach)(int);
325 int pdev_count;
326 };
327
328 /* This allows us to wildcard a device unit. */
329 #define DVUNIT_ANY -1
330
331 #ifdef _KERNEL
332
333 extern struct cfdriverlist allcfdrivers;/* list of all cfdrivers */
334 extern struct devicelist alldevs; /* list of all devices */
335 extern struct evcntlist allevents; /* list of all event counters */
336 extern struct cftablelist allcftables; /* list of all cfdata tables */
337 extern struct device *booted_device; /* the device we booted from */
338 extern struct device *booted_wedge; /* the wedge on that device */
339 extern int booted_partition; /* or the partition on that device */
340
341 extern __volatile int config_pending; /* semaphore for mountroot */
342
343 extern propdb_t dev_propdb; /* device properties database */
344
345 void config_init(void);
346 void configure(void);
347
348 int config_cfdriver_attach(struct cfdriver *);
349 int config_cfdriver_detach(struct cfdriver *);
350
351 int config_cfattach_attach(const char *, struct cfattach *);
352 int config_cfattach_detach(const char *, struct cfattach *);
353
354 int config_cfdata_attach(struct cfdata *, int);
355 int config_cfdata_detach(struct cfdata *);
356
357 struct cfdriver *config_cfdriver_lookup(const char *);
358 struct cfattach *config_cfattach_lookup(const char *, const char *);
359
360 struct cfdata *config_search(cfmatch_t, struct device *, void *);
361 struct cfdata *config_search_loc(cfmatch_loc_t, struct device *,
362 const char *, const locdesc_t *, void *);
363 #define config_search_ia(sm, d, ia, a) \
364 config_search_loc((sm), (d), (ia), NULL, (a))
365 struct cfdata *config_rootsearch(cfmatch_t, const char *, void *);
366 struct device *config_found_sm(struct device *, void *, cfprint_t, cfmatch_t);
367 struct device *config_found_sm_loc(struct device *,
368 const char *, const locdesc_t *, void *,
369 cfprint_t, cfmatch_loc_t);
370 #define config_found_ia(d, ia, a, p) \
371 config_found_sm_loc((d), (ia), NULL, (a), (p), NULL)
372 #define config_found(d, a, p) \
373 config_found_sm_loc((d), NULL, NULL, (a), (p), NULL)
374 struct device *config_rootfound(const char *, void *);
375 struct device *config_attach_loc(struct device *, struct cfdata *,
376 const locdesc_t *, void *, cfprint_t);
377 #define config_attach(p, cf, aux, pr) \
378 config_attach_loc((p), (cf), 0, (aux), (pr))
379 int config_match(struct device *, struct cfdata *, void *);
380
381 struct device *config_attach_pseudo(struct cfdata *);
382
383 void config_makeroom(int n, struct cfdriver *cd);
384 int config_detach(struct device *, int);
385 int config_activate(struct device *);
386 int config_deactivate(struct device *);
387 void config_defer(struct device *, void (*)(struct device *));
388 void config_interrupts(struct device *, void (*)(struct device *));
389 void config_pending_incr(void);
390 void config_pending_decr(void);
391
392 int config_finalize_register(struct device *, int (*)(struct device *));
393 void config_finalize(void);
394
395 #ifdef __HAVE_DEVICE_REGISTER
396 void device_register(struct device *, void *);
397 #endif
398
399 void evcnt_init(void);
400 void evcnt_attach_static(struct evcnt *);
401 void evcnt_attach_dynamic(struct evcnt *, int, const struct evcnt *,
402 const char *, const char *);
403 void evcnt_detach(struct evcnt *);
404
405 /* compatibility definitions */
406 struct device *config_found_sm(struct device *, void *, cfprint_t, cfmatch_t);
407
408 /* convenience definitions */
409 #define device_lookup(cfd, unit) \
410 (((unit) < (cfd)->cd_ndevs) ? (cfd)->cd_devs[(unit)] : NULL)
411
412 #ifdef DDB
413 void event_print(int, void (*)(const char *, ...));
414 #endif
415 #endif /* _KERNEL */
416
417 #endif /* !_SYS_DEVICE_H_ */
Cache object: 64af724e3c16a25d37c71d499ef1cf9b
|