diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-06-28 18:09:43 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-06-28 18:09:43 +0200 |
commit | 4275c49e72544d5b92512e41ddecbd6af5bee6c3 (patch) | |
tree | 22d66cc1e3286e69f50cc676e3c8e7fbd4b0636a /sys/src | |
parent | d8c75e45de9483881f782be0b5e7113e625db571 (diff) |
nusb: implement aijus stable uniqueue device names
instead of naming devices by ther dynamically assigned device address,
we hash device uniqueue fields from the device descriptor and produce
a 5 digit hex string that will identify the device across machines.
when there is a collision (less than 1% chance with 100 devices),
usbd will append the device address to the name to make it uniqueue
for this machine.
the hname is passed to drivers in the devid argument, which now has
the form addr:hname, where the colon and hname can be omited (for backwards
compatibility).
when the new behaviour isnt desired, nousbhname= environment variable
can be defined giving the old behaviour.
Diffstat (limited to 'sys/src')
-rwxr-xr-x | sys/src/9/boot/nusbrc | 27 | ||||
-rw-r--r-- | sys/src/cmd/nusb/audio/audio.c | 2 | ||||
-rw-r--r-- | sys/src/cmd/nusb/disk/disk.c | 7 | ||||
-rw-r--r-- | sys/src/cmd/nusb/ether/ether.c | 4 | ||||
-rw-r--r-- | sys/src/cmd/nusb/joy/joy.c | 2 | ||||
-rw-r--r-- | sys/src/cmd/nusb/kb/kb.c | 2 | ||||
-rw-r--r-- | sys/src/cmd/nusb/lib/dev.c | 32 | ||||
-rw-r--r-- | sys/src/cmd/nusb/lib/usb.h | 3 | ||||
-rw-r--r-- | sys/src/cmd/nusb/ptp/ptp.c | 4 | ||||
-rw-r--r-- | sys/src/cmd/nusb/serial/serial.c | 17 | ||||
-rw-r--r-- | sys/src/cmd/nusb/usbd/fns.h | 1 | ||||
-rw-r--r-- | sys/src/cmd/nusb/usbd/hname.c | 17 | ||||
-rw-r--r-- | sys/src/cmd/nusb/usbd/mkfile | 1 | ||||
-rw-r--r-- | sys/src/cmd/nusb/usbd/usbd.c | 42 |
14 files changed, 122 insertions, 39 deletions
diff --git a/sys/src/9/boot/nusbrc b/sys/src/9/boot/nusbrc index 811f7beeb..29a2d8b56 100755 --- a/sys/src/9/boot/nusbrc +++ b/sys/src/9/boot/nusbrc @@ -11,29 +11,33 @@ if(! nusb/usbd) @{ rfork ne fn attach { + id=$1 + if(~ $#* 5 && ! test -e /env/nousbhname) + id=$1:$5 switch($2$3){ case 0b957720 0b95772a 0db0a877 13b10018 15577720 20013c05 07d13c05 05ac1402 - nusb/ether -t a88772 $etherargs $1 + nusb/ether -t a88772 $etherargs $id case 0b951780 14eaab11 17370039 0411006e 050d5055 - nusb/ether -t a88178 $etherargs $1 + nusb/ether -t a88178 $etherargs $id case 2001abc1 - nusb/ether -t aue $etherargs $1 + nusb/ether -t aue $etherargs $id case 0bda8150 - nusb/ether -t url $etherargs $1 + nusb/ether -t url $etherargs $id case 18d14ee3 0bb40003 - nusb/ether -t rndis $etherargs $1 + nusb/ether -t rndis $etherargs $id case * switch($4){ case *03 - nusb/kb $1 + nusb/kb $id case *02 # CDC ethernet - nusb/ether $etherargs $1 + nusb/ether $etherargs $id case *08 - if(nusb/disk $1) {@{ + if(nusb/disk $id) {@{ rfork ne cd '#σ/usb' - for(dev in sdU^$1.*) if(test -d $dev) { + devs=sdU^($1 $5) + for(dev in $devs $devs.*) if(test -d $dev) { diskparts $dev for(part in $dev/dos* $dev/9fat) if(test -r $part) { mkdir -m 0700 '#σc/'^$dev || exit @@ -45,12 +49,13 @@ if(! nusb/usbd) }&} case * if(~ $2 0424) - nusb/ether -t smsc $etherargs $1 + nusb/ether -t smsc $etherargs $id } } } fn detach { - rm -rf '#σc/usb/'^$1.* '#σc/sdU'^$1.* '#σc/usbnet/'^$1.* + devs='#σc/sdU'^($1 $5) + rm -rf '#σc/usb/'^$1.* '#σc/usbnet/'^$1.* $devs $devs.* } rc < '#σ/usb/usbevent' & } diff --git a/sys/src/cmd/nusb/audio/audio.c b/sys/src/cmd/nusb/audio/audio.c index a187c8f96..08d9f9fc6 100644 --- a/sys/src/cmd/nusb/audio/audio.c +++ b/sys/src/cmd/nusb/audio/audio.c @@ -184,7 +184,7 @@ main(int argc, char *argv[]) if(argc == 0) usage(); - if((d = getdev(atoi(*argv))) == nil) + if((d = getdev(*argv)) == nil) sysfatal("getdev: %r"); audiodev = d; diff --git a/sys/src/cmd/nusb/disk/disk.c b/sys/src/cmd/nusb/disk/disk.c index 0b964f052..b690825ab 100644 --- a/sys/src/cmd/nusb/disk/disk.c +++ b/sys/src/cmd/nusb/disk/disk.c @@ -1042,7 +1042,7 @@ main(int argc, char **argv) if(argc != 1) usage(); - dev = getdev(atoi(*argv)); + dev = getdev(*argv); if(dev == nil) sysfatal("getdev: %r"); ums = dev->aux = emallocz(sizeof(Ums), 1); @@ -1062,7 +1062,10 @@ main(int argc, char **argv) for(i = 0; i <= ums->maxlun; i++){ lun = &ums->lun[i]; - snprint(lun->name, sizeof(lun->name), "sdU%d.%d", dev->id, i); + if(ums->maxlun > 0) + snprint(lun->name, sizeof(lun->name), "sdU%s.%d", dev->hname, i); + else + snprint(lun->name, sizeof(lun->name), "sdU%s", dev->hname); makeparts(lun); } snprint(buf, sizeof buf, "%d.disk", dev->id); diff --git a/sys/src/cmd/nusb/ether/ether.c b/sys/src/cmd/nusb/ether/ether.c index cc3116911..abdb0f897 100644 --- a/sys/src/cmd/nusb/ether/ether.c +++ b/sys/src/cmd/nusb/ether/ether.c @@ -819,7 +819,7 @@ threadmain(int argc, char **argv) if(argc != 1) usage(); - if((d = getdev(atoi(*argv))) == nil) + if((d = getdev(*argv)) == nil) sysfatal("getdev: %r"); if(findendpoints(d, &ei, &eo) < 0) sysfatal("no endpoints found"); @@ -847,7 +847,7 @@ threadmain(int argc, char **argv) atnotify(inote, 1); time0 = time(0); - tab[Qiface].name = smprint("etherU%d", d->id); + tab[Qiface].name = smprint("etherU%s", d->hname); snprint(s, sizeof(s), "%d.ether", d->id); closedev(d); threadpostsharesrv(&fs, nil, "usbnet", s); diff --git a/sys/src/cmd/nusb/joy/joy.c b/sys/src/cmd/nusb/joy/joy.c index cf9b093d7..c1f7cca71 100644 --- a/sys/src/cmd/nusb/joy/joy.c +++ b/sys/src/cmd/nusb/joy/joy.c @@ -410,7 +410,7 @@ threadmain(int argc, char* argv[]) }ARGEND; if(argc != 1) usage(); - d = getdev(atoi(*argv)); + d = getdev(*argv); if(d == nil) sysfatal("getdev: %r"); ud = d->usb; diff --git a/sys/src/cmd/nusb/kb/kb.c b/sys/src/cmd/nusb/kb/kb.c index 73cb52a41..0f60c9bad 100644 --- a/sys/src/cmd/nusb/kb/kb.c +++ b/sys/src/cmd/nusb/kb/kb.c @@ -794,7 +794,7 @@ threadmain(int argc, char* argv[]) }ARGEND; if(argc != 1) usage(); - d = getdev(atoi(*argv)); + d = getdev(*argv); if(d == nil) sysfatal("getdev: %r"); ud = d->usb; diff --git a/sys/src/cmd/nusb/lib/dev.c b/sys/src/cmd/nusb/lib/dev.c index 60d327e87..2eed9490e 100644 --- a/sys/src/cmd/nusb/lib/dev.c +++ b/sys/src/cmd/nusb/lib/dev.c @@ -121,6 +121,7 @@ opendev(char *fn) free(d); return nil; } + d->hname = nil; dprint(2, "%s: opendev %#p %s\n", argv0, d, fn); return d; } @@ -323,6 +324,8 @@ closedev(Dev *d) d->cfd = d->dfd = -1; free(d->dir); d->dir = nil; + free(d->hname); + d->hname = nil; ud = d->usb; d->usb = nil; if(ud != nil){ @@ -509,12 +512,26 @@ devctl(Dev *dev, char *fmt, ...) } Dev * -getdev(int id) +getdev(char *devid) { + char buf[40], *p; Dev *d; - char buf[40]; - - snprint(buf, sizeof buf, "/dev/usb/ep%d.0", id); + + if(devid[0] == '/' || devid[0] == '#'){ + snprint(buf, sizeof buf, "%s", devid); + p = strrchr(buf, '/'); + if(p != nil){ + p = strrchr(buf, ':'); + if(p != nil) + *p = 0; + } + } else { + p = nil; + snprint(buf, sizeof buf, "/dev/usb/ep%ld.0", strtol(devid, &p, 10)); + if(*p != ':') + p = nil; + } + d = opendev(buf); if(d == nil) return nil; @@ -522,5 +539,12 @@ getdev(int id) closedev(d); return nil; } + + if(p == nil){ + snprint(buf, sizeof buf, ":%d", d->id); + p = buf; + } + d->hname = strdup(p+1); + return d; } diff --git a/sys/src/cmd/nusb/lib/usb.h b/sys/src/cmd/nusb/lib/usb.h index 24454a58f..9f47fe116 100644 --- a/sys/src/cmd/nusb/lib/usb.h +++ b/sys/src/cmd/nusb/lib/usb.h @@ -174,6 +174,7 @@ struct Dev Usbdev* usb; /* USB description */ void* aux; /* for the device driver */ void (*free)(void*); /* idem. to release aux */ + char* hname; /* hash name, uniqueue for device */ }; /* @@ -351,7 +352,7 @@ int parsedesc(Usbdev *d, Conf *c, uchar *b, int n); int parsedev(Dev *xd, uchar *b, int n); int unstall(Dev *dev, Dev *ep, int dir); int usbcmd(Dev *d, int type, int req, int value, int index, uchar *data, int count); -Dev* getdev(int id); +Dev* getdev(char *devid); extern int usbdebug; /* more messages for bigger values */ diff --git a/sys/src/cmd/nusb/ptp/ptp.c b/sys/src/cmd/nusb/ptp/ptp.c index c43ef802c..aae70d984 100644 --- a/sys/src/cmd/nusb/ptp/ptp.c +++ b/sys/src/cmd/nusb/ptp/ptp.c @@ -1011,7 +1011,7 @@ threadmain(int argc, char **argv) if(argc == 0) usage(); - if((d = getdev(atoi(*argv))) == nil) + if((d = getdev(*argv)) == nil) sysfatal("opendev: %r"); if(findendpoints(d, &epin, &epout, &epint) < 0) sysfatal("findendpoints: %r"); @@ -1037,7 +1037,7 @@ threadmain(int argc, char **argv) time0 = time(0); - snprint(name, sizeof name, "sdU%d", d->id); + snprint(name, sizeof name, "sdU%s", d->hname); snprint(desc, sizeof desc, "%d.ptp", d->id); threadpostsharesrv(&fs, nil, name, desc); diff --git a/sys/src/cmd/nusb/serial/serial.c b/sys/src/cmd/nusb/serial/serial.c index ad6a93bd7..e5a385600 100644 --- a/sys/src/cmd/nusb/serial/serial.c +++ b/sys/src/cmd/nusb/serial/serial.c @@ -810,7 +810,7 @@ threadmain(int argc, char* argv[]) }ARGEND if(argc != 1) usage(); - dev = getdev(atoi(*argv)); + dev = getdev(*argv); if(dev == nil) sysfatal("getdev: %r"); @@ -859,17 +859,10 @@ threadmain(int argc, char* argv[]) } dsprint(2, "serial: adding interface %d, %p\n", p->interfc, p); - if(p->isjtag){ - snprint(p->name, sizeof p->name, "jtag"); - dsprint(2, "serial: JTAG interface %d %p\n", i, p); - snprint(p->name, sizeof p->name, "jtag%d.%d", dev->id, i); - } else { - snprint(p->name, sizeof p->name, "eiaU"); - if(i == 0) - snprint(p->name, sizeof p->name, "eiaU%d", dev->id); - else - snprint(p->name, sizeof p->name, "eiaU%d.%d", dev->id, i); - } + if(ser->nifcs == 1) + snprint(p->name, sizeof p->name, "%s%s", p->isjtag ? "jtag" : "eiaU", dev->hname); + else + snprint(p->name, sizeof p->name, "%s%s.%d", p->isjtag ? "jtag" : "eiaU", dev->hname, i); fprint(2, "%s...", p->name); incref(dev); p->readrend.l = &p->readq; diff --git a/sys/src/cmd/nusb/usbd/fns.h b/sys/src/cmd/nusb/usbd/fns.h index 9016610c0..981ff0ceb 100644 --- a/sys/src/cmd/nusb/usbd/fns.h +++ b/sys/src/cmd/nusb/usbd/fns.h @@ -2,3 +2,4 @@ int attachdev(Port*); void detachdev(Port*); void work(void); Hub* newhub(char *, Dev *); +void hname(char *); diff --git a/sys/src/cmd/nusb/usbd/hname.c b/sys/src/cmd/nusb/usbd/hname.c new file mode 100644 index 000000000..c88a0faa1 --- /dev/null +++ b/sys/src/cmd/nusb/usbd/hname.c @@ -0,0 +1,17 @@ +#include <u.h> +#include <libc.h> +#include <mp.h> +#include <libsec.h> + +void +hname(char *buf) +{ + uchar d[SHA1dlen]; + u32int x; + int n; + + 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); +} diff --git a/sys/src/cmd/nusb/usbd/mkfile b/sys/src/cmd/nusb/usbd/mkfile index 4e8beeb6a..37fa1759c 100644 --- a/sys/src/cmd/nusb/usbd/mkfile +++ b/sys/src/cmd/nusb/usbd/mkfile @@ -3,6 +3,7 @@ OFILES=\ usbd.$O\ hub.$O\ + hname.$O\ HFILES=\ dat.h\ diff --git a/sys/src/cmd/nusb/usbd/usbd.c b/sys/src/cmd/nusb/usbd/usbd.c index 59a827e01..644c16261 100644 --- a/sys/src/cmd/nusb/usbd/usbd.c +++ b/sys/src/cmd/nusb/usbd/usbd.c @@ -221,8 +221,10 @@ static char * formatdev(Dev *d, int type) { Usbdev *u = d->usb; - - return smprint("%s %d %.4x %.4x %.8lx\n", type ? "detach" : "attach", d->id, u->vid, u->did, u->csp); + return smprint("%s %d %.4x %.4x %.6lx %s\n", + type ? "detach" : "attach", + d->id, u->vid, u->did, u->csp, + d->hname != nil ? d->hname : ""); } static void @@ -335,6 +337,39 @@ Srv usbdsrv = { .destroyfid = usbddestroyfid, }; +static void +assignhname(Dev *dev) +{ + extern Hub *hubs; + char buf[64]; + Usbdev *ud; + Hub *h; + int i; + + ud = dev->usb; + + /* build string of device uniqueue stuff */ + snprint(buf, sizeof(buf), "%.4x%.4x%.4x%.6lx%s", + ud->vid, ud->did, ud->dno, ud->csp, ud->serial); + + hname(buf); + + /* check for collisions */ + for(h = hubs; h != nil; h = h->next){ + for(i = 1; i <= h->nport; i++){ + if(h->port[i].dev == nil) + 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; + } + } + } + dev->hname = strdup(buf); +} + int attachdev(Port *p) { @@ -355,6 +390,9 @@ attachdev(Port *p) /* close control endpoint so driver can open it */ close(d->dfd); d->dfd = -1; + + /* assign stable name based on device descriptor */ + assignhname(d); pushevent(d, formatdev(d, 0)); return 0; |