diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-12-09 14:19:03 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-01-10 09:53:34 +0100 |
commit | 75b706fde4cbf82bcd41a1cec319778aa0f8eb2d (patch) | |
tree | ea39a351a1f6337b5a5dd6036314693adef5ffe6 /freebsd/sys/kern/subr_bus.c | |
parent | VMSTAT(8): Port to RTEMS (diff) | |
download | rtems-libbsd-75b706fde4cbf82bcd41a1cec319778aa0f8eb2d.tar.bz2 |
Update to FreeBSD head 2016-12-10
Git mirror commit 80c55f08a05ab3b26a73b226ccb56adc3122a55c.
Diffstat (limited to 'freebsd/sys/kern/subr_bus.c')
-rw-r--r-- | freebsd/sys/kern/subr_bus.c | 74 |
1 files changed, 67 insertions, 7 deletions
diff --git a/freebsd/sys/kern/subr_bus.c b/freebsd/sys/kern/subr_bus.c index 3eb7d7e9..1175456c 100644 --- a/freebsd/sys/kern/subr_bus.c +++ b/freebsd/sys/kern/subr_bus.c @@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$"); #include <rtems/bsd/local/opt_bus.h> +#include <rtems/bsd/local/opt_ddb.h> #include <rtems/bsd/sys/param.h> #include <sys/conf.h> @@ -67,6 +68,8 @@ __FBSDID("$FreeBSD$"); #include <vm/uma.h> #include <vm/vm.h> +#include <ddb/ddb.h> + SYSCTL_NODE(_hw, OID_AUTO, bus, CTLFLAG_RW, NULL, NULL); SYSCTL_ROOT_NODE(OID_AUTO, dev, CTLFLAG_RW, NULL, NULL); @@ -147,6 +150,9 @@ static MALLOC_DEFINE(M_BUS_SC, "bus-sc", "Bus data structures, softc"); static void devctl2_init(void); #endif /* __rtems__ */ +#define DRIVERNAME(d) ((d)? d->name : "no driver") +#define DEVCLANAME(d) ((d)? d->name : "no devclass") + #ifdef BUS_DEBUG static int bus_debug = 1; @@ -155,8 +161,6 @@ SYSCTL_INT(_debug, OID_AUTO, bus_debug, CTLFLAG_RWTUN, &bus_debug, 0, #define PDEBUG(a) if (bus_debug) {printf("%s:%d: ", __func__, __LINE__), printf a; printf("\n");} #define DEVICENAME(d) ((d)? device_get_name(d): "no device") -#define DRIVERNAME(d) ((d)? d->name : "no driver") -#define DEVCLANAME(d) ((d)? d->name : "no devclass") /** * Produce the indenting, indent*2 spaces plus a '.' ahead of that to @@ -180,8 +184,6 @@ void print_devclass_list(void); /* Make the compiler ignore the function calls */ #define PDEBUG(a) /* nop */ #define DEVICENAME(d) /* nop */ -#define DRIVERNAME(d) /* nop */ -#define DEVCLANAME(d) /* nop */ #define print_device_short(d,i) /* nop */ #define print_device(d,i) /* nop */ @@ -1981,15 +1983,17 @@ device_delete_child(device_t dev, device_t child) PDEBUG(("%s from %s", DEVICENAME(child), DEVICENAME(dev))); - /* remove children first */ + /* detach parent before deleting children, if any */ + if ((error = device_detach(child)) != 0) + return (error); + + /* remove children second */ while ((grandchild = TAILQ_FIRST(&child->children)) != NULL) { error = device_delete_child(child, grandchild); if (error) return (error); } - if ((error = device_detach(child)) != 0) - return (error); if (child->devclass) devclass_delete_device(child->devclass, child); if (child->parent) @@ -2180,6 +2184,12 @@ device_probe_child(device_t dev, device_t child) } /* + * Reset DF_QUIET in case this driver doesn't + * end up as the best driver. + */ + device_verbose(child); + + /* * Probes that return BUS_PROBE_NOWILDCARD or lower * only match on devices whose driver was explicitly * specified. @@ -3008,6 +3018,7 @@ device_detach(device_t dev) if (!(dev->flags & DF_FIXEDCLASS)) devclass_delete_device(dev->devclass, dev); + device_verbose(dev); dev->state = DS_NOTPRESENT; (void)device_set_driver(dev, NULL); device_sysctl_fini(dev); @@ -5396,6 +5407,7 @@ devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, case DEV_SUSPEND: case DEV_RESUME: case DEV_SET_DRIVER: + case DEV_CLEAR_DRIVER: case DEV_RESCAN: case DEV_DELETE: error = priv_check(td, PRIV_DRIVER); @@ -5561,6 +5573,25 @@ devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, error = device_probe_and_attach(dev); break; } + case DEV_CLEAR_DRIVER: + if (!(dev->flags & DF_FIXEDCLASS)) { + error = 0; + break; + } + if (device_is_attached(dev)) { + if (req->dr_flags & DEVF_CLEAR_DRIVER_DETACH) + error = device_detach(dev); + else + error = EBUSY; + if (error) + break; + } + + dev->flags &= ~DF_FIXEDCLASS; + dev->flags |= DF_WILDCARD; + devclass_delete_device(dev->devclass, dev); + error = device_probe_and_attach(dev); + break; case DEV_RESCAN: if (!device_is_attached(dev)) { error = ENXIO; @@ -5604,4 +5635,33 @@ devctl2_init(void) make_dev_credf(MAKEDEV_ETERNAL, &devctl2_cdevsw, 0, NULL, UID_ROOT, GID_WHEEL, 0600, "devctl2"); } + +#ifdef DDB +DB_SHOW_COMMAND(device, db_show_device) +{ + device_t dev; + + if (!have_addr) + return; + + dev = (device_t)addr; + + db_printf("name: %s\n", device_get_nameunit(dev)); + db_printf(" driver: %s\n", DRIVERNAME(dev->driver)); + db_printf(" class: %s\n", DEVCLANAME(dev->devclass)); + db_printf(" addr: %p\n", dev); + db_printf(" parent: %p\n", dev->parent); + db_printf(" softc: %p\n", dev->softc); + db_printf(" ivars: %p\n", dev->ivars); +} + +DB_SHOW_ALL_COMMAND(devices, db_show_all_devices) +{ + device_t dev; + + TAILQ_FOREACH(dev, &bus_data_devices, devlink) { + db_show_device((db_expr_t)dev, true, count, modif); + } +} +#endif #endif /* __rtems__ */ |