diff options
-rwxr-xr-x | rc/bin/nusbrc | 17 | ||||
-rw-r--r-- | sys/man/2/nusb | 3 | ||||
-rw-r--r-- | sys/man/4/nusb | 45 | ||||
-rw-r--r-- | sys/man/8/nusbrc | 14 | ||||
-rw-r--r-- | sys/man/8/plan9.ini | 5 | ||||
-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 |
19 files changed, 182 insertions, 63 deletions
diff --git a/rc/bin/nusbrc b/rc/bin/nusbrc index 546803a4b..1bff5073b 100755 --- a/rc/bin/nusbrc +++ b/rc/bin/nusbrc @@ -7,22 +7,25 @@ if(! bind -a '#u' /dev) @{ rfork ne fn attach { + id=$1 + if(~ $#* 5 && ! test -e /env/nousbhname) + id=$1:$5 switch($4){ case *01 - nusb/audio $1 + nusb/audio $id case *02 # serial and ethernet - nusb/serial $1 + nusb/serial $id # handled /sys/src/9/boot/nusbrc - # nusb/ether $1 + # nusb/ether $id case *03 # handled /sys/src/9/boot/nusbrc - # nusb/kb $1 + # nusb/kb $id case *08 # handled /sys/src/9/boot/nusbrc - # nusb/disk $1 - case *10106 - nusb/ptp $1 + # nusb/disk $id + case 010106 + nusb/ptp $id } } fn detach { diff --git a/sys/man/2/nusb b/sys/man/2/nusb index dfca0cf5c..681a76fbf 100644 --- a/sys/man/2/nusb +++ b/sys/man/2/nusb @@ -28,6 +28,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 */ }; .sp 0.3v struct Usbdev { @@ -119,7 +120,7 @@ Dev* openep(Dev *d, int id); 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); .sp 0.3v extern int usbdebug; /* more messages for bigger values */ .EE diff --git a/sys/man/4/nusb b/sys/man/4/nusb index efcc95eab..fc5d16e42 100644 --- a/sys/man/4/nusb +++ b/sys/man/4/nusb @@ -88,23 +88,41 @@ attachment. It provides a filesystem with the file .B usbevent (usually seen as .BR /dev/usbevent ) -which, when read, returns a 5 column, space separated line of +which, when read, returns a 6 column, space separated line of text, one for each event. The columns are: .B attach or .B detach -.I devid +followed by +.I addr .I vid .I did +.I csp and -.I csp . -All but -.I devid -are formatted as 4 digit hexadecimal. This file is read by +.I hname . +The +.I addr +is the decimal device address assigned. +.I Vid +and +.I did +are formatted as 4 digit hexadecimal. +.I Csp +is the device class, subclass, protocol indentifier +formatd as 6 digit hexadecimal. +.I Usbd +assigns a stable device uniqueue name based on the +device descriptor for +.I hname . +This information is read by .IR nusbrc (8) and the +.I addr +and +.I hname +are passed to a suitable driver as .I devid -is passed to a suitable driver. +in the form \fIaddr\fB:\fIhname .SS Keyboards and mice .I Kb supports USB keyboards and mice either as separate USB devices @@ -123,13 +141,10 @@ configures and manages USB mass storage devices. It provides a file system (usually seen under .BR /dev ) that includes one directory per storage device, named -.BI sdU N . M -in correspondence with the usb device number and the storage -unit number (or LUN). -For example, LUN number 2 on -.B /dev/usb/ep3.0 -can be accessed through -.BR /dev/sdU3.2 . +.BI sdU N [. M ] +in correspondence with the usb device uniqueue name +and the storage unit number (or LUN). The LUN is omited +for single lun devices. .PP The storage device directory contains the usual files served by @@ -183,7 +198,7 @@ provides a file system (usually seen under that includes one directory per USB serial port, named .BI eiaU N or -.BI eiaU N . M. +.BI eiaU N [. M ]. In this directory there are two files, .BR eiaU , similar to diff --git a/sys/man/8/nusbrc b/sys/man/8/nusbrc index 2105be95b..b6c5e5814 100644 --- a/sys/man/8/nusbrc +++ b/sys/man/8/nusbrc @@ -15,9 +15,21 @@ or .IR cpurc (8)), .I nusbrc handles the startup and shutdown of usb drivers on physical -device attach and detach events. +device attach and detach events by reading +.B /dev/usbevent +file. .SH SOURCE .B /rc/bin/nusbrc .B /sys/src/9/boot/nusbrc .SH "SEE ALSO" .IR nusb (4) +.SH BUGS +Usb devices appear as files under +.B /dev +and +.B /shr +identified by the devices uniqueue name assigned by usbd. +When the environment variable +.I nousbhname +is defined, devies are named by ther dynamically assigned +usb device address instead. This emulates the old behaviour. diff --git a/sys/man/8/plan9.ini b/sys/man/8/plan9.ini index 70c04e8fc..6d936f86b 100644 --- a/sys/man/8/plan9.ini +++ b/sys/man/8/plan9.ini @@ -812,6 +812,11 @@ It is not on by default because it causes problems on some laptops. .SS \fLusbwait=\fIvalue\fP This changes the sleep time from the default 2 to value in cases of USB devices taking a long time to come online. +.SS \fLnousbhname=\fP +When defined, +.IR nusbrc (8) +will use the dynamically assigned usb device address to name +usb devices instead of the device uniqueue name. .SS VIDEO .SS \fLmonitor=\fIvalue\fP .SS \fLvgasize=\fIvalue\fP 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; |