Deleted Added
full compact
subr_bus.c (113808) subr_bus.c (114293)
1/*-
2 * Copyright (c) 1997,1998 Doug Rabson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*-
2 * Copyright (c) 1997,1998 Doug Rabson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/kern/subr_bus.c 113808 2003-04-21 18:19:08Z imp $
26 * $FreeBSD: head/sys/kern/subr_bus.c 114293 2003-04-30 12:57:40Z markm $
27 */
28
29#include "opt_bus.h"
30
31#include <sys/param.h>
32#include <sys/conf.h>
33#include <sys/filio.h>
34#include <sys/lock.h>
35#include <sys/kernel.h>
36#include <sys/kobj.h>
37#include <sys/malloc.h>
38#include <sys/module.h>
39#include <sys/mutex.h>
40#include <sys/poll.h>
41#include <sys/proc.h>
42#include <sys/condvar.h>
43#include <sys/queue.h>
44#include <machine/bus.h>
45#include <sys/rman.h>
46#include <sys/selinfo.h>
47#include <sys/signalvar.h>
48#include <sys/sysctl.h>
49#include <sys/systm.h>
50#include <sys/uio.h>
51#include <sys/bus.h>
52
53#include <machine/stdarg.h>
54
55#include <vm/uma.h>
56
57SYSCTL_NODE(_hw, OID_AUTO, bus, CTLFLAG_RW, NULL, NULL);
58
59/*
60 * Used to attach drivers to devclasses.
61 */
62typedef struct driverlink *driverlink_t;
63struct driverlink {
64 driver_t *driver;
65 TAILQ_ENTRY(driverlink) link; /* list of drivers in devclass */
66};
67
68/*
69 * Forward declarations
70 */
71typedef TAILQ_HEAD(devclass_list, devclass) devclass_list_t;
72typedef TAILQ_HEAD(driver_list, driverlink) driver_list_t;
73typedef TAILQ_HEAD(device_list, device) device_list_t;
74
75struct devclass {
76 TAILQ_ENTRY(devclass) link;
77 driver_list_t drivers; /* bus devclasses store drivers for bus */
78 char *name;
79 device_t *devices; /* array of devices indexed by unit */
80 int maxunit; /* size of devices array */
81};
82
83/*
84 * Implementation of device.
85 */
86struct device {
87 /*
88 * A device is a kernel object. The first field must be the
89 * current ops table for the object.
90 */
91 KOBJ_FIELDS;
92
93 /*
94 * Device hierarchy.
95 */
96 TAILQ_ENTRY(device) link; /* list of devices in parent */
97 TAILQ_ENTRY(device) devlink; /* global device list membership */
98 device_t parent;
99 device_list_t children; /* list of subordinate devices */
100
101 /*
102 * Details of this device.
103 */
104 driver_t *driver;
105 devclass_t devclass; /* device class which we are in */
106 int unit;
107 char* nameunit; /* name+unit e.g. foodev0 */
108 char* desc; /* driver specific description */
109 int busy; /* count of calls to device_busy() */
110 device_state_t state;
111 u_int32_t devflags; /* api level flags for device_get_flags() */
112 u_short flags;
113#define DF_ENABLED 1 /* device should be probed/attached */
114#define DF_FIXEDCLASS 2 /* devclass specified at create time */
115#define DF_WILDCARD 4 /* unit was originally wildcard */
116#define DF_DESCMALLOCED 8 /* description was malloced */
117#define DF_QUIET 16 /* don't print verbose attach message */
118#define DF_DONENOMATCH 32 /* don't execute DEVICE_NOMATCH again */
119#define DF_EXTERNALSOFTC 64 /* softc not allocated by us */
120 u_char order; /* order from device_add_child_ordered() */
121 u_char pad;
122 void *ivars;
123 void *softc;
124};
125
126struct device_op_desc {
127 unsigned int offset; /* offset in driver ops */
128 struct method* method; /* internal method implementation */
129 devop_t deflt; /* default implementation */
130 const char* name; /* unique name (for registration) */
131};
132
133static MALLOC_DEFINE(M_BUS, "bus", "Bus data structures");
134
135#ifdef BUS_DEBUG
136
137static int bus_debug = 1;
138TUNABLE_INT("bus.debug", &bus_debug);
139SYSCTL_INT(_debug, OID_AUTO, bus_debug, CTLFLAG_RW, &bus_debug, 0,
140 "Debug bus code");
141
142#define PDEBUG(a) if (bus_debug) {printf("%s:%d: ", __func__, __LINE__), printf a; printf("\n");}
143#define DEVICENAME(d) ((d)? device_get_name(d): "no device")
144#define DRIVERNAME(d) ((d)? d->name : "no driver")
145#define DEVCLANAME(d) ((d)? d->name : "no devclass")
146
147/* Produce the indenting, indent*2 spaces plus a '.' ahead of that to
148 * prevent syslog from deleting initial spaces
149 */
150#define indentprintf(p) do { int iJ; printf("."); for (iJ=0; iJ<indent; iJ++) printf(" "); printf p ; } while (0)
151
152static void print_device_short(device_t dev, int indent);
153static void print_device(device_t dev, int indent);
154void print_device_tree_short(device_t dev, int indent);
155void print_device_tree(device_t dev, int indent);
156static void print_driver_short(driver_t *driver, int indent);
157static void print_driver(driver_t *driver, int indent);
158static void print_driver_list(driver_list_t drivers, int indent);
159static void print_devclass_short(devclass_t dc, int indent);
160static void print_devclass(devclass_t dc, int indent);
161void print_devclass_list_short(void);
162void print_devclass_list(void);
163
164#else
165/* Make the compiler ignore the function calls */
166#define PDEBUG(a) /* nop */
167#define DEVICENAME(d) /* nop */
168#define DRIVERNAME(d) /* nop */
169#define DEVCLANAME(d) /* nop */
170
171#define print_device_short(d,i) /* nop */
172#define print_device(d,i) /* nop */
173#define print_device_tree_short(d,i) /* nop */
174#define print_device_tree(d,i) /* nop */
175#define print_driver_short(d,i) /* nop */
176#define print_driver(d,i) /* nop */
177#define print_driver_list(d,i) /* nop */
178#define print_devclass_short(d,i) /* nop */
179#define print_devclass(d,i) /* nop */
180#define print_devclass_list_short() /* nop */
181#define print_devclass_list() /* nop */
182#endif
183
184/*
185 * /dev/devctl implementation
186 */
187
188/*
189 * This design allows only one reader for /dev/devctl. This is not desirable
190 * in the long run, but will get a lot of hair out of this implementation.
191 * Maybe we should make this device a clonable device.
192 *
193 * Also note: we specifically do not attach a device to the device_t tree
194 * to avoid potential chicken and egg problems. One could argue that all
195 * of this belongs to the root node. One could also further argue that the
196 * sysctl interface that we have not might more properly be an ioctl
197 * interface, but at this stage of the game, I'm not inclined to rock that
198 * boat.
199 *
200 * I'm also not sure that the SIGIO support is done correctly or not, as
201 * I copied it from a driver that had SIGIO support that likely hasn't been
202 * tested since 3.4 or 2.2.8!
203 */
204
205static int sysctl_devctl_disable(SYSCTL_HANDLER_ARGS);
206static int devctl_disable = 0;
207TUNABLE_INT("hw.bus.devctl_disable", &devctl_disable);
208SYSCTL_PROC(_hw_bus, OID_AUTO, devctl_disable,
209 CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_PRISON, 0, 0, sysctl_devctl_disable,
210 "I", "devctl disable");
211
212static d_open_t devopen;
213static d_close_t devclose;
214static d_read_t devread;
215static d_ioctl_t devioctl;
216static d_poll_t devpoll;
217
218#define CDEV_MAJOR 173
219static struct cdevsw dev_cdevsw = {
220 .d_open = devopen,
221 .d_close = devclose,
222 .d_read = devread,
223 .d_ioctl = devioctl,
224 .d_poll = devpoll,
225 .d_name = "devctl",
226 .d_maj = CDEV_MAJOR,
227};
228
229struct dev_event_info
230{
231 char *dei_data;
232 TAILQ_ENTRY(dev_event_info) dei_link;
233};
234
235TAILQ_HEAD(devq, dev_event_info);
236
27 */
28
29#include "opt_bus.h"
30
31#include <sys/param.h>
32#include <sys/conf.h>
33#include <sys/filio.h>
34#include <sys/lock.h>
35#include <sys/kernel.h>
36#include <sys/kobj.h>
37#include <sys/malloc.h>
38#include <sys/module.h>
39#include <sys/mutex.h>
40#include <sys/poll.h>
41#include <sys/proc.h>
42#include <sys/condvar.h>
43#include <sys/queue.h>
44#include <machine/bus.h>
45#include <sys/rman.h>
46#include <sys/selinfo.h>
47#include <sys/signalvar.h>
48#include <sys/sysctl.h>
49#include <sys/systm.h>
50#include <sys/uio.h>
51#include <sys/bus.h>
52
53#include <machine/stdarg.h>
54
55#include <vm/uma.h>
56
57SYSCTL_NODE(_hw, OID_AUTO, bus, CTLFLAG_RW, NULL, NULL);
58
59/*
60 * Used to attach drivers to devclasses.
61 */
62typedef struct driverlink *driverlink_t;
63struct driverlink {
64 driver_t *driver;
65 TAILQ_ENTRY(driverlink) link; /* list of drivers in devclass */
66};
67
68/*
69 * Forward declarations
70 */
71typedef TAILQ_HEAD(devclass_list, devclass) devclass_list_t;
72typedef TAILQ_HEAD(driver_list, driverlink) driver_list_t;
73typedef TAILQ_HEAD(device_list, device) device_list_t;
74
75struct devclass {
76 TAILQ_ENTRY(devclass) link;
77 driver_list_t drivers; /* bus devclasses store drivers for bus */
78 char *name;
79 device_t *devices; /* array of devices indexed by unit */
80 int maxunit; /* size of devices array */
81};
82
83/*
84 * Implementation of device.
85 */
86struct device {
87 /*
88 * A device is a kernel object. The first field must be the
89 * current ops table for the object.
90 */
91 KOBJ_FIELDS;
92
93 /*
94 * Device hierarchy.
95 */
96 TAILQ_ENTRY(device) link; /* list of devices in parent */
97 TAILQ_ENTRY(device) devlink; /* global device list membership */
98 device_t parent;
99 device_list_t children; /* list of subordinate devices */
100
101 /*
102 * Details of this device.
103 */
104 driver_t *driver;
105 devclass_t devclass; /* device class which we are in */
106 int unit;
107 char* nameunit; /* name+unit e.g. foodev0 */
108 char* desc; /* driver specific description */
109 int busy; /* count of calls to device_busy() */
110 device_state_t state;
111 u_int32_t devflags; /* api level flags for device_get_flags() */
112 u_short flags;
113#define DF_ENABLED 1 /* device should be probed/attached */
114#define DF_FIXEDCLASS 2 /* devclass specified at create time */
115#define DF_WILDCARD 4 /* unit was originally wildcard */
116#define DF_DESCMALLOCED 8 /* description was malloced */
117#define DF_QUIET 16 /* don't print verbose attach message */
118#define DF_DONENOMATCH 32 /* don't execute DEVICE_NOMATCH again */
119#define DF_EXTERNALSOFTC 64 /* softc not allocated by us */
120 u_char order; /* order from device_add_child_ordered() */
121 u_char pad;
122 void *ivars;
123 void *softc;
124};
125
126struct device_op_desc {
127 unsigned int offset; /* offset in driver ops */
128 struct method* method; /* internal method implementation */
129 devop_t deflt; /* default implementation */
130 const char* name; /* unique name (for registration) */
131};
132
133static MALLOC_DEFINE(M_BUS, "bus", "Bus data structures");
134
135#ifdef BUS_DEBUG
136
137static int bus_debug = 1;
138TUNABLE_INT("bus.debug", &bus_debug);
139SYSCTL_INT(_debug, OID_AUTO, bus_debug, CTLFLAG_RW, &bus_debug, 0,
140 "Debug bus code");
141
142#define PDEBUG(a) if (bus_debug) {printf("%s:%d: ", __func__, __LINE__), printf a; printf("\n");}
143#define DEVICENAME(d) ((d)? device_get_name(d): "no device")
144#define DRIVERNAME(d) ((d)? d->name : "no driver")
145#define DEVCLANAME(d) ((d)? d->name : "no devclass")
146
147/* Produce the indenting, indent*2 spaces plus a '.' ahead of that to
148 * prevent syslog from deleting initial spaces
149 */
150#define indentprintf(p) do { int iJ; printf("."); for (iJ=0; iJ<indent; iJ++) printf(" "); printf p ; } while (0)
151
152static void print_device_short(device_t dev, int indent);
153static void print_device(device_t dev, int indent);
154void print_device_tree_short(device_t dev, int indent);
155void print_device_tree(device_t dev, int indent);
156static void print_driver_short(driver_t *driver, int indent);
157static void print_driver(driver_t *driver, int indent);
158static void print_driver_list(driver_list_t drivers, int indent);
159static void print_devclass_short(devclass_t dc, int indent);
160static void print_devclass(devclass_t dc, int indent);
161void print_devclass_list_short(void);
162void print_devclass_list(void);
163
164#else
165/* Make the compiler ignore the function calls */
166#define PDEBUG(a) /* nop */
167#define DEVICENAME(d) /* nop */
168#define DRIVERNAME(d) /* nop */
169#define DEVCLANAME(d) /* nop */
170
171#define print_device_short(d,i) /* nop */
172#define print_device(d,i) /* nop */
173#define print_device_tree_short(d,i) /* nop */
174#define print_device_tree(d,i) /* nop */
175#define print_driver_short(d,i) /* nop */
176#define print_driver(d,i) /* nop */
177#define print_driver_list(d,i) /* nop */
178#define print_devclass_short(d,i) /* nop */
179#define print_devclass(d,i) /* nop */
180#define print_devclass_list_short() /* nop */
181#define print_devclass_list() /* nop */
182#endif
183
184/*
185 * /dev/devctl implementation
186 */
187
188/*
189 * This design allows only one reader for /dev/devctl. This is not desirable
190 * in the long run, but will get a lot of hair out of this implementation.
191 * Maybe we should make this device a clonable device.
192 *
193 * Also note: we specifically do not attach a device to the device_t tree
194 * to avoid potential chicken and egg problems. One could argue that all
195 * of this belongs to the root node. One could also further argue that the
196 * sysctl interface that we have not might more properly be an ioctl
197 * interface, but at this stage of the game, I'm not inclined to rock that
198 * boat.
199 *
200 * I'm also not sure that the SIGIO support is done correctly or not, as
201 * I copied it from a driver that had SIGIO support that likely hasn't been
202 * tested since 3.4 or 2.2.8!
203 */
204
205static int sysctl_devctl_disable(SYSCTL_HANDLER_ARGS);
206static int devctl_disable = 0;
207TUNABLE_INT("hw.bus.devctl_disable", &devctl_disable);
208SYSCTL_PROC(_hw_bus, OID_AUTO, devctl_disable,
209 CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_PRISON, 0, 0, sysctl_devctl_disable,
210 "I", "devctl disable");
211
212static d_open_t devopen;
213static d_close_t devclose;
214static d_read_t devread;
215static d_ioctl_t devioctl;
216static d_poll_t devpoll;
217
218#define CDEV_MAJOR 173
219static struct cdevsw dev_cdevsw = {
220 .d_open = devopen,
221 .d_close = devclose,
222 .d_read = devread,
223 .d_ioctl = devioctl,
224 .d_poll = devpoll,
225 .d_name = "devctl",
226 .d_maj = CDEV_MAJOR,
227};
228
229struct dev_event_info
230{
231 char *dei_data;
232 TAILQ_ENTRY(dev_event_info) dei_link;
233};
234
235TAILQ_HEAD(devq, dev_event_info);
236
237struct dev_softc
237static struct dev_softc
238{
239 int inuse;
240 int nonblock;
241 struct mtx mtx;
242 struct cv cv;
243 struct selinfo sel;
244 struct devq devq;
245 struct proc *async_proc;
246} devsoftc;
247
238{
239 int inuse;
240 int nonblock;
241 struct mtx mtx;
242 struct cv cv;
243 struct selinfo sel;
244 struct devq devq;
245 struct proc *async_proc;
246} devsoftc;
247
248dev_t devctl_dev;
248static dev_t devctl_dev;
249
250static void
251devinit(void)
252{
253 devctl_dev = make_dev(&dev_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
254 "devctl");
255 mtx_init(&devsoftc.mtx, "dev mtx", "devd", MTX_DEF);
256 cv_init(&devsoftc.cv, "dev cv");
257 TAILQ_INIT(&devsoftc.devq);
258}
259
260static int
261devopen(dev_t dev, int oflags, int devtype, d_thread_t *td)
262{
263 if (devsoftc.inuse)
264 return (EBUSY);
265 /* move to init */
266 devsoftc.inuse = 1;
267 devsoftc.nonblock = 0;
268 devsoftc.async_proc = NULL;
269 return (0);
270}
271
272static int
273devclose(dev_t dev, int fflag, int devtype, d_thread_t *td)
274{
275 devsoftc.inuse = 0;
276 mtx_lock(&devsoftc.mtx);
277 cv_broadcast(&devsoftc.cv);
278 mtx_unlock(&devsoftc.mtx);
279
280 return (0);
281}
282
283/*
284 * The read channel for this device is used to report changes to
285 * userland in realtime. We are required to free the data as well as
286 * the n1 object because we allocate them separately. Also note that
287 * we return one record at a time. If you try to read this device a
288 * character at a time, you will loose the rest of the data. Listening
289 * programs are expected to cope.
290 */
291static int
292devread(dev_t dev, struct uio *uio, int ioflag)
293{
294 struct dev_event_info *n1;
295 int rv;
296
297 mtx_lock(&devsoftc.mtx);
298 while (TAILQ_EMPTY(&devsoftc.devq)) {
299 if (devsoftc.nonblock) {
300 mtx_unlock(&devsoftc.mtx);
301 return (EAGAIN);
302 }
303 rv = cv_wait_sig(&devsoftc.cv, &devsoftc.mtx);
304 if (rv) {
305 /*
306 * Need to translate ERESTART to EINTR here? -- jake
307 */
308 mtx_unlock(&devsoftc.mtx);
309 return (rv);
310 }
311 }
312 n1 = TAILQ_FIRST(&devsoftc.devq);
313 TAILQ_REMOVE(&devsoftc.devq, n1, dei_link);
314 mtx_unlock(&devsoftc.mtx);
315 rv = uiomove(n1->dei_data, strlen(n1->dei_data), uio);
316 free(n1->dei_data, M_BUS);
317 free(n1, M_BUS);
318 return (rv);
319}
320
321static int
322devioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, d_thread_t *td)
323{
324 switch (cmd) {
325
326 case FIONBIO:
327 if (*(int*)data)
328 devsoftc.nonblock = 1;
329 else
330 devsoftc.nonblock = 0;
331 return (0);
332 case FIOASYNC:
333 if (*(int*)data)
334 devsoftc.async_proc = td->td_proc;
335 else
336 devsoftc.async_proc = NULL;
337 return (0);
338
339 /* (un)Support for other fcntl() calls. */
340 case FIOCLEX:
341 case FIONCLEX:
342 case FIONREAD:
343 case FIOSETOWN:
344 case FIOGETOWN:
345 default:
346 break;
347 }
348 return (ENOTTY);
349}
350
351static int
352devpoll(dev_t dev, int events, d_thread_t *td)
353{
354 int revents = 0;
355
356 mtx_lock(&devsoftc.mtx);
357 if (events & (POLLIN | POLLRDNORM)) {
358 if (!TAILQ_EMPTY(&devsoftc.devq))
359 revents = events & (POLLIN | POLLRDNORM);
360 else
361 selrecord(td, &devsoftc.sel);
362 }
363 mtx_unlock(&devsoftc.mtx);
364
365 return (revents);
366}
367
368/*
369 * Common routine that tries to make sending messages as easy as possible.
370 * We allocate memory for the data, copy strings into that, but do not
371 * free it unless there's an error. The dequeue part of the driver should
372 * free the data. We don't send data when the device is disabled. We do
373 * send data, even when we have no listeners, because we wish to avoid
374 * races relating to startup and restart of listening applications.
375 */
376static void
377devaddq(const char *type, const char *what, device_t dev)
378{
379 struct dev_event_info *n1 = NULL;
380 struct proc *p;
381 char *data = NULL;
382 char *loc;
383 const char *parstr;
384
385 if (devctl_disable)
386 return;
387 n1 = malloc(sizeof(*n1), M_BUS, M_NOWAIT);
388 if (n1 == NULL)
389 goto bad;
390 data = malloc(1024, M_BUS, M_NOWAIT);
391 if (data == NULL)
392 goto bad;
393 loc = malloc(1024, M_BUS, M_NOWAIT);
394 if (loc == NULL)
395 goto bad;
396 *loc = '\0';
397 bus_child_location_str(dev, loc, 1024);
398 if (device_get_parent(dev) == NULL)
399 parstr = "."; /* Or '/' ? */
400 else
401 parstr = device_get_nameunit(device_get_parent(dev));
402 snprintf(data, 1024, "%s%s at %s on %s\n", type, what, loc, parstr);
403 free(loc, M_BUS);
404 n1->dei_data = data;
405 mtx_lock(&devsoftc.mtx);
406 TAILQ_INSERT_TAIL(&devsoftc.devq, n1, dei_link);
407 cv_broadcast(&devsoftc.cv);
408 mtx_unlock(&devsoftc.mtx);
409 selwakeup(&devsoftc.sel);
410 p = devsoftc.async_proc;
411 if (p != NULL) {
412 PROC_LOCK(p);
413 psignal(p, SIGIO);
414 PROC_UNLOCK(p);
415 }
416 return;
417bad:;
418 free(data, M_BUS);
419 free(n1, M_BUS);
420 return;
421}
422
423/*
424 * A device was added to the tree. We are called just after it successfully
425 * attaches (that is, probe and attach success for this device). No call
426 * is made if a device is merely parented into the tree. See devnomatch
427 * if probe fails. If attach fails, no notification is sent (but maybe
428 * we should have a different message for this).
429 */
430static void
431devadded(device_t dev)
432{
433 devaddq("+", device_get_nameunit(dev), dev);
434}
435
436/*
437 * A device was removed from the tree. We are called just before this
438 * happens.
439 */
440static void
441devremoved(device_t dev)
442{
443 devaddq("-", device_get_nameunit(dev), dev);
444}
445
446/*
447 * Called when there's no match for this device. This is only called
448 * the first time that no match happens, so we don't keep getitng this
449 * message. Should that prove to be undesirable, we can change it.
450 * This is called when all drivers that can attach to a given bus
451 * decline to accept this device. Other errrors may not be detected.
452 */
453static void
454devnomatch(device_t dev)
455{
456 char *pnp = NULL;
457
458 pnp = malloc(1024, M_BUS, M_NOWAIT);
459 if (pnp == NULL)
460 return;
461 *pnp = '\0';
462 bus_child_pnpinfo_str(dev, pnp, 1024);
463 devaddq("?", pnp, dev);
464 free(pnp, M_BUS);
465 return;
466}
467
468static int
469sysctl_devctl_disable(SYSCTL_HANDLER_ARGS)
470{
471 struct dev_event_info *n1;
472 int dis, error;
473
474 dis = devctl_disable;
475 error = sysctl_handle_int(oidp, &dis, 0, req);
476 if (error || !req->newptr)
477 return (error);
478 mtx_lock(&devsoftc.mtx);
479 devctl_disable = dis;
480 if (dis) {
481 while (!TAILQ_EMPTY(&devsoftc.devq)) {
482 n1 = TAILQ_FIRST(&devsoftc.devq);
483 TAILQ_REMOVE(&devsoftc.devq, n1, dei_link);
484 free(n1->dei_data, M_BUS);
485 free(n1, M_BUS);
486 }
487 }
488 mtx_unlock(&devsoftc.mtx);
489 return (0);
490}
491
492/* End of /dev/devctl code */
493
494TAILQ_HEAD(,device) bus_data_devices;
495static int bus_data_generation = 1;
496
497kobj_method_t null_methods[] = {
498 { 0, 0 }
499};
500
501DEFINE_CLASS(null, null_methods, 0);
502
503/*
504 * Devclass implementation
505 */
506
507static devclass_list_t devclasses = TAILQ_HEAD_INITIALIZER(devclasses);
508
509static devclass_t
510devclass_find_internal(const char *classname, int create)
511{
512 devclass_t dc;
513
514 PDEBUG(("looking for %s", classname));
515 if (!classname)
516 return (NULL);
517
518 TAILQ_FOREACH(dc, &devclasses, link) {
519 if (!strcmp(dc->name, classname))
520 return (dc);
521 }
522
523 PDEBUG(("%s not found%s", classname, (create? ", creating": "")));
524 if (create) {
525 dc = malloc(sizeof(struct devclass) + strlen(classname) + 1,
526 M_BUS, M_NOWAIT|M_ZERO);
527 if (!dc)
528 return (NULL);
529 dc->name = (char*) (dc + 1);
530 strcpy(dc->name, classname);
531 TAILQ_INIT(&dc->drivers);
532 TAILQ_INSERT_TAIL(&devclasses, dc, link);
533
534 bus_data_generation_update();
535 }
536
537 return (dc);
538}
539
540devclass_t
541devclass_create(const char *classname)
542{
543 return (devclass_find_internal(classname, TRUE));
544}
545
546devclass_t
547devclass_find(const char *classname)
548{
549 return (devclass_find_internal(classname, FALSE));
550}
551
552int
553devclass_add_driver(devclass_t dc, driver_t *driver)
554{
555 driverlink_t dl;
556 int i;
557
558 PDEBUG(("%s", DRIVERNAME(driver)));
559
560 dl = malloc(sizeof *dl, M_BUS, M_NOWAIT|M_ZERO);
561 if (!dl)
562 return (ENOMEM);
563
564 /*
565 * Compile the driver's methods. Also increase the reference count
566 * so that the class doesn't get freed when the last instance
567 * goes. This means we can safely use static methods and avoids a
568 * double-free in devclass_delete_driver.
569 */
570 kobj_class_compile((kobj_class_t) driver);
571
572 /*
573 * Make sure the devclass which the driver is implementing exists.
574 */
575 devclass_find_internal(driver->name, TRUE);
576
577 dl->driver = driver;
578 TAILQ_INSERT_TAIL(&dc->drivers, dl, link);
579 driver->refs++;
580
581 /*
582 * Call BUS_DRIVER_ADDED for any existing busses in this class.
583 */
584 for (i = 0; i < dc->maxunit; i++)
585 if (dc->devices[i])
586 BUS_DRIVER_ADDED(dc->devices[i], driver);
587
588 bus_data_generation_update();
589 return (0);
590}
591
592int
593devclass_delete_driver(devclass_t busclass, driver_t *driver)
594{
595 devclass_t dc = devclass_find(driver->name);
596 driverlink_t dl;
597 device_t dev;
598 int i;
599 int error;
600
601 PDEBUG(("%s from devclass %s", driver->name, DEVCLANAME(busclass)));
602
603 if (!dc)
604 return (0);
605
606 /*
607 * Find the link structure in the bus' list of drivers.
608 */
609 TAILQ_FOREACH(dl, &busclass->drivers, link) {
610 if (dl->driver == driver)
611 break;
612 }
613
614 if (!dl) {
615 PDEBUG(("%s not found in %s list", driver->name,
616 busclass->name));
617 return (ENOENT);
618 }
619
620 /*
621 * Disassociate from any devices. We iterate through all the
622 * devices in the devclass of the driver and detach any which are
623 * using the driver and which have a parent in the devclass which
624 * we are deleting from.
625 *
626 * Note that since a driver can be in multiple devclasses, we
627 * should not detach devices which are not children of devices in
628 * the affected devclass.
629 */
630 for (i = 0; i < dc->maxunit; i++) {
631 if (dc->devices[i]) {
632 dev = dc->devices[i];
633 if (dev->driver == driver && dev->parent &&
634 dev->parent->devclass == busclass) {
635 if ((error = device_detach(dev)) != 0)
636 return (error);
637 device_set_driver(dev, NULL);
638 }
639 }
640 }
641
642 TAILQ_REMOVE(&busclass->drivers, dl, link);
643 free(dl, M_BUS);
644
645 driver->refs--;
646 if (driver->refs == 0)
647 kobj_class_free((kobj_class_t) driver);
648
649 bus_data_generation_update();
650 return (0);
651}
652
653static driverlink_t
654devclass_find_driver_internal(devclass_t dc, const char *classname)
655{
656 driverlink_t dl;
657
658 PDEBUG(("%s in devclass %s", classname, DEVCLANAME(dc)));
659
660 TAILQ_FOREACH(dl, &dc->drivers, link) {
661 if (!strcmp(dl->driver->name, classname))
662 return (dl);
663 }
664
665 PDEBUG(("not found"));
666 return (NULL);
667}
668
669driver_t *
670devclass_find_driver(devclass_t dc, const char *classname)
671{
672 driverlink_t dl;
673
674 dl = devclass_find_driver_internal(dc, classname);
675 if (dl)
676 return (dl->driver);
677 return (NULL);
678}
679
680const char *
681devclass_get_name(devclass_t dc)
682{
683 return (dc->name);
684}
685
686device_t
687devclass_get_device(devclass_t dc, int unit)
688{
689 if (dc == NULL || unit < 0 || unit >= dc->maxunit)
690 return (NULL);
691 return (dc->devices[unit]);
692}
693
694void *
695devclass_get_softc(devclass_t dc, int unit)
696{
697 device_t dev;
698
699 dev = devclass_get_device(dc, unit);
700 if (!dev)
701 return (NULL);
702
703 return (device_get_softc(dev));
704}
705
706int
707devclass_get_devices(devclass_t dc, device_t **devlistp, int *devcountp)
708{
709 int i;
710 int count;
711 device_t *list;
712
713 count = 0;
714 for (i = 0; i < dc->maxunit; i++)
715 if (dc->devices[i])
716 count++;
717
718 list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT|M_ZERO);
719 if (!list)
720 return (ENOMEM);
721
722 count = 0;
723 for (i = 0; i < dc->maxunit; i++) {
724 if (dc->devices[i]) {
725 list[count] = dc->devices[i];
726 count++;
727 }
728 }
729
730 *devlistp = list;
731 *devcountp = count;
732
733 return (0);
734}
735
736int
737devclass_get_maxunit(devclass_t dc)
738{
739 return (dc->maxunit);
740}
741
742int
743devclass_find_free_unit(devclass_t dc, int unit)
744{
745 if (dc == NULL)
746 return (unit);
747 while (unit < dc->maxunit && dc->devices[unit] != NULL)
748 unit++;
749 return (unit);
750}
751
752static int
753devclass_alloc_unit(devclass_t dc, int *unitp)
754{
755 int unit = *unitp;
756
757 PDEBUG(("unit %d in devclass %s", unit, DEVCLANAME(dc)));
758
759 /* If we were given a wired unit number, check for existing device */
760 /* XXX imp XXX */
761 if (unit != -1) {
762 if (unit >= 0 && unit < dc->maxunit &&
763 dc->devices[unit] != NULL) {
764 if (bootverbose)
765 printf("%s: %s%d already exists; skipping it\n",
766 dc->name, dc->name, *unitp);
767 return (EEXIST);
768 }
769 } else {
770 /* Unwired device, find the next available slot for it */
771 unit = 0;
772 while (unit < dc->maxunit && dc->devices[unit] != NULL)
773 unit++;
774 }
775
776 /*
777 * We've selected a unit beyond the length of the table, so let's
778 * extend the table to make room for all units up to and including
779 * this one.
780 */
781 if (unit >= dc->maxunit) {
782 device_t *newlist;
783 int newsize;
784
785 newsize = roundup((unit + 1), MINALLOCSIZE / sizeof(device_t));
786 newlist = malloc(sizeof(device_t) * newsize, M_BUS, M_NOWAIT);
787 if (!newlist)
788 return (ENOMEM);
789 bcopy(dc->devices, newlist, sizeof(device_t) * dc->maxunit);
790 bzero(newlist + dc->maxunit,
791 sizeof(device_t) * (newsize - dc->maxunit));
792 if (dc->devices)
793 free(dc->devices, M_BUS);
794 dc->devices = newlist;
795 dc->maxunit = newsize;
796 }
797 PDEBUG(("now: unit %d in devclass %s", unit, DEVCLANAME(dc)));
798
799 *unitp = unit;
800 return (0);
801}
802
803static int
804devclass_add_device(devclass_t dc, device_t dev)
805{
806 int buflen, error;
807
808 PDEBUG(("%s in devclass %s", DEVICENAME(dev), DEVCLANAME(dc)));
809
810 buflen = snprintf(NULL, 0, "%s%d$", dc->name, dev->unit);
811 if (buflen < 0)
812 return (ENOMEM);
813 dev->nameunit = malloc(buflen, M_BUS, M_NOWAIT|M_ZERO);
814 if (!dev->nameunit)
815 return (ENOMEM);
816
817 if ((error = devclass_alloc_unit(dc, &dev->unit)) != 0) {
818 free(dev->nameunit, M_BUS);
819 dev->nameunit = NULL;
820 return (error);
821 }
822 dc->devices[dev->unit] = dev;
823 dev->devclass = dc;
824 snprintf(dev->nameunit, buflen, "%s%d", dc->name, dev->unit);
825
826 return (0);
827}
828
829static int
830devclass_delete_device(devclass_t dc, device_t dev)
831{
832 if (!dc || !dev)
833 return (0);
834
835 PDEBUG(("%s in devclass %s", DEVICENAME(dev), DEVCLANAME(dc)));
836
837 if (dev->devclass != dc || dc->devices[dev->unit] != dev)
838 panic("devclass_delete_device: inconsistent device class");
839 dc->devices[dev->unit] = NULL;
840 if (dev->flags & DF_WILDCARD)
841 dev->unit = -1;
842 dev->devclass = NULL;
843 free(dev->nameunit, M_BUS);
844 dev->nameunit = NULL;
845
846 return (0);
847}
848
849static device_t
850make_device(device_t parent, const char *name, int unit)
851{
852 device_t dev;
853 devclass_t dc;
854
855 PDEBUG(("%s at %s as unit %d", name, DEVICENAME(parent), unit));
856
857 if (name) {
858 dc = devclass_find_internal(name, TRUE);
859 if (!dc) {
860 printf("make_device: can't find device class %s\n",
861 name);
862 return (NULL);
863 }
864 } else {
865 dc = NULL;
866 }
867
868 dev = malloc(sizeof(struct device), M_BUS, M_NOWAIT|M_ZERO);
869 if (!dev)
870 return (NULL);
871
872 dev->parent = parent;
873 TAILQ_INIT(&dev->children);
874 kobj_init((kobj_t) dev, &null_class);
875 dev->driver = NULL;
876 dev->devclass = NULL;
877 dev->unit = unit;
878 dev->nameunit = NULL;
879 dev->desc = NULL;
880 dev->busy = 0;
881 dev->devflags = 0;
882 dev->flags = DF_ENABLED;
883 dev->order = 0;
884 if (unit == -1)
885 dev->flags |= DF_WILDCARD;
886 if (name) {
887 dev->flags |= DF_FIXEDCLASS;
888 if (devclass_add_device(dc, dev)) {
889 kobj_delete((kobj_t) dev, M_BUS);
890 return (NULL);
891 }
892 }
893 dev->ivars = NULL;
894 dev->softc = NULL;
895
896 dev->state = DS_NOTPRESENT;
897
898 TAILQ_INSERT_TAIL(&bus_data_devices, dev, devlink);
899 bus_data_generation_update();
900
901 return (dev);
902}
903
904static int
905device_print_child(device_t dev, device_t child)
906{
907 int retval = 0;
908
909 if (device_is_alive(child))
910 retval += BUS_PRINT_CHILD(dev, child);
911 else
912 retval += device_printf(child, " not found\n");
913
914 return (retval);
915}
916
917device_t
918device_add_child(device_t dev, const char *name, int unit)
919{
920 return (device_add_child_ordered(dev, 0, name, unit));
921}
922
923device_t
924device_add_child_ordered(device_t dev, int order, const char *name, int unit)
925{
926 device_t child;
927 device_t place;
928
929 PDEBUG(("%s at %s with order %d as unit %d",
930 name, DEVICENAME(dev), order, unit));
931
932 child = make_device(dev, name, unit);
933 if (child == NULL)
934 return (child);
935 child->order = order;
936
937 TAILQ_FOREACH(place, &dev->children, link) {
938 if (place->order > order)
939 break;
940 }
941
942 if (place) {
943 /*
944 * The device 'place' is the first device whose order is
945 * greater than the new child.
946 */
947 TAILQ_INSERT_BEFORE(place, child, link);
948 } else {
949 /*
950 * The new child's order is greater or equal to the order of
951 * any existing device. Add the child to the tail of the list.
952 */
953 TAILQ_INSERT_TAIL(&dev->children, child, link);
954 }
955
956 bus_data_generation_update();
957 return (child);
958}
959
960int
961device_delete_child(device_t dev, device_t child)
962{
963 int error;
964 device_t grandchild;
965
966 PDEBUG(("%s from %s", DEVICENAME(child), DEVICENAME(dev)));
967
968 /* remove children first */
969 while ( (grandchild = TAILQ_FIRST(&child->children)) ) {
970 error = device_delete_child(child, grandchild);
971 if (error)
972 return (error);
973 }
974
975 if ((error = device_detach(child)) != 0)
976 return (error);
977 if (child->devclass)
978 devclass_delete_device(child->devclass, child);
979 TAILQ_REMOVE(&dev->children, child, link);
980 TAILQ_REMOVE(&bus_data_devices, child, devlink);
981 device_set_desc(child, NULL);
982 kobj_delete((kobj_t) child, M_BUS);
983
984 bus_data_generation_update();
985 return (0);
986}
987
988/*
989 * Find only devices attached to this bus.
990 */
991device_t
992device_find_child(device_t dev, const char *classname, int unit)
993{
994 devclass_t dc;
995 device_t child;
996
997 dc = devclass_find(classname);
998 if (!dc)
999 return (NULL);
1000
1001 child = devclass_get_device(dc, unit);
1002 if (child && child->parent == dev)
1003 return (child);
1004 return (NULL);
1005}
1006
1007static driverlink_t
1008first_matching_driver(devclass_t dc, device_t dev)
1009{
1010 if (dev->devclass)
1011 return (devclass_find_driver_internal(dc, dev->devclass->name));
1012 return (TAILQ_FIRST(&dc->drivers));
1013}
1014
1015static driverlink_t
1016next_matching_driver(devclass_t dc, device_t dev, driverlink_t last)
1017{
1018 if (dev->devclass) {
1019 driverlink_t dl;
1020 for (dl = TAILQ_NEXT(last, link); dl; dl = TAILQ_NEXT(dl, link))
1021 if (!strcmp(dev->devclass->name, dl->driver->name))
1022 return (dl);
1023 return (NULL);
1024 }
1025 return (TAILQ_NEXT(last, link));
1026}
1027
1028static int
1029device_probe_child(device_t dev, device_t child)
1030{
1031 devclass_t dc;
1032 driverlink_t best = 0;
1033 driverlink_t dl;
1034 int result, pri = 0;
1035 int hasclass = (child->devclass != 0);
1036
1037 dc = dev->devclass;
1038 if (!dc)
1039 panic("device_probe_child: parent device has no devclass");
1040
1041 if (child->state == DS_ALIVE)
1042 return (0);
1043
1044 for (dl = first_matching_driver(dc, child);
1045 dl;
1046 dl = next_matching_driver(dc, child, dl)) {
1047 PDEBUG(("Trying %s", DRIVERNAME(dl->driver)));
1048 device_set_driver(child, dl->driver);
1049 if (!hasclass)
1050 device_set_devclass(child, dl->driver->name);
1051 result = DEVICE_PROBE(child);
1052 if (!hasclass)
1053 device_set_devclass(child, 0);
1054
1055 /*
1056 * If the driver returns SUCCESS, there can be no higher match
1057 * for this device.
1058 */
1059 if (result == 0) {
1060 best = dl;
1061 pri = 0;
1062 break;
1063 }
1064
1065 /*
1066 * The driver returned an error so it certainly doesn't match.
1067 */
1068 if (result > 0) {
1069 device_set_driver(child, 0);
1070 continue;
1071 }
1072
1073 /*
1074 * A priority lower than SUCCESS, remember the best matching
1075 * driver. Initialise the value of pri for the first match.
1076 */
1077 if (best == 0 || result > pri) {
1078 best = dl;
1079 pri = result;
1080 continue;
1081 }
1082 }
1083
1084 /*
1085 * If we found a driver, change state and initialise the devclass.
1086 */
1087 if (best) {
1088 if (!child->devclass)
1089 device_set_devclass(child, best->driver->name);
1090 device_set_driver(child, best->driver);
1091 if (pri < 0) {
1092 /*
1093 * A bit bogus. Call the probe method again to make
1094 * sure that we have the right description.
1095 */
1096 DEVICE_PROBE(child);
1097 }
1098 child->state = DS_ALIVE;
1099
1100 bus_data_generation_update();
1101 return (0);
1102 }
1103
1104 return (ENXIO);
1105}
1106
1107device_t
1108device_get_parent(device_t dev)
1109{
1110 return (dev->parent);
1111}
1112
1113int
1114device_get_children(device_t dev, device_t **devlistp, int *devcountp)
1115{
1116 int count;
1117 device_t child;
1118 device_t *list;
1119
1120 count = 0;
1121 TAILQ_FOREACH(child, &dev->children, link) {
1122 count++;
1123 }
1124
1125 list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT|M_ZERO);
1126 if (!list)
1127 return (ENOMEM);
1128
1129 count = 0;
1130 TAILQ_FOREACH(child, &dev->children, link) {
1131 list[count] = child;
1132 count++;
1133 }
1134
1135 *devlistp = list;
1136 *devcountp = count;
1137
1138 return (0);
1139}
1140
1141driver_t *
1142device_get_driver(device_t dev)
1143{
1144 return (dev->driver);
1145}
1146
1147devclass_t
1148device_get_devclass(device_t dev)
1149{
1150 return (dev->devclass);
1151}
1152
1153const char *
1154device_get_name(device_t dev)
1155{
1156 if (dev != NULL && dev->devclass)
1157 return (devclass_get_name(dev->devclass));
1158 return (NULL);
1159}
1160
1161const char *
1162device_get_nameunit(device_t dev)
1163{
1164 return (dev->nameunit);
1165}
1166
1167int
1168device_get_unit(device_t dev)
1169{
1170 return (dev->unit);
1171}
1172
1173const char *
1174device_get_desc(device_t dev)
1175{
1176 return (dev->desc);
1177}
1178
1179u_int32_t
1180device_get_flags(device_t dev)
1181{
1182 return (dev->devflags);
1183}
1184
1185int
1186device_print_prettyname(device_t dev)
1187{
1188 const char *name = device_get_name(dev);
1189
1190 if (name == 0)
1191 return (printf("unknown: "));
1192 return (printf("%s%d: ", name, device_get_unit(dev)));
1193}
1194
1195int
1196device_printf(device_t dev, const char * fmt, ...)
1197{
1198 va_list ap;
1199 int retval;
1200
1201 retval = device_print_prettyname(dev);
1202 va_start(ap, fmt);
1203 retval += vprintf(fmt, ap);
1204 va_end(ap);
1205 return (retval);
1206}
1207
1208static void
1209device_set_desc_internal(device_t dev, const char* desc, int copy)
1210{
1211 if (dev->desc && (dev->flags & DF_DESCMALLOCED)) {
1212 free(dev->desc, M_BUS);
1213 dev->flags &= ~DF_DESCMALLOCED;
1214 dev->desc = NULL;
1215 }
1216
1217 if (copy && desc) {
1218 dev->desc = malloc(strlen(desc) + 1, M_BUS, M_NOWAIT);
1219 if (dev->desc) {
1220 strcpy(dev->desc, desc);
1221 dev->flags |= DF_DESCMALLOCED;
1222 }
1223 } else {
1224 /* Avoid a -Wcast-qual warning */
1225 dev->desc = (char *)(uintptr_t) desc;
1226 }
1227
1228 bus_data_generation_update();
1229}
1230
1231void
1232device_set_desc(device_t dev, const char* desc)
1233{
1234 device_set_desc_internal(dev, desc, FALSE);
1235}
1236
1237void
1238device_set_desc_copy(device_t dev, const char* desc)
1239{
1240 device_set_desc_internal(dev, desc, TRUE);
1241}
1242
1243void
1244device_set_flags(device_t dev, u_int32_t flags)
1245{
1246 dev->devflags = flags;
1247}
1248
1249void *
1250device_get_softc(device_t dev)
1251{
1252 return (dev->softc);
1253}
1254
1255void
1256device_set_softc(device_t dev, void *softc)
1257{
1258 if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC))
1259 free(dev->softc, M_BUS);
1260 dev->softc = softc;
1261 if (dev->softc)
1262 dev->flags |= DF_EXTERNALSOFTC;
1263 else
1264 dev->flags &= ~DF_EXTERNALSOFTC;
1265}
1266
1267void *
1268device_get_ivars(device_t dev)
1269{
1270
1271 KASSERT(dev != NULL, ("device_get_ivars(NULL, ...)"));
1272 return (dev->ivars);
1273}
1274
1275void
1276device_set_ivars(device_t dev, void * ivars)
1277{
1278
1279 KASSERT(dev != NULL, ("device_set_ivars(NULL, ...)"));
1280 dev->ivars = ivars;
1281}
1282
1283device_state_t
1284device_get_state(device_t dev)
1285{
1286 return (dev->state);
1287}
1288
1289void
1290device_enable(device_t dev)
1291{
1292 dev->flags |= DF_ENABLED;
1293}
1294
1295void
1296device_disable(device_t dev)
1297{
1298 dev->flags &= ~DF_ENABLED;
1299}
1300
1301void
1302device_busy(device_t dev)
1303{
1304 if (dev->state < DS_ATTACHED)
1305 panic("device_busy: called for unattached device");
1306 if (dev->busy == 0 && dev->parent)
1307 device_busy(dev->parent);
1308 dev->busy++;
1309 dev->state = DS_BUSY;
1310}
1311
1312void
1313device_unbusy(device_t dev)
1314{
1315 if (dev->state != DS_BUSY)
1316 panic("device_unbusy: called for non-busy device");
1317 dev->busy--;
1318 if (dev->busy == 0) {
1319 if (dev->parent)
1320 device_unbusy(dev->parent);
1321 dev->state = DS_ATTACHED;
1322 }
1323}
1324
1325void
1326device_quiet(device_t dev)
1327{
1328 dev->flags |= DF_QUIET;
1329}
1330
1331void
1332device_verbose(device_t dev)
1333{
1334 dev->flags &= ~DF_QUIET;
1335}
1336
1337int
1338device_is_quiet(device_t dev)
1339{
1340 return ((dev->flags & DF_QUIET) != 0);
1341}
1342
1343int
1344device_is_enabled(device_t dev)
1345{
1346 return ((dev->flags & DF_ENABLED) != 0);
1347}
1348
1349int
1350device_is_alive(device_t dev)
1351{
1352 return (dev->state >= DS_ALIVE);
1353}
1354
1355int
1356device_is_attached(device_t dev)
1357{
1358 return (dev->state >= DS_ATTACHED);
1359}
1360
1361int
1362device_set_devclass(device_t dev, const char *classname)
1363{
1364 devclass_t dc;
1365 int error;
1366
1367 if (!classname) {
1368 if (dev->devclass)
1369 devclass_delete_device(dev->devclass, dev);
1370 return (0);
1371 }
1372
1373 if (dev->devclass) {
1374 printf("device_set_devclass: device class already set\n");
1375 return (EINVAL);
1376 }
1377
1378 dc = devclass_find_internal(classname, TRUE);
1379 if (!dc)
1380 return (ENOMEM);
1381
1382 error = devclass_add_device(dc, dev);
1383
1384 bus_data_generation_update();
1385 return (error);
1386}
1387
1388int
1389device_set_driver(device_t dev, driver_t *driver)
1390{
1391 if (dev->state >= DS_ATTACHED)
1392 return (EBUSY);
1393
1394 if (dev->driver == driver)
1395 return (0);
1396
1397 if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC)) {
1398 free(dev->softc, M_BUS);
1399 dev->softc = NULL;
1400 }
1401 kobj_delete((kobj_t) dev, 0);
1402 dev->driver = driver;
1403 if (driver) {
1404 kobj_init((kobj_t) dev, (kobj_class_t) driver);
1405 if (!(dev->flags & DF_EXTERNALSOFTC) && driver->size > 0) {
1406 dev->softc = malloc(driver->size, M_BUS,
1407 M_NOWAIT | M_ZERO);
1408 if (!dev->softc) {
1409 kobj_delete((kobj_t) dev, 0);
1410 kobj_init((kobj_t) dev, &null_class);
1411 dev->driver = NULL;
1412 return (ENOMEM);
1413 }
1414 }
1415 } else {
1416 kobj_init((kobj_t) dev, &null_class);
1417 }
1418
1419 bus_data_generation_update();
1420 return (0);
1421}
1422
1423int
1424device_probe_and_attach(device_t dev)
1425{
1426 device_t bus = dev->parent;
1427 int error = 0;
1428 int hasclass = (dev->devclass != 0);
1429
1430 if (dev->state >= DS_ALIVE)
1431 return (0);
1432
1433 if (dev->flags & DF_ENABLED) {
1434 error = device_probe_child(bus, dev);
1435 if (!error) {
1436 if (!device_is_quiet(dev))
1437 device_print_child(bus, dev);
1438 error = DEVICE_ATTACH(dev);
1439 if (!error) {
1440 dev->state = DS_ATTACHED;
1441 devadded(dev);
1442 } else {
1443 printf("device_probe_and_attach: %s%d attach returned %d\n",
1444 dev->driver->name, dev->unit, error);
1445 /* Unset the class; set in device_probe_child */
1446 if (!hasclass)
1447 device_set_devclass(dev, 0);
1448 device_set_driver(dev, NULL);
1449 dev->state = DS_NOTPRESENT;
1450 }
1451 } else {
1452 if (!(dev->flags & DF_DONENOMATCH)) {
1453 BUS_PROBE_NOMATCH(bus, dev);
1454 devnomatch(dev);
1455 dev->flags |= DF_DONENOMATCH;
1456 }
1457 }
1458 } else {
1459 if (bootverbose) {
1460 device_print_prettyname(dev);
1461 printf("not probed (disabled)\n");
1462 }
1463 }
1464
1465 return (error);
1466}
1467
1468int
1469device_detach(device_t dev)
1470{
1471 int error;
1472
1473 PDEBUG(("%s", DEVICENAME(dev)));
1474 if (dev->state == DS_BUSY)
1475 return (EBUSY);
1476 if (dev->state != DS_ATTACHED)
1477 return (0);
1478
1479 if ((error = DEVICE_DETACH(dev)) != 0)
1480 return (error);
1481 devremoved(dev);
1482 device_printf(dev, "detached\n");
1483 if (dev->parent)
1484 BUS_CHILD_DETACHED(dev->parent, dev);
1485
1486 if (!(dev->flags & DF_FIXEDCLASS))
1487 devclass_delete_device(dev->devclass, dev);
1488
1489 dev->state = DS_NOTPRESENT;
1490 device_set_driver(dev, NULL);
1491
1492 return (0);
1493}
1494
1495int
1496device_shutdown(device_t dev)
1497{
1498 if (dev->state < DS_ATTACHED)
1499 return (0);
1500 return (DEVICE_SHUTDOWN(dev));
1501}
1502
1503int
1504device_set_unit(device_t dev, int unit)
1505{
1506 devclass_t dc;
1507 int err;
1508
1509 dc = device_get_devclass(dev);
1510 if (unit < dc->maxunit && dc->devices[unit])
1511 return (EBUSY);
1512 err = devclass_delete_device(dc, dev);
1513 if (err)
1514 return (err);
1515 dev->unit = unit;
1516 err = devclass_add_device(dc, dev);
1517 if (err)
1518 return (err);
1519
1520 bus_data_generation_update();
1521 return (0);
1522}
1523
1524/*======================================*/
1525/*
1526 * Some useful method implementations to make life easier for bus drivers.
1527 */
1528
1529void
1530resource_list_init(struct resource_list *rl)
1531{
1532 SLIST_INIT(rl);
1533}
1534
1535void
1536resource_list_free(struct resource_list *rl)
1537{
1538 struct resource_list_entry *rle;
1539
1540 while ((rle = SLIST_FIRST(rl)) != NULL) {
1541 if (rle->res)
1542 panic("resource_list_free: resource entry is busy");
1543 SLIST_REMOVE_HEAD(rl, link);
1544 free(rle, M_BUS);
1545 }
1546}
1547
1548int
1549resource_list_add_next(struct resource_list *rl, int type, u_long start,
1550 u_long end, u_long count)
1551{
1552 int rid;
1553
1554 rid = 0;
1555 while (resource_list_find(rl, type, rid) != NULL)
1556 rid++;
1557 resource_list_add(rl, type, rid, start, end, count);
1558 return (rid);
1559}
1560
1561void
1562resource_list_add(struct resource_list *rl, int type, int rid,
1563 u_long start, u_long end, u_long count)
1564{
1565 struct resource_list_entry *rle;
1566
1567 rle = resource_list_find(rl, type, rid);
1568 if (!rle) {
1569 rle = malloc(sizeof(struct resource_list_entry), M_BUS,
1570 M_NOWAIT);
1571 if (!rle)
1572 panic("resource_list_add: can't record entry");
1573 SLIST_INSERT_HEAD(rl, rle, link);
1574 rle->type = type;
1575 rle->rid = rid;
1576 rle->res = NULL;
1577 }
1578
1579 if (rle->res)
1580 panic("resource_list_add: resource entry is busy");
1581
1582 rle->start = start;
1583 rle->end = end;
1584 rle->count = count;
1585}
1586
1587struct resource_list_entry *
1588resource_list_find(struct resource_list *rl, int type, int rid)
1589{
1590 struct resource_list_entry *rle;
1591
1592 SLIST_FOREACH(rle, rl, link) {
1593 if (rle->type == type && rle->rid == rid)
1594 return (rle);
1595 }
1596 return (NULL);
1597}
1598
1599void
1600resource_list_delete(struct resource_list *rl, int type, int rid)
1601{
1602 struct resource_list_entry *rle = resource_list_find(rl, type, rid);
1603
1604 if (rle) {
1605 if (rle->res != NULL)
1606 panic("resource_list_delete: resource has not been released");
1607 SLIST_REMOVE(rl, rle, resource_list_entry, link);
1608 free(rle, M_BUS);
1609 }
1610}
1611
1612struct resource *
1613resource_list_alloc(struct resource_list *rl, device_t bus, device_t child,
1614 int type, int *rid, u_long start, u_long end, u_long count, u_int flags)
1615{
1616 struct resource_list_entry *rle = 0;
1617 int passthrough = (device_get_parent(child) != bus);
1618 int isdefault = (start == 0UL && end == ~0UL);
1619
1620 if (passthrough) {
1621 return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
1622 type, rid, start, end, count, flags));
1623 }
1624
1625 rle = resource_list_find(rl, type, *rid);
1626
1627 if (!rle)
1628 return (NULL); /* no resource of that type/rid */
1629
1630 if (rle->res)
1631 panic("resource_list_alloc: resource entry is busy");
1632
1633 if (isdefault) {
1634 start = rle->start;
1635 count = ulmax(count, rle->count);
1636 end = ulmax(rle->end, start + count - 1);
1637 }
1638
1639 rle->res = BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
1640 type, rid, start, end, count, flags);
1641
1642 /*
1643 * Record the new range.
1644 */
1645 if (rle->res) {
1646 rle->start = rman_get_start(rle->res);
1647 rle->end = rman_get_end(rle->res);
1648 rle->count = count;
1649 }
1650
1651 return (rle->res);
1652}
1653
1654int
1655resource_list_release(struct resource_list *rl, device_t bus, device_t child,
1656 int type, int rid, struct resource *res)
1657{
1658 struct resource_list_entry *rle = 0;
1659 int passthrough = (device_get_parent(child) != bus);
1660 int error;
1661
1662 if (passthrough) {
1663 return (BUS_RELEASE_RESOURCE(device_get_parent(bus), child,
1664 type, rid, res));
1665 }
1666
1667 rle = resource_list_find(rl, type, rid);
1668
1669 if (!rle)
1670 panic("resource_list_release: can't find resource");
1671 if (!rle->res)
1672 panic("resource_list_release: resource entry is not busy");
1673
1674 error = BUS_RELEASE_RESOURCE(device_get_parent(bus), child,
1675 type, rid, res);
1676 if (error)
1677 return (error);
1678
1679 rle->res = NULL;
1680 return (0);
1681}
1682
1683int
1684resource_list_print_type(struct resource_list *rl, const char *name, int type,
1685 const char *format)
1686{
1687 struct resource_list_entry *rle;
1688 int printed, retval;
1689
1690 printed = 0;
1691 retval = 0;
1692 /* Yes, this is kinda cheating */
1693 SLIST_FOREACH(rle, rl, link) {
1694 if (rle->type == type) {
1695 if (printed == 0)
1696 retval += printf(" %s ", name);
1697 else
1698 retval += printf(",");
1699 printed++;
1700 retval += printf(format, rle->start);
1701 if (rle->count > 1) {
1702 retval += printf("-");
1703 retval += printf(format, rle->start +
1704 rle->count - 1);
1705 }
1706 }
1707 }
1708 return (retval);
1709}
1710
1711/*
1712 * Call DEVICE_IDENTIFY for each driver.
1713 */
1714int
1715bus_generic_probe(device_t dev)
1716{
1717 devclass_t dc = dev->devclass;
1718 driverlink_t dl;
1719
1720 TAILQ_FOREACH(dl, &dc->drivers, link) {
1721 DEVICE_IDENTIFY(dl->driver, dev);
1722 }
1723
1724 return (0);
1725}
1726
1727int
1728bus_generic_attach(device_t dev)
1729{
1730 device_t child;
1731
1732 TAILQ_FOREACH(child, &dev->children, link) {
1733 device_probe_and_attach(child);
1734 }
1735
1736 return (0);
1737}
1738
1739int
1740bus_generic_detach(device_t dev)
1741{
1742 device_t child;
1743 int error;
1744
1745 if (dev->state != DS_ATTACHED)
1746 return (EBUSY);
1747
1748 TAILQ_FOREACH(child, &dev->children, link) {
1749 if ((error = device_detach(child)) != 0)
1750 return (error);
1751 }
1752
1753 return (0);
1754}
1755
1756int
1757bus_generic_shutdown(device_t dev)
1758{
1759 device_t child;
1760
1761 TAILQ_FOREACH(child, &dev->children, link) {
1762 device_shutdown(child);
1763 }
1764
1765 return (0);
1766}
1767
1768int
1769bus_generic_suspend(device_t dev)
1770{
1771 int error;
1772 device_t child, child2;
1773
1774 TAILQ_FOREACH(child, &dev->children, link) {
1775 error = DEVICE_SUSPEND(child);
1776 if (error) {
1777 for (child2 = TAILQ_FIRST(&dev->children);
1778 child2 && child2 != child;
1779 child2 = TAILQ_NEXT(child2, link))
1780 DEVICE_RESUME(child2);
1781 return (error);
1782 }
1783 }
1784 return (0);
1785}
1786
1787int
1788bus_generic_resume(device_t dev)
1789{
1790 device_t child;
1791
1792 TAILQ_FOREACH(child, &dev->children, link) {
1793 DEVICE_RESUME(child);
1794 /* if resume fails, there's nothing we can usefully do... */
1795 }
1796 return (0);
1797}
1798
1799int
1800bus_print_child_header (device_t dev, device_t child)
1801{
1802 int retval = 0;
1803
1804 if (device_get_desc(child)) {
1805 retval += device_printf(child, "<%s>", device_get_desc(child));
1806 } else {
1807 retval += printf("%s", device_get_nameunit(child));
1808 }
1809
1810 return (retval);
1811}
1812
1813int
1814bus_print_child_footer (device_t dev, device_t child)
1815{
1816 return (printf(" on %s\n", device_get_nameunit(dev)));
1817}
1818
1819int
1820bus_generic_print_child(device_t dev, device_t child)
1821{
1822 int retval = 0;
1823
1824 retval += bus_print_child_header(dev, child);
1825 retval += bus_print_child_footer(dev, child);
1826
1827 return (retval);
1828}
1829
1830int
1831bus_generic_read_ivar(device_t dev, device_t child, int index,
1832 uintptr_t * result)
1833{
1834 return (ENOENT);
1835}
1836
1837int
1838bus_generic_write_ivar(device_t dev, device_t child, int index,
1839 uintptr_t value)
1840{
1841 return (ENOENT);
1842}
1843
1844struct resource_list *
1845bus_generic_get_resource_list (device_t dev, device_t child)
1846{
1847 return (NULL);
1848}
1849
1850void
1851bus_generic_driver_added(device_t dev, driver_t *driver)
1852{
1853 device_t child;
1854
1855 DEVICE_IDENTIFY(driver, dev);
1856 TAILQ_FOREACH(child, &dev->children, link) {
1857 if (child->state == DS_NOTPRESENT)
1858 device_probe_and_attach(child);
1859 }
1860}
1861
1862int
1863bus_generic_setup_intr(device_t dev, device_t child, struct resource *irq,
1864 int flags, driver_intr_t *intr, void *arg, void **cookiep)
1865{
1866 /* Propagate up the bus hierarchy until someone handles it. */
1867 if (dev->parent)
1868 return (BUS_SETUP_INTR(dev->parent, child, irq, flags,
1869 intr, arg, cookiep));
1870 return (EINVAL);
1871}
1872
1873int
1874bus_generic_teardown_intr(device_t dev, device_t child, struct resource *irq,
1875 void *cookie)
1876{
1877 /* Propagate up the bus hierarchy until someone handles it. */
1878 if (dev->parent)
1879 return (BUS_TEARDOWN_INTR(dev->parent, child, irq, cookie));
1880 return (EINVAL);
1881}
1882
1883struct resource *
1884bus_generic_alloc_resource(device_t dev, device_t child, int type, int *rid,
1885 u_long start, u_long end, u_long count, u_int flags)
1886{
1887 /* Propagate up the bus hierarchy until someone handles it. */
1888 if (dev->parent)
1889 return (BUS_ALLOC_RESOURCE(dev->parent, child, type, rid,
1890 start, end, count, flags));
1891 return (NULL);
1892}
1893
1894int
1895bus_generic_release_resource(device_t dev, device_t child, int type, int rid,
1896 struct resource *r)
1897{
1898 /* Propagate up the bus hierarchy until someone handles it. */
1899 if (dev->parent)
1900 return (BUS_RELEASE_RESOURCE(dev->parent, child, type, rid,
1901 r));
1902 return (EINVAL);
1903}
1904
1905int
1906bus_generic_activate_resource(device_t dev, device_t child, int type, int rid,
1907 struct resource *r)
1908{
1909 /* Propagate up the bus hierarchy until someone handles it. */
1910 if (dev->parent)
1911 return (BUS_ACTIVATE_RESOURCE(dev->parent, child, type, rid,
1912 r));
1913 return (EINVAL);
1914}
1915
1916int
1917bus_generic_deactivate_resource(device_t dev, device_t child, int type,
1918 int rid, struct resource *r)
1919{
1920 /* Propagate up the bus hierarchy until someone handles it. */
1921 if (dev->parent)
1922 return (BUS_DEACTIVATE_RESOURCE(dev->parent, child, type, rid,
1923 r));
1924 return (EINVAL);
1925}
1926
1927int
1928bus_generic_rl_get_resource (device_t dev, device_t child, int type, int rid,
1929 u_long *startp, u_long *countp)
1930{
1931 struct resource_list * rl = NULL;
1932 struct resource_list_entry * rle = NULL;
1933
1934 rl = BUS_GET_RESOURCE_LIST(dev, child);
1935 if (!rl)
1936 return (EINVAL);
1937
1938 rle = resource_list_find(rl, type, rid);
1939 if (!rle)
1940 return (ENOENT);
1941
1942 if (startp)
1943 *startp = rle->start;
1944 if (countp)
1945 *countp = rle->count;
1946
1947 return (0);
1948}
1949
1950int
1951bus_generic_rl_set_resource (device_t dev, device_t child, int type, int rid,
1952 u_long start, u_long count)
1953{
1954 struct resource_list * rl = NULL;
1955
1956 rl = BUS_GET_RESOURCE_LIST(dev, child);
1957 if (!rl)
1958 return (EINVAL);
1959
1960 resource_list_add(rl, type, rid, start, (start + count - 1), count);
1961
1962 return (0);
1963}
1964
1965void
1966bus_generic_rl_delete_resource (device_t dev, device_t child, int type, int rid)
1967{
1968 struct resource_list * rl = NULL;
1969
1970 rl = BUS_GET_RESOURCE_LIST(dev, child);
1971 if (!rl)
1972 return;
1973
1974 resource_list_delete(rl, type, rid);
1975
1976 return;
1977}
1978
1979int
1980bus_generic_rl_release_resource (device_t dev, device_t child, int type,
1981 int rid, struct resource *r)
1982{
1983 struct resource_list * rl = NULL;
1984
1985 rl = BUS_GET_RESOURCE_LIST(dev, child);
1986 if (!rl)
1987 return (EINVAL);
1988
1989 return (resource_list_release(rl, dev, child, type, rid, r));
1990}
1991
1992struct resource *
1993bus_generic_rl_alloc_resource (device_t dev, device_t child, int type,
1994 int *rid, u_long start, u_long end, u_long count, u_int flags)
1995{
1996 struct resource_list * rl = NULL;
1997
1998 rl = BUS_GET_RESOURCE_LIST(dev, child);
1999 if (!rl)
2000 return (NULL);
2001
2002 return (resource_list_alloc(rl, dev, child, type, rid,
2003 start, end, count, flags));
2004}
2005
2006int
2007bus_generic_child_present(device_t bus, device_t child)
2008{
2009 return (BUS_CHILD_PRESENT(device_get_parent(bus), bus));
2010}
2011
2012/*
2013 * Some convenience functions to make it easier for drivers to use the
2014 * resource-management functions. All these really do is hide the
2015 * indirection through the parent's method table, making for slightly
2016 * less-wordy code. In the future, it might make sense for this code
2017 * to maintain some sort of a list of resources allocated by each device.
2018 */
2019struct resource *
2020bus_alloc_resource(device_t dev, int type, int *rid, u_long start, u_long end,
2021 u_long count, u_int flags)
2022{
2023 if (dev->parent == 0)
2024 return (0);
2025 return (BUS_ALLOC_RESOURCE(dev->parent, dev, type, rid, start, end,
2026 count, flags));
2027}
2028
2029int
2030bus_activate_resource(device_t dev, int type, int rid, struct resource *r)
2031{
2032 if (dev->parent == 0)
2033 return (EINVAL);
2034 return (BUS_ACTIVATE_RESOURCE(dev->parent, dev, type, rid, r));
2035}
2036
2037int
2038bus_deactivate_resource(device_t dev, int type, int rid, struct resource *r)
2039{
2040 if (dev->parent == 0)
2041 return (EINVAL);
2042 return (BUS_DEACTIVATE_RESOURCE(dev->parent, dev, type, rid, r));
2043}
2044
2045int
2046bus_release_resource(device_t dev, int type, int rid, struct resource *r)
2047{
2048 if (dev->parent == 0)
2049 return (EINVAL);
2050 return (BUS_RELEASE_RESOURCE(dev->parent, dev, type, rid, r));
2051}
2052
2053int
2054bus_setup_intr(device_t dev, struct resource *r, int flags,
2055 driver_intr_t handler, void *arg, void **cookiep)
2056{
2057 if (dev->parent == 0)
2058 return (EINVAL);
2059 return (BUS_SETUP_INTR(dev->parent, dev, r, flags,
2060 handler, arg, cookiep));
2061}
2062
2063int
2064bus_teardown_intr(device_t dev, struct resource *r, void *cookie)
2065{
2066 if (dev->parent == 0)
2067 return (EINVAL);
2068 return (BUS_TEARDOWN_INTR(dev->parent, dev, r, cookie));
2069}
2070
2071int
2072bus_set_resource(device_t dev, int type, int rid,
2073 u_long start, u_long count)
2074{
2075 return (BUS_SET_RESOURCE(device_get_parent(dev), dev, type, rid,
2076 start, count));
2077}
2078
2079int
2080bus_get_resource(device_t dev, int type, int rid,
2081 u_long *startp, u_long *countp)
2082{
2083 return (BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid,
2084 startp, countp));
2085}
2086
2087u_long
2088bus_get_resource_start(device_t dev, int type, int rid)
2089{
2090 u_long start, count;
2091 int error;
2092
2093 error = BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid,
2094 &start, &count);
2095 if (error)
2096 return (0);
2097 return (start);
2098}
2099
2100u_long
2101bus_get_resource_count(device_t dev, int type, int rid)
2102{
2103 u_long start, count;
2104 int error;
2105
2106 error = BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid,
2107 &start, &count);
2108 if (error)
2109 return (0);
2110 return (count);
2111}
2112
2113void
2114bus_delete_resource(device_t dev, int type, int rid)
2115{
2116 BUS_DELETE_RESOURCE(device_get_parent(dev), dev, type, rid);
2117}
2118
2119int
2120bus_child_present(device_t child)
2121{
2122 return (BUS_CHILD_PRESENT(device_get_parent(child), child));
2123}
2124
2125int
2126bus_child_pnpinfo_str(device_t child, char *buf, size_t buflen)
2127{
2128 device_t parent;
2129
2130 parent = device_get_parent(child);
2131 if (parent == NULL) {
2132 *buf = '\0';
2133 return (0);
2134 }
2135 return (BUS_CHILD_PNPINFO_STR(parent, child, buf, buflen));
2136}
2137
2138int
2139bus_child_location_str(device_t child, char *buf, size_t buflen)
2140{
2141 device_t parent;
2142
2143 parent = device_get_parent(child);
2144 if (parent == NULL) {
2145 *buf = '\0';
2146 return (0);
2147 }
2148 return (BUS_CHILD_LOCATION_STR(parent, child, buf, buflen));
2149}
2150
2151static int
2152root_print_child(device_t dev, device_t child)
2153{
2154 int retval = 0;
2155
2156 retval += bus_print_child_header(dev, child);
2157 retval += printf("\n");
2158
2159 return (retval);
2160}
2161
2162static int
2163root_setup_intr(device_t dev, device_t child, driver_intr_t *intr, void *arg,
2164 void **cookiep)
2165{
2166 /*
2167 * If an interrupt mapping gets to here something bad has happened.
2168 */
2169 panic("root_setup_intr");
2170}
2171
2172/*
2173 * If we get here, assume that the device is permanant and really is
2174 * present in the system. Removable bus drivers are expected to intercept
2175 * this call long before it gets here. We return -1 so that drivers that
2176 * really care can check vs -1 or some ERRNO returned higher in the food
2177 * chain.
2178 */
2179static int
2180root_child_present(device_t dev, device_t child)
2181{
2182 return (-1);
2183}
2184
2185static kobj_method_t root_methods[] = {
2186 /* Device interface */
2187 KOBJMETHOD(device_shutdown, bus_generic_shutdown),
2188 KOBJMETHOD(device_suspend, bus_generic_suspend),
2189 KOBJMETHOD(device_resume, bus_generic_resume),
2190
2191 /* Bus interface */
2192 KOBJMETHOD(bus_print_child, root_print_child),
2193 KOBJMETHOD(bus_read_ivar, bus_generic_read_ivar),
2194 KOBJMETHOD(bus_write_ivar, bus_generic_write_ivar),
2195 KOBJMETHOD(bus_setup_intr, root_setup_intr),
2196 KOBJMETHOD(bus_child_present, root_child_present),
2197
2198 { 0, 0 }
2199};
2200
2201static driver_t root_driver = {
2202 "root",
2203 root_methods,
2204 1, /* no softc */
2205};
2206
2207device_t root_bus;
2208devclass_t root_devclass;
2209
2210static int
2211root_bus_module_handler(module_t mod, int what, void* arg)
2212{
2213 switch (what) {
2214 case MOD_LOAD:
2215 TAILQ_INIT(&bus_data_devices);
2216 kobj_class_compile((kobj_class_t) &root_driver);
2217 root_bus = make_device(NULL, "root", 0);
2218 root_bus->desc = "System root bus";
2219 kobj_init((kobj_t) root_bus, (kobj_class_t) &root_driver);
2220 root_bus->driver = &root_driver;
2221 root_bus->state = DS_ATTACHED;
2222 root_devclass = devclass_find_internal("root", FALSE);
2223 devinit();
2224 return (0);
2225
2226 case MOD_SHUTDOWN:
2227 device_shutdown(root_bus);
2228 return (0);
2229 }
2230
2231 return (0);
2232}
2233
2234static moduledata_t root_bus_mod = {
2235 "rootbus",
2236 root_bus_module_handler,
2237 0
2238};
2239DECLARE_MODULE(rootbus, root_bus_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
2240
2241void
2242root_bus_configure(void)
2243{
2244 device_t dev;
2245
2246 PDEBUG(("."));
2247
2248 TAILQ_FOREACH(dev, &root_bus->children, link) {
2249 device_probe_and_attach(dev);
2250 }
2251}
2252
2253int
2254driver_module_handler(module_t mod, int what, void *arg)
2255{
2256 int error, i;
2257 struct driver_module_data *dmd;
2258 devclass_t bus_devclass;
2259
2260 dmd = (struct driver_module_data *)arg;
2261 bus_devclass = devclass_find_internal(dmd->dmd_busname, TRUE);
2262 error = 0;
2263
2264 switch (what) {
2265 case MOD_LOAD:
2266 if (dmd->dmd_chainevh)
2267 error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
2268
2269 for (i = 0; !error && i < dmd->dmd_ndrivers; i++) {
2270 PDEBUG(("Loading module: driver %s on bus %s",
2271 DRIVERNAME(dmd->dmd_drivers[i]), dmd->dmd_busname));
2272 error = devclass_add_driver(bus_devclass,
2273 dmd->dmd_drivers[i]);
2274 }
2275 if (error)
2276 break;
2277
2278 /*
2279 * The drivers loaded in this way are assumed to all
2280 * implement the same devclass.
2281 */
2282 *dmd->dmd_devclass =
2283 devclass_find_internal(dmd->dmd_drivers[0]->name, TRUE);
2284 break;
2285
2286 case MOD_UNLOAD:
2287 for (i = 0; !error && i < dmd->dmd_ndrivers; i++) {
2288 PDEBUG(("Unloading module: driver %s from bus %s",
2289 DRIVERNAME(dmd->dmd_drivers[i]),
2290 dmd->dmd_busname));
2291 error = devclass_delete_driver(bus_devclass,
2292 dmd->dmd_drivers[i]);
2293 }
2294
2295 if (!error && dmd->dmd_chainevh)
2296 error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
2297 break;
2298 }
2299
2300 return (error);
2301}
2302
2303#ifdef BUS_DEBUG
2304
2305/* the _short versions avoid iteration by not calling anything that prints
2306 * more than oneliners. I love oneliners.
2307 */
2308
2309static void
2310print_device_short(device_t dev, int indent)
2311{
2312 if (!dev)
2313 return;
2314
2315 indentprintf(("device %d: <%s> %sparent,%schildren,%s%s%s%s,%sivars,%ssoftc,busy=%d\n",
2316 dev->unit, dev->desc,
2317 (dev->parent? "":"no "),
2318 (TAILQ_EMPTY(&dev->children)? "no ":""),
2319 (dev->flags&DF_ENABLED? "enabled,":"disabled,"),
2320 (dev->flags&DF_FIXEDCLASS? "fixed,":""),
2321 (dev->flags&DF_WILDCARD? "wildcard,":""),
2322 (dev->flags&DF_DESCMALLOCED? "descmalloced,":""),
2323 (dev->ivars? "":"no "),
2324 (dev->softc? "":"no "),
2325 dev->busy));
2326}
2327
2328static void
2329print_device(device_t dev, int indent)
2330{
2331 if (!dev)
2332 return;
2333
2334 print_device_short(dev, indent);
2335
2336 indentprintf(("Parent:\n"));
2337 print_device_short(dev->parent, indent+1);
2338 indentprintf(("Driver:\n"));
2339 print_driver_short(dev->driver, indent+1);
2340 indentprintf(("Devclass:\n"));
2341 print_devclass_short(dev->devclass, indent+1);
2342}
2343
2344void
2345print_device_tree_short(device_t dev, int indent)
2346/* print the device and all its children (indented) */
2347{
2348 device_t child;
2349
2350 if (!dev)
2351 return;
2352
2353 print_device_short(dev, indent);
2354
2355 TAILQ_FOREACH(child, &dev->children, link) {
2356 print_device_tree_short(child, indent+1);
2357 }
2358}
2359
2360void
2361print_device_tree(device_t dev, int indent)
2362/* print the device and all its children (indented) */
2363{
2364 device_t child;
2365
2366 if (!dev)
2367 return;
2368
2369 print_device(dev, indent);
2370
2371 TAILQ_FOREACH(child, &dev->children, link) {
2372 print_device_tree(child, indent+1);
2373 }
2374}
2375
2376static void
2377print_driver_short(driver_t *driver, int indent)
2378{
2379 if (!driver)
2380 return;
2381
2382 indentprintf(("driver %s: softc size = %zd\n",
2383 driver->name, driver->size));
2384}
2385
2386static void
2387print_driver(driver_t *driver, int indent)
2388{
2389 if (!driver)
2390 return;
2391
2392 print_driver_short(driver, indent);
2393}
2394
2395
2396static void
2397print_driver_list(driver_list_t drivers, int indent)
2398{
2399 driverlink_t driver;
2400
2401 TAILQ_FOREACH(driver, &drivers, link) {
2402 print_driver(driver->driver, indent);
2403 }
2404}
2405
2406static void
2407print_devclass_short(devclass_t dc, int indent)
2408{
2409 if ( !dc )
2410 return;
2411
2412 indentprintf(("devclass %s: max units = %d\n", dc->name, dc->maxunit));
2413}
2414
2415static void
2416print_devclass(devclass_t dc, int indent)
2417{
2418 int i;
2419
2420 if ( !dc )
2421 return;
2422
2423 print_devclass_short(dc, indent);
2424 indentprintf(("Drivers:\n"));
2425 print_driver_list(dc->drivers, indent+1);
2426
2427 indentprintf(("Devices:\n"));
2428 for (i = 0; i < dc->maxunit; i++)
2429 if (dc->devices[i])
2430 print_device(dc->devices[i], indent+1);
2431}
2432
2433void
2434print_devclass_list_short(void)
2435{
2436 devclass_t dc;
2437
2438 printf("Short listing of devclasses, drivers & devices:\n");
2439 TAILQ_FOREACH(dc, &devclasses, link) {
2440 print_devclass_short(dc, 0);
2441 }
2442}
2443
2444void
2445print_devclass_list(void)
2446{
2447 devclass_t dc;
2448
2449 printf("Full listing of devclasses, drivers & devices:\n");
2450 TAILQ_FOREACH(dc, &devclasses, link) {
2451 print_devclass(dc, 0);
2452 }
2453}
2454
2455#endif
2456
2457/*
2458 * User-space access to the device tree.
2459 *
2460 * We implement a small set of nodes:
2461 *
2462 * hw.bus Single integer read method to obtain the
2463 * current generation count.
2464 * hw.bus.devices Reads the entire device tree in flat space.
2465 * hw.bus.rman Resource manager interface
2466 *
2467 * We might like to add the ability to scan devclasses and/or drivers to
2468 * determine what else is currently loaded/available.
2469 */
2470
2471static int
2472sysctl_bus(SYSCTL_HANDLER_ARGS)
2473{
2474 struct u_businfo ubus;
2475
2476 ubus.ub_version = BUS_USER_VERSION;
2477 ubus.ub_generation = bus_data_generation;
2478
2479 return (SYSCTL_OUT(req, &ubus, sizeof(ubus)));
2480}
2481SYSCTL_NODE(_hw_bus, OID_AUTO, info, CTLFLAG_RW, sysctl_bus,
2482 "bus-related data");
2483
2484static int
2485sysctl_devices(SYSCTL_HANDLER_ARGS)
2486{
2487 int *name = (int *)arg1;
2488 u_int namelen = arg2;
2489 int index;
2490 struct device *dev;
2491 struct u_device udev; /* XXX this is a bit big */
2492 int error;
2493
2494 if (namelen != 2)
2495 return (EINVAL);
2496
2497 if (bus_data_generation_check(name[0]))
2498 return (EINVAL);
2499
2500 index = name[1];
2501
2502 /*
2503 * Scan the list of devices, looking for the requested index.
2504 */
2505 TAILQ_FOREACH(dev, &bus_data_devices, devlink) {
2506 if (index-- == 0)
2507 break;
2508 }
2509 if (dev == NULL)
2510 return (ENOENT);
2511
2512 /*
2513 * Populate the return array.
2514 */
2515 udev.dv_handle = (uintptr_t)dev;
2516 udev.dv_parent = (uintptr_t)dev->parent;
2517 if (dev->nameunit == NULL)
2518 udev.dv_name[0] = '\0';
2519 else
2520 strlcpy(udev.dv_name, dev->nameunit, sizeof(udev.dv_name));
2521
2522 if (dev->desc == NULL)
2523 udev.dv_desc[0] = '\0';
2524 else
2525 strlcpy(udev.dv_desc, dev->desc, sizeof(udev.dv_desc));
2526 if (dev->driver == NULL || dev->driver->name == NULL)
2527 udev.dv_drivername[0] = '\0';
2528 else
2529 strlcpy(udev.dv_drivername, dev->driver->name,
2530 sizeof(udev.dv_drivername));
2531 udev.dv_pnpinfo[0] = '\0';
2532 udev.dv_location[0] = '\0';
2533 bus_child_pnpinfo_str(dev, udev.dv_pnpinfo, sizeof(udev.dv_pnpinfo));
2534 bus_child_location_str(dev, udev.dv_location, sizeof(udev.dv_location));
2535 udev.dv_devflags = dev->devflags;
2536 udev.dv_flags = dev->flags;
2537 udev.dv_state = dev->state;
2538 error = SYSCTL_OUT(req, &udev, sizeof(udev));
2539 return (error);
2540}
2541
2542SYSCTL_NODE(_hw_bus, OID_AUTO, devices, CTLFLAG_RD, sysctl_devices,
2543 "system device tree");
2544
2545/*
2546 * Sysctl interface for scanning the resource lists.
2547 *
2548 * We take two input parameters; the index into the list of resource
2549 * managers, and the resource offset into the list.
2550 */
2551static int
2552sysctl_rman(SYSCTL_HANDLER_ARGS)
2553{
2554 int *name = (int *)arg1;
2555 u_int namelen = arg2;
2556 int rman_idx, res_idx;
2557 struct rman *rm;
2558 struct resource *res;
2559 struct u_rman urm;
2560 struct u_resource ures;
2561 int error;
2562
2563 if (namelen != 3)
2564 return (EINVAL);
2565
2566 if (bus_data_generation_check(name[0]))
2567 return (EINVAL);
2568 rman_idx = name[1];
2569 res_idx = name[2];
2570
2571 /*
2572 * Find the indexed resource manager
2573 */
2574 TAILQ_FOREACH(rm, &rman_head, rm_link) {
2575 if (rman_idx-- == 0)
2576 break;
2577 }
2578 if (rm == NULL)
2579 return (ENOENT);
2580
2581 /*
2582 * If the resource index is -1, we want details on the
2583 * resource manager.
2584 */
2585 if (res_idx == -1) {
2586 urm.rm_handle = (uintptr_t)rm;
2587 strlcpy(urm.rm_descr, rm->rm_descr, RM_TEXTLEN);
2588 urm.rm_start = rm->rm_start;
2589 urm.rm_size = rm->rm_end - rm->rm_start + 1;
2590 urm.rm_type = rm->rm_type;
2591
2592 error = SYSCTL_OUT(req, &urm, sizeof(urm));
2593 return (error);
2594 }
2595
2596 /*
2597 * Find the indexed resource and return it.
2598 */
2599 TAILQ_FOREACH(res, &rm->rm_list, r_link) {
2600 if (res_idx-- == 0) {
2601 ures.r_handle = (uintptr_t)res;
2602 ures.r_parent = (uintptr_t)res->r_rm;
2603 ures.r_device = (uintptr_t)res->r_dev;
2604 if (res->r_dev != NULL) {
2605 if (device_get_name(res->r_dev) != NULL) {
2606 snprintf(ures.r_devname, RM_TEXTLEN,
2607 "%s%d",
2608 device_get_name(res->r_dev),
2609 device_get_unit(res->r_dev));
2610 } else {
2611 strlcpy(ures.r_devname, "nomatch",
2612 RM_TEXTLEN);
2613 }
2614 } else {
2615 ures.r_devname[0] = '\0';
2616 }
2617 ures.r_start = res->r_start;
2618 ures.r_size = res->r_end - res->r_start + 1;
2619 ures.r_flags = res->r_flags;
2620
2621 error = SYSCTL_OUT(req, &ures, sizeof(ures));
2622 return (error);
2623 }
2624 }
2625 return (ENOENT);
2626}
2627
2628SYSCTL_NODE(_hw_bus, OID_AUTO, rman, CTLFLAG_RD, sysctl_rman,
2629 "kernel resource manager");
2630
2631int
2632bus_data_generation_check(int generation)
2633{
2634 if (generation != bus_data_generation)
2635 return (1);
2636
2637 /* XXX generate optimised lists here? */
2638 return (0);
2639}
2640
2641void
2642bus_data_generation_update(void)
2643{
2644 bus_data_generation++;
2645}
249
250static void
251devinit(void)
252{
253 devctl_dev = make_dev(&dev_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
254 "devctl");
255 mtx_init(&devsoftc.mtx, "dev mtx", "devd", MTX_DEF);
256 cv_init(&devsoftc.cv, "dev cv");
257 TAILQ_INIT(&devsoftc.devq);
258}
259
260static int
261devopen(dev_t dev, int oflags, int devtype, d_thread_t *td)
262{
263 if (devsoftc.inuse)
264 return (EBUSY);
265 /* move to init */
266 devsoftc.inuse = 1;
267 devsoftc.nonblock = 0;
268 devsoftc.async_proc = NULL;
269 return (0);
270}
271
272static int
273devclose(dev_t dev, int fflag, int devtype, d_thread_t *td)
274{
275 devsoftc.inuse = 0;
276 mtx_lock(&devsoftc.mtx);
277 cv_broadcast(&devsoftc.cv);
278 mtx_unlock(&devsoftc.mtx);
279
280 return (0);
281}
282
283/*
284 * The read channel for this device is used to report changes to
285 * userland in realtime. We are required to free the data as well as
286 * the n1 object because we allocate them separately. Also note that
287 * we return one record at a time. If you try to read this device a
288 * character at a time, you will loose the rest of the data. Listening
289 * programs are expected to cope.
290 */
291static int
292devread(dev_t dev, struct uio *uio, int ioflag)
293{
294 struct dev_event_info *n1;
295 int rv;
296
297 mtx_lock(&devsoftc.mtx);
298 while (TAILQ_EMPTY(&devsoftc.devq)) {
299 if (devsoftc.nonblock) {
300 mtx_unlock(&devsoftc.mtx);
301 return (EAGAIN);
302 }
303 rv = cv_wait_sig(&devsoftc.cv, &devsoftc.mtx);
304 if (rv) {
305 /*
306 * Need to translate ERESTART to EINTR here? -- jake
307 */
308 mtx_unlock(&devsoftc.mtx);
309 return (rv);
310 }
311 }
312 n1 = TAILQ_FIRST(&devsoftc.devq);
313 TAILQ_REMOVE(&devsoftc.devq, n1, dei_link);
314 mtx_unlock(&devsoftc.mtx);
315 rv = uiomove(n1->dei_data, strlen(n1->dei_data), uio);
316 free(n1->dei_data, M_BUS);
317 free(n1, M_BUS);
318 return (rv);
319}
320
321static int
322devioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, d_thread_t *td)
323{
324 switch (cmd) {
325
326 case FIONBIO:
327 if (*(int*)data)
328 devsoftc.nonblock = 1;
329 else
330 devsoftc.nonblock = 0;
331 return (0);
332 case FIOASYNC:
333 if (*(int*)data)
334 devsoftc.async_proc = td->td_proc;
335 else
336 devsoftc.async_proc = NULL;
337 return (0);
338
339 /* (un)Support for other fcntl() calls. */
340 case FIOCLEX:
341 case FIONCLEX:
342 case FIONREAD:
343 case FIOSETOWN:
344 case FIOGETOWN:
345 default:
346 break;
347 }
348 return (ENOTTY);
349}
350
351static int
352devpoll(dev_t dev, int events, d_thread_t *td)
353{
354 int revents = 0;
355
356 mtx_lock(&devsoftc.mtx);
357 if (events & (POLLIN | POLLRDNORM)) {
358 if (!TAILQ_EMPTY(&devsoftc.devq))
359 revents = events & (POLLIN | POLLRDNORM);
360 else
361 selrecord(td, &devsoftc.sel);
362 }
363 mtx_unlock(&devsoftc.mtx);
364
365 return (revents);
366}
367
368/*
369 * Common routine that tries to make sending messages as easy as possible.
370 * We allocate memory for the data, copy strings into that, but do not
371 * free it unless there's an error. The dequeue part of the driver should
372 * free the data. We don't send data when the device is disabled. We do
373 * send data, even when we have no listeners, because we wish to avoid
374 * races relating to startup and restart of listening applications.
375 */
376static void
377devaddq(const char *type, const char *what, device_t dev)
378{
379 struct dev_event_info *n1 = NULL;
380 struct proc *p;
381 char *data = NULL;
382 char *loc;
383 const char *parstr;
384
385 if (devctl_disable)
386 return;
387 n1 = malloc(sizeof(*n1), M_BUS, M_NOWAIT);
388 if (n1 == NULL)
389 goto bad;
390 data = malloc(1024, M_BUS, M_NOWAIT);
391 if (data == NULL)
392 goto bad;
393 loc = malloc(1024, M_BUS, M_NOWAIT);
394 if (loc == NULL)
395 goto bad;
396 *loc = '\0';
397 bus_child_location_str(dev, loc, 1024);
398 if (device_get_parent(dev) == NULL)
399 parstr = "."; /* Or '/' ? */
400 else
401 parstr = device_get_nameunit(device_get_parent(dev));
402 snprintf(data, 1024, "%s%s at %s on %s\n", type, what, loc, parstr);
403 free(loc, M_BUS);
404 n1->dei_data = data;
405 mtx_lock(&devsoftc.mtx);
406 TAILQ_INSERT_TAIL(&devsoftc.devq, n1, dei_link);
407 cv_broadcast(&devsoftc.cv);
408 mtx_unlock(&devsoftc.mtx);
409 selwakeup(&devsoftc.sel);
410 p = devsoftc.async_proc;
411 if (p != NULL) {
412 PROC_LOCK(p);
413 psignal(p, SIGIO);
414 PROC_UNLOCK(p);
415 }
416 return;
417bad:;
418 free(data, M_BUS);
419 free(n1, M_BUS);
420 return;
421}
422
423/*
424 * A device was added to the tree. We are called just after it successfully
425 * attaches (that is, probe and attach success for this device). No call
426 * is made if a device is merely parented into the tree. See devnomatch
427 * if probe fails. If attach fails, no notification is sent (but maybe
428 * we should have a different message for this).
429 */
430static void
431devadded(device_t dev)
432{
433 devaddq("+", device_get_nameunit(dev), dev);
434}
435
436/*
437 * A device was removed from the tree. We are called just before this
438 * happens.
439 */
440static void
441devremoved(device_t dev)
442{
443 devaddq("-", device_get_nameunit(dev), dev);
444}
445
446/*
447 * Called when there's no match for this device. This is only called
448 * the first time that no match happens, so we don't keep getitng this
449 * message. Should that prove to be undesirable, we can change it.
450 * This is called when all drivers that can attach to a given bus
451 * decline to accept this device. Other errrors may not be detected.
452 */
453static void
454devnomatch(device_t dev)
455{
456 char *pnp = NULL;
457
458 pnp = malloc(1024, M_BUS, M_NOWAIT);
459 if (pnp == NULL)
460 return;
461 *pnp = '\0';
462 bus_child_pnpinfo_str(dev, pnp, 1024);
463 devaddq("?", pnp, dev);
464 free(pnp, M_BUS);
465 return;
466}
467
468static int
469sysctl_devctl_disable(SYSCTL_HANDLER_ARGS)
470{
471 struct dev_event_info *n1;
472 int dis, error;
473
474 dis = devctl_disable;
475 error = sysctl_handle_int(oidp, &dis, 0, req);
476 if (error || !req->newptr)
477 return (error);
478 mtx_lock(&devsoftc.mtx);
479 devctl_disable = dis;
480 if (dis) {
481 while (!TAILQ_EMPTY(&devsoftc.devq)) {
482 n1 = TAILQ_FIRST(&devsoftc.devq);
483 TAILQ_REMOVE(&devsoftc.devq, n1, dei_link);
484 free(n1->dei_data, M_BUS);
485 free(n1, M_BUS);
486 }
487 }
488 mtx_unlock(&devsoftc.mtx);
489 return (0);
490}
491
492/* End of /dev/devctl code */
493
494TAILQ_HEAD(,device) bus_data_devices;
495static int bus_data_generation = 1;
496
497kobj_method_t null_methods[] = {
498 { 0, 0 }
499};
500
501DEFINE_CLASS(null, null_methods, 0);
502
503/*
504 * Devclass implementation
505 */
506
507static devclass_list_t devclasses = TAILQ_HEAD_INITIALIZER(devclasses);
508
509static devclass_t
510devclass_find_internal(const char *classname, int create)
511{
512 devclass_t dc;
513
514 PDEBUG(("looking for %s", classname));
515 if (!classname)
516 return (NULL);
517
518 TAILQ_FOREACH(dc, &devclasses, link) {
519 if (!strcmp(dc->name, classname))
520 return (dc);
521 }
522
523 PDEBUG(("%s not found%s", classname, (create? ", creating": "")));
524 if (create) {
525 dc = malloc(sizeof(struct devclass) + strlen(classname) + 1,
526 M_BUS, M_NOWAIT|M_ZERO);
527 if (!dc)
528 return (NULL);
529 dc->name = (char*) (dc + 1);
530 strcpy(dc->name, classname);
531 TAILQ_INIT(&dc->drivers);
532 TAILQ_INSERT_TAIL(&devclasses, dc, link);
533
534 bus_data_generation_update();
535 }
536
537 return (dc);
538}
539
540devclass_t
541devclass_create(const char *classname)
542{
543 return (devclass_find_internal(classname, TRUE));
544}
545
546devclass_t
547devclass_find(const char *classname)
548{
549 return (devclass_find_internal(classname, FALSE));
550}
551
552int
553devclass_add_driver(devclass_t dc, driver_t *driver)
554{
555 driverlink_t dl;
556 int i;
557
558 PDEBUG(("%s", DRIVERNAME(driver)));
559
560 dl = malloc(sizeof *dl, M_BUS, M_NOWAIT|M_ZERO);
561 if (!dl)
562 return (ENOMEM);
563
564 /*
565 * Compile the driver's methods. Also increase the reference count
566 * so that the class doesn't get freed when the last instance
567 * goes. This means we can safely use static methods and avoids a
568 * double-free in devclass_delete_driver.
569 */
570 kobj_class_compile((kobj_class_t) driver);
571
572 /*
573 * Make sure the devclass which the driver is implementing exists.
574 */
575 devclass_find_internal(driver->name, TRUE);
576
577 dl->driver = driver;
578 TAILQ_INSERT_TAIL(&dc->drivers, dl, link);
579 driver->refs++;
580
581 /*
582 * Call BUS_DRIVER_ADDED for any existing busses in this class.
583 */
584 for (i = 0; i < dc->maxunit; i++)
585 if (dc->devices[i])
586 BUS_DRIVER_ADDED(dc->devices[i], driver);
587
588 bus_data_generation_update();
589 return (0);
590}
591
592int
593devclass_delete_driver(devclass_t busclass, driver_t *driver)
594{
595 devclass_t dc = devclass_find(driver->name);
596 driverlink_t dl;
597 device_t dev;
598 int i;
599 int error;
600
601 PDEBUG(("%s from devclass %s", driver->name, DEVCLANAME(busclass)));
602
603 if (!dc)
604 return (0);
605
606 /*
607 * Find the link structure in the bus' list of drivers.
608 */
609 TAILQ_FOREACH(dl, &busclass->drivers, link) {
610 if (dl->driver == driver)
611 break;
612 }
613
614 if (!dl) {
615 PDEBUG(("%s not found in %s list", driver->name,
616 busclass->name));
617 return (ENOENT);
618 }
619
620 /*
621 * Disassociate from any devices. We iterate through all the
622 * devices in the devclass of the driver and detach any which are
623 * using the driver and which have a parent in the devclass which
624 * we are deleting from.
625 *
626 * Note that since a driver can be in multiple devclasses, we
627 * should not detach devices which are not children of devices in
628 * the affected devclass.
629 */
630 for (i = 0; i < dc->maxunit; i++) {
631 if (dc->devices[i]) {
632 dev = dc->devices[i];
633 if (dev->driver == driver && dev->parent &&
634 dev->parent->devclass == busclass) {
635 if ((error = device_detach(dev)) != 0)
636 return (error);
637 device_set_driver(dev, NULL);
638 }
639 }
640 }
641
642 TAILQ_REMOVE(&busclass->drivers, dl, link);
643 free(dl, M_BUS);
644
645 driver->refs--;
646 if (driver->refs == 0)
647 kobj_class_free((kobj_class_t) driver);
648
649 bus_data_generation_update();
650 return (0);
651}
652
653static driverlink_t
654devclass_find_driver_internal(devclass_t dc, const char *classname)
655{
656 driverlink_t dl;
657
658 PDEBUG(("%s in devclass %s", classname, DEVCLANAME(dc)));
659
660 TAILQ_FOREACH(dl, &dc->drivers, link) {
661 if (!strcmp(dl->driver->name, classname))
662 return (dl);
663 }
664
665 PDEBUG(("not found"));
666 return (NULL);
667}
668
669driver_t *
670devclass_find_driver(devclass_t dc, const char *classname)
671{
672 driverlink_t dl;
673
674 dl = devclass_find_driver_internal(dc, classname);
675 if (dl)
676 return (dl->driver);
677 return (NULL);
678}
679
680const char *
681devclass_get_name(devclass_t dc)
682{
683 return (dc->name);
684}
685
686device_t
687devclass_get_device(devclass_t dc, int unit)
688{
689 if (dc == NULL || unit < 0 || unit >= dc->maxunit)
690 return (NULL);
691 return (dc->devices[unit]);
692}
693
694void *
695devclass_get_softc(devclass_t dc, int unit)
696{
697 device_t dev;
698
699 dev = devclass_get_device(dc, unit);
700 if (!dev)
701 return (NULL);
702
703 return (device_get_softc(dev));
704}
705
706int
707devclass_get_devices(devclass_t dc, device_t **devlistp, int *devcountp)
708{
709 int i;
710 int count;
711 device_t *list;
712
713 count = 0;
714 for (i = 0; i < dc->maxunit; i++)
715 if (dc->devices[i])
716 count++;
717
718 list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT|M_ZERO);
719 if (!list)
720 return (ENOMEM);
721
722 count = 0;
723 for (i = 0; i < dc->maxunit; i++) {
724 if (dc->devices[i]) {
725 list[count] = dc->devices[i];
726 count++;
727 }
728 }
729
730 *devlistp = list;
731 *devcountp = count;
732
733 return (0);
734}
735
736int
737devclass_get_maxunit(devclass_t dc)
738{
739 return (dc->maxunit);
740}
741
742int
743devclass_find_free_unit(devclass_t dc, int unit)
744{
745 if (dc == NULL)
746 return (unit);
747 while (unit < dc->maxunit && dc->devices[unit] != NULL)
748 unit++;
749 return (unit);
750}
751
752static int
753devclass_alloc_unit(devclass_t dc, int *unitp)
754{
755 int unit = *unitp;
756
757 PDEBUG(("unit %d in devclass %s", unit, DEVCLANAME(dc)));
758
759 /* If we were given a wired unit number, check for existing device */
760 /* XXX imp XXX */
761 if (unit != -1) {
762 if (unit >= 0 && unit < dc->maxunit &&
763 dc->devices[unit] != NULL) {
764 if (bootverbose)
765 printf("%s: %s%d already exists; skipping it\n",
766 dc->name, dc->name, *unitp);
767 return (EEXIST);
768 }
769 } else {
770 /* Unwired device, find the next available slot for it */
771 unit = 0;
772 while (unit < dc->maxunit && dc->devices[unit] != NULL)
773 unit++;
774 }
775
776 /*
777 * We've selected a unit beyond the length of the table, so let's
778 * extend the table to make room for all units up to and including
779 * this one.
780 */
781 if (unit >= dc->maxunit) {
782 device_t *newlist;
783 int newsize;
784
785 newsize = roundup((unit + 1), MINALLOCSIZE / sizeof(device_t));
786 newlist = malloc(sizeof(device_t) * newsize, M_BUS, M_NOWAIT);
787 if (!newlist)
788 return (ENOMEM);
789 bcopy(dc->devices, newlist, sizeof(device_t) * dc->maxunit);
790 bzero(newlist + dc->maxunit,
791 sizeof(device_t) * (newsize - dc->maxunit));
792 if (dc->devices)
793 free(dc->devices, M_BUS);
794 dc->devices = newlist;
795 dc->maxunit = newsize;
796 }
797 PDEBUG(("now: unit %d in devclass %s", unit, DEVCLANAME(dc)));
798
799 *unitp = unit;
800 return (0);
801}
802
803static int
804devclass_add_device(devclass_t dc, device_t dev)
805{
806 int buflen, error;
807
808 PDEBUG(("%s in devclass %s", DEVICENAME(dev), DEVCLANAME(dc)));
809
810 buflen = snprintf(NULL, 0, "%s%d$", dc->name, dev->unit);
811 if (buflen < 0)
812 return (ENOMEM);
813 dev->nameunit = malloc(buflen, M_BUS, M_NOWAIT|M_ZERO);
814 if (!dev->nameunit)
815 return (ENOMEM);
816
817 if ((error = devclass_alloc_unit(dc, &dev->unit)) != 0) {
818 free(dev->nameunit, M_BUS);
819 dev->nameunit = NULL;
820 return (error);
821 }
822 dc->devices[dev->unit] = dev;
823 dev->devclass = dc;
824 snprintf(dev->nameunit, buflen, "%s%d", dc->name, dev->unit);
825
826 return (0);
827}
828
829static int
830devclass_delete_device(devclass_t dc, device_t dev)
831{
832 if (!dc || !dev)
833 return (0);
834
835 PDEBUG(("%s in devclass %s", DEVICENAME(dev), DEVCLANAME(dc)));
836
837 if (dev->devclass != dc || dc->devices[dev->unit] != dev)
838 panic("devclass_delete_device: inconsistent device class");
839 dc->devices[dev->unit] = NULL;
840 if (dev->flags & DF_WILDCARD)
841 dev->unit = -1;
842 dev->devclass = NULL;
843 free(dev->nameunit, M_BUS);
844 dev->nameunit = NULL;
845
846 return (0);
847}
848
849static device_t
850make_device(device_t parent, const char *name, int unit)
851{
852 device_t dev;
853 devclass_t dc;
854
855 PDEBUG(("%s at %s as unit %d", name, DEVICENAME(parent), unit));
856
857 if (name) {
858 dc = devclass_find_internal(name, TRUE);
859 if (!dc) {
860 printf("make_device: can't find device class %s\n",
861 name);
862 return (NULL);
863 }
864 } else {
865 dc = NULL;
866 }
867
868 dev = malloc(sizeof(struct device), M_BUS, M_NOWAIT|M_ZERO);
869 if (!dev)
870 return (NULL);
871
872 dev->parent = parent;
873 TAILQ_INIT(&dev->children);
874 kobj_init((kobj_t) dev, &null_class);
875 dev->driver = NULL;
876 dev->devclass = NULL;
877 dev->unit = unit;
878 dev->nameunit = NULL;
879 dev->desc = NULL;
880 dev->busy = 0;
881 dev->devflags = 0;
882 dev->flags = DF_ENABLED;
883 dev->order = 0;
884 if (unit == -1)
885 dev->flags |= DF_WILDCARD;
886 if (name) {
887 dev->flags |= DF_FIXEDCLASS;
888 if (devclass_add_device(dc, dev)) {
889 kobj_delete((kobj_t) dev, M_BUS);
890 return (NULL);
891 }
892 }
893 dev->ivars = NULL;
894 dev->softc = NULL;
895
896 dev->state = DS_NOTPRESENT;
897
898 TAILQ_INSERT_TAIL(&bus_data_devices, dev, devlink);
899 bus_data_generation_update();
900
901 return (dev);
902}
903
904static int
905device_print_child(device_t dev, device_t child)
906{
907 int retval = 0;
908
909 if (device_is_alive(child))
910 retval += BUS_PRINT_CHILD(dev, child);
911 else
912 retval += device_printf(child, " not found\n");
913
914 return (retval);
915}
916
917device_t
918device_add_child(device_t dev, const char *name, int unit)
919{
920 return (device_add_child_ordered(dev, 0, name, unit));
921}
922
923device_t
924device_add_child_ordered(device_t dev, int order, const char *name, int unit)
925{
926 device_t child;
927 device_t place;
928
929 PDEBUG(("%s at %s with order %d as unit %d",
930 name, DEVICENAME(dev), order, unit));
931
932 child = make_device(dev, name, unit);
933 if (child == NULL)
934 return (child);
935 child->order = order;
936
937 TAILQ_FOREACH(place, &dev->children, link) {
938 if (place->order > order)
939 break;
940 }
941
942 if (place) {
943 /*
944 * The device 'place' is the first device whose order is
945 * greater than the new child.
946 */
947 TAILQ_INSERT_BEFORE(place, child, link);
948 } else {
949 /*
950 * The new child's order is greater or equal to the order of
951 * any existing device. Add the child to the tail of the list.
952 */
953 TAILQ_INSERT_TAIL(&dev->children, child, link);
954 }
955
956 bus_data_generation_update();
957 return (child);
958}
959
960int
961device_delete_child(device_t dev, device_t child)
962{
963 int error;
964 device_t grandchild;
965
966 PDEBUG(("%s from %s", DEVICENAME(child), DEVICENAME(dev)));
967
968 /* remove children first */
969 while ( (grandchild = TAILQ_FIRST(&child->children)) ) {
970 error = device_delete_child(child, grandchild);
971 if (error)
972 return (error);
973 }
974
975 if ((error = device_detach(child)) != 0)
976 return (error);
977 if (child->devclass)
978 devclass_delete_device(child->devclass, child);
979 TAILQ_REMOVE(&dev->children, child, link);
980 TAILQ_REMOVE(&bus_data_devices, child, devlink);
981 device_set_desc(child, NULL);
982 kobj_delete((kobj_t) child, M_BUS);
983
984 bus_data_generation_update();
985 return (0);
986}
987
988/*
989 * Find only devices attached to this bus.
990 */
991device_t
992device_find_child(device_t dev, const char *classname, int unit)
993{
994 devclass_t dc;
995 device_t child;
996
997 dc = devclass_find(classname);
998 if (!dc)
999 return (NULL);
1000
1001 child = devclass_get_device(dc, unit);
1002 if (child && child->parent == dev)
1003 return (child);
1004 return (NULL);
1005}
1006
1007static driverlink_t
1008first_matching_driver(devclass_t dc, device_t dev)
1009{
1010 if (dev->devclass)
1011 return (devclass_find_driver_internal(dc, dev->devclass->name));
1012 return (TAILQ_FIRST(&dc->drivers));
1013}
1014
1015static driverlink_t
1016next_matching_driver(devclass_t dc, device_t dev, driverlink_t last)
1017{
1018 if (dev->devclass) {
1019 driverlink_t dl;
1020 for (dl = TAILQ_NEXT(last, link); dl; dl = TAILQ_NEXT(dl, link))
1021 if (!strcmp(dev->devclass->name, dl->driver->name))
1022 return (dl);
1023 return (NULL);
1024 }
1025 return (TAILQ_NEXT(last, link));
1026}
1027
1028static int
1029device_probe_child(device_t dev, device_t child)
1030{
1031 devclass_t dc;
1032 driverlink_t best = 0;
1033 driverlink_t dl;
1034 int result, pri = 0;
1035 int hasclass = (child->devclass != 0);
1036
1037 dc = dev->devclass;
1038 if (!dc)
1039 panic("device_probe_child: parent device has no devclass");
1040
1041 if (child->state == DS_ALIVE)
1042 return (0);
1043
1044 for (dl = first_matching_driver(dc, child);
1045 dl;
1046 dl = next_matching_driver(dc, child, dl)) {
1047 PDEBUG(("Trying %s", DRIVERNAME(dl->driver)));
1048 device_set_driver(child, dl->driver);
1049 if (!hasclass)
1050 device_set_devclass(child, dl->driver->name);
1051 result = DEVICE_PROBE(child);
1052 if (!hasclass)
1053 device_set_devclass(child, 0);
1054
1055 /*
1056 * If the driver returns SUCCESS, there can be no higher match
1057 * for this device.
1058 */
1059 if (result == 0) {
1060 best = dl;
1061 pri = 0;
1062 break;
1063 }
1064
1065 /*
1066 * The driver returned an error so it certainly doesn't match.
1067 */
1068 if (result > 0) {
1069 device_set_driver(child, 0);
1070 continue;
1071 }
1072
1073 /*
1074 * A priority lower than SUCCESS, remember the best matching
1075 * driver. Initialise the value of pri for the first match.
1076 */
1077 if (best == 0 || result > pri) {
1078 best = dl;
1079 pri = result;
1080 continue;
1081 }
1082 }
1083
1084 /*
1085 * If we found a driver, change state and initialise the devclass.
1086 */
1087 if (best) {
1088 if (!child->devclass)
1089 device_set_devclass(child, best->driver->name);
1090 device_set_driver(child, best->driver);
1091 if (pri < 0) {
1092 /*
1093 * A bit bogus. Call the probe method again to make
1094 * sure that we have the right description.
1095 */
1096 DEVICE_PROBE(child);
1097 }
1098 child->state = DS_ALIVE;
1099
1100 bus_data_generation_update();
1101 return (0);
1102 }
1103
1104 return (ENXIO);
1105}
1106
1107device_t
1108device_get_parent(device_t dev)
1109{
1110 return (dev->parent);
1111}
1112
1113int
1114device_get_children(device_t dev, device_t **devlistp, int *devcountp)
1115{
1116 int count;
1117 device_t child;
1118 device_t *list;
1119
1120 count = 0;
1121 TAILQ_FOREACH(child, &dev->children, link) {
1122 count++;
1123 }
1124
1125 list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT|M_ZERO);
1126 if (!list)
1127 return (ENOMEM);
1128
1129 count = 0;
1130 TAILQ_FOREACH(child, &dev->children, link) {
1131 list[count] = child;
1132 count++;
1133 }
1134
1135 *devlistp = list;
1136 *devcountp = count;
1137
1138 return (0);
1139}
1140
1141driver_t *
1142device_get_driver(device_t dev)
1143{
1144 return (dev->driver);
1145}
1146
1147devclass_t
1148device_get_devclass(device_t dev)
1149{
1150 return (dev->devclass);
1151}
1152
1153const char *
1154device_get_name(device_t dev)
1155{
1156 if (dev != NULL && dev->devclass)
1157 return (devclass_get_name(dev->devclass));
1158 return (NULL);
1159}
1160
1161const char *
1162device_get_nameunit(device_t dev)
1163{
1164 return (dev->nameunit);
1165}
1166
1167int
1168device_get_unit(device_t dev)
1169{
1170 return (dev->unit);
1171}
1172
1173const char *
1174device_get_desc(device_t dev)
1175{
1176 return (dev->desc);
1177}
1178
1179u_int32_t
1180device_get_flags(device_t dev)
1181{
1182 return (dev->devflags);
1183}
1184
1185int
1186device_print_prettyname(device_t dev)
1187{
1188 const char *name = device_get_name(dev);
1189
1190 if (name == 0)
1191 return (printf("unknown: "));
1192 return (printf("%s%d: ", name, device_get_unit(dev)));
1193}
1194
1195int
1196device_printf(device_t dev, const char * fmt, ...)
1197{
1198 va_list ap;
1199 int retval;
1200
1201 retval = device_print_prettyname(dev);
1202 va_start(ap, fmt);
1203 retval += vprintf(fmt, ap);
1204 va_end(ap);
1205 return (retval);
1206}
1207
1208static void
1209device_set_desc_internal(device_t dev, const char* desc, int copy)
1210{
1211 if (dev->desc && (dev->flags & DF_DESCMALLOCED)) {
1212 free(dev->desc, M_BUS);
1213 dev->flags &= ~DF_DESCMALLOCED;
1214 dev->desc = NULL;
1215 }
1216
1217 if (copy && desc) {
1218 dev->desc = malloc(strlen(desc) + 1, M_BUS, M_NOWAIT);
1219 if (dev->desc) {
1220 strcpy(dev->desc, desc);
1221 dev->flags |= DF_DESCMALLOCED;
1222 }
1223 } else {
1224 /* Avoid a -Wcast-qual warning */
1225 dev->desc = (char *)(uintptr_t) desc;
1226 }
1227
1228 bus_data_generation_update();
1229}
1230
1231void
1232device_set_desc(device_t dev, const char* desc)
1233{
1234 device_set_desc_internal(dev, desc, FALSE);
1235}
1236
1237void
1238device_set_desc_copy(device_t dev, const char* desc)
1239{
1240 device_set_desc_internal(dev, desc, TRUE);
1241}
1242
1243void
1244device_set_flags(device_t dev, u_int32_t flags)
1245{
1246 dev->devflags = flags;
1247}
1248
1249void *
1250device_get_softc(device_t dev)
1251{
1252 return (dev->softc);
1253}
1254
1255void
1256device_set_softc(device_t dev, void *softc)
1257{
1258 if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC))
1259 free(dev->softc, M_BUS);
1260 dev->softc = softc;
1261 if (dev->softc)
1262 dev->flags |= DF_EXTERNALSOFTC;
1263 else
1264 dev->flags &= ~DF_EXTERNALSOFTC;
1265}
1266
1267void *
1268device_get_ivars(device_t dev)
1269{
1270
1271 KASSERT(dev != NULL, ("device_get_ivars(NULL, ...)"));
1272 return (dev->ivars);
1273}
1274
1275void
1276device_set_ivars(device_t dev, void * ivars)
1277{
1278
1279 KASSERT(dev != NULL, ("device_set_ivars(NULL, ...)"));
1280 dev->ivars = ivars;
1281}
1282
1283device_state_t
1284device_get_state(device_t dev)
1285{
1286 return (dev->state);
1287}
1288
1289void
1290device_enable(device_t dev)
1291{
1292 dev->flags |= DF_ENABLED;
1293}
1294
1295void
1296device_disable(device_t dev)
1297{
1298 dev->flags &= ~DF_ENABLED;
1299}
1300
1301void
1302device_busy(device_t dev)
1303{
1304 if (dev->state < DS_ATTACHED)
1305 panic("device_busy: called for unattached device");
1306 if (dev->busy == 0 && dev->parent)
1307 device_busy(dev->parent);
1308 dev->busy++;
1309 dev->state = DS_BUSY;
1310}
1311
1312void
1313device_unbusy(device_t dev)
1314{
1315 if (dev->state != DS_BUSY)
1316 panic("device_unbusy: called for non-busy device");
1317 dev->busy--;
1318 if (dev->busy == 0) {
1319 if (dev->parent)
1320 device_unbusy(dev->parent);
1321 dev->state = DS_ATTACHED;
1322 }
1323}
1324
1325void
1326device_quiet(device_t dev)
1327{
1328 dev->flags |= DF_QUIET;
1329}
1330
1331void
1332device_verbose(device_t dev)
1333{
1334 dev->flags &= ~DF_QUIET;
1335}
1336
1337int
1338device_is_quiet(device_t dev)
1339{
1340 return ((dev->flags & DF_QUIET) != 0);
1341}
1342
1343int
1344device_is_enabled(device_t dev)
1345{
1346 return ((dev->flags & DF_ENABLED) != 0);
1347}
1348
1349int
1350device_is_alive(device_t dev)
1351{
1352 return (dev->state >= DS_ALIVE);
1353}
1354
1355int
1356device_is_attached(device_t dev)
1357{
1358 return (dev->state >= DS_ATTACHED);
1359}
1360
1361int
1362device_set_devclass(device_t dev, const char *classname)
1363{
1364 devclass_t dc;
1365 int error;
1366
1367 if (!classname) {
1368 if (dev->devclass)
1369 devclass_delete_device(dev->devclass, dev);
1370 return (0);
1371 }
1372
1373 if (dev->devclass) {
1374 printf("device_set_devclass: device class already set\n");
1375 return (EINVAL);
1376 }
1377
1378 dc = devclass_find_internal(classname, TRUE);
1379 if (!dc)
1380 return (ENOMEM);
1381
1382 error = devclass_add_device(dc, dev);
1383
1384 bus_data_generation_update();
1385 return (error);
1386}
1387
1388int
1389device_set_driver(device_t dev, driver_t *driver)
1390{
1391 if (dev->state >= DS_ATTACHED)
1392 return (EBUSY);
1393
1394 if (dev->driver == driver)
1395 return (0);
1396
1397 if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC)) {
1398 free(dev->softc, M_BUS);
1399 dev->softc = NULL;
1400 }
1401 kobj_delete((kobj_t) dev, 0);
1402 dev->driver = driver;
1403 if (driver) {
1404 kobj_init((kobj_t) dev, (kobj_class_t) driver);
1405 if (!(dev->flags & DF_EXTERNALSOFTC) && driver->size > 0) {
1406 dev->softc = malloc(driver->size, M_BUS,
1407 M_NOWAIT | M_ZERO);
1408 if (!dev->softc) {
1409 kobj_delete((kobj_t) dev, 0);
1410 kobj_init((kobj_t) dev, &null_class);
1411 dev->driver = NULL;
1412 return (ENOMEM);
1413 }
1414 }
1415 } else {
1416 kobj_init((kobj_t) dev, &null_class);
1417 }
1418
1419 bus_data_generation_update();
1420 return (0);
1421}
1422
1423int
1424device_probe_and_attach(device_t dev)
1425{
1426 device_t bus = dev->parent;
1427 int error = 0;
1428 int hasclass = (dev->devclass != 0);
1429
1430 if (dev->state >= DS_ALIVE)
1431 return (0);
1432
1433 if (dev->flags & DF_ENABLED) {
1434 error = device_probe_child(bus, dev);
1435 if (!error) {
1436 if (!device_is_quiet(dev))
1437 device_print_child(bus, dev);
1438 error = DEVICE_ATTACH(dev);
1439 if (!error) {
1440 dev->state = DS_ATTACHED;
1441 devadded(dev);
1442 } else {
1443 printf("device_probe_and_attach: %s%d attach returned %d\n",
1444 dev->driver->name, dev->unit, error);
1445 /* Unset the class; set in device_probe_child */
1446 if (!hasclass)
1447 device_set_devclass(dev, 0);
1448 device_set_driver(dev, NULL);
1449 dev->state = DS_NOTPRESENT;
1450 }
1451 } else {
1452 if (!(dev->flags & DF_DONENOMATCH)) {
1453 BUS_PROBE_NOMATCH(bus, dev);
1454 devnomatch(dev);
1455 dev->flags |= DF_DONENOMATCH;
1456 }
1457 }
1458 } else {
1459 if (bootverbose) {
1460 device_print_prettyname(dev);
1461 printf("not probed (disabled)\n");
1462 }
1463 }
1464
1465 return (error);
1466}
1467
1468int
1469device_detach(device_t dev)
1470{
1471 int error;
1472
1473 PDEBUG(("%s", DEVICENAME(dev)));
1474 if (dev->state == DS_BUSY)
1475 return (EBUSY);
1476 if (dev->state != DS_ATTACHED)
1477 return (0);
1478
1479 if ((error = DEVICE_DETACH(dev)) != 0)
1480 return (error);
1481 devremoved(dev);
1482 device_printf(dev, "detached\n");
1483 if (dev->parent)
1484 BUS_CHILD_DETACHED(dev->parent, dev);
1485
1486 if (!(dev->flags & DF_FIXEDCLASS))
1487 devclass_delete_device(dev->devclass, dev);
1488
1489 dev->state = DS_NOTPRESENT;
1490 device_set_driver(dev, NULL);
1491
1492 return (0);
1493}
1494
1495int
1496device_shutdown(device_t dev)
1497{
1498 if (dev->state < DS_ATTACHED)
1499 return (0);
1500 return (DEVICE_SHUTDOWN(dev));
1501}
1502
1503int
1504device_set_unit(device_t dev, int unit)
1505{
1506 devclass_t dc;
1507 int err;
1508
1509 dc = device_get_devclass(dev);
1510 if (unit < dc->maxunit && dc->devices[unit])
1511 return (EBUSY);
1512 err = devclass_delete_device(dc, dev);
1513 if (err)
1514 return (err);
1515 dev->unit = unit;
1516 err = devclass_add_device(dc, dev);
1517 if (err)
1518 return (err);
1519
1520 bus_data_generation_update();
1521 return (0);
1522}
1523
1524/*======================================*/
1525/*
1526 * Some useful method implementations to make life easier for bus drivers.
1527 */
1528
1529void
1530resource_list_init(struct resource_list *rl)
1531{
1532 SLIST_INIT(rl);
1533}
1534
1535void
1536resource_list_free(struct resource_list *rl)
1537{
1538 struct resource_list_entry *rle;
1539
1540 while ((rle = SLIST_FIRST(rl)) != NULL) {
1541 if (rle->res)
1542 panic("resource_list_free: resource entry is busy");
1543 SLIST_REMOVE_HEAD(rl, link);
1544 free(rle, M_BUS);
1545 }
1546}
1547
1548int
1549resource_list_add_next(struct resource_list *rl, int type, u_long start,
1550 u_long end, u_long count)
1551{
1552 int rid;
1553
1554 rid = 0;
1555 while (resource_list_find(rl, type, rid) != NULL)
1556 rid++;
1557 resource_list_add(rl, type, rid, start, end, count);
1558 return (rid);
1559}
1560
1561void
1562resource_list_add(struct resource_list *rl, int type, int rid,
1563 u_long start, u_long end, u_long count)
1564{
1565 struct resource_list_entry *rle;
1566
1567 rle = resource_list_find(rl, type, rid);
1568 if (!rle) {
1569 rle = malloc(sizeof(struct resource_list_entry), M_BUS,
1570 M_NOWAIT);
1571 if (!rle)
1572 panic("resource_list_add: can't record entry");
1573 SLIST_INSERT_HEAD(rl, rle, link);
1574 rle->type = type;
1575 rle->rid = rid;
1576 rle->res = NULL;
1577 }
1578
1579 if (rle->res)
1580 panic("resource_list_add: resource entry is busy");
1581
1582 rle->start = start;
1583 rle->end = end;
1584 rle->count = count;
1585}
1586
1587struct resource_list_entry *
1588resource_list_find(struct resource_list *rl, int type, int rid)
1589{
1590 struct resource_list_entry *rle;
1591
1592 SLIST_FOREACH(rle, rl, link) {
1593 if (rle->type == type && rle->rid == rid)
1594 return (rle);
1595 }
1596 return (NULL);
1597}
1598
1599void
1600resource_list_delete(struct resource_list *rl, int type, int rid)
1601{
1602 struct resource_list_entry *rle = resource_list_find(rl, type, rid);
1603
1604 if (rle) {
1605 if (rle->res != NULL)
1606 panic("resource_list_delete: resource has not been released");
1607 SLIST_REMOVE(rl, rle, resource_list_entry, link);
1608 free(rle, M_BUS);
1609 }
1610}
1611
1612struct resource *
1613resource_list_alloc(struct resource_list *rl, device_t bus, device_t child,
1614 int type, int *rid, u_long start, u_long end, u_long count, u_int flags)
1615{
1616 struct resource_list_entry *rle = 0;
1617 int passthrough = (device_get_parent(child) != bus);
1618 int isdefault = (start == 0UL && end == ~0UL);
1619
1620 if (passthrough) {
1621 return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
1622 type, rid, start, end, count, flags));
1623 }
1624
1625 rle = resource_list_find(rl, type, *rid);
1626
1627 if (!rle)
1628 return (NULL); /* no resource of that type/rid */
1629
1630 if (rle->res)
1631 panic("resource_list_alloc: resource entry is busy");
1632
1633 if (isdefault) {
1634 start = rle->start;
1635 count = ulmax(count, rle->count);
1636 end = ulmax(rle->end, start + count - 1);
1637 }
1638
1639 rle->res = BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
1640 type, rid, start, end, count, flags);
1641
1642 /*
1643 * Record the new range.
1644 */
1645 if (rle->res) {
1646 rle->start = rman_get_start(rle->res);
1647 rle->end = rman_get_end(rle->res);
1648 rle->count = count;
1649 }
1650
1651 return (rle->res);
1652}
1653
1654int
1655resource_list_release(struct resource_list *rl, device_t bus, device_t child,
1656 int type, int rid, struct resource *res)
1657{
1658 struct resource_list_entry *rle = 0;
1659 int passthrough = (device_get_parent(child) != bus);
1660 int error;
1661
1662 if (passthrough) {
1663 return (BUS_RELEASE_RESOURCE(device_get_parent(bus), child,
1664 type, rid, res));
1665 }
1666
1667 rle = resource_list_find(rl, type, rid);
1668
1669 if (!rle)
1670 panic("resource_list_release: can't find resource");
1671 if (!rle->res)
1672 panic("resource_list_release: resource entry is not busy");
1673
1674 error = BUS_RELEASE_RESOURCE(device_get_parent(bus), child,
1675 type, rid, res);
1676 if (error)
1677 return (error);
1678
1679 rle->res = NULL;
1680 return (0);
1681}
1682
1683int
1684resource_list_print_type(struct resource_list *rl, const char *name, int type,
1685 const char *format)
1686{
1687 struct resource_list_entry *rle;
1688 int printed, retval;
1689
1690 printed = 0;
1691 retval = 0;
1692 /* Yes, this is kinda cheating */
1693 SLIST_FOREACH(rle, rl, link) {
1694 if (rle->type == type) {
1695 if (printed == 0)
1696 retval += printf(" %s ", name);
1697 else
1698 retval += printf(",");
1699 printed++;
1700 retval += printf(format, rle->start);
1701 if (rle->count > 1) {
1702 retval += printf("-");
1703 retval += printf(format, rle->start +
1704 rle->count - 1);
1705 }
1706 }
1707 }
1708 return (retval);
1709}
1710
1711/*
1712 * Call DEVICE_IDENTIFY for each driver.
1713 */
1714int
1715bus_generic_probe(device_t dev)
1716{
1717 devclass_t dc = dev->devclass;
1718 driverlink_t dl;
1719
1720 TAILQ_FOREACH(dl, &dc->drivers, link) {
1721 DEVICE_IDENTIFY(dl->driver, dev);
1722 }
1723
1724 return (0);
1725}
1726
1727int
1728bus_generic_attach(device_t dev)
1729{
1730 device_t child;
1731
1732 TAILQ_FOREACH(child, &dev->children, link) {
1733 device_probe_and_attach(child);
1734 }
1735
1736 return (0);
1737}
1738
1739int
1740bus_generic_detach(device_t dev)
1741{
1742 device_t child;
1743 int error;
1744
1745 if (dev->state != DS_ATTACHED)
1746 return (EBUSY);
1747
1748 TAILQ_FOREACH(child, &dev->children, link) {
1749 if ((error = device_detach(child)) != 0)
1750 return (error);
1751 }
1752
1753 return (0);
1754}
1755
1756int
1757bus_generic_shutdown(device_t dev)
1758{
1759 device_t child;
1760
1761 TAILQ_FOREACH(child, &dev->children, link) {
1762 device_shutdown(child);
1763 }
1764
1765 return (0);
1766}
1767
1768int
1769bus_generic_suspend(device_t dev)
1770{
1771 int error;
1772 device_t child, child2;
1773
1774 TAILQ_FOREACH(child, &dev->children, link) {
1775 error = DEVICE_SUSPEND(child);
1776 if (error) {
1777 for (child2 = TAILQ_FIRST(&dev->children);
1778 child2 && child2 != child;
1779 child2 = TAILQ_NEXT(child2, link))
1780 DEVICE_RESUME(child2);
1781 return (error);
1782 }
1783 }
1784 return (0);
1785}
1786
1787int
1788bus_generic_resume(device_t dev)
1789{
1790 device_t child;
1791
1792 TAILQ_FOREACH(child, &dev->children, link) {
1793 DEVICE_RESUME(child);
1794 /* if resume fails, there's nothing we can usefully do... */
1795 }
1796 return (0);
1797}
1798
1799int
1800bus_print_child_header (device_t dev, device_t child)
1801{
1802 int retval = 0;
1803
1804 if (device_get_desc(child)) {
1805 retval += device_printf(child, "<%s>", device_get_desc(child));
1806 } else {
1807 retval += printf("%s", device_get_nameunit(child));
1808 }
1809
1810 return (retval);
1811}
1812
1813int
1814bus_print_child_footer (device_t dev, device_t child)
1815{
1816 return (printf(" on %s\n", device_get_nameunit(dev)));
1817}
1818
1819int
1820bus_generic_print_child(device_t dev, device_t child)
1821{
1822 int retval = 0;
1823
1824 retval += bus_print_child_header(dev, child);
1825 retval += bus_print_child_footer(dev, child);
1826
1827 return (retval);
1828}
1829
1830int
1831bus_generic_read_ivar(device_t dev, device_t child, int index,
1832 uintptr_t * result)
1833{
1834 return (ENOENT);
1835}
1836
1837int
1838bus_generic_write_ivar(device_t dev, device_t child, int index,
1839 uintptr_t value)
1840{
1841 return (ENOENT);
1842}
1843
1844struct resource_list *
1845bus_generic_get_resource_list (device_t dev, device_t child)
1846{
1847 return (NULL);
1848}
1849
1850void
1851bus_generic_driver_added(device_t dev, driver_t *driver)
1852{
1853 device_t child;
1854
1855 DEVICE_IDENTIFY(driver, dev);
1856 TAILQ_FOREACH(child, &dev->children, link) {
1857 if (child->state == DS_NOTPRESENT)
1858 device_probe_and_attach(child);
1859 }
1860}
1861
1862int
1863bus_generic_setup_intr(device_t dev, device_t child, struct resource *irq,
1864 int flags, driver_intr_t *intr, void *arg, void **cookiep)
1865{
1866 /* Propagate up the bus hierarchy until someone handles it. */
1867 if (dev->parent)
1868 return (BUS_SETUP_INTR(dev->parent, child, irq, flags,
1869 intr, arg, cookiep));
1870 return (EINVAL);
1871}
1872
1873int
1874bus_generic_teardown_intr(device_t dev, device_t child, struct resource *irq,
1875 void *cookie)
1876{
1877 /* Propagate up the bus hierarchy until someone handles it. */
1878 if (dev->parent)
1879 return (BUS_TEARDOWN_INTR(dev->parent, child, irq, cookie));
1880 return (EINVAL);
1881}
1882
1883struct resource *
1884bus_generic_alloc_resource(device_t dev, device_t child, int type, int *rid,
1885 u_long start, u_long end, u_long count, u_int flags)
1886{
1887 /* Propagate up the bus hierarchy until someone handles it. */
1888 if (dev->parent)
1889 return (BUS_ALLOC_RESOURCE(dev->parent, child, type, rid,
1890 start, end, count, flags));
1891 return (NULL);
1892}
1893
1894int
1895bus_generic_release_resource(device_t dev, device_t child, int type, int rid,
1896 struct resource *r)
1897{
1898 /* Propagate up the bus hierarchy until someone handles it. */
1899 if (dev->parent)
1900 return (BUS_RELEASE_RESOURCE(dev->parent, child, type, rid,
1901 r));
1902 return (EINVAL);
1903}
1904
1905int
1906bus_generic_activate_resource(device_t dev, device_t child, int type, int rid,
1907 struct resource *r)
1908{
1909 /* Propagate up the bus hierarchy until someone handles it. */
1910 if (dev->parent)
1911 return (BUS_ACTIVATE_RESOURCE(dev->parent, child, type, rid,
1912 r));
1913 return (EINVAL);
1914}
1915
1916int
1917bus_generic_deactivate_resource(device_t dev, device_t child, int type,
1918 int rid, struct resource *r)
1919{
1920 /* Propagate up the bus hierarchy until someone handles it. */
1921 if (dev->parent)
1922 return (BUS_DEACTIVATE_RESOURCE(dev->parent, child, type, rid,
1923 r));
1924 return (EINVAL);
1925}
1926
1927int
1928bus_generic_rl_get_resource (device_t dev, device_t child, int type, int rid,
1929 u_long *startp, u_long *countp)
1930{
1931 struct resource_list * rl = NULL;
1932 struct resource_list_entry * rle = NULL;
1933
1934 rl = BUS_GET_RESOURCE_LIST(dev, child);
1935 if (!rl)
1936 return (EINVAL);
1937
1938 rle = resource_list_find(rl, type, rid);
1939 if (!rle)
1940 return (ENOENT);
1941
1942 if (startp)
1943 *startp = rle->start;
1944 if (countp)
1945 *countp = rle->count;
1946
1947 return (0);
1948}
1949
1950int
1951bus_generic_rl_set_resource (device_t dev, device_t child, int type, int rid,
1952 u_long start, u_long count)
1953{
1954 struct resource_list * rl = NULL;
1955
1956 rl = BUS_GET_RESOURCE_LIST(dev, child);
1957 if (!rl)
1958 return (EINVAL);
1959
1960 resource_list_add(rl, type, rid, start, (start + count - 1), count);
1961
1962 return (0);
1963}
1964
1965void
1966bus_generic_rl_delete_resource (device_t dev, device_t child, int type, int rid)
1967{
1968 struct resource_list * rl = NULL;
1969
1970 rl = BUS_GET_RESOURCE_LIST(dev, child);
1971 if (!rl)
1972 return;
1973
1974 resource_list_delete(rl, type, rid);
1975
1976 return;
1977}
1978
1979int
1980bus_generic_rl_release_resource (device_t dev, device_t child, int type,
1981 int rid, struct resource *r)
1982{
1983 struct resource_list * rl = NULL;
1984
1985 rl = BUS_GET_RESOURCE_LIST(dev, child);
1986 if (!rl)
1987 return (EINVAL);
1988
1989 return (resource_list_release(rl, dev, child, type, rid, r));
1990}
1991
1992struct resource *
1993bus_generic_rl_alloc_resource (device_t dev, device_t child, int type,
1994 int *rid, u_long start, u_long end, u_long count, u_int flags)
1995{
1996 struct resource_list * rl = NULL;
1997
1998 rl = BUS_GET_RESOURCE_LIST(dev, child);
1999 if (!rl)
2000 return (NULL);
2001
2002 return (resource_list_alloc(rl, dev, child, type, rid,
2003 start, end, count, flags));
2004}
2005
2006int
2007bus_generic_child_present(device_t bus, device_t child)
2008{
2009 return (BUS_CHILD_PRESENT(device_get_parent(bus), bus));
2010}
2011
2012/*
2013 * Some convenience functions to make it easier for drivers to use the
2014 * resource-management functions. All these really do is hide the
2015 * indirection through the parent's method table, making for slightly
2016 * less-wordy code. In the future, it might make sense for this code
2017 * to maintain some sort of a list of resources allocated by each device.
2018 */
2019struct resource *
2020bus_alloc_resource(device_t dev, int type, int *rid, u_long start, u_long end,
2021 u_long count, u_int flags)
2022{
2023 if (dev->parent == 0)
2024 return (0);
2025 return (BUS_ALLOC_RESOURCE(dev->parent, dev, type, rid, start, end,
2026 count, flags));
2027}
2028
2029int
2030bus_activate_resource(device_t dev, int type, int rid, struct resource *r)
2031{
2032 if (dev->parent == 0)
2033 return (EINVAL);
2034 return (BUS_ACTIVATE_RESOURCE(dev->parent, dev, type, rid, r));
2035}
2036
2037int
2038bus_deactivate_resource(device_t dev, int type, int rid, struct resource *r)
2039{
2040 if (dev->parent == 0)
2041 return (EINVAL);
2042 return (BUS_DEACTIVATE_RESOURCE(dev->parent, dev, type, rid, r));
2043}
2044
2045int
2046bus_release_resource(device_t dev, int type, int rid, struct resource *r)
2047{
2048 if (dev->parent == 0)
2049 return (EINVAL);
2050 return (BUS_RELEASE_RESOURCE(dev->parent, dev, type, rid, r));
2051}
2052
2053int
2054bus_setup_intr(device_t dev, struct resource *r, int flags,
2055 driver_intr_t handler, void *arg, void **cookiep)
2056{
2057 if (dev->parent == 0)
2058 return (EINVAL);
2059 return (BUS_SETUP_INTR(dev->parent, dev, r, flags,
2060 handler, arg, cookiep));
2061}
2062
2063int
2064bus_teardown_intr(device_t dev, struct resource *r, void *cookie)
2065{
2066 if (dev->parent == 0)
2067 return (EINVAL);
2068 return (BUS_TEARDOWN_INTR(dev->parent, dev, r, cookie));
2069}
2070
2071int
2072bus_set_resource(device_t dev, int type, int rid,
2073 u_long start, u_long count)
2074{
2075 return (BUS_SET_RESOURCE(device_get_parent(dev), dev, type, rid,
2076 start, count));
2077}
2078
2079int
2080bus_get_resource(device_t dev, int type, int rid,
2081 u_long *startp, u_long *countp)
2082{
2083 return (BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid,
2084 startp, countp));
2085}
2086
2087u_long
2088bus_get_resource_start(device_t dev, int type, int rid)
2089{
2090 u_long start, count;
2091 int error;
2092
2093 error = BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid,
2094 &start, &count);
2095 if (error)
2096 return (0);
2097 return (start);
2098}
2099
2100u_long
2101bus_get_resource_count(device_t dev, int type, int rid)
2102{
2103 u_long start, count;
2104 int error;
2105
2106 error = BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid,
2107 &start, &count);
2108 if (error)
2109 return (0);
2110 return (count);
2111}
2112
2113void
2114bus_delete_resource(device_t dev, int type, int rid)
2115{
2116 BUS_DELETE_RESOURCE(device_get_parent(dev), dev, type, rid);
2117}
2118
2119int
2120bus_child_present(device_t child)
2121{
2122 return (BUS_CHILD_PRESENT(device_get_parent(child), child));
2123}
2124
2125int
2126bus_child_pnpinfo_str(device_t child, char *buf, size_t buflen)
2127{
2128 device_t parent;
2129
2130 parent = device_get_parent(child);
2131 if (parent == NULL) {
2132 *buf = '\0';
2133 return (0);
2134 }
2135 return (BUS_CHILD_PNPINFO_STR(parent, child, buf, buflen));
2136}
2137
2138int
2139bus_child_location_str(device_t child, char *buf, size_t buflen)
2140{
2141 device_t parent;
2142
2143 parent = device_get_parent(child);
2144 if (parent == NULL) {
2145 *buf = '\0';
2146 return (0);
2147 }
2148 return (BUS_CHILD_LOCATION_STR(parent, child, buf, buflen));
2149}
2150
2151static int
2152root_print_child(device_t dev, device_t child)
2153{
2154 int retval = 0;
2155
2156 retval += bus_print_child_header(dev, child);
2157 retval += printf("\n");
2158
2159 return (retval);
2160}
2161
2162static int
2163root_setup_intr(device_t dev, device_t child, driver_intr_t *intr, void *arg,
2164 void **cookiep)
2165{
2166 /*
2167 * If an interrupt mapping gets to here something bad has happened.
2168 */
2169 panic("root_setup_intr");
2170}
2171
2172/*
2173 * If we get here, assume that the device is permanant and really is
2174 * present in the system. Removable bus drivers are expected to intercept
2175 * this call long before it gets here. We return -1 so that drivers that
2176 * really care can check vs -1 or some ERRNO returned higher in the food
2177 * chain.
2178 */
2179static int
2180root_child_present(device_t dev, device_t child)
2181{
2182 return (-1);
2183}
2184
2185static kobj_method_t root_methods[] = {
2186 /* Device interface */
2187 KOBJMETHOD(device_shutdown, bus_generic_shutdown),
2188 KOBJMETHOD(device_suspend, bus_generic_suspend),
2189 KOBJMETHOD(device_resume, bus_generic_resume),
2190
2191 /* Bus interface */
2192 KOBJMETHOD(bus_print_child, root_print_child),
2193 KOBJMETHOD(bus_read_ivar, bus_generic_read_ivar),
2194 KOBJMETHOD(bus_write_ivar, bus_generic_write_ivar),
2195 KOBJMETHOD(bus_setup_intr, root_setup_intr),
2196 KOBJMETHOD(bus_child_present, root_child_present),
2197
2198 { 0, 0 }
2199};
2200
2201static driver_t root_driver = {
2202 "root",
2203 root_methods,
2204 1, /* no softc */
2205};
2206
2207device_t root_bus;
2208devclass_t root_devclass;
2209
2210static int
2211root_bus_module_handler(module_t mod, int what, void* arg)
2212{
2213 switch (what) {
2214 case MOD_LOAD:
2215 TAILQ_INIT(&bus_data_devices);
2216 kobj_class_compile((kobj_class_t) &root_driver);
2217 root_bus = make_device(NULL, "root", 0);
2218 root_bus->desc = "System root bus";
2219 kobj_init((kobj_t) root_bus, (kobj_class_t) &root_driver);
2220 root_bus->driver = &root_driver;
2221 root_bus->state = DS_ATTACHED;
2222 root_devclass = devclass_find_internal("root", FALSE);
2223 devinit();
2224 return (0);
2225
2226 case MOD_SHUTDOWN:
2227 device_shutdown(root_bus);
2228 return (0);
2229 }
2230
2231 return (0);
2232}
2233
2234static moduledata_t root_bus_mod = {
2235 "rootbus",
2236 root_bus_module_handler,
2237 0
2238};
2239DECLARE_MODULE(rootbus, root_bus_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
2240
2241void
2242root_bus_configure(void)
2243{
2244 device_t dev;
2245
2246 PDEBUG(("."));
2247
2248 TAILQ_FOREACH(dev, &root_bus->children, link) {
2249 device_probe_and_attach(dev);
2250 }
2251}
2252
2253int
2254driver_module_handler(module_t mod, int what, void *arg)
2255{
2256 int error, i;
2257 struct driver_module_data *dmd;
2258 devclass_t bus_devclass;
2259
2260 dmd = (struct driver_module_data *)arg;
2261 bus_devclass = devclass_find_internal(dmd->dmd_busname, TRUE);
2262 error = 0;
2263
2264 switch (what) {
2265 case MOD_LOAD:
2266 if (dmd->dmd_chainevh)
2267 error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
2268
2269 for (i = 0; !error && i < dmd->dmd_ndrivers; i++) {
2270 PDEBUG(("Loading module: driver %s on bus %s",
2271 DRIVERNAME(dmd->dmd_drivers[i]), dmd->dmd_busname));
2272 error = devclass_add_driver(bus_devclass,
2273 dmd->dmd_drivers[i]);
2274 }
2275 if (error)
2276 break;
2277
2278 /*
2279 * The drivers loaded in this way are assumed to all
2280 * implement the same devclass.
2281 */
2282 *dmd->dmd_devclass =
2283 devclass_find_internal(dmd->dmd_drivers[0]->name, TRUE);
2284 break;
2285
2286 case MOD_UNLOAD:
2287 for (i = 0; !error && i < dmd->dmd_ndrivers; i++) {
2288 PDEBUG(("Unloading module: driver %s from bus %s",
2289 DRIVERNAME(dmd->dmd_drivers[i]),
2290 dmd->dmd_busname));
2291 error = devclass_delete_driver(bus_devclass,
2292 dmd->dmd_drivers[i]);
2293 }
2294
2295 if (!error && dmd->dmd_chainevh)
2296 error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
2297 break;
2298 }
2299
2300 return (error);
2301}
2302
2303#ifdef BUS_DEBUG
2304
2305/* the _short versions avoid iteration by not calling anything that prints
2306 * more than oneliners. I love oneliners.
2307 */
2308
2309static void
2310print_device_short(device_t dev, int indent)
2311{
2312 if (!dev)
2313 return;
2314
2315 indentprintf(("device %d: <%s> %sparent,%schildren,%s%s%s%s,%sivars,%ssoftc,busy=%d\n",
2316 dev->unit, dev->desc,
2317 (dev->parent? "":"no "),
2318 (TAILQ_EMPTY(&dev->children)? "no ":""),
2319 (dev->flags&DF_ENABLED? "enabled,":"disabled,"),
2320 (dev->flags&DF_FIXEDCLASS? "fixed,":""),
2321 (dev->flags&DF_WILDCARD? "wildcard,":""),
2322 (dev->flags&DF_DESCMALLOCED? "descmalloced,":""),
2323 (dev->ivars? "":"no "),
2324 (dev->softc? "":"no "),
2325 dev->busy));
2326}
2327
2328static void
2329print_device(device_t dev, int indent)
2330{
2331 if (!dev)
2332 return;
2333
2334 print_device_short(dev, indent);
2335
2336 indentprintf(("Parent:\n"));
2337 print_device_short(dev->parent, indent+1);
2338 indentprintf(("Driver:\n"));
2339 print_driver_short(dev->driver, indent+1);
2340 indentprintf(("Devclass:\n"));
2341 print_devclass_short(dev->devclass, indent+1);
2342}
2343
2344void
2345print_device_tree_short(device_t dev, int indent)
2346/* print the device and all its children (indented) */
2347{
2348 device_t child;
2349
2350 if (!dev)
2351 return;
2352
2353 print_device_short(dev, indent);
2354
2355 TAILQ_FOREACH(child, &dev->children, link) {
2356 print_device_tree_short(child, indent+1);
2357 }
2358}
2359
2360void
2361print_device_tree(device_t dev, int indent)
2362/* print the device and all its children (indented) */
2363{
2364 device_t child;
2365
2366 if (!dev)
2367 return;
2368
2369 print_device(dev, indent);
2370
2371 TAILQ_FOREACH(child, &dev->children, link) {
2372 print_device_tree(child, indent+1);
2373 }
2374}
2375
2376static void
2377print_driver_short(driver_t *driver, int indent)
2378{
2379 if (!driver)
2380 return;
2381
2382 indentprintf(("driver %s: softc size = %zd\n",
2383 driver->name, driver->size));
2384}
2385
2386static void
2387print_driver(driver_t *driver, int indent)
2388{
2389 if (!driver)
2390 return;
2391
2392 print_driver_short(driver, indent);
2393}
2394
2395
2396static void
2397print_driver_list(driver_list_t drivers, int indent)
2398{
2399 driverlink_t driver;
2400
2401 TAILQ_FOREACH(driver, &drivers, link) {
2402 print_driver(driver->driver, indent);
2403 }
2404}
2405
2406static void
2407print_devclass_short(devclass_t dc, int indent)
2408{
2409 if ( !dc )
2410 return;
2411
2412 indentprintf(("devclass %s: max units = %d\n", dc->name, dc->maxunit));
2413}
2414
2415static void
2416print_devclass(devclass_t dc, int indent)
2417{
2418 int i;
2419
2420 if ( !dc )
2421 return;
2422
2423 print_devclass_short(dc, indent);
2424 indentprintf(("Drivers:\n"));
2425 print_driver_list(dc->drivers, indent+1);
2426
2427 indentprintf(("Devices:\n"));
2428 for (i = 0; i < dc->maxunit; i++)
2429 if (dc->devices[i])
2430 print_device(dc->devices[i], indent+1);
2431}
2432
2433void
2434print_devclass_list_short(void)
2435{
2436 devclass_t dc;
2437
2438 printf("Short listing of devclasses, drivers & devices:\n");
2439 TAILQ_FOREACH(dc, &devclasses, link) {
2440 print_devclass_short(dc, 0);
2441 }
2442}
2443
2444void
2445print_devclass_list(void)
2446{
2447 devclass_t dc;
2448
2449 printf("Full listing of devclasses, drivers & devices:\n");
2450 TAILQ_FOREACH(dc, &devclasses, link) {
2451 print_devclass(dc, 0);
2452 }
2453}
2454
2455#endif
2456
2457/*
2458 * User-space access to the device tree.
2459 *
2460 * We implement a small set of nodes:
2461 *
2462 * hw.bus Single integer read method to obtain the
2463 * current generation count.
2464 * hw.bus.devices Reads the entire device tree in flat space.
2465 * hw.bus.rman Resource manager interface
2466 *
2467 * We might like to add the ability to scan devclasses and/or drivers to
2468 * determine what else is currently loaded/available.
2469 */
2470
2471static int
2472sysctl_bus(SYSCTL_HANDLER_ARGS)
2473{
2474 struct u_businfo ubus;
2475
2476 ubus.ub_version = BUS_USER_VERSION;
2477 ubus.ub_generation = bus_data_generation;
2478
2479 return (SYSCTL_OUT(req, &ubus, sizeof(ubus)));
2480}
2481SYSCTL_NODE(_hw_bus, OID_AUTO, info, CTLFLAG_RW, sysctl_bus,
2482 "bus-related data");
2483
2484static int
2485sysctl_devices(SYSCTL_HANDLER_ARGS)
2486{
2487 int *name = (int *)arg1;
2488 u_int namelen = arg2;
2489 int index;
2490 struct device *dev;
2491 struct u_device udev; /* XXX this is a bit big */
2492 int error;
2493
2494 if (namelen != 2)
2495 return (EINVAL);
2496
2497 if (bus_data_generation_check(name[0]))
2498 return (EINVAL);
2499
2500 index = name[1];
2501
2502 /*
2503 * Scan the list of devices, looking for the requested index.
2504 */
2505 TAILQ_FOREACH(dev, &bus_data_devices, devlink) {
2506 if (index-- == 0)
2507 break;
2508 }
2509 if (dev == NULL)
2510 return (ENOENT);
2511
2512 /*
2513 * Populate the return array.
2514 */
2515 udev.dv_handle = (uintptr_t)dev;
2516 udev.dv_parent = (uintptr_t)dev->parent;
2517 if (dev->nameunit == NULL)
2518 udev.dv_name[0] = '\0';
2519 else
2520 strlcpy(udev.dv_name, dev->nameunit, sizeof(udev.dv_name));
2521
2522 if (dev->desc == NULL)
2523 udev.dv_desc[0] = '\0';
2524 else
2525 strlcpy(udev.dv_desc, dev->desc, sizeof(udev.dv_desc));
2526 if (dev->driver == NULL || dev->driver->name == NULL)
2527 udev.dv_drivername[0] = '\0';
2528 else
2529 strlcpy(udev.dv_drivername, dev->driver->name,
2530 sizeof(udev.dv_drivername));
2531 udev.dv_pnpinfo[0] = '\0';
2532 udev.dv_location[0] = '\0';
2533 bus_child_pnpinfo_str(dev, udev.dv_pnpinfo, sizeof(udev.dv_pnpinfo));
2534 bus_child_location_str(dev, udev.dv_location, sizeof(udev.dv_location));
2535 udev.dv_devflags = dev->devflags;
2536 udev.dv_flags = dev->flags;
2537 udev.dv_state = dev->state;
2538 error = SYSCTL_OUT(req, &udev, sizeof(udev));
2539 return (error);
2540}
2541
2542SYSCTL_NODE(_hw_bus, OID_AUTO, devices, CTLFLAG_RD, sysctl_devices,
2543 "system device tree");
2544
2545/*
2546 * Sysctl interface for scanning the resource lists.
2547 *
2548 * We take two input parameters; the index into the list of resource
2549 * managers, and the resource offset into the list.
2550 */
2551static int
2552sysctl_rman(SYSCTL_HANDLER_ARGS)
2553{
2554 int *name = (int *)arg1;
2555 u_int namelen = arg2;
2556 int rman_idx, res_idx;
2557 struct rman *rm;
2558 struct resource *res;
2559 struct u_rman urm;
2560 struct u_resource ures;
2561 int error;
2562
2563 if (namelen != 3)
2564 return (EINVAL);
2565
2566 if (bus_data_generation_check(name[0]))
2567 return (EINVAL);
2568 rman_idx = name[1];
2569 res_idx = name[2];
2570
2571 /*
2572 * Find the indexed resource manager
2573 */
2574 TAILQ_FOREACH(rm, &rman_head, rm_link) {
2575 if (rman_idx-- == 0)
2576 break;
2577 }
2578 if (rm == NULL)
2579 return (ENOENT);
2580
2581 /*
2582 * If the resource index is -1, we want details on the
2583 * resource manager.
2584 */
2585 if (res_idx == -1) {
2586 urm.rm_handle = (uintptr_t)rm;
2587 strlcpy(urm.rm_descr, rm->rm_descr, RM_TEXTLEN);
2588 urm.rm_start = rm->rm_start;
2589 urm.rm_size = rm->rm_end - rm->rm_start + 1;
2590 urm.rm_type = rm->rm_type;
2591
2592 error = SYSCTL_OUT(req, &urm, sizeof(urm));
2593 return (error);
2594 }
2595
2596 /*
2597 * Find the indexed resource and return it.
2598 */
2599 TAILQ_FOREACH(res, &rm->rm_list, r_link) {
2600 if (res_idx-- == 0) {
2601 ures.r_handle = (uintptr_t)res;
2602 ures.r_parent = (uintptr_t)res->r_rm;
2603 ures.r_device = (uintptr_t)res->r_dev;
2604 if (res->r_dev != NULL) {
2605 if (device_get_name(res->r_dev) != NULL) {
2606 snprintf(ures.r_devname, RM_TEXTLEN,
2607 "%s%d",
2608 device_get_name(res->r_dev),
2609 device_get_unit(res->r_dev));
2610 } else {
2611 strlcpy(ures.r_devname, "nomatch",
2612 RM_TEXTLEN);
2613 }
2614 } else {
2615 ures.r_devname[0] = '\0';
2616 }
2617 ures.r_start = res->r_start;
2618 ures.r_size = res->r_end - res->r_start + 1;
2619 ures.r_flags = res->r_flags;
2620
2621 error = SYSCTL_OUT(req, &ures, sizeof(ures));
2622 return (error);
2623 }
2624 }
2625 return (ENOENT);
2626}
2627
2628SYSCTL_NODE(_hw_bus, OID_AUTO, rman, CTLFLAG_RD, sysctl_rman,
2629 "kernel resource manager");
2630
2631int
2632bus_data_generation_check(int generation)
2633{
2634 if (generation != bus_data_generation)
2635 return (1);
2636
2637 /* XXX generate optimised lists here? */
2638 return (0);
2639}
2640
2641void
2642bus_data_generation_update(void)
2643{
2644 bus_data_generation++;
2645}