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>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/usb/hcd/xhci/xhci_usba.c
          +++ new/usr/src/uts/common/io/usb/hcd/xhci/xhci_usba.c
↓ open down ↓ 2 lines elided ↑ open up ↑
   3    3   * Common Development and Distribution License ("CDDL"), version 1.0.
   4    4   * You may only use this file in accordance with the terms of version
   5    5   * 1.0 of the CDDL.
   6    6   *
   7    7   * A full copy of the text of the CDDL should have accompanied this
   8    8   * source.  A copy of the CDDL is also available via the Internet at
   9    9   * http://www.illumos.org/license/CDDL.
  10   10   */
  11   11  
  12   12  /*
  13      - * Copyright 2016 Joyent, Inc.
       13 + * Copyright (c) 2018, Joyent, Inc.
  14   14   */
  15   15  
  16   16  /*
  17   17   * illumos USB framework endpoints and functions for xHCI.
  18   18   *
  19   19   * Please see the big theory statement in xhci.c for more information.
  20   20   */
  21   21  
  22   22  #include <sys/usb/hcd/xhci/xhci.h>
  23   23  #include <sys/sysmacros.h>
↓ open down ↓ 141 lines elided ↑ open up ↑
 165  165                          xhci_fm_runtime_reset(xhcip);
 166  166                  }
 167  167                  return (USB_HC_HARDWARE_ERROR);
 168  168          }
 169  169          xep = xd->xd_endpoints[epid];
 170  170  
 171  171          mutex_enter(&xd->xd_imtx);
 172  172          mutex_exit(&xhcip->xhci_lock);
 173  173  
 174  174          /*
 175      -         * Update the slot and input context for this endpoint.
      175 +         * Update the slot and input context for this endpoint. We make sure to
      176 +         * always set the slot as having changed in the context field as the
      177 +         * specification suggests we should and some hardware requires it.
 176  178           */
 177  179          xd->xd_input->xic_drop_flags = LE_32(0);
 178      -        xd->xd_input->xic_add_flags = LE_32(XHCI_INCTX_MASK_DCI(epid + 1));
      180 +        xd->xd_input->xic_add_flags = LE_32(XHCI_INCTX_MASK_DCI(0) |
      181 +            XHCI_INCTX_MASK_DCI(epid + 1));
 179  182  
 180  183          if (epid + 1 > XHCI_SCTX_GET_DCI(LE_32(xd->xd_slotin->xsc_info))) {
 181  184                  uint32_t info;
 182  185  
 183  186                  info = xd->xd_slotin->xsc_info;
 184  187                  info &= ~XHCI_SCTX_DCI_MASK;
 185  188                  info |= XHCI_SCTX_SET_DCI(epid + 1);
 186  189                  xd->xd_slotin->xsc_info = info;
 187  190          }
 188  191  
↓ open down ↓ 275 lines elided ↑ open up ↑
 464  467  
 465  468          /*
 466  469           * We need to clean up the endpoint. So the first thing we need to do is
 467  470           * stop it with a configure endpoint command. Once it's stopped, we can
 468  471           * free all associated resources.
 469  472           */
 470  473          mutex_enter(&xd->xd_imtx);
 471  474  
 472  475          /*
 473  476           * Potentially update the slot input context about the current max
 474      -         * endpoint. While we don't update the slot context with this,
 475      -         * surrounding code expects it to be updated to be consistent.
      477 +         * endpoint. Make sure to set that the slot context is being updated
      478 +         * here as it may be changing and some hardware requires it.
 476  479           */
 477  480          xd->xd_input->xic_drop_flags = LE_32(XHCI_INCTX_MASK_DCI(epid + 1));
 478      -        xd->xd_input->xic_add_flags = LE_32(0);
      481 +        xd->xd_input->xic_add_flags = LE_32(XHCI_INCTX_MASK_DCI(0));
 479  482          for (i = XHCI_NUM_ENDPOINTS - 1; i >= 0; i--) {
 480  483                  if (xd->xd_endpoints[i] != NULL &&
 481  484                      xd->xd_endpoints[i] != xep)
 482  485                          break;
 483  486          }
 484  487          info = xd->xd_slotin->xsc_info;
 485  488          info &= ~XHCI_SCTX_DCI_MASK;
 486  489          info |= XHCI_SCTX_SET_DCI(i + 1);
 487  490          xd->xd_slotin->xsc_info = info;
 488  491  
↓ open down ↓ 302 lines elided ↑ open up ↑
 791  794              XHCI_TRB_TYPE_SETUP);
 792  795  
 793  796          if (ucrp->ctrl_wLength > 0)
 794  797                  xhci_transfer_trb_fill_data(xep, xt, 1, datain);
 795  798  
 796  799          xt->xt_trbs[xt->xt_ntrbs - 1].trb_addr = 0;
 797  800          xt->xt_trbs[xt->xt_ntrbs - 1].trb_status = LE_32(XHCI_TRB_INTR(0));
 798  801          xt->xt_trbs[xt->xt_ntrbs - 1].trb_flags = LE_32(XHCI_TRB_TYPE_STATUS |
 799  802              XHCI_TRB_IOC | statusdir);
 800  803  
      804 +
 801  805          mutex_enter(&xhcip->xhci_lock);
 802  806  
 803  807          /*
 804  808           * Schedule the transfer, allocating resources in the process.
 805  809           */
 806  810          if (xhci_endpoint_schedule(xhcip, xd, xep, xt, B_TRUE) != 0) {
 807  811                  xhci_transfer_free(xhcip, xt);
 808  812                  mutex_exit(&xhcip->xhci_lock);
 809  813                  return (USB_NO_RESOURCES);
 810  814          }
↓ open down ↓ 112 lines elided ↑ open up ↑
 923  927          for (i = 0; i < usrp->isoc_pkts_count; i++) {
 924  928                  int flags;
 925  929                  uint_t tbc, tlbpc;
 926  930  
 927  931                  ushort_t len = usrp->isoc_pkt_descr[i].isoc_pkt_length;
 928  932                  xhci_trb_t *trb = &xt->xt_trbs[i];
 929  933  
 930  934                  trb->trb_addr = LE_64(buf);
 931  935  
 932  936                  /*
 933      -                 * Beacuse we know that a single frame can have all of its data
 934      -                 * in a single instance, we know that we don't neeed to do
      937 +                 * Because we know that a single frame can have all of its data
      938 +                 * in a single instance, we know that we don't need to do
 935  939                   * anything special here.
 936  940                   */
 937  941                  trb->trb_status = LE_32(XHCI_TRB_LEN(len) | XHCI_TRB_TDREM(0) |
 938  942                      XHCI_TRB_INTR(0));
 939  943  
 940  944                  /*
 941  945                   * Always enable SIA to start the frame ASAP. We also always
 942  946                   * enable an interrupt on a short packet. If this is the last
 943      -                 * trb, then we will set IOC.
      947 +                 * trb, then we will set IOC. Each TRB created here is really
      948 +                 * its own TD. However, we only set an interrupt on the last
      949 +                 * entry to better deal with scheduling.
 944  950                   */
 945  951                  flags = XHCI_TRB_SIA | XHCI_TRB_ISP | XHCI_TRB_SET_FRAME(0);
 946  952                  flags |= XHCI_TRB_TYPE_ISOCH;
 947  953  
 948  954                  if (i + 1 == usrp->isoc_pkts_count)
 949  955                          flags |= XHCI_TRB_IOC;
 950  956  
 951  957                  /*
 952  958                   * Now we need to calculate the TBC and the TLBPC.
 953  959                   */
↓ open down ↓ 1036 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX