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.
This commit is contained in:
cinap_lenrek 2015-11-22 03:17:15 +01:00
parent 98363cb272
commit 7e3b2cdb55
4 changed files with 31 additions and 5 deletions

View file

@ -33,7 +33,7 @@ if(! nusb/usbd)
# CDC ethernet # CDC ethernet
nusb/ether $etherargs $id nusb/ether $etherargs $id
case *08 case *08
if(nusb/disk $id) {@{ if(nusb/disk $id) @{
rfork ne rfork ne
cd '#σ/usb' cd '#σ/usb'
devs=sdU^($1 $5) devs=sdU^($1 $5)
@ -46,7 +46,7 @@ if(! nusb/usbd)
exit exit
} }
} }
}&} }
case * case *
# Raspberry Pi ethernet will always appear as /net/etherU0 # Raspberry Pi ethernet will always appear as /net/etherU0
if(~ $2 0424) if(~ $2 0424)
@ -61,5 +61,9 @@ if(! nusb/usbd)
rc < '#σ/usb/usbevent' & 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 '#σ/usb' /dev
bind -a '#σ/usbnet' /net bind -a '#σ/usbnet' /net

View file

@ -3,3 +3,4 @@ void detachdev(Port*);
void work(void); void work(void);
Hub* newhub(char *, Dev *); Hub* newhub(char *, Dev *);
void hname(char *); void hname(char *);
void checkidle(void);

View file

@ -692,6 +692,7 @@ Again:
goto Again; goto Again;
} }
qunlock(&hublock); qunlock(&hublock);
checkidle();
sleep(pollms); sleep(pollms);
if(mustdump) if(mustdump)
dump(); dump();

View file

@ -146,15 +146,17 @@ dirgen(int n, Dir *d, void *)
return -1; return -1;
d->qid.path = n + 1; d->qid.path = n + 1;
d->qid.vers = 0; d->qid.vers = 0;
if(n >= 0) if(n >= 0){
d->qid.type = 0; d->qid.type = 0;
else d->mode = 0444;
}else{
d->qid.type = QTDIR; d->qid.type = QTDIR;
d->mode = 0555 | DMDIR;
}
d->uid = estrdup9p(getuser()); d->uid = estrdup9p(getuser());
d->gid = estrdup9p(d->uid); d->gid = estrdup9p(d->uid);
d->muid = estrdup9p(d->uid); d->muid = estrdup9p(d->uid);
d->name = estrdup9p(names[n+1]); d->name = estrdup9p(names[n+1]);
d->mode = 0555 | (d->qid.type << 24);
d->atime = d->mtime = time(0); d->atime = d->mtime = time(0);
d->length = 0; d->length = 0;
return 0; return 0;
@ -413,6 +415,23 @@ detachdev(Port *p)
pushevent(d, formatdev(d, 1)); 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 void
main(int argc, char **argv) main(int argc, char **argv)
{ {
@ -428,6 +447,7 @@ main(int argc, char **argv)
break; break;
} ARGEND; } ARGEND;
busyfd = create("/env/usbbusy", ORCLOSE, 0600);
quotefmtinstall(); quotefmtinstall();
initevent(); initevent();
rfork(RFNOTEG); rfork(RFNOTEG);