Changeset 51c1d500 in mainline for uspace/drv/bus/usb/xhci/hc.c


Ignore:
Timestamp:
2018-01-20T17:16:33Z (7 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6271a34
Parents:
abb5d08
Message:

xhci: move HC semantics from endpoint/device to hc module

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/xhci/hc.c

    rabb5d08 r51c1d500  
    703703}
    704704
     705unsigned 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
    705711/**
    706712 * Ring a xHC Doorbell. Implements section 4.7.
     
    715721
    716722/**
     723 * Return an index to device context.
     724 */
     725static 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
     732void 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/**
    717742 * Issue an Enable Slot command. Allocate memory for the slot and fill the
    718743 * DCBAA with the newly created slot.
     
    772797
    773798/**
    774  * Fill a slot context that is part of an Input Context with appropriate
    775  * 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, to
    788          *       issue the address device command. It is OK, because these
    789          *       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 yet
    796         }
    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 maximum
    806         XHCI_SLOT_CTX_ENTRIES_SET(*ctx, 31);
    807 }
    808 
    809 /**
    810799 * Prepare an empty Endpoint Input Context inside a dma buffer.
    811800 */
     
    832821 *
    833822 * @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 */
     824int hc_address_device(xhci_device_t *dev)
    837825{
    838826        int err = ENOMEM;
    839827        xhci_hc_t * const hc = bus_to_hc(dev->base.bus);
     828        xhci_endpoint_t *ep0 = xhci_endpoint_get(dev->base.endpoints[0]);
    840829
    841830        /* Although we have the precise PSIV value on devices of tier 1,
     
    854843        /* Copy endpoint 0 context and set A1 flag. */
    855844        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);
    857846        xhci_setup_endpoint_context(ep0, ep_ctx);
     847
    858848        /* Address device needs Ctx entries set to 1 only */
    859849        xhci_slot_ctx_t *slot_ctx = XHCI_GET_SLOT_CTX(XHCI_GET_DEVICE_CTX(ictx, hc), hc);
     
    909899 * @param ep_ctx Endpoint context of the endpoint
    910900 */
    911 int hc_add_endpoint(xhci_device_t *dev, uint8_t ep_idx, xhci_ep_ctx_t *ep_ctx)
    912 {
     901int 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
    913906        /* Issue configure endpoint command (sec 4.3.5). */
    914907        dma_buffer_t ictx_dma_buf;
     
    920913
    921914        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);
    926919
    927920        return xhci_cmd_sync_inline(hc, CONFIGURE_ENDPOINT, .slot_id = dev->slot_id, .input_ctx = ictx_dma_buf);
     
    934927 * @param ep_idx Endpoint DCI in question
    935928 */
    936 int hc_drop_endpoint(xhci_device_t *dev, uint8_t ep_idx)
    937 {
     929int 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
    938934        /* Issue configure endpoint command (sec 4.3.5). */
    939935        dma_buffer_t ictx_dma_buf;
     
    944940        xhci_hc_t * const hc = bus_to_hc(dev->base.bus);
    945941        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);
    947943
    948944        return xhci_cmd_sync_inline(hc, CONFIGURE_ENDPOINT, .slot_id = dev->slot_id, .input_ctx = ictx_dma_buf);
     
    957953 * @param ep_ctx Endpoint context of the endpoint
    958954 */
    959 int hc_update_endpoint(xhci_device_t *dev, uint8_t ep_idx, xhci_ep_ctx_t *ep_ctx)
    960 {
     955int 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
    961960        dma_buffer_t ictx_dma_buf;
    962961        xhci_hc_t * const hc = bus_to_hc(dev->base.bus);
     
    969968        memset(ictx, 0, XHCI_INPUT_CTX_SIZE(hc));
    970969
    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);
    974973
    975974        return xhci_cmd_sync_inline(hc, EVALUATE_CONTEXT, .slot_id = dev->slot_id, .input_ctx = ictx_dma_buf);
     
    982981 * @param ep_idx Endpoint DCI in question
    983982 */
    984 int hc_stop_endpoint(xhci_device_t *dev, uint8_t ep_idx)
    985 {
     983int 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);
    986987        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);
    988989}
    989990
     
    994995 * @param ep_idx Endpoint DCI in question
    995996 */
    996 int hc_reset_endpoint(xhci_device_t *dev, uint8_t ep_idx)
    997 {
     997int 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);
    9981001        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 */
     1010int 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                        );
    10001026}
    10011027
Note: See TracChangeset for help on using the changeset viewer.