ref: a610f2eac21804f178494f1f90787f7fe0f9d187
parent: 235681677d512abed4ce217c2e358f3fcefd6465
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Wed Oct 23 17:30:49 EDT 2024
nusb/disk: kill 9p procs before sysfatal(), devctl() before opendevdata() This is an error probably when converting from libthread to classid plan9 procs. umsrequest() used to just sysfatal() once the error counter reached some value. But this leaves 9p procs (created by srvrelease()) around keeping the device hanging around. Instead, reply first, then attempt some recovery. If that fails, kill our notegroup. Also, for upcoming devusb changes, make sure we do devctl() while the endpoint is not in use.
--- a/sys/src/cmd/nusb/disk/disk.c
+++ b/sys/src/cmd/nusb/disk/disk.c
@@ -241,17 +241,19 @@
return 0;
}
-static int
+static void
umsrecover(void)
{
- if(umsreset() < 0)
- return -1;
+ if(umsreset() < 0){
+ /* kill the 9p procs */
+ postnote(PNGROUP, getpid(), "shutdown");
+ sysfatal("umsrecover: %r");
+ }
if(unstall(dev, ums->epin, Ein) < 0)
dprint(2, "%s: unstall epin: %r\n", argv0);
/* do we need this when epin == epout? */
if(unstall(dev, ums->epout, Eout) < 0)
dprint(2, "%s: unstall epout: %r\n", argv0);
- return 0;
}
static int
@@ -500,14 +502,10 @@
dprint(2, "%s: phase error\n", argv0);
goto Fail;
}
- ums->nerrs = 0;
return data->count - csw.dataresidue;
Fail:
*status = STharderr;
- if(ums->nerrs++ > 15)
- sysfatal("%s: too many errors", dev->dir);
- umsrecover();
return -1;
}
@@ -765,6 +763,7 @@
if(count < 0){
lun->lbsize = 0; /* medium may have changed */
responderror(req);
+ umsrecover();
}else{
req->ofcall.count = count;
respond(req, nil);
@@ -878,6 +877,7 @@
if(count < 0){
lun->lbsize = 0; /* medium may have changed */
responderror(req);
+ umsrecover();
}else{
req->ofcall.count = count;
respond(req, nil);
@@ -997,6 +997,15 @@
closedev(ums->epin);
return -1;
}
+
+ devctl(ums->epin, "timeout 2000");
+ devctl(ums->epout, "timeout 2000");
+ if(usbdebug > 1 || diskdebug > 2){
+ devctl(ums->epin, "debug 1");
+ devctl(ums->epout, "debug 1");
+ devctl(dev, "debug 1");
+ }
+
if(ums->epin == ums->epout)
opendevdata(ums->epin, ORDWR);
else{
@@ -1009,15 +1018,6 @@
return -1;
}
dprint(2, "%s: ep in %s out %s\n", argv0, ums->epin->dir, ums->epout->dir);
-
- devctl(ums->epin, "timeout 2000");
- devctl(ums->epout, "timeout 2000");
-
- if(usbdebug > 1 || diskdebug > 2){
- devctl(ums->epin, "debug 1");
- devctl(ums->epout, "debug 1");
- devctl(dev, "debug 1");
- }
return 0;
}
--- a/sys/src/cmd/nusb/disk/ums.h
+++ b/sys/src/cmd/nusb/disk/ums.h
@@ -96,7 +96,6 @@
Umsc *lun;
uchar maxlun;
int seq;
- int nerrs;
int wrongresidues;
};
--
⑨