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
|