shithub: riscv

Download patch

ref: efd64da989f1b6585e5413b1b61413509ae49eaf
parent: 1a1b4b54b3e1553b36f18f1617ad8cb487442155
author: cinap_lenrek <[email protected]>
date: Sat Mar 7 17:26:49 EST 2020

nusb/usbd: fix /env/usbbusy bug

run the usb hub poll "work()" proc in the same filedescriptor
group as the fileserver by forking the process in Srv.start
callback.

this also prevents the usbbusy filedescriptor from being kept
open by the fileserver process.

--- a/sys/src/cmd/nusb/usbd/dat.h
+++ b/sys/src/cmd/nusb/usbd/dat.h
@@ -122,3 +122,5 @@
 	uchar	wHubDelay[2];
 	uchar	DeviceRemovable[1];	/* variable length */
 };
+
+extern Hub *hubs;
--- a/sys/src/cmd/nusb/usbd/hub.c
+++ b/sys/src/cmd/nusb/usbd/hub.c
@@ -670,21 +670,8 @@
 void
 work(void)
 {
-	char *fn;
 	Hub *h;
 	int i;
-
-	hubs = nil;
-	while((fn = rendezvous(work, nil)) != nil){
-		dprint(2, "%s: %s starting\n", argv0, fn);
-		h = newhub(fn, nil);
-		if(h == nil)
-			fprint(2, "%s: %s: newhub failed: %r\n", argv0, fn);
-		free(fn);
-	}
-
-	if(hubs == nil)
-		return;
 
 	/*
 	 * Enumerate (and acknowledge after first enumeration).
--- a/sys/src/cmd/nusb/usbd/usbd.c
+++ b/sys/src/cmd/nusb/usbd/usbd.c
@@ -329,7 +329,17 @@
 	respond(req, nil);
 }
 
+static void
+usbdstart(Srv*)
+{
+	switch(rfork(RFPROC|RFMEM|RFNOWAIT)){
+	case -1: sysfatal("rfork: %r");
+	case 0: work(); exits(nil);
+	}
+}
+
 Srv usbdsrv = {
+	.start = usbdstart,
 	.attach = usbdattach,
 	.walk1 = usbdwalk,
 	.read = usbdread,
@@ -447,6 +457,7 @@
 main(int argc, char **argv)
 {
 	int fd, i, nd;
+	char *fn;
 	Dir *d;
 
 	ARGBEGIN {
@@ -458,34 +469,33 @@
 		break;
 	} ARGEND;
 
-	busyfd = create("/env/usbbusy", ORCLOSE, 0600);
 	quotefmtinstall();
 	fmtinstall('U', Ufmt);
 	initevent();
-	rfork(RFNOTEG);
-	switch(rfork(RFPROC|RFMEM|RFNOWAIT)){
-	case -1: sysfatal("rfork: %r");
-	case 0: work(); exits(nil);
-	}
+
+	hubs = nil;
 	if(argc == 0){
-		if((fd = open("/dev/usb", OREAD)) < 0){
-			rendezvous(work, nil);
+		if((fd = open("/dev/usb", OREAD)) < 0)
 			sysfatal("/dev/usb: %r");
-		}
 		nd = dirreadall(fd, &d);
 		close(fd);
-		if(nd < 2){
-			rendezvous(work, nil);
-			sysfatal("/dev/usb: no hubs");
+		for(i = 0; i < nd; i++){
+			if(strcmp(d[i].name, "ctl") != 0){
+				fn = smprint("/dev/usb/%s", d[i].name);
+				newhub(fn, nil);
+				free(fn);
+			}
 		}
-		for(i = 0; i < nd; i++)
-			if(strcmp(d[i].name, "ctl") != 0)
-				rendezvous(work, smprint("/dev/usb/%s", d[i].name));
 		free(d);
-	}else
+	}else {
 		for(i = 0; i < argc; i++)
-			rendezvous(work, estrdup9p(argv[i]));
-	rendezvous(work, nil);
+			newhub(argv[i], nil);
+	}
+
+	if(hubs == nil)
+		sysfatal("no hubs");
+
+	busyfd = create("/env/usbbusy", ORCLOSE, 0600);
 	postsharesrv(&usbdsrv, nil, "usb", "usbd");
 	exits(nil);
 }