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>
   1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2016 Joyent, Inc.
  14  */
  15 
  16 /*
  17  * illumos USB framework endpoints and functions for xHCI.
  18  *
  19  * Please see the big theory statement in xhci.c for more information.
  20  */
  21 
  22 #include <sys/usb/hcd/xhci/xhci.h>
  23 #include <sys/sysmacros.h>
  24 #include <sys/strsun.h>
  25 #include <sys/strsubr.h>
  26 
  27 static xhci_t *
  28 xhci_hcdi_get_xhcip_from_dev(usba_device_t *ud)
  29 {
  30         dev_info_t *dip = ud->usb_root_hub_dip;
  31         xhci_t *xhcip = ddi_get_soft_state(xhci_soft_state,
  32             ddi_get_instance(dip));
  33         VERIFY(xhcip != NULL);


 155          */
 156         ret = xhci_endpoint_init(xhcip, xd, ph);
 157         if (ret != 0) {
 158                 mutex_exit(&xhcip->xhci_lock);
 159                 kmem_free(pipe, sizeof (xhci_pipe_t));
 160                 if (ret == EIO) {
 161                         xhci_error(xhcip, "failed to initialize endpoint %d "
 162                             "on device slot %d and port %d: encountered fatal "
 163                             "FM error, resetting device", epid, xd->xd_slot,
 164                             xd->xd_port);
 165                         xhci_fm_runtime_reset(xhcip);
 166                 }
 167                 return (USB_HC_HARDWARE_ERROR);
 168         }
 169         xep = xd->xd_endpoints[epid];
 170 
 171         mutex_enter(&xd->xd_imtx);
 172         mutex_exit(&xhcip->xhci_lock);
 173 
 174         /*
 175          * Update the slot and input context for this endpoint.


 176          */
 177         xd->xd_input->xic_drop_flags = LE_32(0);
 178         xd->xd_input->xic_add_flags = LE_32(XHCI_INCTX_MASK_DCI(epid + 1));

 179 
 180         if (epid + 1 > XHCI_SCTX_GET_DCI(LE_32(xd->xd_slotin->xsc_info))) {
 181                 uint32_t info;
 182 
 183                 info = xd->xd_slotin->xsc_info;
 184                 info &= ~XHCI_SCTX_DCI_MASK;
 185                 info |= XHCI_SCTX_SET_DCI(epid + 1);
 186                 xd->xd_slotin->xsc_info = info;
 187         }
 188 
 189         XHCI_DMA_SYNC(xd->xd_ictx, DDI_DMA_SYNC_FORDEV);
 190         if (xhci_check_dma_handle(xhcip, &xd->xd_ictx) != DDI_FM_OK) {
 191                 mutex_exit(&xd->xd_imtx);
 192                 xhci_endpoint_fini(xd, epid);
 193                 kmem_free(pipe, sizeof (xhci_pipe_t));
 194                 xhci_error(xhcip, "failed to open pipe on endpoint %d of "
 195                     "device with slot %d and port %d: encountered fatal FM "
 196                     "error syncing device input context, resetting device",
 197                     epid, xd->xd_slot, xd->xd_port);
 198                 xhci_fm_runtime_reset(xhcip);


 454                     "port %d, endpoint: %d, but no endpoint structure",
 455                     xd->xd_slot, xd->xd_port, epid);
 456                 return (USB_FAILURE);
 457         }
 458         xep = xd->xd_endpoints[epid];
 459 
 460         if (xp->xp_ep != NULL && xp->xp_ep->xep_num == XHCI_DEFAULT_ENDPOINT) {
 461                 xep->xep_pipe = NULL;
 462                 goto remove;
 463         }
 464 
 465         /*
 466          * We need to clean up the endpoint. So the first thing we need to do is
 467          * stop it with a configure endpoint command. Once it's stopped, we can
 468          * free all associated resources.
 469          */
 470         mutex_enter(&xd->xd_imtx);
 471 
 472         /*
 473          * 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.
 476          */
 477         xd->xd_input->xic_drop_flags = LE_32(XHCI_INCTX_MASK_DCI(epid + 1));
 478         xd->xd_input->xic_add_flags = LE_32(0);
 479         for (i = XHCI_NUM_ENDPOINTS - 1; i >= 0; i--) {
 480                 if (xd->xd_endpoints[i] != NULL &&
 481                     xd->xd_endpoints[i] != xep)
 482                         break;
 483         }
 484         info = xd->xd_slotin->xsc_info;
 485         info &= ~XHCI_SCTX_DCI_MASK;
 486         info |= XHCI_SCTX_SET_DCI(i + 1);
 487         xd->xd_slotin->xsc_info = info;
 488 
 489         /*
 490          * Also zero out our context for this endpoint. Note that we don't
 491          * bother with syncing DMA memory here as it's not required to be synced
 492          * for this operation.
 493          */
 494         bzero(xd->xd_endin[xep->xep_num], sizeof (xhci_endpoint_context_t));
 495 
 496         /*
 497          * Stop the device and kill our timeout. Note, it is safe to hold the
 498          * device's input mutex across the untimeout, this lock should never be


 781 
 782         /*
 783          * We always fill in the required setup and status TRBs ourselves;
 784          * however, to minimize our knowledge about how the data has been split
 785          * across multiple DMA cookies in an SGL, we leave that to the transfer
 786          * logic to fill in.
 787          */
 788         xt->xt_trbs[0].trb_addr = xhci_hcdi_ctrl_req_to_trb(ucrp);
 789         xt->xt_trbs[0].trb_status = LE_32(XHCI_TRB_LEN(8) | XHCI_TRB_INTR(0));
 790         xt->xt_trbs[0].trb_flags = LE_32(trt | XHCI_TRB_IDT |
 791             XHCI_TRB_TYPE_SETUP);
 792 
 793         if (ucrp->ctrl_wLength > 0)
 794                 xhci_transfer_trb_fill_data(xep, xt, 1, datain);
 795 
 796         xt->xt_trbs[xt->xt_ntrbs - 1].trb_addr = 0;
 797         xt->xt_trbs[xt->xt_ntrbs - 1].trb_status = LE_32(XHCI_TRB_INTR(0));
 798         xt->xt_trbs[xt->xt_ntrbs - 1].trb_flags = LE_32(XHCI_TRB_TYPE_STATUS |
 799             XHCI_TRB_IOC | statusdir);
 800 

 801         mutex_enter(&xhcip->xhci_lock);
 802 
 803         /*
 804          * Schedule the transfer, allocating resources in the process.
 805          */
 806         if (xhci_endpoint_schedule(xhcip, xd, xep, xt, B_TRUE) != 0) {
 807                 xhci_transfer_free(xhcip, xt);
 808                 mutex_exit(&xhcip->xhci_lock);
 809                 return (USB_NO_RESOURCES);
 810         }
 811 
 812         mutex_exit(&xhcip->xhci_lock);
 813 
 814         return (USB_SUCCESS);
 815 }
 816 
 817 /*
 818  * This request is trying to get the upper bound on the amount of data we're
 819  * willing transfer in one go. Note that this amount can be broken down into
 820  * multiple SGL entries, this interface doesn't particularly care about that.


 913 }
 914 
 915 static void
 916 xhci_hcdi_isoc_transfer_fill(xhci_device_t *xd, xhci_endpoint_t *xep,
 917     xhci_transfer_t *xt, usb_isoc_req_t *usrp)
 918 {
 919         int i;
 920         uintptr_t buf;
 921 
 922         buf = xt->xt_buffer.xdb_cookies[0].dmac_laddress;
 923         for (i = 0; i < usrp->isoc_pkts_count; i++) {
 924                 int flags;
 925                 uint_t tbc, tlbpc;
 926 
 927                 ushort_t len = usrp->isoc_pkt_descr[i].isoc_pkt_length;
 928                 xhci_trb_t *trb = &xt->xt_trbs[i];
 929 
 930                 trb->trb_addr = LE_64(buf);
 931 
 932                 /*
 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
 935                  * anything special here.
 936                  */
 937                 trb->trb_status = LE_32(XHCI_TRB_LEN(len) | XHCI_TRB_TDREM(0) |
 938                     XHCI_TRB_INTR(0));
 939 
 940                 /*
 941                  * Always enable SIA to start the frame ASAP. We also always
 942                  * enable an interrupt on a short packet. If this is the last
 943                  * trb, then we will set IOC.


 944                  */
 945                 flags = XHCI_TRB_SIA | XHCI_TRB_ISP | XHCI_TRB_SET_FRAME(0);
 946                 flags |= XHCI_TRB_TYPE_ISOCH;
 947 
 948                 if (i + 1 == usrp->isoc_pkts_count)
 949                         flags |= XHCI_TRB_IOC;
 950 
 951                 /*
 952                  * Now we need to calculate the TBC and the TLBPC.
 953                  */
 954                 xhci_transfer_calculate_isoc(xd, xep, len, &tbc, &tlbpc);
 955                 flags |= XHCI_TRB_SET_TBC(tbc);
 956                 flags |= XHCI_TRB_SET_TLBPC(tlbpc);
 957 
 958                 trb->trb_flags = LE_32(flags);
 959                 buf += len;
 960 
 961                 /*
 962                  * Go through and copy the required data to our local copy of
 963                  * the isoc descriptor. By default, we assume that all data will


   1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright (c) 2018, Joyent, Inc.
  14  */
  15 
  16 /*
  17  * illumos USB framework endpoints and functions for xHCI.
  18  *
  19  * Please see the big theory statement in xhci.c for more information.
  20  */
  21 
  22 #include <sys/usb/hcd/xhci/xhci.h>
  23 #include <sys/sysmacros.h>
  24 #include <sys/strsun.h>
  25 #include <sys/strsubr.h>
  26 
  27 static xhci_t *
  28 xhci_hcdi_get_xhcip_from_dev(usba_device_t *ud)
  29 {
  30         dev_info_t *dip = ud->usb_root_hub_dip;
  31         xhci_t *xhcip = ddi_get_soft_state(xhci_soft_state,
  32             ddi_get_instance(dip));
  33         VERIFY(xhcip != NULL);


 155          */
 156         ret = xhci_endpoint_init(xhcip, xd, ph);
 157         if (ret != 0) {
 158                 mutex_exit(&xhcip->xhci_lock);
 159                 kmem_free(pipe, sizeof (xhci_pipe_t));
 160                 if (ret == EIO) {
 161                         xhci_error(xhcip, "failed to initialize endpoint %d "
 162                             "on device slot %d and port %d: encountered fatal "
 163                             "FM error, resetting device", epid, xd->xd_slot,
 164                             xd->xd_port);
 165                         xhci_fm_runtime_reset(xhcip);
 166                 }
 167                 return (USB_HC_HARDWARE_ERROR);
 168         }
 169         xep = xd->xd_endpoints[epid];
 170 
 171         mutex_enter(&xd->xd_imtx);
 172         mutex_exit(&xhcip->xhci_lock);
 173 
 174         /*
 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.
 178          */
 179         xd->xd_input->xic_drop_flags = LE_32(0);
 180         xd->xd_input->xic_add_flags = LE_32(XHCI_INCTX_MASK_DCI(0) |
 181             XHCI_INCTX_MASK_DCI(epid + 1));
 182 
 183         if (epid + 1 > XHCI_SCTX_GET_DCI(LE_32(xd->xd_slotin->xsc_info))) {
 184                 uint32_t info;
 185 
 186                 info = xd->xd_slotin->xsc_info;
 187                 info &= ~XHCI_SCTX_DCI_MASK;
 188                 info |= XHCI_SCTX_SET_DCI(epid + 1);
 189                 xd->xd_slotin->xsc_info = info;
 190         }
 191 
 192         XHCI_DMA_SYNC(xd->xd_ictx, DDI_DMA_SYNC_FORDEV);
 193         if (xhci_check_dma_handle(xhcip, &xd->xd_ictx) != DDI_FM_OK) {
 194                 mutex_exit(&xd->xd_imtx);
 195                 xhci_endpoint_fini(xd, epid);
 196                 kmem_free(pipe, sizeof (xhci_pipe_t));
 197                 xhci_error(xhcip, "failed to open pipe on endpoint %d of "
 198                     "device with slot %d and port %d: encountered fatal FM "
 199                     "error syncing device input context, resetting device",
 200                     epid, xd->xd_slot, xd->xd_port);
 201                 xhci_fm_runtime_reset(xhcip);


 457                     "port %d, endpoint: %d, but no endpoint structure",
 458                     xd->xd_slot, xd->xd_port, epid);
 459                 return (USB_FAILURE);
 460         }
 461         xep = xd->xd_endpoints[epid];
 462 
 463         if (xp->xp_ep != NULL && xp->xp_ep->xep_num == XHCI_DEFAULT_ENDPOINT) {
 464                 xep->xep_pipe = NULL;
 465                 goto remove;
 466         }
 467 
 468         /*
 469          * We need to clean up the endpoint. So the first thing we need to do is
 470          * stop it with a configure endpoint command. Once it's stopped, we can
 471          * free all associated resources.
 472          */
 473         mutex_enter(&xd->xd_imtx);
 474 
 475         /*
 476          * Potentially update the slot input context about the current max
 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.
 479          */
 480         xd->xd_input->xic_drop_flags = LE_32(XHCI_INCTX_MASK_DCI(epid + 1));
 481         xd->xd_input->xic_add_flags = LE_32(XHCI_INCTX_MASK_DCI(0));
 482         for (i = XHCI_NUM_ENDPOINTS - 1; i >= 0; i--) {
 483                 if (xd->xd_endpoints[i] != NULL &&
 484                     xd->xd_endpoints[i] != xep)
 485                         break;
 486         }
 487         info = xd->xd_slotin->xsc_info;
 488         info &= ~XHCI_SCTX_DCI_MASK;
 489         info |= XHCI_SCTX_SET_DCI(i + 1);
 490         xd->xd_slotin->xsc_info = info;
 491 
 492         /*
 493          * Also zero out our context for this endpoint. Note that we don't
 494          * bother with syncing DMA memory here as it's not required to be synced
 495          * for this operation.
 496          */
 497         bzero(xd->xd_endin[xep->xep_num], sizeof (xhci_endpoint_context_t));
 498 
 499         /*
 500          * Stop the device and kill our timeout. Note, it is safe to hold the
 501          * device's input mutex across the untimeout, this lock should never be


 784 
 785         /*
 786          * We always fill in the required setup and status TRBs ourselves;
 787          * however, to minimize our knowledge about how the data has been split
 788          * across multiple DMA cookies in an SGL, we leave that to the transfer
 789          * logic to fill in.
 790          */
 791         xt->xt_trbs[0].trb_addr = xhci_hcdi_ctrl_req_to_trb(ucrp);
 792         xt->xt_trbs[0].trb_status = LE_32(XHCI_TRB_LEN(8) | XHCI_TRB_INTR(0));
 793         xt->xt_trbs[0].trb_flags = LE_32(trt | XHCI_TRB_IDT |
 794             XHCI_TRB_TYPE_SETUP);
 795 
 796         if (ucrp->ctrl_wLength > 0)
 797                 xhci_transfer_trb_fill_data(xep, xt, 1, datain);
 798 
 799         xt->xt_trbs[xt->xt_ntrbs - 1].trb_addr = 0;
 800         xt->xt_trbs[xt->xt_ntrbs - 1].trb_status = LE_32(XHCI_TRB_INTR(0));
 801         xt->xt_trbs[xt->xt_ntrbs - 1].trb_flags = LE_32(XHCI_TRB_TYPE_STATUS |
 802             XHCI_TRB_IOC | statusdir);
 803 
 804 
 805         mutex_enter(&xhcip->xhci_lock);
 806 
 807         /*
 808          * Schedule the transfer, allocating resources in the process.
 809          */
 810         if (xhci_endpoint_schedule(xhcip, xd, xep, xt, B_TRUE) != 0) {
 811                 xhci_transfer_free(xhcip, xt);
 812                 mutex_exit(&xhcip->xhci_lock);
 813                 return (USB_NO_RESOURCES);
 814         }
 815 
 816         mutex_exit(&xhcip->xhci_lock);
 817 
 818         return (USB_SUCCESS);
 819 }
 820 
 821 /*
 822  * This request is trying to get the upper bound on the amount of data we're
 823  * willing transfer in one go. Note that this amount can be broken down into
 824  * multiple SGL entries, this interface doesn't particularly care about that.


 917 }
 918 
 919 static void
 920 xhci_hcdi_isoc_transfer_fill(xhci_device_t *xd, xhci_endpoint_t *xep,
 921     xhci_transfer_t *xt, usb_isoc_req_t *usrp)
 922 {
 923         int i;
 924         uintptr_t buf;
 925 
 926         buf = xt->xt_buffer.xdb_cookies[0].dmac_laddress;
 927         for (i = 0; i < usrp->isoc_pkts_count; i++) {
 928                 int flags;
 929                 uint_t tbc, tlbpc;
 930 
 931                 ushort_t len = usrp->isoc_pkt_descr[i].isoc_pkt_length;
 932                 xhci_trb_t *trb = &xt->xt_trbs[i];
 933 
 934                 trb->trb_addr = LE_64(buf);
 935 
 936                 /*
 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
 939                  * anything special here.
 940                  */
 941                 trb->trb_status = LE_32(XHCI_TRB_LEN(len) | XHCI_TRB_TDREM(0) |
 942                     XHCI_TRB_INTR(0));
 943 
 944                 /*
 945                  * Always enable SIA to start the frame ASAP. We also always
 946                  * enable an interrupt on a short packet. If this is the last
 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.
 950                  */
 951                 flags = XHCI_TRB_SIA | XHCI_TRB_ISP | XHCI_TRB_SET_FRAME(0);
 952                 flags |= XHCI_TRB_TYPE_ISOCH;
 953 
 954                 if (i + 1 == usrp->isoc_pkts_count)
 955                         flags |= XHCI_TRB_IOC;
 956 
 957                 /*
 958                  * Now we need to calculate the TBC and the TLBPC.
 959                  */
 960                 xhci_transfer_calculate_isoc(xd, xep, len, &tbc, &tlbpc);
 961                 flags |= XHCI_TRB_SET_TBC(tbc);
 962                 flags |= XHCI_TRB_SET_TLBPC(tlbpc);
 963 
 964                 trb->trb_flags = LE_32(flags);
 965                 buf += len;
 966 
 967                 /*
 968                  * Go through and copy the required data to our local copy of
 969                  * the isoc descriptor. By default, we assume that all data will