tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[patch] xhci patch 20160809
Hello,
I'll post xhci patches for HEAD.
x-addrendian.diff
+ Fix endian issue of device address.
x-linktrb2.diff
+ Put Link TRB always at the end of ring.
Should fix ctrl xfer problem on Intel xHC.
Thanks,
--
t-hash
--- sys/dev/usb/xhci.c.orig 2016-07-18 07:07:53.000000000 +0900
+++ sys/dev/usb/xhci.c 2016-08-07 14:17:46.000000000 +0900
@@ -2229,7 +2246,7 @@ xhci_new_device(device_t parent, struct
cp = xhci_slot_get_dcv(sc, xs, XHCI_DCI_SLOT);
//hexdump("slot context", cp, sc->sc_ctxsz);
- uint8_t addr = XHCI_SCTX_3_DEV_ADDR_GET(cp[3]);
+ uint8_t addr = XHCI_SCTX_3_DEV_ADDR_GET(le32toh(cp[3]));
DPRINTFN(4, "device address %u", addr, 0, 0, 0);
/* XXX ensure we know when the hardware does something
we can't yet cope with */
--- sys/dev/usb/xhci.c.orig 2016-07-18 07:07:53.000000000 +0900
+++ sys/dev/usb/xhci.c 2016-08-09 17:37:40.000000000 +0900
@@ -2374,58 +2397,63 @@ xhci_ring_put(struct xhci_softc * const
* The code should write the 'cycle' bit on the link trb AFTER
* adding the other trb.
*/
- if (ri + ntrbs >= (xr->xr_ntrb - 1)) {
- parameter = xhci_ring_trbp(xr, 0);
- status = 0;
- control = XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_LINK) |
- XHCI_TRB_3_TC_BIT | (cs ? XHCI_TRB_3_CYCLE_BIT : 0);
- xhci_trb_put(&xr->xr_trb[ri], parameter, status, control);
- usb_syncmem(&xr->xr_dma, XHCI_TRB_SIZE * ri, XHCI_TRB_SIZE * 1,
- BUS_DMASYNC_PREWRITE);
- xr->xr_cookies[ri] = NULL;
- xr->xr_ep = 0;
- xr->xr_cs ^= 1;
- ri = xr->xr_ep;
- cs = xr->xr_cs;
- }
-
- ri++;
-
- /* Write any subsequent TRB first */
- for (i = 1; i < ntrbs; i++) {
- parameter = trbs[i].trb_0;
- status = trbs[i].trb_2;
- control = trbs[i].trb_3;
+ u_int firstep = xr->xr_ep;
+ u_int firstcs = xr->xr_cs;
- if (cs) {
- control |= XHCI_TRB_3_CYCLE_BIT;
+ for (i = 0; i < ntrbs; ) {
+ u_int oldri = ri;
+ u_int oldcs = cs;
+
+ if (ri >= (xr->xr_ntrb - 1)) {
+ /* Put Link TD at the end of ring */
+ parameter = xhci_ring_trbp(xr, 0);
+ status = 0;
+ control = XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_LINK) |
+ XHCI_TRB_3_TC_BIT;
+ xr->xr_cookies[ri] = NULL;
+ xr->xr_ep = 0;
+ xr->xr_cs ^= 1;
+ ri = xr->xr_ep;
+ cs = xr->xr_cs;
} else {
- control &= ~XHCI_TRB_3_CYCLE_BIT;
+ parameter = trbs[i].trb_0;
+ status = trbs[i].trb_2;
+ control = trbs[i].trb_3;
+
+ xr->xr_cookies[ri] = cookie;
+ ri++;
+ i++;
}
-
- xhci_trb_put(&xr->xr_trb[ri], parameter, status, control);
- usb_syncmem(&xr->xr_dma, XHCI_TRB_SIZE * ri, XHCI_TRB_SIZE * 1,
- BUS_DMASYNC_PREWRITE);
- xr->xr_cookies[ri] = cookie;
- ri++;
+ /*
+ * If this is a first TRB, mark it invalid to prevent
+ * xHC from running it immediately.
+ */
+ if (oldri == firstep) {
+ if (oldcs) {
+ control &= ~XHCI_TRB_3_CYCLE_BIT;
+ } else {
+ control |= XHCI_TRB_3_CYCLE_BIT;
+ }
+ } else {
+ if (oldcs) {
+ control |= XHCI_TRB_3_CYCLE_BIT;
+ } else {
+ control &= ~XHCI_TRB_3_CYCLE_BIT;
+ }
+ }
+ xhci_trb_put(&xr->xr_trb[oldri], parameter, status, control);
+ usb_syncmem(&xr->xr_dma, XHCI_TRB_SIZE * oldri,
+ XHCI_TRB_SIZE * 1, BUS_DMASYNC_PREWRITE);
}
- /* Write the first TRB last */
- i = 0;
- parameter = trbs[i].trb_0;
- status = trbs[i].trb_2;
- control = trbs[i].trb_3;
-
- if (xr->xr_cs) {
- control |= XHCI_TRB_3_CYCLE_BIT;
+ /* Now invert cycle bit of first TRB */
+ if (firstcs) {
+ xr->xr_trb[firstep].trb_3 |= htole32(XHCI_TRB_3_CYCLE_BIT);
} else {
- control &= ~XHCI_TRB_3_CYCLE_BIT;
+ xr->xr_trb[firstep].trb_3 &= ~htole32(XHCI_TRB_3_CYCLE_BIT);
}
-
- xhci_trb_put(&xr->xr_trb[xr->xr_ep], parameter, status, control);
- usb_syncmem(&xr->xr_dma, XHCI_TRB_SIZE * xr->xr_ep, XHCI_TRB_SIZE * 1,
- BUS_DMASYNC_PREWRITE);
- xr->xr_cookies[xr->xr_ep] = cookie;
+ usb_syncmem(&xr->xr_dma, XHCI_TRB_SIZE * firstep,
+ XHCI_TRB_SIZE * 1, BUS_DMASYNC_PREWRITE);
xr->xr_ep = ri;
xr->xr_cs = cs;
Home |
Main Index |
Thread Index |
Old Index