Changeset 51c1d500 in mainline


Ignore:
Timestamp:
2018-01-20T17:16:33Z (6 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

Location:
uspace/drv/bus/usb/xhci
Files:
10 edited

Legend:

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

    rabb5d08 r51c1d500  
    5252#include "bus.h"
    5353#include "endpoint.h"
     54#include "hw_struct/context.h"
    5455
    5556#include "device.h"
     
    8687        dev->base.endpoints[0] = ep0_base;
    8788
    88         xhci_endpoint_t *ep0 = xhci_endpoint_get(ep0_base);
    89 
    9089        /* Address device */
    91         if ((err = hc_address_device(dev, ep0)))
     90        if ((err = hc_address_device(dev)))
    9291                goto err_added;
    9392
     
    127126        ep0->base.max_transfer_size = max_packet_size * ep0->base.packets_per_uframe;
    128127
    129         xhci_ep_ctx_t ep_ctx;
    130         xhci_setup_endpoint_context(ep0, &ep_ctx);
    131 
    132         if ((err = hc_update_endpoint(dev, 0, &ep_ctx)))
     128        if ((err = hc_update_endpoint(ep0)))
    133129                return err;
    134130
     
    306302}
    307303
     304/**
     305 * Fill a slot context that is part of an Input Context with appropriate
     306 * values.
     307 *
     308 * @param ctx Slot context, zeroed out.
     309 */
     310void xhci_setup_slot_context(xhci_device_t *dev, xhci_slot_ctx_t *ctx)
     311{
     312        /* Initialize slot_ctx according to section 4.3.3 point 3. */
     313        XHCI_SLOT_ROOT_HUB_PORT_SET(*ctx, dev->rh_port);
     314        XHCI_SLOT_ROUTE_STRING_SET(*ctx, dev->route_str);
     315        XHCI_SLOT_SPEED_SET(*ctx, hc_speed_to_psiv(dev->base.speed));
     316
     317        /*
     318         * Note: This function is used even before this flag can be set, to
     319         *       issue the address device command. It is OK, because these
     320         *       flags are not required to be valid for that command.
     321         */
     322        if (dev->is_hub) {
     323                XHCI_SLOT_HUB_SET(*ctx, 1);
     324                XHCI_SLOT_NUM_PORTS_SET(*ctx, dev->num_ports);
     325                XHCI_SLOT_TT_THINK_TIME_SET(*ctx, dev->tt_think_time);
     326                XHCI_SLOT_MTT_SET(*ctx, 0); // MTT not supported yet
     327        }
     328
     329        /* Setup Transaction Translation. TODO: Test this with HS hub. */
     330        if (dev->base.tt.dev != NULL) {
     331                xhci_device_t *hub = xhci_device_get(dev->base.tt.dev);
     332                XHCI_SLOT_TT_HUB_SLOT_ID_SET(*ctx, hub->slot_id);
     333                XHCI_SLOT_TT_HUB_PORT_SET(*ctx, dev->base.tt.port);
     334        }
     335
     336        // As we always allocate space for whole input context, we can set this to maximum
     337        XHCI_SLOT_CTX_ENTRIES_SET(*ctx, 31);
     338}
     339
    308340
    309341/**
  • uspace/drv/bus/usb/xhci/device.h

    rabb5d08 r51c1d500  
    3838#include <usb/host/dma_buffer.h>
    3939
     40typedef struct xhci_slot_ctx xhci_slot_ctx_t;
     41
    4042typedef struct xhci_device {
    4143        device_t base;          /**< Inheritance. Keep this first. */
     
    7173void xhci_device_gone(device_t *);
    7274
     75void xhci_setup_slot_context(xhci_device_t *, xhci_slot_ctx_t *);
     76
    7377static inline xhci_device_t * xhci_device_get(device_t *dev)
    7478{
  • uspace/drv/bus/usb/xhci/endpoint.c

    rabb5d08 r51c1d500  
    172172        int err;
    173173        xhci_endpoint_t *ep = xhci_endpoint_get(ep_base);
    174         xhci_device_t *dev = xhci_device_get(ep_base->device);
    175 
    176         xhci_ep_ctx_t ep_ctx;
    177         xhci_setup_endpoint_context(ep, &ep_ctx);
    178 
    179         if ((err = hc_add_endpoint(dev, xhci_endpoint_index(ep), &ep_ctx)))
     174
     175        if ((err = hc_add_endpoint(ep)))
    180176                return err;
    181177
     
    189185{
    190186        xhci_device_t *dev = xhci_device_get(ep->device);
     187        xhci_endpoint_t *xhci_ep = xhci_endpoint_get(ep);
    191188
    192189        usb_transfer_batch_t *batch = NULL;
     
    194191        if (ep->active_batch) {
    195192                if (dev->slot_id) {
    196                         const int err = hc_stop_endpoint(dev, xhci_endpoint_dci(xhci_endpoint_get(ep)));
     193                        const int err = hc_stop_endpoint(xhci_ep);
    197194                        if (err) {
    198195                                usb_log_warning("Failed to stop endpoint %u of device " XHCI_DEV_FMT ": %s",
     
    235232        if (dev->slot_id) {
    236233
    237                 if ((err = hc_drop_endpoint(dev, xhci_endpoint_index(ep)))) {
     234                if ((err = hc_drop_endpoint(ep))) {
    238235                        usb_log_error("Failed to drop endpoint " XHCI_EP_FMT ": %s", XHCI_EP_ARGS(*ep), str_error(err));
    239236                }
     
    318315}
    319316
    320 /** See section 4.5.1 of the xHCI spec.
    321  */
    322 uint8_t xhci_endpoint_dci(xhci_endpoint_t *ep)
    323 {
    324         return (2 * ep->base.endpoint) +
    325                 (ep->base.transfer_type == USB_TRANSFER_CONTROL
    326                  || ep->base.direction == USB_DIRECTION_IN);
    327 }
    328 
    329 /** Return an index to the endpoint array. The indices are assigned as follows:
    330  * 0    EP0 BOTH
    331  * 1    EP1 OUT
    332  * 2    EP1 IN
    333  *
    334  * For control endpoints >0, the IN endpoint index is used.
    335  *
    336  * The index returned must be usually offset by a number of contexts preceding
    337  * the endpoint contexts themselves.
    338  */
    339 uint8_t xhci_endpoint_index(xhci_endpoint_t *ep)
    340 {
    341         return xhci_endpoint_dci(ep) - 1;
     317xhci_trb_ring_t *xhci_endpoint_get_ring(xhci_endpoint_t *ep, uint32_t stream_id)
     318{
     319        if (ep->primary_stream_data_size == 0)
     320                return stream_id == 0 ? &ep->ring : NULL;
     321
     322        xhci_stream_data_t *stream_data = xhci_get_stream_ctx_data(ep, stream_id);
     323        if (stream_data == NULL) {
     324                usb_log_warning("No transfer ring was found for stream %u.", stream_id);
     325                return NULL;
     326        }
     327
     328        return &stream_data->ring;
    342329}
    343330
     
    435422}
    436423
    437 uint8_t xhci_endpoint_get_state(xhci_endpoint_t *ep)
    438 {
    439         assert(ep);
    440 
    441         xhci_device_t *dev = xhci_device_get(ep->base.device);
    442         if (!dev->slot_id)
    443                 return EP_STATE_DISABLED;
    444 
    445         unsigned idx = xhci_endpoint_index(ep);
    446         xhci_device_ctx_t *ctx = dev->dev_ctx.virt;
    447         const xhci_hc_t * hc = bus_to_hc(dev->base.bus);
    448         xhci_ep_ctx_t *ep_ctx = XHCI_GET_EP_CTX(ctx, hc, idx);
    449 
    450         return XHCI_EP_STATE(*ep_ctx);
    451 }
    452 
    453424/**
    454425 * Clear endpoint halt condition by resetting the endpoint and skipping the
    455426 * offending transfer.
    456427 */
    457 int xhci_endpoint_clear_halt(xhci_endpoint_t *ep, unsigned stream_id)
     428int xhci_endpoint_clear_halt(xhci_endpoint_t *ep, uint32_t stream_id)
    458429{
    459430        int err;
    460431
    461         xhci_device_t * const dev = xhci_device_get(ep->base.device);
    462         xhci_bus_t * const bus = bus_to_xhci_bus(dev->base.bus);
    463         xhci_hc_t * const hc = bus->hc;
    464 
    465         const unsigned slot_id = dev->slot_id;
    466         const unsigned dci = xhci_endpoint_dci(ep);
    467 
    468         if ((err = hc_reset_endpoint(dev, dci)))
     432        if ((err = hc_reset_endpoint(ep)))
    469433                return err;
    470434
    471         uintptr_t addr;
    472 
    473         xhci_trb_ring_reset_dequeue_state(&ep->ring, &addr);
    474 
    475         if ((err = xhci_cmd_sync_inline(hc, SET_TR_DEQUEUE_POINTER,
    476                             .slot_id = slot_id,
    477                             .endpoint_id = dci,
    478                             .stream_id = stream_id,
    479                             .dequeue_ptr = addr,
    480                         )))
     435        if ((err = hc_reset_ring(ep, stream_id)))
    481436                return err;
    482437
  • uspace/drv/bus/usb/xhci/endpoint.h

    rabb5d08 r51c1d500  
    113113void xhci_endpoint_destroy(endpoint_t *);
    114114
    115 void xhci_endpoint_free_transfer_ds(xhci_endpoint_t *xhci_ep);
    116 
    117 uint8_t xhci_endpoint_dci(xhci_endpoint_t *);
    118 uint8_t xhci_endpoint_index(xhci_endpoint_t *);
     115void xhci_endpoint_free_transfer_ds(xhci_endpoint_t *);
     116xhci_trb_ring_t *xhci_endpoint_get_ring(xhci_endpoint_t *, uint32_t);
    119117
    120118void xhci_setup_endpoint_context(xhci_endpoint_t *, xhci_ep_ctx_t *);
     
    133131}
    134132
    135 uint8_t xhci_endpoint_get_state(xhci_endpoint_t *ep);
    136 
    137133#endif
    138134
  • 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
  • uspace/drv/bus/usb/xhci/hc.h

    rabb5d08 r51c1d500  
    120120int hc_start(xhci_hc_t *, bool);
    121121void hc_fini(xhci_hc_t *);
     122
    122123void hc_ring_doorbell(xhci_hc_t *, unsigned, unsigned);
     124void hc_ring_ep_doorbell(xhci_endpoint_t *, uint32_t);
     125unsigned hc_speed_to_psiv(usb_speed_t);
    123126
    124127int hc_enable_slot(xhci_device_t *);
    125128int hc_disable_slot(xhci_device_t *);
    126 int hc_address_device(xhci_device_t *, xhci_endpoint_t *);
     129int hc_address_device(xhci_device_t *);
    127130int hc_configure_device(xhci_device_t *);
    128131int hc_deconfigure_device(xhci_device_t *);
    129 int hc_add_endpoint(xhci_device_t *, uint8_t, xhci_ep_ctx_t *);
    130 int hc_drop_endpoint(xhci_device_t *, uint8_t);
    131 int hc_update_endpoint(xhci_device_t *, uint8_t, xhci_ep_ctx_t *);
    132 int hc_stop_endpoint(xhci_device_t *, uint8_t);
    133 int hc_reset_endpoint(xhci_device_t *, uint8_t);
     132int hc_add_endpoint(xhci_endpoint_t *);
     133int hc_drop_endpoint(xhci_endpoint_t *);
     134int hc_update_endpoint(xhci_endpoint_t *);
     135int hc_stop_endpoint(xhci_endpoint_t *);
     136int hc_reset_endpoint(xhci_endpoint_t *);
     137int hc_reset_ring(xhci_endpoint_t *, uint32_t);
    134138
    135139int hc_status(bus_t *, uint32_t *);
  • uspace/drv/bus/usb/xhci/hw_struct/context.h

    rabb5d08 r51c1d500  
    179179#define XHCI_CTX_SIZE_SMALL 32
    180180#define XHCI_ONE_CTX_SIZE(hc) (XHCI_CTX_SIZE_SMALL << hc->csz)
    181 #define XHCI_SLOT_CTX_OFFSET 0
    182 #define XHCI_EP_ARRAY_OFFSET 1
    183 #define XHCI_DEVICE_CTX_SIZE(hc) ((XHCI_EP_ARRAY_OFFSET + XHCI_EP_COUNT) * XHCI_ONE_CTX_SIZE(hc))
     181#define XHCI_DEVICE_CTX_SIZE(hc) ((1 + XHCI_EP_COUNT) * XHCI_ONE_CTX_SIZE(hc))
    184182
    185183/**
    186184 * Device context: section 6.2.1
    187185 */
    188 #define XHCI_GET_SLOT_CTX(dev_ctx, hc) (xhci_slot_ctx_t *)((char*)dev_ctx + XHCI_SLOT_CTX_OFFSET * XHCI_ONE_CTX_SIZE(hc))
    189 #define XHCI_GET_EP_CTX(dev_ctx, hc, dci) (xhci_ep_ctx_t *)((char*)dev_ctx + (dci + XHCI_EP_ARRAY_OFFSET) * XHCI_ONE_CTX_SIZE(hc))
     186#define XHCI_GET_DC_FIELD(dev_ctx, hc, dci) ((char*)dev_ctx + (dci) * XHCI_ONE_CTX_SIZE(hc))
     187#define XHCI_GET_EP_CTX(dev_ctx, hc, dci) ((xhci_ep_ctx_t *)   XHCI_GET_DC_FIELD(dev_ctx, hc, dci))
     188#define XHCI_GET_SLOT_CTX(dev_ctx, hc)    ((xhci_slot_ctx_t *) XHCI_GET_DC_FIELD(dev_ctx, hc, 0))
    190189
    191190/**
  • uspace/drv/bus/usb/xhci/isoch.c

    rabb5d08 r51c1d500  
    347347out:
    348348        if (fed) {
    349                 const uint8_t slot_id = xhci_device_get(ep->base.device)->slot_id;
    350                 const uint8_t target = xhci_endpoint_index(ep) + 1; /* EP Doorbells start at 1 */
    351                 hc_ring_doorbell(hc, slot_id, target);
     349                hc_ring_ep_doorbell(ep, 0);
    352350                /* The ring may be dead. If no event happens until the delay, reset the endpoint. */
    353351                timer_schedule_reset(ep);
     
    436434
    437435        if (fed) {
    438                 const uint8_t slot_id = xhci_device_get(ep->base.device)->slot_id;
    439                 const uint8_t target = xhci_endpoint_index(ep) + 1; /* EP Doorbells start at 1 */
    440                 hc_ring_doorbell(hc, slot_id, target);
     436                hc_ring_ep_doorbell(ep, 0);
    441437                /* The ring may be dead. If no event happens until the delay, reset the endpoint. */
    442438                timer_schedule_reset(ep);
  • uspace/drv/bus/usb/xhci/streams.c

    rabb5d08 r51c1d500  
    327327        }
    328328
    329         hc_stop_endpoint(dev, xhci_endpoint_index(xhci_ep));
     329        hc_stop_endpoint(xhci_ep);
    330330        xhci_endpoint_free_transfer_ds(xhci_ep);
    331331
     
    337337        }
    338338
    339         xhci_ep_ctx_t ep_ctx;
    340         memset(&ep_ctx, 0, XHCI_ONE_CTX_SIZE(hc));
    341         xhci_setup_endpoint_context(xhci_ep, &ep_ctx);
    342         return hc_update_endpoint(dev, xhci_endpoint_index(xhci_ep), &ep_ctx);
     339        return hc_update_endpoint(xhci_ep);
    343340}
    344341
     
    361358         * Stop the endpoint, destroy the ring, and transition to streams.
    362359         */
    363         hc_stop_endpoint(dev, xhci_endpoint_index(xhci_ep));
     360        hc_stop_endpoint(xhci_ep);
    364361        xhci_endpoint_free_transfer_ds(xhci_ep);
    365362
     
    381378        setup_stream_context(xhci_ep, &ep_ctx, pstreams, 1);
    382379
    383         return hc_update_endpoint(dev, xhci_endpoint_index(xhci_ep), &ep_ctx);
     380        return hc_update_endpoint(xhci_ep);
    384381}
    385382
     
    434431         * Stop the endpoint, destroy the ring, and transition to streams.
    435432         */
    436         hc_stop_endpoint(dev, xhci_endpoint_index(xhci_ep));
     433        hc_stop_endpoint(xhci_ep);
    437434        xhci_endpoint_free_transfer_ds(xhci_ep);
    438435
     
    455452        setup_stream_context(xhci_ep, &ep_ctx, pstreams, 0);
    456453
    457         return hc_update_endpoint(dev, xhci_endpoint_index(xhci_ep), &ep_ctx);
     454        return hc_update_endpoint(xhci_ep);
    458455
    459456err_init:
  • uspace/drv/bus/usb/xhci/transfers.c

    rabb5d08 r51c1d500  
    120120}
    121121
    122 static xhci_trb_ring_t *get_ring(xhci_hc_t *hc, xhci_transfer_t *transfer)
    123 {
    124         xhci_endpoint_t *ep = xhci_endpoint_get(transfer->batch.ep);
    125         if (ep->primary_stream_data_size == 0) return &ep->ring;
    126         uint32_t stream_id = transfer->batch.target.stream;
    127 
    128         xhci_stream_data_t *stream_data = xhci_get_stream_ctx_data(ep, stream_id);
    129         if (stream_data == NULL) {
    130                 usb_log_warning("No transfer ring was found for stream %u.", stream_id);
    131                 return NULL;
    132         }
    133 
    134         return &stream_data->ring;
     122static xhci_trb_ring_t *get_ring(xhci_transfer_t *transfer)
     123{
     124        xhci_endpoint_t *xhci_ep = xhci_endpoint_get(transfer->batch.ep);
     125        return xhci_endpoint_get_ring(xhci_ep, transfer->batch.target.stream);
    135126}
    136127
     
    138129{
    139130        usb_transfer_batch_t *batch = &transfer->batch;
    140         xhci_trb_ring_t *ring = get_ring(hc, transfer);
    141131        xhci_endpoint_t *xhci_ep = xhci_endpoint_get(transfer->batch.ep);
    142132
     
    202192        }
    203193
    204         return xhci_trb_ring_enqueue_multiple(ring, trbs, trbs_used, &transfer->interrupt_trb_phys);
     194        return xhci_trb_ring_enqueue_multiple(get_ring(transfer), trbs, trbs_used, &transfer->interrupt_trb_phys);
    205195}
    206196
     
    224214                TRB_CTRL_SET_TRB_TYPE(trb, XHCI_TRB_TYPE_NORMAL);
    225215
    226                 xhci_trb_ring_t* ring = get_ring(hc, transfer);
     216                xhci_trb_ring_t* ring = get_ring(transfer);
    227217                return xhci_trb_ring_enqueue(ring, &trb, &transfer->interrupt_trb_phys);
    228218        }
     
    233223                TRB_CTRL_SET_ENT(trb, 1);
    234224
    235                 xhci_trb_ring_t* ring = get_ring(hc, transfer);
     225                xhci_trb_ring_t* ring = get_ring(transfer);
    236226                if (!ring) {
    237227                        return EINVAL;
     
    269259        TRB_CTRL_SET_TRB_TYPE(trb, XHCI_TRB_TYPE_NORMAL);
    270260
    271         xhci_trb_ring_t* ring = get_ring(hc, transfer);
     261        xhci_trb_ring_t* ring = get_ring(transfer);
    272262
    273263        return xhci_trb_ring_enqueue(ring, &trb, &transfer->interrupt_trb_phys);
     
    313303                /* We are received transfer pointer instead - work with that */
    314304                transfer = (xhci_transfer_t *) addr;
    315                 xhci_trb_ring_t * ring = get_ring(hc, transfer);
    316                 xhci_trb_ring_update_dequeue(ring, transfer->interrupt_trb_phys);
     305                xhci_trb_ring_update_dequeue(get_ring(transfer), transfer->interrupt_trb_phys);
    317306                batch = &transfer->batch;
    318307
     
    497486        }
    498487
     488        hc_ring_ep_doorbell(xhci_ep, batch->target.stream);
     489
    499490        /* After the critical section, the transfer can already be finished or aborted. */
    500491        transfer = NULL; batch = NULL;
    501492        fibril_mutex_unlock(&ep->guard);
    502 
    503         const uint8_t slot_id = xhci_dev->slot_id;
    504         /* EP Doorbells start at 1 */
    505         const uint8_t target = (xhci_endpoint_index(xhci_ep) + 1) | (batch->target.stream << 16);
    506         hc_ring_doorbell(hc, slot_id, target);
    507493        return EOK;
    508494}
Note: See TracChangeset for help on using the changeset viewer.