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).
This commit is contained in:
cinap_lenrek 2022-02-06 01:19:01 +00:00
parent fc0357b3de
commit 4ab2d149d4
3 changed files with 14 additions and 10 deletions

View file

@ -2,5 +2,5 @@ int attachdev(Port*);
void detachdev(Port*); void detachdev(Port*);
void work(void); void work(void);
Hub* newhub(char *, Dev*); Hub* newhub(char *, Dev*);
void hname(char *); int hname(char *);
void checkidle(void); void checkidle(void);

View file

@ -3,7 +3,7 @@
#include <mp.h> #include <mp.h>
#include <libsec.h> #include <libsec.h>
void int
hname(char *buf) hname(char *buf)
{ {
uchar d[SHA1dlen]; uchar d[SHA1dlen];
@ -13,5 +13,5 @@ hname(char *buf)
n = strlen(buf); n = strlen(buf);
sha1((uchar*)buf, n, d, nil); sha1((uchar*)buf, n, d, nil);
x = d[0] | d[1]<<8 | d[2]<<16; x = d[0] | d[1]<<8 | d[2]<<16;
snprint(buf, n+1, "%.5ux", x & 0xfffff); return snprint(buf, n+1, "%.5ux", x & 0xfffff);
} }

View file

@ -363,7 +363,8 @@ assignhname(Dev *dev)
char buf[64]; char buf[64];
Usbdev *ud; Usbdev *ud;
Hub *h; Hub *h;
int i; int col;
int i, n;
ud = dev->usb; ud = dev->usb;
@ -371,22 +372,25 @@ assignhname(Dev *dev)
snprint(buf, sizeof(buf), "%.4x%.4x%.4x%.6lx%s", snprint(buf, sizeof(buf), "%.4x%.4x%.4x%.6lx%s",
ud->vid, ud->did, ud->dno, ud->csp, ud->serial); ud->vid, ud->did, ud->dno, ud->csp, ud->serial);
hname(buf); n = hname(buf);
/* check for collisions */ /* check for collisions */
col = 0;
for(h = hubs; h != nil; h = h->next){ for(h = hubs; h != nil; h = h->next){
for(i = 1; i <= h->nport; i++){ for(i = 1; i <= h->nport; i++){
if(h->port[i].dev == nil) if(h->port[i].dev == nil)
continue; continue;
if(h->port[i].dev->hname == nil || h->port[i].dev == dev) if(h->port[i].dev->hname == nil || h->port[i].dev == dev)
continue; continue;
if(strcmp(h->port[i].dev->hname, buf) == 0){ if(strncmp(h->port[i].dev->hname, buf, n) == 0)
dev->hname = smprint("%s%d", buf, dev->id); col++;
return;
}
} }
} }
dev->hname = strdup(buf);
if(col == 0)
dev->hname = strdup(buf);
else
dev->hname = smprint("%s%d", buf, col);
} }
int int