shithub: riscv

Download patch

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);