ref: 1054458bc845d2f4376efb200fb894e860af83d3
parent: b438f745a48db2a0098cfe8b5a72bcdbdc64e618
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;
};
--
⑨