Changeset 2bff2cc2 in mainline for uspace/drv/bus/usb/xhci/trb_ring.c


Ignore:
Timestamp:
2018-01-18T14:00:57Z (7 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
2c0564c
Parents:
0f79283b
git-author:
Ondřej Hlavatý <aearsis@…> (2018-01-18 13:30:15)
git-committer:
Ondřej Hlavatý <aearsis@…> (2018-01-18 14:00:57)
Message:

xhci: implement sw trb ring

File:
1 edited

Legend:

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

    r0f79283b r2bff2cc2  
    376376        return EOK;
    377377}
     378
     379void xhci_sw_ring_init(xhci_sw_ring_t *ring, size_t size)
     380{
     381        ring->begin = calloc(size, sizeof(xhci_trb_t));
     382        ring->end = ring->begin + size;
     383
     384        ring->enqueue = ring->dequeue = ring->begin;
     385
     386        fibril_mutex_initialize(&ring->guard);
     387        fibril_condvar_initialize(&ring->enqueued_cv);
     388        fibril_condvar_initialize(&ring->dequeued_cv);
     389
     390        ring->running = true;
     391}
     392
     393int xhci_sw_ring_enqueue(xhci_sw_ring_t *ring, xhci_trb_t *trb)
     394{
     395        assert(ring);
     396        assert(trb);
     397
     398        fibril_mutex_lock(&ring->guard);
     399        while (ring->running && TRB_CYCLE(*ring->enqueue))
     400                fibril_condvar_wait(&ring->dequeued_cv, &ring->guard);
     401
     402        *ring->enqueue = *trb;
     403        TRB_SET_CYCLE(*ring->enqueue, 1);
     404        if (++ring->enqueue == ring->end)
     405                ring->enqueue = ring->begin;
     406        fibril_condvar_signal(&ring->enqueued_cv);
     407        fibril_mutex_unlock(&ring->guard);
     408
     409        return ring->running ? EOK : EINTR;
     410}
     411
     412int xhci_sw_ring_dequeue(xhci_sw_ring_t *ring, xhci_trb_t *trb)
     413{
     414        assert(ring);
     415        assert(trb);
     416
     417        fibril_mutex_lock(&ring->guard);
     418        while (ring->running && !TRB_CYCLE(*ring->dequeue))
     419                fibril_condvar_wait(&ring->enqueued_cv, &ring->guard);
     420
     421        *trb = *ring->dequeue;
     422        TRB_SET_CYCLE(*ring->dequeue, 0);
     423        if (++ring->dequeue == ring->end)
     424                ring->dequeue = ring->begin;
     425        fibril_condvar_signal(&ring->dequeued_cv);
     426        fibril_mutex_unlock(&ring->guard);
     427
     428        return ring->running ? EOK : EINTR;
     429}
     430
     431void xhci_sw_ring_stop(xhci_sw_ring_t *ring)
     432{
     433        ring->running = false;
     434        fibril_condvar_broadcast(&ring->enqueued_cv);
     435        fibril_condvar_broadcast(&ring->dequeued_cv);
     436}
     437
     438void xhci_sw_ring_fini(xhci_sw_ring_t *ring)
     439{
     440        free(ring->begin);
     441}
     442
     443/**
     444 * @}
     445 */
Note: See TracChangeset for help on using the changeset viewer.