Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset bdd8842c in mainline


Ignore:
Timestamp:
2018-01-08T19:26:41Z (4 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master
Children:
17c5e62
Parents:
1102eca
Message:

xhci: revised handling of max_burst, mult and max_streams

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

Legend:

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

    r1102eca rbdd8842c  
    134134
    135135        ep0->base.max_packet_size = max_packet_size;
     136        ep0->base.max_transfer_size = max_packet_size * ep0->base.packets_per_uframe;
    136137
    137138        xhci_ep_ctx_t ep_ctx;
  • uspace/drv/bus/usb/xhci/endpoint.c

    r1102eca rbdd8842c  
    6161        endpoint_init(ep, dev, desc);
    6262
    63         xhci_ep->max_streams = USB_SSC_MAX_STREAMS(desc->companion);
     63        xhci_ep->max_streams = 1 << (USB_SSC_MAX_STREAMS(desc->companion));
    6464        xhci_ep->max_burst = desc->companion.max_burst + 1;
    6565        xhci_ep->mult = USB_SSC_MULT(desc->companion) + 1;
     
    7474
    7575        xhci_ep->interval = desc->endpoint.poll_interval;
    76         /* Only Low/Full speed interrupt endpoints have interval set directly,
     76
     77        /*
     78         * Only Low/Full speed interrupt endpoints have interval as a linear field,
    7779         * others have 2-based log of it.
    7880         */
    7981        if (dev->speed >= USB_SPEED_HIGH || ep->transfer_type != USB_TRANSFER_INTERRUPT) {
    80                 xhci_ep->interval = 1 << (xhci_ep->interval - 1);
     82                xhci_ep->interval = desc->endpoint.poll_interval;
     83        }
     84
     85        /* Full speed devices have interval in frames */
     86        if (dev->speed <= USB_SPEED_FULL) {
     87                xhci_ep->interval *= 8;
    8188        }
    8289
     
    149156{
    150157        return xhci_ep->primary_stream_ctx_array != NULL;
    151 }
    152 
    153 /** Determine maximum size of XHCI endpoint's Primary Stream Context Array.
    154  * @param[in] xhci_ep XHCI endpoint to query.
    155  *
    156  * @return Number of items in the Primary Stream Context Array.
    157  */
    158 static size_t primary_stream_ctx_array_max_size(xhci_endpoint_t *xhci_ep)
    159 {
    160         if (!xhci_ep->max_streams)
    161                 return 0;
    162 
    163         /* Section 6.2.3, Table 61 */
    164         return 1 << (xhci_ep->max_streams + 1);
    165158}
    166159
     
    202195        XHCI_EP_TYPE_SET(*ctx, xhci_endpoint_type(xhci_ep));
    203196        XHCI_EP_MAX_PACKET_SIZE_SET(*ctx, xhci_ep->base.max_packet_size);
    204         XHCI_EP_MAX_BURST_SIZE_SET(*ctx, xhci_ep->max_burst);
     197        XHCI_EP_MAX_BURST_SIZE_SET(*ctx, xhci_ep->max_burst - 1);
    205198        XHCI_EP_ERROR_COUNT_SET(*ctx, 3);
    206199
     
    220213        }
    221214
    222         if (!primary_stream_ctx_array_max_size(xhci_ep)) {
     215        if (xhci_ep->max_streams == 1) {
    223216                usb_log_error("Streams are not supported by endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep));
    224217                return EINVAL;
     
    231224        }
    232225
    233         if (count > (unsigned) (1 << xhci_ep->max_streams)) {
    234                 usb_log_error("Endpoint " XHCI_EP_FMT " supports only %u streams.",
    235                         XHCI_EP_ARGS(*xhci_ep), (1 << xhci_ep->max_streams));
     226        if (count > xhci_ep->max_streams) {
     227                usb_log_error("Endpoint " XHCI_EP_FMT " supports only %" PRIu32 " streams.",
     228                        XHCI_EP_ARGS(*xhci_ep), xhci_ep->max_streams);
    236229                return EINVAL;
    237230        }
     
    386379        XHCI_EP_TYPE_SET(*ctx, xhci_endpoint_type(ep));
    387380        XHCI_EP_MAX_PACKET_SIZE_SET(*ctx, ep->base.max_packet_size);
    388         XHCI_EP_MAX_BURST_SIZE_SET(*ctx, ep->max_burst);
    389         XHCI_EP_MULT_SET(*ctx, ep->mult);
     381        XHCI_EP_MAX_BURST_SIZE_SET(*ctx, ep->max_burst - 1);
     382        XHCI_EP_MULT_SET(*ctx, ep->mult - 1);
    390383        XHCI_EP_ERROR_COUNT_SET(*ctx, 3);
    391384        XHCI_EP_TR_DPTR_SET(*ctx, ep->ring.dequeue);
     
    401394        XHCI_EP_TYPE_SET(*ctx, xhci_endpoint_type(ep));
    402395        XHCI_EP_MAX_PACKET_SIZE_SET(*ctx, ep->base.max_packet_size);
    403         XHCI_EP_MAX_BURST_SIZE_SET(*ctx, ep->max_burst);
     396        XHCI_EP_MAX_BURST_SIZE_SET(*ctx, ep->max_burst - 1);
    404397        XHCI_EP_ERROR_COUNT_SET(*ctx, 3);
    405398
     
    417410        XHCI_EP_TYPE_SET(*ctx, xhci_endpoint_type(ep));
    418411        XHCI_EP_MAX_PACKET_SIZE_SET(*ctx, ep->base.max_packet_size & 0x07FF);
    419         XHCI_EP_MAX_BURST_SIZE_SET(*ctx, ep->max_burst);
    420         XHCI_EP_MULT_SET(*ctx, ep->mult);
     412        XHCI_EP_MAX_BURST_SIZE_SET(*ctx, ep->max_burst - 1);
     413        XHCI_EP_MULT_SET(*ctx, ep->mult - 1);
    421414        XHCI_EP_ERROR_COUNT_SET(*ctx, 0);
    422415        XHCI_EP_TR_DPTR_SET(*ctx, ep->ring.dequeue);
    423416        XHCI_EP_DCS_SET(*ctx, 1);
    424         XHCI_EP_INTERVAL_SET(*ctx, ep->interval);
     417        XHCI_EP_INTERVAL_SET(*ctx, fnzb32(ep->interval) % 32 - 1);
    425418
    426419        XHCI_EP_MAX_ESIT_PAYLOAD_LO_SET(*ctx, ep->isoch_max_size & 0xFFFF);
     
    436429        XHCI_EP_TYPE_SET(*ctx, xhci_endpoint_type(ep));
    437430        XHCI_EP_MAX_PACKET_SIZE_SET(*ctx, ep->base.max_packet_size & 0x07FF);
    438         XHCI_EP_MAX_BURST_SIZE_SET(*ctx, ep->max_burst);
     431        XHCI_EP_MAX_BURST_SIZE_SET(*ctx, ep->max_burst - 1);
    439432        XHCI_EP_MULT_SET(*ctx, 0);
    440433        XHCI_EP_ERROR_COUNT_SET(*ctx, 3);
    441434        XHCI_EP_TR_DPTR_SET(*ctx, ep->ring.dequeue);
    442435        XHCI_EP_DCS_SET(*ctx, 1);
    443 
    444         XHCI_EP_INTERVAL_SET(*ctx, ep->interval);
     436        XHCI_EP_INTERVAL_SET(*ctx, fnzb32(ep->interval) % 32 - 1);
    445437        // TODO: max ESIT payload
    446438}
  • uspace/drv/bus/usb/xhci/endpoint.h

    r1102eca rbdd8842c  
    8181        uint16_t primary_stream_ctx_array_size;
    8282
    83         /** 2-log of maximum number of primary streams (0-16). Not to be used directly. */
    84         uint8_t max_streams;
     83        /* Maximum number of primary streams (0 - 2^16). */
     84        uint32_t max_streams;
    8585
    8686        /** Maximum number of consecutive USB transactions (0-15) that should be executed per scheduling opportunity */
     
    9090        uint8_t mult;
    9191
    92         /** Scheduling interval for periodic endpoints */
    93         size_t interval;
     92        /** Scheduling interval for periodic endpoints, as a number of 125us units. (0 - 2^16) */
     93        uint32_t interval;
    9494
    9595        /** The maximum size of an isochronous transfer and therefore the size of buffers */
  • uspace/drv/bus/usb/xhci/transfers.c

    r1102eca rbdd8842c  
    263263        // see 4.14.1 and 4.11.2.3 for the explanation, how to calculate those
    264264        size_t tdpc = len / 1024 + ((len % 1024) ? 1 : 0);
    265         size_t tbc = tdpc / (ep->max_burst + 1);
    266         if (!tdpc % (ep->max_burst + 1)) --tbc;
    267         size_t bsp = tdpc % (ep->max_burst + 1);
    268         size_t tlbpc = (bsp ? bsp - 1 : ep->max_burst);
     265        size_t tbc = tdpc / ep->max_burst;
     266        if (!tdpc % ep->max_burst) --tbc;
     267        size_t bsp = tdpc % ep->max_burst;
     268        size_t tlbpc = (bsp ? bsp : ep->max_burst) - 1;
    269269
    270270        TRB_CTRL_SET_TBC(*trb, tbc);
Note: See TracChangeset for help on using the changeset viewer.