ref: efd64da989f1b6585e5413b1b61413509ae49eaf
parent: 1a1b4b54b3e1553b36f18f1617ad8cb487442155
author: cinap_lenrek <cinap_lenrek@felloff.net>
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);
}