1 /**	$MirOS: src/sys/sys/device.h,v 1.3 2005/07/04 03:36:38 tg Exp $	*/
2 /*	$NetBSD: device.h,v 1.64 2002/11/24 17:33:43 thorpej Exp $ */
3 /*	$OpenBSD: device.h,v 1.29 2004/11/23 19:08:55 miod Exp $	*/
4 /*	$NetBSD: device.h,v 1.15 1996/04/09 20:55:24 cgd Exp $	*/
5 
6 /*
7  * Copyright (c) 1992, 1993
8  *	The Regents of the University of California.  All rights reserved.
9  *
10  * This software was developed by the Computer Systems Engineering group
11  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
12  * contributed to Berkeley.
13  *
14  * All advertising materials mentioning features or use of this software
15  * must display the following acknowledgement:
16  *	This product includes software developed by the University of
17  *	California, Lawrence Berkeley Laboratory.
18  *
19  * Redistribution and use in source and binary forms, with or without
20  * modification, are permitted provided that the following conditions
21  * are met:
22  * 1. Redistributions of source code must retain the above copyright
23  *    notice, this list of conditions and the following disclaimer.
24  * 2. Redistributions in binary form must reproduce the above copyright
25  *    notice, this list of conditions and the following disclaimer in the
26  *    documentation and/or other materials provided with the distribution.
27  * 3. Neither the name of the University nor the names of its contributors
28  *    may be used to endorse or promote products derived from this software
29  *    without specific prior written permission.
30  *
31  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
32  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
35  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
40  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41  * SUCH DAMAGE.
42  *
43  *	@(#)device.h	8.2 (Berkeley) 2/17/94
44  */
45 /*
46  * Copyright (c) 1996, 2000 Christopher G. Demetriou
47  * All rights reserved.
48  *
49  * Redistribution and use in source and binary forms, with or without
50  * modification, are permitted provided that the following conditions
51  * are met:
52  * 1. Redistributions of source code must retain the above copyright
53  *    notice, this list of conditions and the following disclaimer.
54  * 2. Redistributions in binary form must reproduce the above copyright
55  *    notice, this list of conditions and the following disclaimer in the
56  *    documentation and/or other materials provided with the distribution.
57  * 3. All advertising materials mentioning features or use of this software
58  *    must display the following acknowledgement:
59  *          This product includes software developed for the
60  *          NetBSD Project.  See http://www.netbsd.org/ for
61  *          information about NetBSD.
62  * 4. The name of the author may not be used to endorse or promote products
63  *    derived from this software without specific prior written permission.
64  *
65  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
66  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
67  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
68  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
69  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
70  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
71  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
72  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
74  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75  *
76  * --(license Id: LICENSE.proto,v 1.1 2000/06/13 21:40:26 cgd Exp )--
77  */
78 
79 #ifndef _SYS_DEVICE_H_
80 #define	_SYS_DEVICE_H_
81 
82 #include <sys/queue.h>
83 
84 /*
85  * Minimal device structures.
86  * Note that all ``system'' device types are listed here.
87  */
88 enum devclass {
89 	DV_DULL,		/* generic, no special info */
90 	DV_CPU,			/* CPU (carries resource utilization) */
91 	DV_DISK,		/* disk drive (label, etc) */
92 	DV_IFNET,		/* network interface */
93 	DV_TAPE,		/* tape device */
94 	DV_TTY			/* serial line interface (???) */
95 };
96 
97 /*
98  * Actions for ca_activate.
99  */
100 enum devact {
101 	DVACT_ACTIVATE,		/* activate the device */
102 	DVACT_DEACTIVATE	/* deactivate the device */
103 };
104 
105 #include <sys/lock.h>
106 
107 struct device {
108 	enum	devclass dv_class;	/* this device's classification */
109 	TAILQ_ENTRY(device) dv_list;	/* entry on list of all devices */
110 	struct	cfdata *dv_cfdata;	/* config data that found us */
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 	int	dv_flags;		/* misc. flags; see below */
115 	int	dv_ref;			/* ref count */
116 };
117 
118 /* dv_flags */
119 #define	DVF_ACTIVE	0x0001		/* device is activated */
120 
121 TAILQ_HEAD(devicelist, device);
122 
123 /* `event' counters (use zero or more per device instance, as needed) */
124 struct evcnt {
125 	TAILQ_ENTRY(evcnt) ev_list;	/* entry on list of all counters */
126 	struct	device *ev_dev;		/* associated device */
127 	int	ev_count;		/* how many have occurred */
128 	char	ev_name[8];		/* what to call them (systat display) */
129 };
130 TAILQ_HEAD(evcntlist, evcnt);
131 
132 /*
133  * Configuration data (i.e., data placed in ioconf.c).
134  */
135 struct cfdata {
136 	struct	cfattach *cf_attach;	/* config attachment */
137 	struct	cfdriver *cf_driver;	/* config driver */
138 	short	cf_unit;		/* unit number */
139 	short	cf_fstate;		/* finding state (below) */
140 	int	*cf_loc;		/* locators (machine dependent) */
141 	int	cf_flags;		/* flags from config */
142 	short	*cf_parents;		/* potential parents */
143 	int	cf_locnames;		/* start of names */
144 	void	(**cf_ivstubs)(void);	/* config-generated vectors, if any */
145 	short	cf_starunit1;		/* 1st usable unit number by STAR */
146 };
147 extern struct cfdata cfdata[];
148 #define FSTATE_NOTFOUND	0	/* has not been found */
149 #define	FSTATE_FOUND	1	/* has been found */
150 #define	FSTATE_STAR	2	/* duplicable */
151 #define FSTATE_DNOTFOUND 3	/* has not been found, and is disabled */
152 #define FSTATE_DSTAR	4	/* duplicable, and is disabled */
153 
154 typedef int (*cfmatch_t)(struct device *, void *, void *);
155 typedef void (*cfscan_t)(struct device *, void *);
156 
157 /*
158  * `configuration' attachment and driver (what the machine-independent
159  * autoconf uses).  As devices are found, they are applied against all
160  * the potential matches.  The one with the best match is taken, and a
161  * device structure (plus any other data desired) is allocated.  Pointers
162  * to these are placed into an array of pointers.  The array itself must
163  * be dynamic since devices can be found long after the machine is up
164  * and running.
165  *
166  * Devices can have multiple configuration attachments if they attach
167  * to different attributes (busses, or whatever), to allow specification
168  * of multiple match and attach functions.  There is only one configuration
169  * driver per driver, so that things like unit numbers and the device
170  * structure array will be shared.
171  */
172 struct cfattach {
173 	size_t	  ca_devsize;		/* size of dev data (for malloc) */
174 	cfmatch_t ca_match;		/* returns a match level */
175 	void	(*ca_attach)(struct device *, struct device *, void *);
176 	int	(*ca_detach)(struct device *, int);
177 	int	(*ca_activate)(struct device *, enum devact);
178 	void    (*ca_zeroref)(struct device *);
179 };
180 
181 #define	CFATTACH_DECL(name, ddsize, matfn, attfn, detfn, actfn)		\
182 struct cfattach __CONCAT(name,_ca) = {					\
183 	(size_t)ddsize,							\
184 	(cfmatch_t)matfn,						\
185 	(void (*)(struct device *, struct device *, void *))attfn,	\
186 	(int (*)(struct device *, int))detfn,				\
187 	(int (*)(struct device *, enum devact))actfn,			\
188 }
189 
190 /* Flags given to config_detach(), and the ca_detach function. */
191 #define	DETACH_FORCE	0x01		/* force detachment; hardware gone */
192 #define	DETACH_QUIET	0x02		/* don't print a notice */
193 
194 struct cfdriver {
195 	void	**cd_devs;		/* devices found */
196 	char	*cd_name;		/* device name */
197 	enum	devclass cd_class;	/* device classification */
198 	int	cd_indirect;		/* indirectly configure subdevices */
199 	int	cd_ndevs;		/* size of cd_devs array */
200 };
201 
202 /*
203  * Configuration printing functions, and their return codes.  The second
204  * argument is NULL if the device was configured; otherwise it is the name
205  * of the parent device.  The return value is ignored if the device was
206  * configured, so most functions can return UNCONF unconditionally.
207  */
208 typedef int (*cfprint_t)(void *, const char *);
209 #define	QUIET	0		/* print nothing */
210 #define	UNCONF	1		/* print " not configured\n" */
211 #define	UNSUPP	2		/* print " not supported\n" */
212 
213 /*
214  * Pseudo-device attach information (function + number of pseudo-devs).
215  */
216 struct pdevinit {
217 	void	(*pdev_attach)(int);
218 	int	pdev_count;
219 };
220 
221 #ifdef _KERNEL
222 struct cftable {
223 	struct cfdata *tab;
224 	TAILQ_ENTRY(cftable) list;
225 };
226 TAILQ_HEAD(cftable_head, cftable);
227 
228 extern struct devicelist alldevs;	/* list of all devices */
229 extern struct evcntlist allevents;	/* list of all event counters */
230 
231 extern int autoconf_verbose;
232 extern __volatile int config_pending;	/* semaphore for mountroot */
233 
234 void config_init(void);
235 void *config_search(cfmatch_t, struct device *, void *);
236 void *config_rootsearch(cfmatch_t, char *, void *);
237 struct device *config_found_sm(struct device *, void *, cfprint_t,
238     cfmatch_t);
239 struct device *config_rootfound(char *, void *);
240 void config_scan(cfscan_t, struct device *);
241 struct device *config_attach(struct device *, void *, void *, cfprint_t);
242 int config_detach(struct device *, int);
243 int config_detach_children(struct device *, int);
244 int config_activate(struct device *);
245 int config_deactivate(struct device *);
246 int config_activate_children(struct device *, enum devact);
247 struct device *config_make_softc(struct device *parent,
248     struct cfdata *cf);
249 void config_defer(struct device *, void (*)(struct device *));
250 void evcnt_attach(struct device *, const char *, struct evcnt *);
251 void config_pending_incr(void);
252 void config_pending_decr(void);
253 
254 struct device *device_lookup(struct cfdriver *, int unit);
255 void device_ref(struct device *);
256 void device_unref(struct device *);
257 
258 #ifdef __HAVE_DEVICE_REGISTER
259 void device_register(struct device *, void *);
260 #endif
261 
262 /* compatibility definitions */
263 #define config_found(d, a, p)	config_found_sm((d), (a), (p), NULL)
264 
265 #endif /* _KERNEL */
266 
267 #endif /* !_SYS_DEVICE_H_ */
268