ref: 3a4a3faf291b21624a4521fe1e22aec5bec7843d
parent: ceed9b8853ab7b10e5a9e39704e712bfce53ce8a
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Tue May 7 05:19:53 EDT 2019
nusb/usbd: work around devices that ignore the high byte of wLength in control transfer reads there appear to be devices out there such as Realtek RTL2838UHIDIR SDR that do not process control transfers correctly, ignoring the high byte of the wLength field. to work around this, we specify an odd number of bytes for read sizes >= 256 which keeps the low byte 0xFF.
--- a/sys/src/cmd/nusb/kb/kb.c
+++ b/sys/src/cmd/nusb/kb/kb.c
@@ -42,7 +42,12 @@
/* report descriptor */
int nrep;
- uchar rep[512];
+
+ /*
+ * use odd size as some devices ignore the high byte of
+ * wLength in control transfer reads.
+ */
+ uchar rep[512-1];
};
typedef struct Hidreport Hidreport;
--- a/sys/src/cmd/nusb/lib/dev.c
+++ b/sys/src/cmd/nusb/lib/dev.c
@@ -136,8 +136,10 @@
/*
* Max device conf is also limited by max control request size as
* limited by Maxctllen in the kernel usb.h (both limits are arbitrary).
+ * Some devices ignore the high byte of control transfer reads so keep
+ * the low byte all ones. asking for 16K kills Newsham's disk.
*/
- Maxdevconf = 4 * 1024, /* asking for 16K kills Newsham's disk */
+ Maxdevconf = 4*1024 - 1,
};
int
@@ -201,7 +203,7 @@
char*
loaddevstr(Dev *d, int sid)
{
- uchar buf[256];
+ uchar buf[256-2]; /* keep size < 256 */
int langid;
int type;
int nr;