xref: /netbsd/sys/sys/device.h (revision bf9ec67e)
1 /* $NetBSD: device.h,v 1.49 2002/02/15 11:18:26 simonb 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. All advertising materials mentioning features or use of this software
59  *    must display the following acknowledgement:
60  *	This product includes software developed by the University of
61  *	California, Berkeley and its contributors.
62  * 4. Neither the name of the University nor the names of its contributors
63  *    may be used to endorse or promote products derived from this software
64  *    without specific prior written permission.
65  *
66  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
67  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
68  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
69  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
70  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
71  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
72  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
73  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
74  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
75  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
76  * SUCH DAMAGE.
77  *
78  *	@(#)device.h	8.2 (Berkeley) 2/17/94
79  */
80 
81 #ifndef _SYS_DEVICE_H_
82 #define	_SYS_DEVICE_H_
83 
84 #include <sys/queue.h>
85 
86 /*
87  * Minimal device structures.
88  * Note that all ``system'' device types are listed here.
89  */
90 enum devclass {
91 	DV_DULL,		/* generic, no special info */
92 	DV_CPU,			/* CPU (carries resource utilization) */
93 	DV_DISK,		/* disk drive (label, etc) */
94 	DV_IFNET,		/* network interface */
95 	DV_TAPE,		/* tape device */
96 	DV_TTY			/* serial line interface (?) */
97 };
98 
99 /*
100  * Actions for ca_activate.
101  */
102 enum devact {
103 	DVACT_ACTIVATE,		/* activate the device */
104 	DVACT_DEACTIVATE	/* deactivate the device */
105 };
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 };
116 
117 /* dv_flags */
118 #define	DVF_ACTIVE	0x0001		/* device is activated */
119 
120 TAILQ_HEAD(devicelist, device);
121 
122 /*
123  * `event' counters (use zero or more per device instance, as needed)
124  */
125 
126 struct evcnt {
127 	u_int64_t	ev_count;	/* how many have occurred */
128 	TAILQ_ENTRY(evcnt) ev_list;	/* entry on list of all counters */
129 	unsigned char	ev_type;	/* counter type; see below */
130 	unsigned char	ev_grouplen;	/* 'group' len, excluding NUL */
131 	unsigned char	ev_namelen;	/* 'name' len, excluding NUL */
132 	char		ev_pad1;	/* reserved (for now); 0 */
133 	const struct evcnt *ev_parent;	/* parent, for hierarchical ctrs */
134 	const char	*ev_group;	/* name of group */
135 	const char	*ev_name;	/* name of specific event */
136 };
137 TAILQ_HEAD(evcntlist, evcnt);
138 
139 /* maximum group/name lengths, including trailing NUL */
140 #define	EVCNT_STRING_MAX	256
141 
142 /* ev_type values */
143 #define	EVCNT_TYPE_MISC		0	/* miscellaneous; catch all */
144 #define	EVCNT_TYPE_INTR		1	/* interrupt; count with vmstat -i */
145 #define	EVCNT_TYPE_TRAP		2	/* processor trap/execption */
146 
147 /*
148  * initializer for an event count structure.  the lengths are initted and
149  * it is added to the evcnt list at attach time.
150  */
151 #define	EVCNT_INITIALIZER(type, parent, group, name)			\
152     {									\
153 	0,			/* ev_count */				\
154 	{ },			/* ev_list */				\
155 	type,			/* ev_type */				\
156 	0,			/* ev_grouplen */			\
157 	0,			/* ev_namelen */			\
158 	0,			/* ev_pad1 */				\
159 	parent,			/* ev_parent */				\
160 	group,			/* ev_group */				\
161 	name,			/* ev_name */				\
162     }
163 
164 /*
165  * Configuration data (i.e., data placed in ioconf.c).
166  */
167 struct cfdata {
168 	struct	cfattach *cf_attach;	/* config attachment */
169 	struct	cfdriver *cf_driver;	/* config driver */
170 	short	cf_unit;		/* unit number */
171 	short	cf_fstate;		/* finding state (below) */
172 	int	*cf_loc;		/* locators (machine dependent) */
173 	int	cf_flags;		/* flags from config */
174 	short	*cf_parents;		/* potential parents */
175 	const char **cf_locnames;	/* locator names (machine dependent) */
176 };
177 #define FSTATE_NOTFOUND		0	/* has not been found */
178 #define	FSTATE_FOUND		1	/* has been found */
179 #define	FSTATE_STAR		2	/* duplicable */
180 #define FSTATE_DSTAR		3	/* has not been found, and disabled */
181 #define FSTATE_DNOTFOUND	4	/* duplicate, and disabled */
182 
183 typedef int (*cfmatch_t)(struct device *, struct cfdata *, void *);
184 
185 /*
186  * `configuration' attachment and driver (what the machine-independent
187  * autoconf uses).  As devices are found, they are applied against all
188  * the potential matches.  The one with the best match is taken, and a
189  * device structure (plus any other data desired) is allocated.  Pointers
190  * to these are placed into an array of pointers.  The array itself must
191  * be dynamic since devices can be found long after the machine is up
192  * and running.
193  *
194  * Devices can have multiple configuration attachments if they attach
195  * to different attributes (busses, or whatever), to allow specification
196  * of multiple match and attach functions.  There is only one configuration
197  * driver per driver, so that things like unit numbers and the device
198  * structure array will be shared.
199  */
200 struct cfattach {
201 	size_t	  ca_devsize;		/* size of dev data (for malloc) */
202 	cfmatch_t ca_match;		/* returns a match level */
203 	void	(*ca_attach)(struct device *, struct device *, void *);
204 	int	(*ca_detach)(struct device *, int);
205 	int	(*ca_activate)(struct device *, enum devact);
206 };
207 
208 /* Flags given to config_detach(), and the ca_detach function. */
209 #define	DETACH_FORCE	0x01		/* force detachment; hardware gone */
210 #define	DETACH_QUIET	0x02		/* don't print a notice */
211 
212 struct cfdriver {
213 	void	**cd_devs;		/* devices found */
214 	char	*cd_name;		/* device name */
215 	enum	devclass cd_class;	/* device classification */
216 	int	cd_ndevs;		/* size of cd_devs array */
217 };
218 
219 /*
220  * Configuration printing functions, and their return codes.  The second
221  * argument is NULL if the device was configured; otherwise it is the name
222  * of the parent device.  The return value is ignored if the device was
223  * configured, so most functions can return UNCONF unconditionally.
224  */
225 typedef int (*cfprint_t)(void *, const char *);		/* XXX const char * */
226 #define	QUIET	0		/* print nothing */
227 #define	UNCONF	1		/* print " not configured\n" */
228 #define	UNSUPP	2		/* print " not supported\n" */
229 
230 /*
231  * Pseudo-device attach information (function + number of pseudo-devs).
232  */
233 struct pdevinit {
234 	void	(*pdev_attach)(int);
235 	int	pdev_count;
236 };
237 
238 #ifdef _KERNEL
239 
240 extern struct devicelist alldevs;	/* list of all devices */
241 extern struct evcntlist allevents;	/* list of all event counters */
242 extern struct device *booted_device;	/* the device we booted from */
243 
244 extern __volatile int config_pending; 	/* semaphore for mountroot */
245 
246 void configure(void);
247 struct cfdata *config_search(cfmatch_t, struct device *, void *);
248 struct cfdata *config_rootsearch(cfmatch_t, const char *, void *);
249 struct device *config_found_sm(struct device *, void *, cfprint_t, cfmatch_t);
250 struct device *config_rootfound(const char *, void *);
251 struct device *config_attach(struct device *, struct cfdata *, void *,
252     cfprint_t);
253 void config_makeroom(int n, struct cfdriver *cd);
254 int config_detach(struct device *, int);
255 int config_activate(struct device *);
256 int config_deactivate(struct device *);
257 void config_defer(struct device *, void (*)(struct device *));
258 void config_interrupts(struct device *, void (*)(struct device *));
259 void config_pending_incr(void);
260 void config_pending_decr(void);
261 
262 #ifdef __HAVE_DEVICE_REGISTER
263 void device_register(struct device *, void *);
264 #endif
265 
266 void	evcnt_attach_static(struct evcnt *);
267 void	evcnt_attach_dynamic(struct evcnt *, int, const struct evcnt *,
268 	    const char *, const char *);
269 void	evcnt_detach(struct evcnt *);
270 
271 /* compatibility definitions */
272 #define config_found(d, a, p)	config_found_sm((d), (a), (p), NULL)
273 
274 /* convenience definitions */
275 #define	device_lookup(cfd, unit)					\
276 	(((unit) < (cfd)->cd_ndevs) ? (cfd)->cd_devs[(unit)] : NULL)
277 
278 #ifdef DDB
279 void event_print(int, void (*)(const char *, ...));
280 #endif
281 #endif /* _KERNEL */
282 
283 #endif /* !_SYS_DEVICE_H_ */
284