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)