git: 9front

Download patch

ref: cf180ac97241fb84830cbdacfeb334c0092afafc
parent: 0ca1aa01a7df8a4a15a0580dd5401ad8c4d26595
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Dec 25 16:14:01 EST 2025

nusb/disk: re-read command status on tag mismatch

With k0gas hdd umsready() fails the first few SRready()
commands with various usb errors.

Later on SRready() commands succeed, but then read
the status block of the previously failed commands
and then fail with a command tag mismatch.

To recover from the latter, continue reading command
status from the endpoint until the tag matches.

--- a/sys/src/cmd/nusb/disk/disk.c
+++ b/sys/src/cmd/nusb/disk/disk.c
@@ -459,6 +459,7 @@
 		}
 	}
 
+Again:
 	/* read the transfer's status */
 	n = read(ums->epin->dfd, &csw, CswLen);
 	if(n <= 0){
@@ -472,8 +473,8 @@
 		goto Fail;
 	}
 	if(csw.tag != cbw.tag){
-		dprint(2, "%s: status tag mismatch\n", argv0);
-		goto Fail;
+		dprint(2, "%s: status tag mismatch: %lux != %lux\n", argv0, csw.tag, cbw.tag);
+		goto Again;
 	}
 	if(csw.status >= CswPhaseErr){
 		dprint(2, "%s: phase error\n", argv0);
--