Changeset 51c1d500 in mainline for uspace/drv/bus/usb/xhci/hc.c
- Timestamp:
- 2018-01-20T17:16:33Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6271a34
- Parents:
- abb5d08
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/hc.c
rabb5d08 r51c1d500 703 703 } 704 704 705 unsigned hc_speed_to_psiv(usb_speed_t speed) 706 { 707 assert(speed < ARRAY_SIZE(usb_speed_to_psiv)); 708 return usb_speed_to_psiv[speed]; 709 } 710 705 711 /** 706 712 * Ring a xHC Doorbell. Implements section 4.7. … … 715 721 716 722 /** 723 * Return an index to device context. 724 */ 725 static uint8_t endpoint_dci(xhci_endpoint_t *ep) 726 { 727 return (2 * ep->base.endpoint) + 728 (ep->base.transfer_type == USB_TRANSFER_CONTROL 729 || ep->base.direction == USB_DIRECTION_IN); 730 } 731 732 void hc_ring_ep_doorbell(xhci_endpoint_t *ep, uint32_t stream_id) 733 { 734 xhci_device_t * const dev = xhci_ep_to_dev(ep); 735 xhci_hc_t * const hc = bus_to_hc(dev->base.bus); 736 const uint8_t dci = endpoint_dci(ep); 737 const uint32_t target = (stream_id << 16) | (dci & 0x1ff); 738 hc_ring_doorbell(hc, dev->slot_id, target); 739 } 740 741 /** 717 742 * Issue an Enable Slot command. Allocate memory for the slot and fill the 718 743 * DCBAA with the newly created slot. … … 772 797 773 798 /** 774 * Fill a slot context that is part of an Input Context with appropriate775 * values.776 *777 * @param ctx Slot context, zeroed out.778 */779 static void xhci_setup_slot_context(xhci_device_t *dev, xhci_slot_ctx_t *ctx)780 {781 /* Initialize slot_ctx according to section 4.3.3 point 3. */782 XHCI_SLOT_ROOT_HUB_PORT_SET(*ctx, dev->rh_port);783 XHCI_SLOT_ROUTE_STRING_SET(*ctx, dev->route_str);784 XHCI_SLOT_SPEED_SET(*ctx, usb_speed_to_psiv[dev->base.speed]);785 786 /*787 * Note: This function is used even before this flag can be set, to788 * issue the address device command. It is OK, because these789 * flags are not required to be valid for that command.790 */791 if (dev->is_hub) {792 XHCI_SLOT_HUB_SET(*ctx, 1);793 XHCI_SLOT_NUM_PORTS_SET(*ctx, dev->num_ports);794 XHCI_SLOT_TT_THINK_TIME_SET(*ctx, dev->tt_think_time);795 XHCI_SLOT_MTT_SET(*ctx, 0); // MTT not supported yet796 }797 798 /* Setup Transaction Translation. TODO: Test this with HS hub. */799 if (dev->base.tt.dev != NULL) {800 xhci_device_t *hub = xhci_device_get(dev->base.tt.dev);801 XHCI_SLOT_TT_HUB_SLOT_ID_SET(*ctx, hub->slot_id);802 XHCI_SLOT_TT_HUB_PORT_SET(*ctx, dev->base.tt.port);803 }804 805 // As we always allocate space for whole input context, we can set this to maximum806 XHCI_SLOT_CTX_ENTRIES_SET(*ctx, 31);807 }808 809 /**810 799 * Prepare an empty Endpoint Input Context inside a dma buffer. 811 800 */ … … 832 821 * 833 822 * @param dev Device to assing an address (unconfigured yet) 834 * @param ep0 EP0 of device TODO remove, can be fetched from dev 835 */ 836 int hc_address_device(xhci_device_t *dev, xhci_endpoint_t *ep0) 823 */ 824 int hc_address_device(xhci_device_t *dev) 837 825 { 838 826 int err = ENOMEM; 839 827 xhci_hc_t * const hc = bus_to_hc(dev->base.bus); 828 xhci_endpoint_t *ep0 = xhci_endpoint_get(dev->base.endpoints[0]); 840 829 841 830 /* Although we have the precise PSIV value on devices of tier 1, … … 854 843 /* Copy endpoint 0 context and set A1 flag. */ 855 844 XHCI_INPUT_CTRL_CTX_ADD_SET(*XHCI_GET_CTRL_CTX(ictx, hc), 1); 856 xhci_ep_ctx_t *ep_ctx = XHCI_GET_EP_CTX(XHCI_GET_DEVICE_CTX(ictx, hc), hc, 0);845 xhci_ep_ctx_t *ep_ctx = XHCI_GET_EP_CTX(XHCI_GET_DEVICE_CTX(ictx, hc), hc, 1); 857 846 xhci_setup_endpoint_context(ep0, ep_ctx); 847 858 848 /* Address device needs Ctx entries set to 1 only */ 859 849 xhci_slot_ctx_t *slot_ctx = XHCI_GET_SLOT_CTX(XHCI_GET_DEVICE_CTX(ictx, hc), hc); … … 909 899 * @param ep_ctx Endpoint context of the endpoint 910 900 */ 911 int hc_add_endpoint(xhci_device_t *dev, uint8_t ep_idx, xhci_ep_ctx_t *ep_ctx) 912 { 901 int hc_add_endpoint(xhci_endpoint_t *ep) 902 { 903 xhci_device_t * const dev = xhci_ep_to_dev(ep); 904 const unsigned dci = endpoint_dci(ep); 905 913 906 /* Issue configure endpoint command (sec 4.3.5). */ 914 907 dma_buffer_t ictx_dma_buf; … … 920 913 921 914 xhci_hc_t * const hc = bus_to_hc(dev->base.bus); 922 XHCI_INPUT_CTRL_CTX_ADD_SET(*XHCI_GET_CTRL_CTX(ictx, hc), ep_idx + 1); /* Preceded by slot ctx */923 924 xhci_ep_ctx_t * _ep_ctx = XHCI_GET_EP_CTX(XHCI_GET_DEVICE_CTX(ictx, hc), hc, ep_idx);925 memcpy(_ep_ctx, ep_ctx, XHCI_ONE_CTX_SIZE(hc));915 XHCI_INPUT_CTRL_CTX_ADD_SET(*XHCI_GET_CTRL_CTX(ictx, hc), dci); 916 917 xhci_ep_ctx_t *ep_ctx = XHCI_GET_EP_CTX(XHCI_GET_DEVICE_CTX(ictx, hc), hc, dci); 918 xhci_setup_endpoint_context(ep, ep_ctx); 926 919 927 920 return xhci_cmd_sync_inline(hc, CONFIGURE_ENDPOINT, .slot_id = dev->slot_id, .input_ctx = ictx_dma_buf); … … 934 927 * @param ep_idx Endpoint DCI in question 935 928 */ 936 int hc_drop_endpoint(xhci_device_t *dev, uint8_t ep_idx) 937 { 929 int hc_drop_endpoint(xhci_endpoint_t *ep) 930 { 931 xhci_device_t * const dev = xhci_ep_to_dev(ep); 932 const unsigned dci = endpoint_dci(ep); 933 938 934 /* Issue configure endpoint command (sec 4.3.5). */ 939 935 dma_buffer_t ictx_dma_buf; … … 944 940 xhci_hc_t * const hc = bus_to_hc(dev->base.bus); 945 941 xhci_input_ctx_t *ictx = ictx_dma_buf.virt; 946 XHCI_INPUT_CTRL_CTX_DROP_SET(*XHCI_GET_CTRL_CTX(ictx, hc), ep_idx + 1); /* Preceded by slot ctx */942 XHCI_INPUT_CTRL_CTX_DROP_SET(*XHCI_GET_CTRL_CTX(ictx, hc), dci); 947 943 948 944 return xhci_cmd_sync_inline(hc, CONFIGURE_ENDPOINT, .slot_id = dev->slot_id, .input_ctx = ictx_dma_buf); … … 957 953 * @param ep_ctx Endpoint context of the endpoint 958 954 */ 959 int hc_update_endpoint(xhci_device_t *dev, uint8_t ep_idx, xhci_ep_ctx_t *ep_ctx) 960 { 955 int hc_update_endpoint(xhci_endpoint_t *ep) 956 { 957 xhci_device_t * const dev = xhci_ep_to_dev(ep); 958 const unsigned dci = endpoint_dci(ep); 959 961 960 dma_buffer_t ictx_dma_buf; 962 961 xhci_hc_t * const hc = bus_to_hc(dev->base.bus); … … 969 968 memset(ictx, 0, XHCI_INPUT_CTX_SIZE(hc)); 970 969 971 XHCI_INPUT_CTRL_CTX_ADD_SET(*XHCI_GET_CTRL_CTX(ictx, hc), ep_idx + 1);972 xhci_ep_ctx_t * _ep_ctx = XHCI_GET_EP_CTX(XHCI_GET_DEVICE_CTX(ictx, hc), hc, 0);973 memcpy(_ep_ctx, ep_ctx, sizeof(xhci_ep_ctx_t));970 XHCI_INPUT_CTRL_CTX_ADD_SET(*XHCI_GET_CTRL_CTX(ictx, hc), dci); 971 xhci_ep_ctx_t *ep_ctx = XHCI_GET_EP_CTX(XHCI_GET_DEVICE_CTX(ictx, hc), hc, dci); 972 xhci_setup_endpoint_context(ep, ep_ctx); 974 973 975 974 return xhci_cmd_sync_inline(hc, EVALUATE_CONTEXT, .slot_id = dev->slot_id, .input_ctx = ictx_dma_buf); … … 982 981 * @param ep_idx Endpoint DCI in question 983 982 */ 984 int hc_stop_endpoint(xhci_device_t *dev, uint8_t ep_idx) 985 { 983 int hc_stop_endpoint(xhci_endpoint_t *ep) 984 { 985 xhci_device_t * const dev = xhci_ep_to_dev(ep); 986 const unsigned dci = endpoint_dci(ep); 986 987 xhci_hc_t * const hc = bus_to_hc(dev->base.bus); 987 return xhci_cmd_sync_inline(hc, STOP_ENDPOINT, .slot_id = dev->slot_id, .endpoint_id = ep_idx);988 return xhci_cmd_sync_inline(hc, STOP_ENDPOINT, .slot_id = dev->slot_id, .endpoint_id = dci); 988 989 } 989 990 … … 994 995 * @param ep_idx Endpoint DCI in question 995 996 */ 996 int hc_reset_endpoint(xhci_device_t *dev, uint8_t ep_idx) 997 { 997 int hc_reset_endpoint(xhci_endpoint_t *ep) 998 { 999 xhci_device_t * const dev = xhci_ep_to_dev(ep); 1000 const unsigned dci = endpoint_dci(ep); 998 1001 xhci_hc_t * const hc = bus_to_hc(dev->base.bus); 999 return xhci_cmd_sync_inline(hc, RESET_ENDPOINT, .slot_id = dev->slot_id, .endpoint_id = ep_idx); 1002 return xhci_cmd_sync_inline(hc, RESET_ENDPOINT, .slot_id = dev->slot_id, .endpoint_id = dci); 1003 } 1004 1005 /** 1006 * Reset a ring position in both software and hardware. 1007 * 1008 * @param dev The owner of the endpoint 1009 */ 1010 int hc_reset_ring(xhci_endpoint_t *ep, uint32_t stream_id) 1011 { 1012 xhci_device_t * const dev = xhci_ep_to_dev(ep); 1013 const unsigned dci = endpoint_dci(ep); 1014 uintptr_t addr; 1015 1016 xhci_trb_ring_t *ring = xhci_endpoint_get_ring(ep, stream_id); 1017 xhci_trb_ring_reset_dequeue_state(ring, &addr); 1018 1019 xhci_hc_t * const hc = bus_to_hc(endpoint_get_bus(&ep->base)); 1020 return xhci_cmd_sync_inline(hc, SET_TR_DEQUEUE_POINTER, 1021 .slot_id = dev->slot_id, 1022 .endpoint_id = dci, 1023 .stream_id = stream_id, 1024 .dequeue_ptr = addr, 1025 ); 1000 1026 } 1001 1027
Note:
See TracChangeset
for help on using the changeset viewer.