Changeset 17c5e62 in mainline for uspace/drv/bus/usb/xhci/transfers.c


Ignore:
Timestamp:
2018-01-08T22:30:12Z (7 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0eadfd1e
Parents:
bdd8842c
Message:

xhci: make isoch part of endpoint optional

File:
1 edited

Legend:

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

    rbdd8842c r17c5e62  
    237237
    238238static xhci_isoch_transfer_t* isoch_transfer_get_enqueue(xhci_endpoint_t *ep) {
    239         if (((ep->isoch_enqueue + 1) % XHCI_ISOCH_BUFFER_COUNT) == ep->isoch_dequeue) {
     239        if (((ep->isoch->enqueue + 1) % XHCI_ISOCH_BUFFER_COUNT) == ep->isoch->dequeue) {
    240240                /* None ready */
    241241                return NULL;
    242242        }
    243         xhci_isoch_transfer_t *isoch_transfer = &ep->isoch_transfers[ep->isoch_enqueue];
    244         ep->isoch_enqueue = (ep->isoch_enqueue + 1) % XHCI_ISOCH_BUFFER_COUNT;
     243        xhci_isoch_transfer_t *isoch_transfer = &ep->isoch->transfers[ep->isoch->enqueue];
     244        ep->isoch->enqueue = (ep->isoch->enqueue + 1) % XHCI_ISOCH_BUFFER_COUNT;
    245245        return isoch_transfer;
    246246}
    247247
    248248static xhci_isoch_transfer_t* isoch_transfer_get_dequeue(xhci_endpoint_t *ep) {
    249         xhci_isoch_transfer_t *isoch_transfer = &ep->isoch_transfers[ep->isoch_dequeue];
    250         ep->isoch_dequeue = (ep->isoch_dequeue + 1) % XHCI_ISOCH_BUFFER_COUNT;
     249        xhci_isoch_transfer_t *isoch_transfer = &ep->isoch->transfers[ep->isoch->dequeue];
     250        ep->isoch->dequeue = (ep->isoch->dequeue + 1) % XHCI_ISOCH_BUFFER_COUNT;
    251251        return isoch_transfer;
    252252}
     
    283283        xhci_trb_clean(&trb);
    284284
    285         fibril_mutex_lock(&xhci_ep->isoch_guard);
     285        fibril_mutex_lock(&xhci_ep->isoch->guard);
    286286        xhci_isoch_transfer_t *isoch_transfer = isoch_transfer_get_enqueue(xhci_ep);
    287287        while (!isoch_transfer) {
    288                 fibril_condvar_wait(&xhci_ep->isoch_avail, &xhci_ep->isoch_guard);
     288                fibril_condvar_wait(&xhci_ep->isoch->avail, &xhci_ep->isoch->guard);
    289289                isoch_transfer = isoch_transfer_get_enqueue(xhci_ep);
    290290        }
     
    301301                &isoch_transfer->interrupt_trb_phys);
    302302        if (err) {
    303                 fibril_mutex_unlock(&xhci_ep->isoch_guard);
     303                fibril_mutex_unlock(&xhci_ep->isoch->guard);
    304304                return err;
    305305        }
     
    307307        /* If not yet started, start the isochronous endpoint transfers - after buffer count - 1 writes */
    308308        /* The -1 is there because of the enqueue != dequeue check. The buffer must have at least 2 transfers. */
    309         if (((xhci_ep->isoch_enqueue + 1) % XHCI_ISOCH_BUFFER_COUNT) == xhci_ep->isoch_dequeue && !xhci_ep->isoch_started) {
     309        if (((xhci_ep->isoch->enqueue + 1) % XHCI_ISOCH_BUFFER_COUNT) == xhci_ep->isoch->dequeue && !xhci_ep->isoch->started) {
    310310                const uint8_t slot_id = xhci_dev->slot_id;
    311311                const uint8_t target = xhci_endpoint_index(xhci_ep) + 1; /* EP Doorbells start at 1 */
    312312                err = hc_ring_doorbell(hc, slot_id, target);
    313                 xhci_ep->isoch_started = true;
    314         }
    315         fibril_mutex_unlock(&xhci_ep->isoch_guard);
     313                xhci_ep->isoch->started = true;
     314        }
     315        fibril_mutex_unlock(&xhci_ep->isoch->guard);
    316316        if (err) {
    317317                return err;
     
    331331                xhci_trb_clean(&trb);
    332332                trb.parameter = isoch_transfer->data.phys;
    333                 isoch_transfer->size = xhci_ep->isoch_max_size;
     333                isoch_transfer->size = xhci_ep->isoch->max_size;
    334334
    335335                int err = schedule_isochronous_trb(ring, xhci_ep, &trb, isoch_transfer->size,
     
    344344        xhci_device_t *xhci_dev)
    345345{
    346         fibril_mutex_lock(&xhci_ep->isoch_guard);
     346        fibril_mutex_lock(&xhci_ep->isoch->guard);
    347347        /* If not yet started, start the isochronous endpoint transfers - before first read */
    348         if (!xhci_ep->isoch_started) {
     348        if (!xhci_ep->isoch->started) {
    349349                xhci_trb_ring_t *ring = get_ring(hc, transfer);
    350350                /* Fill the TRB ring. */
    351351                int err = schedule_isochronous_in_trbs(xhci_ep, ring);
    352352                if (err) {
    353                         fibril_mutex_unlock(&xhci_ep->isoch_guard);
     353                        fibril_mutex_unlock(&xhci_ep->isoch->guard);
    354354                        return err;
    355355                }
     
    359359                err = hc_ring_doorbell(hc, slot_id, target);
    360360                if (err) {
    361                         fibril_mutex_unlock(&xhci_ep->isoch_guard);
     361                        fibril_mutex_unlock(&xhci_ep->isoch->guard);
    362362                        return err;
    363363                }
    364                 xhci_ep->isoch_started = true;
     364                xhci_ep->isoch->started = true;
    365365        }
    366366
    367367        xhci_isoch_transfer_t *isoch_transfer = isoch_transfer_get_enqueue(xhci_ep);
    368368        while(!isoch_transfer) {
    369                 fibril_condvar_wait(&xhci_ep->isoch_avail, &xhci_ep->isoch_guard);
     369                fibril_condvar_wait(&xhci_ep->isoch->avail, &xhci_ep->isoch->guard);
    370370                isoch_transfer = isoch_transfer_get_enqueue(xhci_ep);
    371371        }
     
    391391
    392392        trb.parameter = isoch_transfer->data.phys;
    393         isoch_transfer->size = xhci_ep->isoch_max_size;
     393        isoch_transfer->size = xhci_ep->isoch->max_size;
    394394
    395395        xhci_trb_ring_t *ring = get_ring(hc, transfer);
    396396        int err = schedule_isochronous_trb(ring, xhci_ep, &trb, isoch_transfer->size,
    397397                &isoch_transfer->interrupt_trb_phys);
    398         fibril_mutex_unlock(&xhci_ep->isoch_guard);
     398        fibril_mutex_unlock(&xhci_ep->isoch->guard);
    399399
    400400        if (err) {
     
    411411        xhci_device_t *xhci_dev)
    412412{
    413         if (transfer->batch.buffer_size > xhci_ep->isoch_max_size) {
     413        if (transfer->batch.buffer_size > xhci_ep->isoch->max_size) {
    414414                usb_log_error("Cannot schedule an oversized isochronous transfer.");
    415415                return EINVAL;
     
    425425
    426426static int handle_isochronous_transfer_event(xhci_hc_t *hc, xhci_trb_t *trb, xhci_endpoint_t *ep) {
    427         fibril_mutex_lock(&ep->isoch_guard);
     427        fibril_mutex_lock(&ep->isoch->guard);
    428428
    429429        int err = EOK;
     
    434434                case XHCI_TRBC_RING_UNDERRUN:
    435435                        /* Rings are unscheduled by xHC now */
    436                         ep->isoch_started = false;
     436                        ep->isoch->started = false;
    437437                        /* For OUT, there was nothing to process */
    438438                        /* For IN, the buffer has overfilled, we empty the buffers and readd TRBs */
    439                         ep->isoch_enqueue = ep->isoch_dequeue = 0;
     439                        ep->isoch->enqueue = ep->isoch->dequeue = 0;
    440440                        err = EIO;
    441441                        break;
     
    462462        }
    463463
    464         fibril_condvar_signal(&ep->isoch_avail);
    465         fibril_mutex_unlock(&ep->isoch_guard);
     464        fibril_condvar_signal(&ep->isoch->avail);
     465        fibril_mutex_unlock(&ep->isoch->guard);
    466466        return err;
    467467}
Note: See TracChangeset for help on using the changeset viewer.