ref: 7e3b2cdb557b49e0862079f38f14c777b9240e0f
parent: 98363cb27276b29ff3795d1ef93e4ea2e82e106f
author: cinap_lenrek <[email protected]>
date: Sat Nov 21 22:17:15 EST 2015
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.
--- a/sys/src/9/boot/nusbrc
+++ b/sys/src/9/boot/nusbrc
@@ -33,7 +33,7 @@
# 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 @@
exit
}
}
- }&}
+ }
case *
# Raspberry Pi ethernet will always appear as /net/etherU0
if(~ $2 0424)
@@ -60,6 +60,10 @@
}
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
--- a/sys/src/cmd/nusb/usbd/fns.h
+++ b/sys/src/cmd/nusb/usbd/fns.h
@@ -3,3 +3,4 @@
void work(void);
Hub* newhub(char *, Dev *);
void hname(char *);
+void checkidle(void);
--- a/sys/src/cmd/nusb/usbd/hub.c
+++ b/sys/src/cmd/nusb/usbd/hub.c
@@ -692,6 +692,7 @@
goto Again;
}
qunlock(&hublock);
+ checkidle();
sleep(pollms);
if(mustdump)
dump();
--- a/sys/src/cmd/nusb/usbd/usbd.c
+++ b/sys/src/cmd/nusb/usbd/usbd.c
@@ -146,15 +146,17 @@
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,7 +415,24 @@
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)
{
int fd, i, nd;
@@ -428,6 +447,7 @@
break;
} ARGEND;
+ busyfd = create("/env/usbbusy", ORCLOSE, 0600);
quotefmtinstall();
initevent();
rfork(RFNOTEG);