there are a lot of usb devices that attach more than 16 things at once,
notably the "endless stream of nonsense uhid" type gadgetry. increase the
limit.
this will use more kernel memory of course (only a tiny bit really, but
whatever) so it's allocated at first open. if you don't use hotplug, you
don't waste memory on it. we could in theory make the buffer quite a bit
larger even now.
Index: hotplug.c
===================================================================
RCS file: /home/tedu/cvs/src/sys/dev/hotplug.c,v
retrieving revision 1.9
diff -u -r1.9 hotplug.c
--- hotplug.c 9 Nov 2009 17:53:39 -0000 1.9
+++ hotplug.c 30 Nov 2010 21:44:43 -0000
@@ -26,13 +26,14 @@
#include <sys/fcntl.h>
#include <sys/hotplug.h>
#include <sys/ioctl.h>
+#include <sys/malloc.h>
#include <sys/poll.h>
#include <sys/vnode.h>
-#define HOTPLUG_MAXEVENTS 16
+#define HOTPLUG_MAXEVENTS 64
static int opened;
-static struct hotplug_event evqueue[HOTPLUG_MAXEVENTS];
+static struct hotplug_event *evqueue;
static int evqueue_head, evqueue_tail, evqueue_count;
static struct selinfo hotplug_sel;
@@ -88,6 +89,8 @@
printf("hotplug: event lost, queue full\n");
return (1);
}
+ if (!evqueue)
+ return (1);
evqueue[evqueue_head] = *he;
evqueue_head = EVQUEUE_NEXT(evqueue_head);
@@ -119,12 +122,22 @@
int
hotplugopen(dev_t dev, int flag, int mode, struct proc *p)
{
+ struct hotplug_event *q;
+
if (minor(dev) != 0)
return (ENXIO);
if ((flag & FWRITE))
return (EPERM);
if (opened)
return (EBUSY);
+ if (!evqueue) {
+ q = malloc(sizeof(*q) * HOTPLUG_MAXEVENTS, M_DEVBUF, M_WAITOK);
+ if (opened) {
+ free(q, M_DEVBUF);
+ return (EBUSY);
+ }
+ evqueue = q;
+ }
opened = 1;
return (0);
}
@@ -155,7 +168,7 @@
if (flags & IO_NDELAY)
return (EAGAIN);
- error = tsleep(evqueue, PRIBIO | PCATCH, "htplev", 0);
+ error = tsleep(&evqueue, PRIBIO | PCATCH, "htplev", 0);
if (error)
return (error);
goto again;