PageRenderTime 42ms CodeModel.GetById 12ms app.highlight 21ms RepoModel.GetById 1ms app.codeStats 0ms

/testbed/sys/device.h

http://rtems-atapi.googlecode.com/
C++ Header | 527 lines | 313 code | 70 blank | 144 comment | 1 complexity | cd9b1caa2537dac32e6e658f1fcd2d4c MD5 | raw file
  1/* $NetBSD: device.h,v 1.112.6.1 2009/03/15 19:43:48 snj 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 <rtems/bsd/sys/queue.h>
 82
 83//typedef struct device *device_t;
 84#ifdef _KERNEL
 85#include "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 */
 94typedef 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 */
109typedef enum devact {
110	DVACT_ACTIVATE,		/* activate the device */
111	DVACT_DEACTIVATE	/* deactivate the device */
112} devact_t;
113
114typedef enum {
115	DVA_SYSTEM,
116	DVA_HARDWARE
117} devactive_t;
118
119typedef struct cfdata *cfdata_t;
120typedef struct cfdriver *cfdriver_t;
121typedef struct cfattach *cfattach_t;
122
123struct 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
171TAILQ_HEAD(devicelist, device);
172
173enum 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
180typedef enum deviter_flags deviter_flags_t;
181
182struct deviter {
183	device_t	di_prev;
184	deviter_flags_t	di_flags;
185	int		di_curdepth;
186	int		di_maxdepth;
187};
188
189typedef struct deviter deviter_t;
190
191/*
192 * Description of a locator, as part of interface attribute definitions.
193 */
194struct 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 */
204struct 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 */
220struct 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 */
230struct 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 */
249struct cftable {
250	cfdata_t	ct_cfdata;	/* pointer to cfdata table */
251	TAILQ_ENTRY(cftable) ct_list;	/* list linkage */
252};
253TAILQ_HEAD(cftablelist, cftable);
254
255typedef 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 */
272struct 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};
286LIST_HEAD(cfattachlist, cfattach);
287
288#define	CFATTACH_DECL2(name, ddsize, matfn, attfn, detfn, actfn, \
289	rescanfn, chdetfn) \
290struct 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) \
306struct 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
325struct 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};
334LIST_HEAD(cfdriverlist, cfdriver);
335
336#define	CFDRIVER_DECL(name, class, attrs)				\
337struct 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 */
347struct 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 */
355struct 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 */
366typedef 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 */
374struct 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
384extern struct cfdriverlist allcfdrivers;/* list of all cfdrivers */
385extern struct devicelist alldevs;	/* list of all devices */
386extern struct cftablelist allcftables;	/* list of all cfdata tables */
387extern device_t booted_device;		/* the device we booted from */
388extern device_t booted_wedge;		/* the wedge on that device */
389extern int booted_partition;		/* or the partition on that device */
390
391struct vnode *opendisk(struct device *);
392int config_handle_wedges(struct device *, int);
393
394void	config_init(void);
395void	drvctl_init(void);
396void	configure(void);
397void	configure2(void);
398
399int	config_cfdriver_attach(struct cfdriver *);
400int	config_cfdriver_detach(struct cfdriver *);
401
402int	config_cfattach_attach(const char *, struct cfattach *);
403int	config_cfattach_detach(const char *, struct cfattach *);
404
405int	config_cfdata_attach(cfdata_t, int);
406int	config_cfdata_detach(cfdata_t);
407
408struct cfdriver *config_cfdriver_lookup(const char *);
409struct cfattach *config_cfattach_lookup(const char *, const char *);
410const struct cfiattrdata *cfiattr_lookup(const char *, const struct cfdriver *);
411
412int	config_stdsubmatch(device_t, cfdata_t, const int *, void *);
413cfdata_t config_search_loc(cfsubmatch_t, device_t,
414				 const char *, const int *, void *);
415cfdata_t config_search_ia(cfsubmatch_t, device_t,
416				 const char *, void *);
417cfdata_t config_rootsearch(cfsubmatch_t, const char *, void *);
418device_t config_found_sm_loc(device_t, const char *, const int *,
419			     void *, cfprint_t, cfsubmatch_t);
420device_t config_found_ia(device_t, const char *, void *, cfprint_t);
421device_t config_found(device_t, void *, cfprint_t);
422device_t config_rootfound(const char *, void *);
423device_t config_attach_loc(device_t, cfdata_t, const int *, void *, cfprint_t);
424device_t config_attach(device_t, cfdata_t, void *, cfprint_t);
425int	config_match(device_t, cfdata_t, void *);
426
427device_t config_attach_pseudo(cfdata_t);
428
429int	config_detach(device_t, int);
430int	config_detach_children(device_t, int flags);
431int	config_activate(device_t);
432int	config_deactivate(device_t);
433void	config_defer(device_t, void (*)(device_t));
434void	config_deferred(device_t);
435void	config_interrupts(device_t, void (*)(device_t));
436void	config_pending_incr(void);
437void	config_pending_decr(void);
438
439int	config_finalize_register(device_t, int (*)(device_t));
440void	config_finalize(void);
441
442device_t	device_lookup(cfdriver_t, int);
443void		*device_lookup_private(cfdriver_t, int);
444#ifdef __HAVE_DEVICE_REGISTER
445void		device_register(device_t, void *);
446#endif
447
448devclass_t	device_class(device_t);
449cfdata_t	device_cfdata(device_t);
450cfdriver_t	device_cfdriver(device_t);
451cfattach_t	device_cfattach(device_t);
452int		device_unit(device_t);
453const char	*device_xname(device_t);
454device_t	device_parent(device_t);
455bool		device_is_active(device_t);
456bool		device_is_enabled(device_t);
457bool		device_has_power(device_t);
458int		device_locator(device_t, u_int);
459void		*device_private(device_t);
460//prop_dictionary_t device_properties(device_t);
461
462device_t	deviter_first(deviter_t *, deviter_flags_t);
463void		deviter_init(deviter_t *, deviter_flags_t);
464device_t	deviter_next(deviter_t *);
465void		deviter_release(deviter_t *);
466
467bool		device_active(device_t, devactive_t);
468bool		device_active_register(device_t,
469				       void (*)(device_t, devactive_t));
470void		device_active_deregister(device_t,
471				         void (*)(device_t, devactive_t));
472
473bool		device_is_a(device_t, const char *);
474
475device_t	device_find_by_xname(const char *);
476device_t	device_find_by_driver_unit(const char *, int);
477
478bool		device_pmf_is_registered(device_t);
479
480bool		device_pmf_driver_suspend(device_t PMF_FN_PROTO);
481bool		device_pmf_driver_resume(device_t PMF_FN_PROTO);
482bool		device_pmf_driver_shutdown(device_t, int);
483
484bool		device_pmf_driver_register(device_t,
485		    bool (*)(device_t PMF_FN_PROTO),
486		    bool (*)(device_t PMF_FN_PROTO),
487		    bool (*)(device_t, int));
488void		device_pmf_driver_deregister(device_t);
489
490bool		device_pmf_driver_child_register(device_t);
491void		device_pmf_driver_set_child_register(device_t,
492		    bool (*)(device_t));
493
494void		*device_pmf_bus_private(device_t);
495bool		device_pmf_bus_suspend(device_t PMF_FN_PROTO);
496bool		device_pmf_bus_resume(device_t PMF_FN_PROTO);
497bool		device_pmf_bus_shutdown(device_t, int);
498
499void		*device_pmf_private(device_t);
500void		device_pmf_unlock(device_t PMF_FN_PROTO);
501bool		device_pmf_lock(device_t PMF_FN_PROTO);
502
503bool		device_is_self_suspended(device_t);
504void		device_pmf_self_suspend(device_t PMF_FN_PROTO);
505void		device_pmf_self_resume(device_t PMF_FN_PROTO);
506bool		device_pmf_self_wait(device_t PMF_FN_PROTO);
507
508void		device_pmf_bus_register(device_t, void *,
509		    bool (*)(device_t PMF_FN_PROTO),
510		    bool (*)(device_t PMF_FN_PROTO),
511		    bool (*)(device_t, int),
512		    void (*)(device_t));
513void		device_pmf_bus_deregister(device_t);
514
515void		*device_pmf_class_private(device_t);
516bool		device_pmf_class_suspend(device_t PMF_FN_PROTO);
517bool		device_pmf_class_resume(device_t PMF_FN_PROTO);
518
519void		device_pmf_class_register(device_t, void *,
520		    bool (*)(device_t PMF_FN_PROTO),
521		    bool (*)(device_t PMF_FN_PROTO),
522		    void (*)(device_t));
523void		device_pmf_class_deregister(device_t);
524
525#endif /* _KERNEL */
526
527#endif /* !_SYS_DEVICE_H_ */