git: 9front

Download patch

ref: 0cf6756da17a8b1b7b46136369a1078552f58551
parent: 3f1265b2e01af3c0f8eb6fc995703889f160100a
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
--