Module Name:    src
Committed By:   mrg
Date:           Sun Mar 24 03:23:19 UTC 2024

Modified Files:
        src/usr.sbin/usbdevs: usbdevs.c

Log Message:
usbdevs(8): don't assume usb bus count is the same as max usb bus unit

keep track of the highest usbN value, not the count of busses.

fixes a problem where you do "drvctl -d usb0" (or a parent), and then
"usbdevs" won't print info on the last bus.


To generate a diff of this commit:
cvs rdiff -u -r1.41 -r1.42 src/usr.sbin/usbdevs/usbdevs.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.sbin/usbdevs/usbdevs.c
diff -u src/usr.sbin/usbdevs/usbdevs.c:1.41 src/usr.sbin/usbdevs/usbdevs.c:1.42
--- src/usr.sbin/usbdevs/usbdevs.c:1.41	Tue Sep 13 08:34:37 2022
+++ src/usr.sbin/usbdevs/usbdevs.c	Sun Mar 24 03:23:19 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: usbdevs.c,v 1.41 2022/09/13 08:34:37 riastradh Exp $	*/
+/*	$NetBSD: usbdevs.c,v 1.42 2024/03/24 03:23:19 mrg Exp $	*/
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -31,10 +31,10 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: usbdevs.c,v 1.41 2022/09/13 08:34:37 riastradh Exp $");
+__RCSID("$NetBSD: usbdevs.c,v 1.42 2024/03/24 03:23:19 mrg Exp $");
 #endif
 
-#include <sys/types.h>
+#include <sys/param.h>
 
 #include <sys/drvctlio.h>
 
@@ -328,8 +328,12 @@ dumpone(char *name, int f, int addr)
 		usbdump(f);
 }
 
+/*
+ * Find the highest usb device unit.  Searches recursively
+ * thought the device list, tracking highest unit seen.
+ */
 static int
-getusbcount_device(int fd, const char *dev, int depth)
+get_highest_usb_device_unit(int fd, const char *dev, int depth)
 {
 	struct devlistargs laa = {
 		.l_childname = NULL,
@@ -337,19 +341,23 @@ getusbcount_device(int fd, const char *d
 	};
 	size_t i;
 	size_t children;
-	int nbusses = 0;
+	int highbus = 0;
 
 	if (depth && (dev == NULL || *dev == '\0'))
 		return 0;
 
 	/*
-	 * Look for children that match "usb[0-9]*".  Could maybe
+	 * Look for children that match "usb[0-9]*".  The high 
+	 * bus from this value, regardles
 	 * simply return 1 here, but there's always a chance that
 	 * someone has eg, a USB to PCI bridge, with a USB
 	 * controller behind PCI.
 	 */
-	if (strncmp(dev, "usb", 3) == 0 && isdigit((int)dev[3]))
-		nbusses++;
+	if (strncmp(dev, "usb", 3) == 0 && isdigit((int)dev[3])) {
+		int new_high = atoi(dev+3);
+
+		highbus = MAX(new_high, highbus);
+	}
 
 	strlcpy(laa.l_devname, dev, sizeof(laa.l_devname));
 
@@ -366,11 +374,14 @@ getusbcount_device(int fd, const char *d
 		err(EXIT_FAILURE, "DRVLISTDEV: number of children grew");
 
 	for (i = 0; i < laa.l_children; i++) {
-		nbusses += getusbcount_device(fd, laa.l_childname[i],
+		int new_high;
+
+		new_high = get_highest_usb_device_unit(fd, laa.l_childname[i],
 		    depth + 1);
+		highbus = MAX(new_high, highbus);
 	}
 
-	return nbusses;
+	return highbus;
 }
 
 int
@@ -411,17 +422,17 @@ main(int argc, char **argv)
 	argv += optind;
 
 	if (dev == NULL) {
-		int nbusses;
+		int highbus;
 		int fd = open(DRVCTLDEV, O_RDONLY, 0);
 
 		/* If no drvctl configured, default to 16. */
 		if (fd != -1)
-			nbusses = getusbcount_device(fd, "", 0);
+			highbus = get_highest_usb_device_unit(fd, "", 0);
 		else
-			nbusses = 16;
+			highbus = 16;
 		close(fd);
 
-		for (ncont = 0, i = 0; i < nbusses; i++) {
+		for (ncont = 0, i = 0; i <= highbus; i++) {
 			snprintf(buf, sizeof(buf), "%s%d", USBDEV, i);
 			f = open(buf, O_RDONLY);
 			if (f >= 0) {

Reply via email to