From 7e3b2cdb557b49e0862079f38f14c777b9240e0f Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sun, 22 Nov 2015 03:17:15 +0100 Subject: [PATCH] usbd: intoruce /env/usbbusy to solve the usb device enumeration race on boot, usbd creates /env/usbbusy on startup and once all devices have been enumerated and readers have consumed all the events, we remove the file so nusbrc/bootrc can continue. this makes sure all the usb devices that where plugged in on boot are made available. --- sys/src/9/boot/nusbrc | 8 ++++++-- sys/src/cmd/nusb/usbd/fns.h | 1 + sys/src/cmd/nusb/usbd/hub.c | 1 + sys/src/cmd/nusb/usbd/usbd.c | 26 +++++++++++++++++++++++--- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/sys/src/9/boot/nusbrc b/sys/src/9/boot/nusbrc index 56ee25332..6c8ee5715 100755 --- a/sys/src/9/boot/nusbrc +++ b/sys/src/9/boot/nusbrc @@ -33,7 +33,7 @@ if(! nusb/usbd) # CDC ethernet nusb/ether $etherargs $id case *08 - if(nusb/disk $id) {@{ + if(nusb/disk $id) @{ rfork ne cd '#σ/usb' devs=sdU^($1 $5) @@ -46,7 +46,7 @@ if(! nusb/usbd) exit } } - }&} + } case * # Raspberry Pi ethernet will always appear as /net/etherU0 if(~ $2 0424) @@ -61,5 +61,9 @@ if(! nusb/usbd) rc < '#σ/usb/usbevent' & } +# usbd removes this file once all devices have been enumerated +while(test -e /env/usbbusy) + sleep 1 + bind -a '#σ/usb' /dev bind -a '#σ/usbnet' /net diff --git a/sys/src/cmd/nusb/usbd/fns.h b/sys/src/cmd/nusb/usbd/fns.h index 981ff0ceb..cec17cc21 100644 --- a/sys/src/cmd/nusb/usbd/fns.h +++ b/sys/src/cmd/nusb/usbd/fns.h @@ -3,3 +3,4 @@ void detachdev(Port*); void work(void); Hub* newhub(char *, Dev *); void hname(char *); +void checkidle(void); diff --git a/sys/src/cmd/nusb/usbd/hub.c b/sys/src/cmd/nusb/usbd/hub.c index 760f160aa..2ca713e5c 100644 --- a/sys/src/cmd/nusb/usbd/hub.c +++ b/sys/src/cmd/nusb/usbd/hub.c @@ -692,6 +692,7 @@ Again: goto Again; } qunlock(&hublock); + checkidle(); sleep(pollms); if(mustdump) dump(); diff --git a/sys/src/cmd/nusb/usbd/usbd.c b/sys/src/cmd/nusb/usbd/usbd.c index 7b7f998b7..38acf310b 100644 --- a/sys/src/cmd/nusb/usbd/usbd.c +++ b/sys/src/cmd/nusb/usbd/usbd.c @@ -146,15 +146,17 @@ dirgen(int n, Dir *d, void *) return -1; d->qid.path = n + 1; d->qid.vers = 0; - if(n >= 0) + if(n >= 0){ d->qid.type = 0; - else + d->mode = 0444; + }else{ d->qid.type = QTDIR; + d->mode = 0555 | DMDIR; + } d->uid = estrdup9p(getuser()); d->gid = estrdup9p(d->uid); d->muid = estrdup9p(d->uid); d->name = estrdup9p(names[n+1]); - d->mode = 0555 | (d->qid.type << 24); d->atime = d->mtime = time(0); d->length = 0; return 0; @@ -413,6 +415,23 @@ detachdev(Port *p) pushevent(d, formatdev(d, 1)); } +/* + * we create /env/usbbusy on startup and once all devices have been + * enumerated and readers have consumed all the events, we remove the + * file so nusbrc can continue. + */ +static int busyfd = -1; + +void +checkidle(void) +{ + if(busyfd < 0 || reqlast == nil || evlast == nil || evlast->prev > 0) + return; + + close(busyfd); + busyfd = -1; +} + void main(int argc, char **argv) { @@ -428,6 +447,7 @@ main(int argc, char **argv) break; } ARGEND; + busyfd = create("/env/usbbusy", ORCLOSE, 0600); quotefmtinstall(); initevent(); rfork(RFNOTEG);