diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2023-04-12 21:35:21 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2023-04-12 21:35:21 +0000 |
commit | 76142255a117a21da665282e7c6754b8b389bbc7 (patch) | |
tree | 72e13727804aafa5474988fc073ba569e35d03c6 /sys/src/cmd | |
parent | 8420d3ad6929c2f6963bcef80797f8cc2b3d90f8 (diff) |
nusb/usbd: only fetch first 8 bytes of device descriptor for getmaxpkt() (thanks k0ga)
The first usb transaction we run on a device is reading the
device descriptor, but todo this we need to know the maximum
packet size on the control endpoint.
But the packet size itself is stored in the device descriptor
which needs to be read over the control endpoint.
We used to fetch up to 64 bytes of device descriptor, and
if that fails assume some default values.
But this seems to cause errors down the line for some devices
like k0gas usb keyboard.
The new way is to read *ONLY* the first 8 bytes (that contain
the bMaxPktSize0 field) and fetch the full device descriptor
later once we have set the correct packet size.
Diffstat (limited to 'sys/src/cmd')
-rw-r--r-- | sys/src/cmd/nusb/usbd/hub.c | 12 |
1 files changed, 4 insertions, 8 deletions
diff --git a/sys/src/cmd/nusb/usbd/hub.c b/sys/src/cmd/nusb/usbd/hub.c index 4ff03b3f0..2397fe2c6 100644 --- a/sys/src/cmd/nusb/usbd/hub.c +++ b/sys/src/cmd/nusb/usbd/hub.c @@ -326,19 +326,15 @@ stsstr(int sts, int isusb3) } static int -getmaxpkt(Dev *d, int islow) +getmaxpkt(Dev *d) { - uchar buf[64]; /* More room to try to get device-specific descriptors */ + uchar buf[8]; DDev *dd; if(d->isusb3) return 512; dd = (DDev*)buf; - if(islow) - dd->bMaxPacketSize0 = 8; - else - dd->bMaxPacketSize0 = 64; - if(usbcmd(d, Rd2h|Rstd|Rdev, Rgetdesc, Ddev<<8|0, 0, buf, sizeof(buf)) < 0) + if(usbcmd(d, Rd2h|Rstd|Rdev, Rgetdesc, Ddev<<8|0, 0, buf, sizeof(buf)) != sizeof(buf)) return -1; return dd->bMaxPacketSize0; } @@ -440,7 +436,7 @@ portattach(Hub *h, int p, u32int sts) dprint(2, "%s: %s: port %d: set address: %r\n", argv0, d->dir, p); goto Fail; } - mp=getmaxpkt(nd, strcmp(sp, "low") == 0); + mp=getmaxpkt(nd); if(mp < 0){ dprint(2, "%s: %s: port %d: getmaxpkt: %r\n", argv0, d->dir, p); goto Fail; |