Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 13 Feb 2003 11:02:29 -0500
From:      Adam Migus <amigus@tislabs.com>
To:        current@FreeBSD.org
Subject:   usbd patch (MAXUSBDEV no more)
Message-ID:  <20030213160229.GA9742@raven.gw.tislabs.com>

next in thread | raw e-mail | index | archive | help

--k+w/mQv8wyuph6w0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

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)

--k+w/mQv8wyuph6w0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="usbd.diff"

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

--k+w/mQv8wyuph6w0--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030213160229.GA9742>