code: plan9front

Download patch

ref: 4ab2d149d46c6762c9b8d9fd24d0bf92b10704f6
parent: fc0357b3decd0dc9848892a823d63070fde09a89
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Feb 5 20:19:01 EST 2022

nusb/usbd: use per hname collision counter instead of device address to resolve collisions

The device address is highly variable and depends on
all prior enumerated devices.

This can happen with some devices that do not have
a serial number and all devices of the same type
having the same hname.

Using a counter of collisions per hname makes more sense
and is more stable (given that the order devices are
enumerated is deterministic).

--- a/sys/src/cmd/nusb/usbd/fns.h
+++ b/sys/src/cmd/nusb/usbd/fns.h
@@ -2,5 +2,5 @@
 void	detachdev(Port*);
 void	work(void);
 Hub*	newhub(char *, Dev*);
-void	hname(char *);
+int	hname(char *);
 void	checkidle(void);
--- a/sys/src/cmd/nusb/usbd/hname.c
+++ b/sys/src/cmd/nusb/usbd/hname.c
@@ -3,7 +3,7 @@
 #include <mp.h>
 #include <libsec.h>
 
-void
+int
 hname(char *buf)
 {
 	uchar d[SHA1dlen];
@@ -13,5 +13,5 @@
 	n = strlen(buf);
 	sha1((uchar*)buf, n, d, nil);
 	x = d[0] | d[1]<<8 | d[2]<<16;
-	snprint(buf, n+1, "%.5ux", x & 0xfffff);
+	return snprint(buf, n+1, "%.5ux", x & 0xfffff);
 }
--- a/sys/src/cmd/nusb/usbd/usbd.c
+++ b/sys/src/cmd/nusb/usbd/usbd.c
@@ -363,7 +363,8 @@
 	char buf[64];
 	Usbdev *ud;
 	Hub *h;
-	int i;
+	int col;
+	int i, n;
 
 	ud = dev->usb;
 
@@ -371,9 +372,10 @@
 	snprint(buf, sizeof(buf), "%.4x%.4x%.4x%.6lx%s",
 		ud->vid, ud->did, ud->dno, ud->csp, ud->serial);
 
-	hname(buf);
+	n = hname(buf);
 
 	/* check for collisions */
+	col = 0;
 	for(h = hubs; h != nil; h = h->next){
 		for(i = 1; i <= h->nport; i++){
 			if(h->port[i].dev == nil)
@@ -380,13 +382,15 @@
 				continue;
 			if(h->port[i].dev->hname == nil || h->port[i].dev == dev)
 				continue;
-			if(strcmp(h->port[i].dev->hname, buf) == 0){
-				dev->hname = smprint("%s%d", buf, dev->id);
-				return;
-			}
+			if(strncmp(h->port[i].dev->hname, buf, n) == 0)
+				col++;
 		}
 	}
-	dev->hname = strdup(buf);
+
+	if(col == 0)
+		dev->hname = strdup(buf);
+	else
+		dev->hname = smprint("%s%d", buf, col);
 }
 
 int