Changeset f92f6b1 in mainline for uspace/drv/bus/usb/xhci/isoch.c


Ignore:
Timestamp:
2018-01-10T01:11:01Z (6 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4a00bc9
Parents:
708d8fcd
Message:

xhci isoch: made buffer count variable

File:
1 edited

Legend:

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

    r708d8fcd rf92f6b1  
    3535
    3636#include <str_error.h>
     37#include <macros.h>
    3738
    3839#include "endpoint.h"
     
    5657                ? desc->companion.bytes_per_interval
    5758                : ep->base.max_transfer_size;
    58         /* Technically there could be superspeed plus too. */
     59
     60        const xhci_hc_t *hc = bus_to_xhci_bus(ep->base.device->bus)->hc;
     61
     62        /*
     63         * We shall cover at least twice the IST period, otherwise we will get
     64         * an over/underrun every time.
     65         */
     66        isoch->buffer_count = (2 * hc->ist) / ep->interval;
     67
     68        /* 2 buffers are the very minimum. */
     69        isoch->buffer_count = max(2, isoch->buffer_count);
     70
     71        usb_log_error("[isoch] isoch setup with %zu buffers", isoch->buffer_count);
    5972}
    6073
     
    6679        isoch->dequeue = isoch->enqueue = isoch->hw_enqueue = 0;
    6780
    68         for (size_t i = 0; i < XHCI_ISOCH_BUFFER_COUNT; ++i) {
     81        for (size_t i = 0; i < isoch->buffer_count; ++i) {
    6982                isoch->transfers[i].state = ISOCH_EMPTY;
    7083        }
     
    8598        }
    8699
    87         for (size_t i = 0; i < XHCI_ISOCH_BUFFER_COUNT; ++i)
    88                 dma_buffer_free(&isoch->transfers[i].data);
     100        if (isoch->transfers) {
     101                for (size_t i = 0; i < isoch->buffer_count; ++i)
     102                        dma_buffer_free(&isoch->transfers[i].data);
     103                free(isoch->transfers);
     104        }
    89105}
    90106
     
    100116                return ENOMEM;
    101117
    102         for (size_t i = 0; i < XHCI_ISOCH_BUFFER_COUNT; ++i) {
     118        isoch->transfers = calloc(isoch->buffer_count, sizeof(xhci_isoch_transfer_t));
     119        if(!isoch->transfers)
     120                goto err;
     121 
     122        for (size_t i = 0; i < isoch->buffer_count; ++i) {
    103123                xhci_isoch_transfer_t *transfer = &isoch->transfers[i];
    104124                if (dma_buffer_alloc(&transfer->data, isoch->max_size)) {
    105                         isoch_fini(ep);
    106                         return ENOMEM;
     125                        goto err;
    107126                }
    108127        }
     
    113132
    114133        return EOK;
     134err:
     135        isoch_fini(ep);
     136        return ENOMEM;
    115137}
    116138
     
    151173                 * buffers */
    152174                it->mfindex = XHCI_REG_RD(hc->rt_regs, XHCI_RT_MFINDEX) + 1
    153                        + XHCI_ISOCH_BUFFER_COUNT * ep->interval
     175                       + isoch->buffer_count * ep->interval
    154176                       + hc->ist;
    155177
     
    207229         * TODO: The "size" of the clock is too low. We have to scale it a bit
    208230         * to ensure correct scheduling of transfers, that are
    209          * XHCI_ISOCH_BUFFER_COUNT * interval away from now.
     231         * buffer_count * interval away from now.
    210232         * Maximum interval is 8 seconds, which means we need a size of
    211233         * 16 seconds. The size of MFIINDEX is 2 seconds only.
     
    268290                        }
    269291
    270                         isoch->hw_enqueue = (isoch->hw_enqueue + 1) % XHCI_ISOCH_BUFFER_COUNT;
     292                        isoch->hw_enqueue = (isoch->hw_enqueue + 1) % isoch->buffer_count;
    271293                        break;
    272294
     
    279301                        it->size = 0;
    280302
    281                         isoch->hw_enqueue = (isoch->hw_enqueue + 1) % XHCI_ISOCH_BUFFER_COUNT;
     303                        isoch->hw_enqueue = (isoch->hw_enqueue + 1) % isoch->buffer_count;
    282304                        break;
    283305                }
     
    353375                        /* fallthrough */
    354376                case WINDOW_INSIDE:
    355                         isoch->enqueue = (isoch->enqueue + 1) % XHCI_ISOCH_BUFFER_COUNT;
     377                        isoch->enqueue = (isoch->enqueue + 1) % isoch->buffer_count;
    356378                        isoch->last_mfindex = it->mfindex;
    357379
     
    417439        }
    418440
    419         isoch->enqueue = (isoch->enqueue + 1) % XHCI_ISOCH_BUFFER_COUNT;
     441        isoch->enqueue = (isoch->enqueue + 1) % isoch->buffer_count;
    420442
    421443        /* Withdraw results from previous transfers. */
     
    423445        xhci_isoch_transfer_t *res = &isoch->transfers[isoch->dequeue];
    424446        while (res->state == ISOCH_COMPLETE) {
    425                 isoch->dequeue = (isoch->dequeue + 1) % XHCI_ISOCH_BUFFER_COUNT;
     447                isoch->dequeue = (isoch->dequeue + 1) % isoch->buffer_count;
    426448
    427449                res->state = ISOCH_EMPTY;
     
    487509        }
    488510
    489         isoch->dequeue = (isoch->dequeue + 1) % XHCI_ISOCH_BUFFER_COUNT;
     511        isoch->dequeue = (isoch->dequeue + 1) % isoch->buffer_count;
    490512
    491513        /* Withdraw results from previous transfer. */
     
    543565         * which one it is.
    544566         */
    545         for (size_t i = 0; i < XHCI_ISOCH_BUFFER_COUNT; ++i) {
     567        for (size_t i = 0; i < isoch->buffer_count; ++i) {
    546568                xhci_isoch_transfer_t * const it = &isoch->transfers[i];
    547569
Note: See TracChangeset for help on using the changeset viewer.