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;

Reply via email to