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

Changeset 6b433a8 in mainline


Ignore:
Timestamp:
2017-11-20T19:14:31Z (3 years ago)
Author:
Salmelu <salmelu@…>
Branches:
master
Children:
27b0ea0
Parents:
d3086873
Message:

Isochronous transfers - endpoint initialization

Location:
uspace
Files:
10 edited

Legend:

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

    rd3086873 r6b433a8  
    6868        ep->max_streams = desc->usb3.max_streams;
    6969        ep->max_burst = desc->usb3.max_burst;
    70         // TODO add this property to usb_endpoint_desc_t and fetch it from ss companion desc
    71         ep->mult = 0;
     70        ep->mult = desc->usb3.mult;
     71
     72        if (ep->base.transfer_type == USB_TRANSFER_ISOCHRONOUS) {
     73                if (ep->base.device->speed <= USB_SPEED_HIGH) {
     74                        ep->isoch_max_size = desc->max_packet_size * (desc->packets + 1);
     75                }
     76                else if (ep->base.device->speed == USB_SPEED_SUPER) {
     77                        ep->isoch_max_size = desc->usb3.bytes_per_interval;
     78                }
     79                /* Technically there could be superspeed plus too. */
     80
     81                /* Allocate and setup isochronous-specific structures. */
     82                ep->isoch_enqueue = 0;
     83                ep->isoch_dequeue = XHCI_ISOCH_BUFFER_COUNT - 1;
     84                ep->isoch_started = false;
     85        }
    7286
    7387        return xhci_endpoint_alloc_transfer_ds(ep);
  • uspace/drv/bus/usb/xhci/endpoint.c

    rd3086873 r6b433a8  
    193193}
    194194
     195static int xhci_isoch_alloc_transfers(xhci_endpoint_t *xhci_ep) {
     196        int i = 0;
     197        int err = EOK;
     198        while (i < XHCI_ISOCH_BUFFER_COUNT) {
     199                xhci_isoch_transfer_t *transfer = xhci_ep->isoch_transfers[i];
     200                if (dma_buffer_alloc(&transfer->data, xhci_ep->isoch_max_size)) {
     201                        err = ENOMEM;
     202                        break;
     203                }
     204                transfer->size = 0;
     205                ++i;
     206        }
     207
     208        if (err) {
     209                --i;
     210                while(i >= 0) {
     211                        dma_buffer_free(&xhci_ep->isoch_transfers[i]->data);
     212                        --i;
     213                }
     214        }
     215
     216        return err;
     217}
     218
    195219int xhci_endpoint_alloc_transfer_ds(xhci_endpoint_t *xhci_ep)
    196220{
     
    203227        if ((err = xhci_trb_ring_init(&xhci_ep->ring))) {
    204228                return err;
     229        }
     230
     231        if (xhci_ep->base.transfer_type == USB_TRANSFER_ISOCHRONOUS) {
     232                if((err = xhci_isoch_alloc_transfers(xhci_ep))) {
     233                        xhci_trb_ring_fini(&xhci_ep->ring);
     234                        return err;
     235                }
    205236        }
    206237
     
    289320        XHCI_EP_TR_DPTR_SET(*ctx, ep->ring.dequeue);
    290321        XHCI_EP_DCS_SET(*ctx, 1);
    291         // TODO: max ESIT payload
     322
     323        XHCI_EP_MAX_ESIT_PAYLOAD_LO_SET(*ctx, ep->isoch_max_size & 0xFFFF);
     324        XHCI_EP_MAX_ESIT_PAYLOAD_HI_SET(*ctx, (ep->isoch_max_size >> 16) & 0xFF);
    292325}
    293326
  • uspace/drv/bus/usb/xhci/hw_struct/context.h

    rd3086873 r6b433a8  
    7676#define XHCI_EP_MAX_ESIT_PAYLOAD_LO_SET(ctx, val) \
    7777        xhci_dword_set_bits(&(ctx).data3, val, 31, 16)
     78#define XHCI_EP_MAX_ESIT_PAYLOAD_HI_SET(ctx, val) \
     79        xhci_dword_set_bits(&(ctx).data[0], val, 31, 24)
    7880#define XHCI_EP_INTERVAL_SET(ctx, val) \
    7981        xhci_dword_set_bits(&(ctx).data[0], val, 23, 16)
     
    102104#define XHCI_EP_TR_DPTR(ctx)            XHCI_QWORD_EXTRACT((ctx).data2, 63,  4)
    103105
    104 #define XHCI_EP_MAX_ESIT_PAYLOAD_LO(ctx) XHCI_DWORD_EXTRACT((ctx).data3, 31,  16)
     106#define XHCI_EP_MAX_ESIT_PAYLOAD_LO(ctx) XHCI_DWORD_EXTRACT((ctx).data3, 31, 16)
     107#define XHCI_EP_MAX_ESIT_PAYLOAD_HI(ctx) XHCI_DWORD_EXTRACT((ctx).data[0], 31, 24)
    105108
    106109} __attribute__((packed)) xhci_ep_ctx_t;
  • uspace/drv/bus/usb/xhci/transfers.c

    rd3086873 r6b433a8  
    287287        isoch_transfer->size = transfer->batch.buffer_size;
    288288        if (isoch_transfer->size > 0) {
    289                 memcpy(isoch_transfer->data_virt, transfer->batch.buffer, isoch_transfer->size);
    290         }
    291 
    292         trb.parameter = isoch_transfer->data_phys;
     289                memcpy(isoch_transfer->data.virt, transfer->batch.buffer, isoch_transfer->size);
     290        }
     291
     292        trb.parameter = isoch_transfer->data.phys;
    293293
    294294        xhci_trb_ring_t *ring = get_ring(hc, transfer);
     
    341341        if (transfer->batch.buffer_size <= isoch_transfer->size) {
    342342                if (transfer->batch.buffer_size > 0) {
    343                         memcpy(transfer->batch.buffer, isoch_transfer->data_virt, transfer->batch.buffer_size);
     343                        memcpy(transfer->batch.buffer, isoch_transfer->data.virt, transfer->batch.buffer_size);
    344344                }
    345345                if (transfer->batch.buffer_size < isoch_transfer->size) {
     
    349349        }
    350350        else {
    351                 memcpy(transfer->batch.buffer, isoch_transfer->data_virt, isoch_transfer->size);
     351                memcpy(transfer->batch.buffer, isoch_transfer->data.virt, isoch_transfer->size);
    352352                transfer->batch.transfered_size = isoch_transfer->size;
    353353        }
     
    357357        xhci_trb_clean(&trb);
    358358
    359         trb.parameter = isoch_transfer->data_phys;
     359        trb.parameter = isoch_transfer->data.phys;
    360360        isoch_transfer->size = xhci_ep->isoch_max_size;
    361361
  • uspace/drv/bus/usb/xhci/transfers.h

    rd3086873 r6b433a8  
    5858        /* Used buffer size */
    5959        uint64_t size;
    60         /* Pointer to data in virt memory */
    61         void *data_virt;
    62         /* Physical address of the buffer */
    63         uintptr_t data_phys;
     60        /* Buffer with data */
     61        dma_buffer_t data;
    6462        /* Physical address of enqueued TRB */
    6563        uintptr_t interrupt_trb_phys;
  • uspace/lib/drv/include/usb_iface.h

    rd3086873 r6b433a8  
    126126                unsigned max_burst;
    127127                unsigned max_streams;
     128                unsigned mult;
     129                unsigned bytes_per_interval;
    128130        } usb3;
    129131} usb_endpoint_desc_t;
  • uspace/lib/usb/include/usb/descriptor.h

    rd3086873 r6b433a8  
    240240         * For bulk endpoints, this field contains the amount of streams
    241241         * supported by the endpoint.
    242          * For isochronous endpoints, this field contains either maximum
    243          * number of packets supported within a service interval, or
    244          * whether an isochronous endpoint companion descriptor follows.
     242         * For isochronous endpoints, this field contains maximum
     243         * number of packets supported within a service interval.
     244         * Warning: the values returned by macros may not make any sense
     245         * for specific endpoint types.
    245246         */
    246247        uint8_t attributes;
    247248#define SS_COMPANION_MAX_STREAMS(attributes) \
    248249        (attributes & 0x1f)
     250#define SS_COMPANION_MULT(attributes) \
     251        (attributes & 0x3)
    249252        /** The total number of bytes this endpoint will transfer
    250253         * every service interval (SI).
  • uspace/lib/usbdev/include/usb/dev/pipes.h

    rd3086873 r6b433a8  
    9797
    9898int usb_pipe_initialize(usb_pipe_t *, usb_endpoint_t, usb_transfer_type_t,
    99     size_t, usb_direction_t, unsigned, unsigned, unsigned, usb_dev_session_t *);
     99    size_t, usb_direction_t, unsigned, unsigned, unsigned, unsigned, unsigned, usb_dev_session_t *);
    100100int usb_pipe_initialize_default_control(usb_pipe_t *, usb_dev_session_t *);
    101101
  • uspace/lib/usbdev/src/pipes.c

    rd3086873 r6b433a8  
    255255    usb_transfer_type_t transfer_type, size_t max_packet_size,
    256256    usb_direction_t direction, unsigned packets,
    257     unsigned max_burst, unsigned max_streams, usb_dev_session_t *bus_session)
    258 {
    259         // FIXME refactor this function
     257    unsigned max_burst, unsigned max_streams, unsigned bytes_per_interval,
     258        unsigned mult, usb_dev_session_t *bus_session)
     259{
     260        // FIXME: refactor this function PLEASE
    260261        assert(pipe);
    261262
     
    267268        pipe->desc.usb3.max_burst = max_burst;
    268269        pipe->desc.usb3.max_streams = max_streams;
     270        pipe->desc.usb3.mult = mult;
     271        pipe->desc.usb3.bytes_per_interval = bytes_per_interval;
    269272        pipe->auto_reset_halt = false;
    270273        pipe->bus_session = bus_session;
     
    284287
    285288        const int rc = usb_pipe_initialize(pipe, 0, USB_TRANSFER_CONTROL,
    286             CTRL_PIPE_MIN_PACKET_SIZE, USB_DIRECTION_BOTH, 1, 0, 0, bus_session);
     289            CTRL_PIPE_MIN_PACKET_SIZE, USB_DIRECTION_BOTH, 1, 0, 0, 0, 0, bus_session);
    287290
    288291        pipe->auto_reset_halt = true;
  • uspace/lib/usbdev/src/pipesinit.c

    rd3086873 r6b433a8  
    210210        unsigned max_burst = 0;
    211211        unsigned max_streams = 0;
     212        unsigned bytes_per_interval = 0;
     213        unsigned mult = 0;
    212214        if(companion_desc) {
    213215                max_burst = companion_desc->max_burst;
    214216                max_streams = SS_COMPANION_MAX_STREAMS(companion_desc->attributes);
    215         }
    216 
     217                bytes_per_interval = companion_desc->bytes_per_interval;
     218                mult = SS_COMPANION_MULT(companion_desc->attributes);
     219        }
     220
     221        // FIXME: USB2 packets and USB3 max_burst are probably the same thing
     222        // See 4.14.2.1.1 of XHCI specification -> possibly refactor into one somehow-named field
    217223        int rc = usb_pipe_initialize(&ep_mapping->pipe,
    218224            ep_no, description.transfer_type,
     
    221227            description.direction, ED_MPS_TRANS_OPPORTUNITIES_GET(
    222228                uint16_usb2host(endpoint_desc->max_packet_size)),
    223             max_burst, max_streams, bus_session);
     229            max_burst, max_streams, bytes_per_interval, mult, bus_session);
    224230        if (rc != EOK) {
    225231                return rc;
Note: See TracChangeset for help on using the changeset viewer.