ref: 0b4ace02c469484c9f2a42fdc79ffe1d123d04d8
parent: f72bcce2c745ad3a7ac2a28323edbde2eb3b85ce
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Jul 22 15:35:32 EDT 2017
usbxhci: handle changing maxpkt on control endpoint by reevaluating endpoint context while endpoints != 0 are opend after the device descriptor has been parsed and the endpoint properties like maxpkt have been set, the control endpoint is opend with a guessed maxpkt value. once the first 8 bytes of the descriptor have been read by usbd, maxpkt gets set and we need to reevaluate the control endpoint 0 context to update the value.
--- a/sys/src/9/pc/usbxhci.c
+++ b/sys/src/9/pc/usbxhci.c
@@ -1062,12 +1062,24 @@
if((err = unstall(ring)) != nil)
error(err);
+ if((ring->ctx[1]>>16) != ep->maxpkt){
+ Slot *slot = ring->slot;
+ Ctlr *ctlr = slot->ctlr;
+ u32int *w = slot->ibase;
+ w[0] = 0;
+ w[1] = 1<<ring->id;
+ w += (ring->id+1)*8<<ctlr->csz;
+ initepctx(w, ring, ep);
+ if((err = ctlrcmd(ctlr, CR_EVALCTX | (slot->id<<24), 0, PADDR(slot->ibase), nil)) != nil)
+ error(err);
+ }
+
ilock(ring);
queuetd(ring, TR_SETUPSTAGE | (len > 0 ? 2+dir : 0)<<16 | 1<<6 | 1<<5, 8,
p[0] | p[1]<<8 | GET2(&p[2])<<16 |
(u64int)(GET2(&p[4]) | len<<16)<<32, &ws[0]);
if(len > 0)
- queuetd(ring, TR_DATASTAGE | dir<<16 | 0<<6 | 1<<5 | 0<<2, len,
+ queuetd(ring, TR_DATASTAGE | dir<<16 | 1<<5, len,
PADDR(io->cb->rp), &ws[1]);
queuetd(ring, TR_STATUSSTAGE | (len == 0 || !dir)<<16 | 1<<5, 0, 0, &ws[2]);
iunlock(ring);
@@ -1085,7 +1097,6 @@
}
if((err = waittd((Ctlr*)ep->hp->aux, &ws[2], ep->tmout, nil)) != nil)
error(err);
-
qunlock(io);
poperror();