This patch makes usbd track a dynamic number of devices using a list
instead of the static array of 4 devices.  It's implemented as a list
but it's very easy to change.
--
Adam Migus - Research Scientist
Network Associates Laboratories (http://www.nailabs.com)
TrustedBSD (http://www.trustedbsd.org)
FreeBSD (http://www.freebsd.org)
--- ../../../../freebsd/src/usr.sbin/usbd/usbd.c        Thu Jan 23 05:36:35 2003
+++ usbd.c      Tue Feb 11 21:21:55 2003
@@ -74,11 +74,6 @@
  */
 #define USBDEV         "/dev/usb"
 
-/* Maximum number of USB busses expected to be in a system
- * XXX should be replaced by dynamic allocation.
- */
-#define MAXUSBDEV      4
-
 /* Sometimes a device does not respond in time for interrupt
  * driven explore to find it.  Therefore we run an exploration
  * at regular intervals to catch those.
@@ -95,9 +90,13 @@
 
 char *configfile = CONFIGFILE; /* name of configuration file */
 
-char *devs[MAXUSBDEV];         /* device names */
-int fds[MAXUSBDEV];            /* file descriptors for USBDEV\d+ */
-int ndevs = 0;                 /* number of entries in fds / devs */
+struct usb_dev {
+       char *ud_name;
+       int ud_fd;
+       LIST_ENTRY(usb_dev) ud_list;
+};
+LIST_HEAD(usb_dev_list, usb_dev) _usb_devs;
+struct usb_dev_list *uds = &_usb_devs;
 int fd = -1;                   /* file descriptor for USBDEV */
 
 int lineno;
@@ -758,6 +757,7 @@
        pid_t pid;
        struct sigaction ign, intact, quitact;
        sigset_t newsigblock, oldsigblock;
+       struct usb_dev *ud;
        int status;
        int i;
 
@@ -789,8 +789,9 @@
                /* child here */
 
                /* close all open file handles for USBDEV\d* devices */
-               for (i = 0; i < ndevs; i++)
-                       close(fds[i]);          /* USBDEV\d+ */
+               LIST_FOREACH(ud, uds, ud_list) {
+                       close(ud->ud_fd);               /* USBDEV\d+ */
+               }
                close(fd);                      /* USBDEV */
 
                /* Restore original signal dispositions and exec the command. */
@@ -936,6 +937,9 @@
        fd_set r,w;
        int itimeout = TIMEOUT; /* timeout for select */
        struct timeval tv;
+       struct usb_dev *ud = NULL, *ud0 = NULL;
+       int fds;
+       LIST_INIT(uds);
 
        if (modfind(USB_UHUB) < 0) {
                if (kldload(USB_KLD) < 0 || modfind(USB_UHUB) < 0) {
@@ -960,8 +964,18 @@
                        explore_once = 1;
                        break;
                case 'f':
-                       if (ndevs < MAXUSBDEV)
-                               devs[ndevs++] = optarg;
+                       ud0 = ud;
+                       ud = (struct usb_dev *)malloc(sizeof(*ud));
+                       if (ud == NULL) {
+                               fprintf(stderr,
+                                   "can't alloc space for %s\n", buf);
+                               return 1;
+                       }
+                       ud->ud_name = optarg;
+                       if (ud0 != NULL && !(LIST_EMPTY(uds)))
+                               LIST_INSERT_AFTER(ud0, ud, ud_list);
+                       else
+                               LIST_INSERT_HEAD(uds, ud, ud_list);
                        break;
                case 'n':
                        handle_events = 0;
@@ -981,51 +995,64 @@
        argv += optind;
 
        maxfd = 0;
-       if (ndevs == 0) {
+       if (LIST_EMPTY(uds)) {
                /* open all the USBDEVS\d+ devices */
-               for (i = 0; i < MAXUSBDEV; i++) {
+               for (i = 0;; i++) {
                        sprintf(buf, "%s%d", USBDEV, i);
-                       fds[ndevs] = open(buf, O_RDWR);
-                       if (fds[ndevs] >= 0) {
-                               devs[ndevs] = strdup(buf);
-                               if (devs[ndevs] == NULL) {
-                                       fprintf(stderr, "strdup returned NULL\n");
-                                       return 1;
-                               }
-                               if (verbose)
-                                       printf("%s: opened %s\n", 
-                                              __progname, devs[ndevs]);
-                               if (fds[ndevs] > maxfd)
-                                       maxfd = fds[ndevs];
-                               ndevs++;
-                       } else if (errno != ENXIO && errno != ENOENT) {
-                               /* there was an error, on a device that does
-                                * exist (device is configured)
-                                */
-                               fprintf(stderr, "%s: Could not open %s, %s\n",
-                                       __progname, buf, strerror(errno));
-                               exit(1);
+                       fds = open(buf, O_RDWR);
+                       if (fds < 0) {
+                               if (errno != ENXIO && errno != ENOENT) {
+                                       /* there was an error, on a device
+                                          that does exist */
+                                       fprintf(stderr, "%s: could not open %s,"       
+                                     " %s\n", __progname, buf,
+                                           strerror(errno));
+                                       exit(1);
+                               } else
+                                       break;
+                       }
+                       ud0 = ud;
+                       ud = (struct usb_dev *)malloc(sizeof(*ud));
+                       if (ud == NULL) {
+                               fprintf(stderr,
+                                   "can't alloc space for %s\n", buf);
+                               return 1;
                        }
+                       ud->ud_name = strdup(buf);
+                       if (ud->ud_name == NULL) {
+                               fprintf(stderr,
+                           "strdup failed for %s\n", buf);
+                               return 1;
+                       }
+                       ud->ud_fd = fds;
+                       if (verbose)
+                               printf("%s: opened %s\n", 
+                                      __progname, ud->ud_name);
+                       if (fds > maxfd)
+                               maxfd = fds;
+                       if (ud0 != NULL && !(LIST_EMPTY(uds)))
+                               LIST_INSERT_AFTER(ud0, ud, ud_list);
+                       else
+                               LIST_INSERT_HEAD(uds, ud, ud_list);
                }
        } else {
                /* open all the files specified with -f */
-               for (i = 0; i < ndevs; i++) {
-                       fds[i] = open(devs[i], O_RDWR);
-                       if (fds[i] < 0) {
+               LIST_FOREACH(ud, uds, ud_list) {
+                       ud->ud_fd = open(ud->ud_name, O_RDWR);
+                       if (ud->ud_fd < 0) {
                                fprintf(stderr, "%s: Could not open %s, %s\n",
-                                       __progname, devs[i], strerror(errno));
+                                   __progname, ud->ud_name, strerror(errno));
                                exit(1);
                        } else {
                                if (verbose)
                                        printf("%s: opened %s\n", 
-                                              __progname, devs[i]);
-                               if (fds[i] > maxfd)
-                                       maxfd = fds[i];
+                                           __progname, ud->ud_name);
+                               if (ud->ud_fd > maxfd)
+                                       maxfd = ud->ud_fd;
                        }
                }
        }
 
-       if (ndevs == 0) {
+       if (LIST_EMPTY(uds)) {
                fprintf(stderr, "No USB host controllers found\n");
                exit(1);
        }
@@ -1033,12 +1060,12 @@
 
        /* Do the explore once and exit */
        if (explore_once) {
-               for (i = 0; i < ndevs; i++) {
-                       error = ioctl(fds[i], USB_DISCOVER);
+               LIST_FOREACH(ud, uds, ud_list) {
+                       error = ioctl(ud->ud_fd, USB_DISCOVER);
                        if (error < 0) {
                                fprintf(stderr, "%s: ioctl(%s, USB_DISCOVER) "
-                                       "failed, %s\n",
-                                       __progname, devs[i], strerror(errno));
+                                   "failed, %s\n", __progname, ud->ud_name,
+                                   strerror(errno));
                                exit(1);
                        }
                }
@@ -1075,8 +1102,9 @@
                FD_ZERO(&w);
                if (handle_events)
                        FD_SET(fd, &r);         /* device USBDEV */
-               for (i = 0; i < ndevs; i++)
-                       FD_SET(fds[i], &w);     /* device USBDEV\d+ */
+               LIST_FOREACH(ud, uds, ud_list) {
+                       FD_SET(ud->ud_fd, &w);  /* device USBDEV\d+ */
+               }
                tv.tv_usec = 0;
                tv.tv_sec = itimeout;
                error = select(maxfd+1, &r, &w, 0, itimeout ? &tv : 0);
@@ -1087,16 +1115,16 @@
                }
 
                /* USBDEV\d+ devices have signaled change, do a usb_discover */
-               for (i = 0; i < ndevs; i++) {
-                       if (error == 0 || FD_ISSET(fds[i], &w)) {
+               LIST_FOREACH(ud, uds, ud_list) {
+                       if (error == 0 || FD_ISSET(ud->ud_fd, &w)) {
                                if (verbose >= 2)
                                        printf("%s: doing %sdiscovery on %s\n", 
                                               __progname,
-                                              (error? "":"timeout "), devs[i]);
-                               if (ioctl(fds[i], USB_DISCOVER) < 0) {
+                                              (error? "":"timeout "), ud->ud_name);
+                               if (ioctl(ud->ud_fd, USB_DISCOVER) < 0) {
                                        fprintf(stderr, "%s: ioctl(%s, "
                                                "USB_DISCOVER) failed, %s\n",
-                                               __progname, devs[i],
+                                               __progname, ud->ud_name,
                                                strerror(errno));
                                        exit(1);
                                }


Reply via email to