summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_bus.c
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2002-11-30 00:49:43 +0000
committerimp <imp@FreeBSD.org>2002-11-30 00:49:43 +0000
commit5c7f6dfe4e716409ffc46b8f8d7880e174d6eb02 (patch)
tree750d6e0c8954ee07932ba7a00487d5f26c9d2f52 /sys/kern/subr_bus.c
parent5993de8d7f96ca1c37ff1cd4afc2c2c4b29983b6 (diff)
downloadFreeBSD-src-5c7f6dfe4e716409ffc46b8f8d7880e174d6eb02.zip
FreeBSD-src-5c7f6dfe4e716409ffc46b8f8d7880e174d6eb02.tar.gz
devd kernel improvements:
1) Record all device events when devctl is enabled, rather than just when devd has devctl open. This is necessary to prevent races between when a device arrives, and when devd starts. 2) Add hw.bus.devctl_disable to disable devctl, this can also be set as a tunable. 3) Fix async support. Reset nonblocking and async_td in open. remove async flags. 4) Free all memory when devctl is disabled. Approved by: re (blanket)
Diffstat (limited to 'sys/kern/subr_bus.c')
-rw-r--r--sys/kern/subr_bus.c59
1 files changed, 38 insertions, 21 deletions
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 4791f4c..20262cd 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -54,6 +54,8 @@
#include <vm/uma.h>
+SYSCTL_NODE(_hw, OID_AUTO, bus, CTLFLAG_RW, NULL, NULL);
+
/*
* Used to attach drivers to devclasses.
*/
@@ -200,6 +202,13 @@ void print_devclass_list(void);
* tested since 3.4 or 2.2.8!
*/
+static int sysctl_devctl_disable(SYSCTL_HANDLER_ARGS);
+static int devctl_disable = 0;
+TUNABLE_INT("hw.bus.devctl_disable", &devctl_disable);
+SYSCTL_PROC(_hw_bus, OID_AUTO, devctl_disable,
+ CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_PRISON, 0, 0, sysctl_devctl_disable,
+ "I", "devctl disable");
+
static d_open_t devopen;
static d_close_t devclose;
static d_read_t devread;
@@ -235,7 +244,6 @@ struct dev_softc
{
int inuse;
int nonblock;
- int async;
struct mtx mtx;
struct cv cv;
struct selinfo sel;
@@ -261,27 +269,17 @@ devopen(dev_t dev, int oflags, int devtype, d_thread_t *td)
return (EBUSY);
/* move to init */
devsoftc.inuse = 1;
+ devsoftc.nonblock = 0;
+ devsoftc.async_td = NULL;
return (0);
}
static int
devclose(dev_t dev, int fflag, int devtype, d_thread_t *td)
{
- struct dev_event_info *n1;
-
devsoftc.inuse = 0;
mtx_lock(&devsoftc.mtx);
cv_broadcast(&devsoftc.cv);
- /*
- * See note in devread. If we deside to keep data until read, then
- * remove the following while loop. XXX
- */
- while (!TAILQ_EMPTY(&devsoftc.devq)) {
- n1 = TAILQ_FIRST(&devsoftc.devq);
- TAILQ_REMOVE(&devsoftc.devq, n1, dei_link);
- free(n1->dei_data, M_BUS);
- free(n1, M_BUS);
- }
mtx_unlock(&devsoftc.mtx);
return (0);
@@ -337,14 +335,10 @@ devioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, d_thread_t *td)
devsoftc.nonblock = 0;
return (0);
case FIOASYNC:
- if (*(int*)data) {
- devsoftc.async = 1;
+ if (*(int*)data)
devsoftc.async_td = td;
- }
- else {
- devsoftc.async = 0;
+ else
devsoftc.async_td = NULL;
- }
return (0);
/* (un)Support for other fcntl() calls. */
@@ -408,7 +402,7 @@ devaddq(const char *type, const char *what, device_t dev)
char *loc;
const char *parstr;
- if (!devsoftc.inuse)
+ if (devctl_disable)
return;
n1 = malloc(sizeof(*n1), M_BUS, M_NOWAIT);
if (n1 == NULL)
@@ -487,6 +481,30 @@ devnomatch(device_t dev)
return;
}
+static int
+sysctl_devctl_disable(SYSCTL_HANDLER_ARGS)
+{
+ struct dev_event_info *n1;
+ int dis, error;
+
+ dis = devctl_disable;
+ error = sysctl_handle_int(oidp, &dis, 0, req);
+ if (error || !req->newptr)
+ return (error);
+ mtx_lock(&devsoftc.mtx);
+ devctl_disable = dis;
+ if (dis) {
+ while (!TAILQ_EMPTY(&devsoftc.devq)) {
+ n1 = TAILQ_FIRST(&devsoftc.devq);
+ TAILQ_REMOVE(&devsoftc.devq, n1, dei_link);
+ free(n1->dei_data, M_BUS);
+ free(n1, M_BUS);
+ }
+ }
+ mtx_unlock(&devsoftc.mtx);
+ return (0);
+}
+
/* End of /dev/devctl code */
TAILQ_HEAD(,device) bus_data_devices;
@@ -2458,7 +2476,6 @@ print_devclass_list(void)
* We might like to add the ability to scan devclasses and/or drivers to
* determine what else is currently loaded/available.
*/
-SYSCTL_NODE(_hw, OID_AUTO, bus, CTLFLAG_RW, NULL, NULL);
static int
sysctl_bus(SYSCTL_HANDLER_ARGS)
OpenPOWER on IntegriCloud