Changeset 998773d in mainline


Ignore:
Timestamp:
2018-01-22T14:27:24Z (6 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
effbef3
Parents:
db51a6a6
git-author:
Ondřej Hlavatý <aearsis@…> (2018-01-22 14:11:42)
git-committer:
Ondřej Hlavatý <aearsis@…> (2018-01-22 14:27:24)
Message:

xhci trb_ring: make initial ring size variable

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

Legend:

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

    rdb51a6a6 r998773d  
    7777        int err;
    7878
    79         if ((err = xhci_trb_ring_init(&cr->trb_ring)))
     79        if ((err = xhci_trb_ring_init(&cr->trb_ring, 0)))
    8080                return err;
    8181
  • uspace/drv/bus/usb/xhci/endpoint.c

    rdb51a6a6 r998773d  
    285285
    286286        int err;
    287         if ((err = xhci_trb_ring_init(&xhci_ep->ring))) {
     287        if ((err = xhci_trb_ring_init(&xhci_ep->ring, 0))) {
    288288                return err;
    289289        }
  • uspace/drv/bus/usb/xhci/hc.c

    rdb51a6a6 r998773d  
    262262        hc->dcbaa = hc->dcbaa_dma.virt;
    263263
    264         if ((err = xhci_event_ring_init(&hc->event_ring)))
     264        if ((err = xhci_event_ring_init(&hc->event_ring, 1)))
    265265                goto err_dcbaa;
    266266
     
    494494        XHCI_REG_WR(intr0, XHCI_INTR_ERSTBA_HI, UPPER32(erstptr));
    495495
    496 
    497496        if (irq) {
    498497                XHCI_REG_SET(intr0, XHCI_INTR_IE, 1);
  • uspace/drv/bus/usb/xhci/streams.c

    rdb51a6a6 r998773d  
    154154
    155155        /* Init and register TRB ring for the primary stream */
    156         if ((err = xhci_trb_ring_init(&data->ring))) {
     156        if ((err = xhci_trb_ring_init(&data->ring, 0))) {
    157157                return err;
    158158        }
     
    233233                xhci_stream_data_t *secondary_data = &data->secondary_data[index];
    234234                /* Init and register TRB ring for every secondary stream */
    235                 if ((err = xhci_trb_ring_init(&secondary_data->ring))) {
     235                if ((err = xhci_trb_ring_init(&secondary_data->ring, 0))) {
    236236                        goto err_init;
    237237                }
     
    332332        /* Streams are now removed, proceed with reconfiguring endpoint. */
    333333        int err;
    334         if ((err = xhci_trb_ring_init(&xhci_ep->ring))) {
     334        if ((err = xhci_trb_ring_init(&xhci_ep->ring, 0))) {
    335335                usb_log_error("Failed to initialize a transfer ring.");
    336336                return err;
  • uspace/drv/bus/usb/xhci/trb_ring.c

    rdb51a6a6 r998773d  
    3737#include "trb_ring.h"
    3838
    39 #define SEGMENT_HEADER_SIZE (sizeof(link_t) + sizeof(uintptr_t))
    40 
    41 /**
    42  * Number of TRBs in a segment (with our header).
    43  */
    44 #define SEGMENT_TRB_COUNT ((PAGE_SIZE - SEGMENT_HEADER_SIZE) / sizeof(xhci_trb_t))
     39/**
     40 * A structure representing a segment of a TRB ring.
     41 */
     42
     43#define SEGMENT_FOOTER_SIZE (sizeof(link_t) + sizeof(uintptr_t))
     44
     45#define SEGMENT_TRB_COUNT ((PAGE_SIZE - SEGMENT_FOOTER_SIZE) / sizeof(xhci_trb_t))
     46#define SEGMENT_TRB_USEFUL_COUNT (SEGMENT_TRB_COUNT - 1)
    4547
    4648struct trb_segment {
     
    5153} __attribute__((aligned(PAGE_SIZE)));
    5254
     55static_assert(sizeof(trb_segment_t) == PAGE_SIZE);
     56
    5357
    5458/**
     
    6670{
    6771        return segment_begin(segment) + SEGMENT_TRB_COUNT;
     72}
     73
     74/**
     75 * Return a first segment of a list of segments.
     76 */
     77static inline trb_segment_t *get_first_segment(list_t *segments)
     78{
     79        return list_get_instance(list_first(segments), trb_segment_t, segments_link);
     80
    6881}
    6982
     
    97110/**
    98111 * Initializes the ring with one segment.
    99  */
    100 int xhci_trb_ring_init(xhci_trb_ring_t *ring)
    101 {
    102         struct trb_segment *segment;
     112 *
     113 * @param[in] initial_size A number of free slots on the ring, 0 leaves the
     114 * choice on a reasonable default (one page-sized segment).
     115 */
     116int xhci_trb_ring_init(xhci_trb_ring_t *ring, size_t initial_size)
     117{
    103118        int err;
     119        if (initial_size == 0)
     120                initial_size = SEGMENT_TRB_USEFUL_COUNT;
    104121
    105122        list_initialize(&ring->segments);
    106 
    107         if ((err = trb_segment_alloc(&segment)) != EOK)
    108                 return err;
    109 
    110         list_append(&segment->segments_link, &ring->segments);
    111         ring->segment_count = 1;
    112 
     123        size_t segment_count = (initial_size + SEGMENT_TRB_USEFUL_COUNT - 1)
     124                / SEGMENT_TRB_USEFUL_COUNT;
     125
     126        for (size_t i = 0; i < segment_count; ++i) {
     127                struct trb_segment *segment;
     128                if ((err = trb_segment_alloc(&segment)) != EOK)
     129                        return err;
     130
     131                list_append(&segment->segments_link, &ring->segments);
     132                ring->segment_count = i + 1;
     133        }
     134
     135        trb_segment_t * const segment = get_first_segment(&ring->segments);
    113136        xhci_trb_t *last = segment_end(segment) - 1;
    114137        xhci_trb_link_fill(last, segment->phys);
     
    284307/**
    285308 * Initializes an event ring.
    286  */
    287 int xhci_event_ring_init(xhci_event_ring_t *ring)
    288 {
    289         struct trb_segment *segment;
     309 *
     310 * @param[in] initial_size A number of free slots on the ring, 0 leaves the
     311 * choice on a reasonable default (one page-sized segment).
     312 */
     313int xhci_event_ring_init(xhci_event_ring_t *ring, size_t initial_size)
     314{
    290315        int err;
     316        if (initial_size == 0)
     317                initial_size = SEGMENT_TRB_COUNT;
    291318
    292319        list_initialize(&ring->segments);
    293320
    294         if ((err = trb_segment_alloc(&segment)) != EOK)
    295                 return err;
    296 
    297         list_append(&segment->segments_link, &ring->segments);
    298         ring->segment_count = 1;
    299 
     321        size_t segment_count = (initial_size + SEGMENT_TRB_COUNT - 1) / SEGMENT_TRB_COUNT;
     322        size_t erst_size = segment_count * sizeof(xhci_erst_entry_t);
     323
     324        if (dma_buffer_alloc(&ring->erst, erst_size)) {
     325                xhci_event_ring_fini(ring);
     326                return ENOMEM;
     327        }
     328
     329        xhci_erst_entry_t *erst = ring->erst.virt;
     330        memset(erst, 0, erst_size);
     331
     332        for (size_t i = 0; i < segment_count; i++) {
     333                trb_segment_t *segment;
     334                if ((err = trb_segment_alloc(&segment)) != EOK) {
     335                        xhci_event_ring_fini(ring);
     336                        return err;
     337                }
     338
     339                list_append(&segment->segments_link, &ring->segments);
     340                ring->segment_count = i + 1;
     341                xhci_fill_erst_entry(&erst[i], segment->phys, SEGMENT_TRB_COUNT);
     342        }
     343
     344        trb_segment_t * const segment = get_first_segment(&ring->segments);
    300345        ring->dequeue_segment = segment;
    301346        ring->dequeue_trb = segment_begin(segment);
    302347        ring->dequeue_ptr = segment->phys;
    303 
    304         if (dma_buffer_alloc(&ring->erst, PAGE_SIZE)) {
    305                 xhci_event_ring_fini(ring);
    306                 return ENOMEM;
    307         }
    308         xhci_erst_entry_t *erst = ring->erst.virt;
    309 
    310         memset(erst, 0, PAGE_SIZE);
    311         xhci_fill_erst_entry(&erst[0], segment->phys, SEGMENT_TRB_COUNT);
    312 
    313348        ring->ccs = 1;
    314349
     
    316351
    317352        usb_log_debug("Initialized event ring.");
    318 
    319353        return EOK;
    320354}
     
    324358        list_foreach_safe(ring->segments, cur, next) {
    325359                trb_segment_t *segment = list_get_instance(cur, trb_segment_t, segments_link);
    326                 dmamem_unmap_anonymous(segment);
     360                trb_segment_free(segment);
    327361        }
    328362
  • uspace/drv/bus/usb/xhci/trb_ring.h

    rdb51a6a6 r998773d  
    7474} xhci_trb_ring_t;
    7575
    76 int xhci_trb_ring_init(xhci_trb_ring_t *);
     76int xhci_trb_ring_init(xhci_trb_ring_t *, size_t);
    7777void xhci_trb_ring_fini(xhci_trb_ring_t *);
    7878int xhci_trb_ring_enqueue(xhci_trb_ring_t *, xhci_trb_t *, uintptr_t *);
     
    107107} xhci_event_ring_t;
    108108
    109 int xhci_event_ring_init(xhci_event_ring_t *);
     109int xhci_event_ring_init(xhci_event_ring_t *, size_t);
    110110void xhci_event_ring_fini(xhci_event_ring_t *);
    111111int xhci_event_ring_dequeue(xhci_event_ring_t *, xhci_trb_t *);
Note: See TracChangeset for help on using the changeset viewer.