Print this page
MFV: illumos-gate@2aba3acda67326648fd60aaf2bfb4e18ee8c04ed
9816 Multi-TRB xhci transfers should use event data
9817 xhci needs to always set slot context
8550 increase xhci bulk transfer sgl count
9818 xhci_transfer_get_tdsize can return values that are too large
Reviewed by: Alex Wilson <alex.wilson@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Approved by: Joshua M. Clulow <josh@sysmgr.org>
Author: Robert Mustacchi <rm@joyent.com>

*** 8,18 **** * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* ! * Copyright 2016 Joyent, Inc. */ /* * illumos USB framework endpoints and functions for xHCI. * --- 8,18 ---- * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* ! * Copyright (c) 2018, Joyent, Inc. */ /* * illumos USB framework endpoints and functions for xHCI. *
*** 170,183 **** mutex_enter(&xd->xd_imtx); mutex_exit(&xhcip->xhci_lock); /* ! * Update the slot and input context for this endpoint. */ xd->xd_input->xic_drop_flags = LE_32(0); ! xd->xd_input->xic_add_flags = LE_32(XHCI_INCTX_MASK_DCI(epid + 1)); if (epid + 1 > XHCI_SCTX_GET_DCI(LE_32(xd->xd_slotin->xsc_info))) { uint32_t info; info = xd->xd_slotin->xsc_info; --- 170,186 ---- mutex_enter(&xd->xd_imtx); mutex_exit(&xhcip->xhci_lock); /* ! * Update the slot and input context for this endpoint. We make sure to ! * always set the slot as having changed in the context field as the ! * specification suggests we should and some hardware requires it. */ xd->xd_input->xic_drop_flags = LE_32(0); ! xd->xd_input->xic_add_flags = LE_32(XHCI_INCTX_MASK_DCI(0) | ! XHCI_INCTX_MASK_DCI(epid + 1)); if (epid + 1 > XHCI_SCTX_GET_DCI(LE_32(xd->xd_slotin->xsc_info))) { uint32_t info; info = xd->xd_slotin->xsc_info;
*** 469,483 **** */ mutex_enter(&xd->xd_imtx); /* * Potentially update the slot input context about the current max ! * endpoint. While we don't update the slot context with this, ! * surrounding code expects it to be updated to be consistent. */ xd->xd_input->xic_drop_flags = LE_32(XHCI_INCTX_MASK_DCI(epid + 1)); ! xd->xd_input->xic_add_flags = LE_32(0); for (i = XHCI_NUM_ENDPOINTS - 1; i >= 0; i--) { if (xd->xd_endpoints[i] != NULL && xd->xd_endpoints[i] != xep) break; } --- 472,486 ---- */ mutex_enter(&xd->xd_imtx); /* * Potentially update the slot input context about the current max ! * endpoint. Make sure to set that the slot context is being updated ! * here as it may be changing and some hardware requires it. */ xd->xd_input->xic_drop_flags = LE_32(XHCI_INCTX_MASK_DCI(epid + 1)); ! xd->xd_input->xic_add_flags = LE_32(XHCI_INCTX_MASK_DCI(0)); for (i = XHCI_NUM_ENDPOINTS - 1; i >= 0; i--) { if (xd->xd_endpoints[i] != NULL && xd->xd_endpoints[i] != xep) break; }
*** 796,805 **** --- 799,809 ---- xt->xt_trbs[xt->xt_ntrbs - 1].trb_addr = 0; xt->xt_trbs[xt->xt_ntrbs - 1].trb_status = LE_32(XHCI_TRB_INTR(0)); xt->xt_trbs[xt->xt_ntrbs - 1].trb_flags = LE_32(XHCI_TRB_TYPE_STATUS | XHCI_TRB_IOC | statusdir); + mutex_enter(&xhcip->xhci_lock); /* * Schedule the transfer, allocating resources in the process. */
*** 928,948 **** xhci_trb_t *trb = &xt->xt_trbs[i]; trb->trb_addr = LE_64(buf); /* ! * Beacuse we know that a single frame can have all of its data ! * in a single instance, we know that we don't neeed to do * anything special here. */ trb->trb_status = LE_32(XHCI_TRB_LEN(len) | XHCI_TRB_TDREM(0) | XHCI_TRB_INTR(0)); /* * Always enable SIA to start the frame ASAP. We also always * enable an interrupt on a short packet. If this is the last ! * trb, then we will set IOC. */ flags = XHCI_TRB_SIA | XHCI_TRB_ISP | XHCI_TRB_SET_FRAME(0); flags |= XHCI_TRB_TYPE_ISOCH; if (i + 1 == usrp->isoc_pkts_count) --- 932,954 ---- xhci_trb_t *trb = &xt->xt_trbs[i]; trb->trb_addr = LE_64(buf); /* ! * Because we know that a single frame can have all of its data ! * in a single instance, we know that we don't need to do * anything special here. */ trb->trb_status = LE_32(XHCI_TRB_LEN(len) | XHCI_TRB_TDREM(0) | XHCI_TRB_INTR(0)); /* * Always enable SIA to start the frame ASAP. We also always * enable an interrupt on a short packet. If this is the last ! * trb, then we will set IOC. Each TRB created here is really ! * its own TD. However, we only set an interrupt on the last ! * entry to better deal with scheduling. */ flags = XHCI_TRB_SIA | XHCI_TRB_ISP | XHCI_TRB_SET_FRAME(0); flags |= XHCI_TRB_TYPE_ISOCH; if (i + 1 == usrp->isoc_pkts_count)