Changeset 5c75456 in mainline for uspace/drv/bus/usb/xhci/transfers.c


Ignore:
Timestamp:
2017-12-29T17:11:14Z (6 years ago)
Author:
Salmelu <salmelu@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
bf7b747
Parents:
5dfb70c9
git-author:
Salmelu <salmelu@…> (2017-12-29 17:10:05)
git-committer:
Salmelu <salmelu@…> (2017-12-29 17:11:14)
Message:

xhci: isochronous transfers made working

File:
1 edited

Legend:

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

    r5dfb70c9 r5c75456  
    234234
    235235static xhci_isoch_transfer_t* isoch_transfer_get_enqueue(xhci_endpoint_t *ep) {
    236         if ((ep->isoch_enqueue % XHCI_ISOCH_BUFFER_COUNT) == ep->isoch_dequeue) {
     236        if (((ep->isoch_enqueue + 1) % XHCI_ISOCH_BUFFER_COUNT) == ep->isoch_dequeue) {
    237237                /* None ready */
    238238                return NULL;
     
    303303
    304304        /* If not yet started, start the isochronous endpoint transfers - after buffer count - 1 writes */
    305         /* The -2 is there because of the enqueue != dequeue check. The buffer must have at least 2 transfers. */
    306         if (xhci_ep->isoch_enqueue == XHCI_ISOCH_BUFFER_COUNT - 2 && !xhci_ep->isoch_started) {
     305        /* The -1 is there because of the enqueue != dequeue check. The buffer must have at least 2 transfers. */
     306        if (((xhci_ep->isoch_enqueue + 1) % XHCI_ISOCH_BUFFER_COUNT) == xhci_ep->isoch_dequeue && !xhci_ep->isoch_started) {
    307307                const uint8_t slot_id = xhci_dev->slot_id;
    308308                const uint8_t target = xhci_endpoint_index(xhci_ep) + 1; /* EP Doorbells start at 1 */
     
    322322}
    323323
     324static int schedule_isochronous_in_trbs(xhci_endpoint_t *xhci_ep, xhci_trb_ring_t *ring) {
     325        xhci_trb_t trb;
     326        xhci_isoch_transfer_t *isoch_transfer;
     327        while ((isoch_transfer = isoch_transfer_get_enqueue(xhci_ep)) != NULL) {
     328                xhci_trb_clean(&trb);
     329                trb.parameter = isoch_transfer->data.phys;
     330                isoch_transfer->size = xhci_ep->isoch_max_size;
     331
     332                int err = schedule_isochronous_trb(ring, xhci_ep, &trb, isoch_transfer->size,
     333                        &isoch_transfer->interrupt_trb_phys);
     334                if (err)
     335                        return err;
     336        }
     337        return EOK;
     338}
     339
    324340static int schedule_isochronous_in(xhci_hc_t* hc, xhci_transfer_t* transfer, xhci_endpoint_t *xhci_ep,
    325341        xhci_device_t *xhci_dev)
     
    328344        /* If not yet started, start the isochronous endpoint transfers - before first read */
    329345        if (!xhci_ep->isoch_started) {
     346                xhci_trb_ring_t *ring = get_ring(hc, transfer);
     347                /* Fill the TRB ring. */
     348                int err = schedule_isochronous_in_trbs(xhci_ep, ring);
     349                if (err) {
     350                        fibril_mutex_unlock(&xhci_ep->isoch_guard);
     351                        return err;
     352                }
     353                /* Ring the doorbell to start it. */
    330354                const uint8_t slot_id = xhci_dev->slot_id;
    331355                const uint8_t target = xhci_endpoint_index(xhci_ep) + 1; /* EP Doorbells start at 1 */
    332                 int err = hc_ring_doorbell(hc, slot_id, target);
     356                err = hc_ring_doorbell(hc, slot_id, target);
    333357                if (err) {
    334358                        fibril_mutex_unlock(&xhci_ep->isoch_guard);
     
    406430                case XHCI_TRBC_RING_OVERRUN:
    407431                case XHCI_TRBC_RING_UNDERRUN:
    408                         // TODO: abort the phone; rings are unscheduled by xHC by now
     432                        /* Rings are unscheduled by xHC now */
    409433                        ep->isoch_started = false;
     434                        /* For OUT, there was nothing to process */
     435                        /* For IN, the buffer has overfilled, we empty the buffers and readd TRBs */
     436                        ep->isoch_enqueue = ep->isoch_dequeue = 0;
    410437                        err = EIO;
    411438                        break;
Note: See TracChangeset for help on using the changeset viewer.