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);
}