Changeset 47e9494 in mainline for uspace/drv/bus/usb/xhci/endpoint.c


Ignore:
Timestamp:
2018-01-16T18:02:46Z (7 years ago)
Author:
Salmelu <salmelu@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
eeca8a6
Parents:
7d1dd2b
Message:

xhci: stub for streams support

File:
1 edited

Legend:

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

    r7d1dd2b r47e9494  
    4444#include "commands.h"
    4545#include "endpoint.h"
     46#include "streams.h"
    4647
    4748static int alloc_transfer_ds(xhci_endpoint_t *);
     
    131132 * @return EP_TYPE_[CONTROL|ISOCH|BULK|INTERRUPT]_[IN|OUT]
    132133 */
    133 static int xhci_endpoint_type(xhci_endpoint_t *ep)
     134int xhci_endpoint_type(xhci_endpoint_t *ep)
    134135{
    135136        const bool in = ep->base.direction == USB_DIRECTION_IN;
     
    153154
    154155        return EP_TYPE_INVALID;
    155 }
    156 
    157 /**
    158  * Test whether an XHCI endpoint uses streams.
    159  * @param[in] xhci_ep XHCI endpoint to query.
    160  *
    161  * @return True if the endpoint uses streams.
    162  */
    163 static bool endpoint_using_streams(xhci_endpoint_t *xhci_ep)
    164 {
    165         return xhci_ep->primary_stream_ctx_array != NULL;
    166 }
    167 
    168 // static bool primary_stream_ctx_has_secondary_array(xhci_stream_ctx_t *primary_ctx) {
    169 //      /* Section 6.2.4.1, SCT values */
    170 //      return XHCI_STREAM_SCT(*primary_ctx) >= 2;
    171 // }
    172 //
    173 // static size_t secondary_stream_ctx_array_size(xhci_stream_ctx_t *primary_ctx) {
    174 //      if (XHCI_STREAM_SCT(*primary_ctx) < 2) return 0;
    175 //      return 2 << XHCI_STREAM_SCT(*primary_ctx);
    176 // }
    177 
    178 /** Initialize primary streams of XHCI bulk endpoint.
    179  * @param[in] hc Host controller of the endpoint.
    180  * @param[in] xhci_epi XHCI bulk endpoint to use.
    181  * @param[in] count Number of primary streams to initialize.
    182  */
    183 static void initialize_primary_streams(xhci_hc_t *hc, xhci_endpoint_t *xhci_ep, unsigned count) {
    184         for (size_t index = 0; index < count; ++index) {
    185                 xhci_stream_ctx_t *ctx = &xhci_ep->primary_stream_ctx_array[index];
    186                 xhci_trb_ring_t *ring = &xhci_ep->primary_stream_rings[index];
    187 
    188                 /* Init and register TRB ring for every primary stream */
    189                 xhci_trb_ring_init(ring); // FIXME: Not checking error code?
    190                 XHCI_STREAM_DEQ_PTR_SET(*ctx, ring->dequeue);
    191 
    192                 /* Set to linear stream array */
    193                 XHCI_STREAM_SCT_SET(*ctx, 1);
    194         }
    195 }
    196 
    197 /** Configure XHCI bulk endpoint's stream context.
    198  * @param[in] xhci_ep Associated XHCI bulk endpoint.
    199  * @param[in] ctx Endpoint context to configure.
    200  * @param[in] pstreams The value of MaxPStreams.
    201  */
    202 static void setup_stream_context(xhci_endpoint_t *xhci_ep, xhci_ep_ctx_t *ctx, unsigned pstreams) {
    203         XHCI_EP_TYPE_SET(*ctx, xhci_endpoint_type(xhci_ep));
    204         XHCI_EP_MAX_PACKET_SIZE_SET(*ctx, xhci_ep->base.max_packet_size);
    205         XHCI_EP_MAX_BURST_SIZE_SET(*ctx, xhci_ep->max_burst - 1);
    206         XHCI_EP_ERROR_COUNT_SET(*ctx, 3);
    207 
    208         XHCI_EP_MAX_P_STREAMS_SET(*ctx, pstreams);
    209         XHCI_EP_TR_DPTR_SET(*ctx, xhci_ep->primary_stream_ctx_dma.phys);
    210         // TODO: set HID?
    211         XHCI_EP_LSA_SET(*ctx, 1);
    212 }
    213 
    214 /** TODO document this
    215  */
    216 int xhci_endpoint_request_streams(xhci_hc_t *hc, xhci_device_t *dev, xhci_endpoint_t *xhci_ep, unsigned count) {
    217         if (xhci_ep->base.transfer_type != USB_TRANSFER_BULK
    218                 || dev->base.speed != USB_SPEED_SUPER) {
    219                 usb_log_error("Streams are only supported by superspeed bulk endpoints.");
    220                 return EINVAL;
    221         }
    222 
    223         if (xhci_ep->max_streams == 1) {
    224                 usb_log_error("Streams are not supported by endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep));
    225                 return EINVAL;
    226         }
    227 
    228         uint8_t max_psa_size = 2 << XHCI_REG_RD(hc->cap_regs, XHCI_CAP_MAX_PSA_SIZE);
    229         if (count > max_psa_size) {
    230                 // FIXME: We don't support secondary stream arrays yet, so we just give up for this
    231                 return ENOTSUP;
    232         }
    233 
    234         if (count > xhci_ep->max_streams) {
    235                 usb_log_error("Endpoint " XHCI_EP_FMT " supports only %" PRIu32 " streams.",
    236                         XHCI_EP_ARGS(*xhci_ep), xhci_ep->max_streams);
    237                 return EINVAL;
    238         }
    239 
    240         if (count <= 1024) {
    241                 usb_log_debug2("Allocating primary stream context array of size %u for endpoint " XHCI_EP_FMT,
    242                         count, XHCI_EP_ARGS(*xhci_ep));
    243                 if ((dma_buffer_alloc(&xhci_ep->primary_stream_ctx_dma, count * sizeof(xhci_stream_ctx_t))))
    244                         return ENOMEM;
    245                 xhci_ep->primary_stream_ctx_array = xhci_ep->primary_stream_ctx_dma.virt;
    246 
    247                 xhci_ep->primary_stream_rings = calloc(count, sizeof(xhci_trb_ring_t));
    248                 if (!xhci_ep->primary_stream_rings) {
    249                         dma_buffer_free(&xhci_ep->primary_stream_ctx_dma);
    250                         return ENOMEM;
    251                 }
    252 
    253                 // FIXME: count should be rounded to nearest power of 2 for xHC, workaround for now
    254                 count = 1024;
    255                 // FIXME: pstreams are "log2(count) - 1"
    256                 const size_t pstreams = 9;
    257                 xhci_ep->primary_stream_ctx_array_size = count;
    258 
    259                 memset(xhci_ep->primary_stream_ctx_array, 0, count * sizeof(xhci_stream_ctx_t));
    260                 initialize_primary_streams(hc, xhci_ep, count);
    261 
    262                 xhci_ep_ctx_t ep_ctx;
    263                 setup_stream_context(xhci_ep, &ep_ctx, pstreams);
    264                 return hc_add_endpoint(hc, dev->slot_id, xhci_endpoint_index(xhci_ep), &ep_ctx);
    265         }
    266         // FIXME: Complex stuff not supported yet
    267         return ENOTSUP;
    268156}
    269157
     
    300188static void free_transfer_ds(xhci_endpoint_t *xhci_ep)
    301189{
    302         if (endpoint_using_streams(xhci_ep)) {
    303                 usb_log_debug2("Freeing primary stream context array of endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep));
    304 
    305                 // maybe check if LSA, then skip?
    306                 // for (size_t index = 0; index < primary_stream_ctx_array_size(xhci_ep); ++index) {
    307                 //      xhci_stream_ctx_t *primary_ctx = xhci_ep->primary_stream_ctx_array + index;
    308                 //      if (primary_stream_ctx_has_secondary_array(primary_ctx)) {
    309                 //              // uintptr_t phys = XHCI_STREAM_DEQ_PTR(*primary_ctx);
    310                 //              /* size_t size = */ secondary_stream_ctx_array_size(primary_ctx);
    311                 //              // TODO: somehow map the address to virtual and free the secondary array
    312                 //      }
    313                 // }
    314                 for (size_t index = 0; index < xhci_ep->primary_stream_ctx_array_size; ++index) {
    315                         // FIXME: Get the trb ring associated with stream [index] and fini it
    316                 }
    317                 dma_buffer_free(&xhci_ep->primary_stream_ctx_dma);
     190        if (xhci_ep->primary_stream_data_size) {
     191                xhci_stream_free_ds(xhci_ep);
    318192        } else {
    319193                usb_log_debug2("Freeing main transfer ring of endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep));
    320 
    321194                xhci_trb_ring_fini(&xhci_ep->ring);
    322195        }
Note: See TracChangeset for help on using the changeset viewer.