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


Ignore:
Timestamp:
2017-10-21T10:34:45Z (6 years ago)
Author:
Petr Manek <petr.manek@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8ea7459
Parents:
1252e81
Message:

Added option to enqueue multiple TDs at once. Demoted some log messages.

File:
1 edited

Legend:

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

    r1252e81 rd1d7a92  
    116116        fibril_mutex_initialize(&ring->guard);
    117117
    118         usb_log_debug("Initialized new TRB ring.");
     118        usb_log_debug2("Initialized new TRB ring.");
    119119
    120120        return EOK;
     
    156156
    157157/**
    158  * Enqueue a TD composed of TRBs.
    159  *
    160  * This will copy all TRBs chained together into the ring. The cycle flag in
    161  * TRBs may be changed.
    162  *
    163  * The chained TRBs must be contiguous in memory, and must not contain Link TRBs.
     158 * Enqueue TDs composed of TRBs.
     159 *
     160 * This will copy specified number of TRBs chained together into the ring. The
     161 * cycle flag in TRBs may be changed.
     162 *
     163 * The copied TRBs must be contiguous in memory, and must not contain Link TRBs.
    164164 *
    165165 * We cannot avoid the copying, because the TRB in ring should be updated atomically.
    166166 *
    167  * @param td the first TRB of TD
    168  * @param phys returns address of the first TRB enqueued
     167 * @param first_trb the first TRB
     168 * @param trbs number of TRBS to enqueue
     169 * @param phys returns address of the last TRB enqueued
    169170 * @return EOK on success,
    170171 *         EAGAIN when the ring is too full to fit all TRBs (temporary)
    171172 */
    172 int xhci_trb_ring_enqueue(xhci_trb_ring_t *ring, xhci_trb_t *td, uintptr_t *phys)
    173 {
     173int xhci_trb_ring_enqueue_multiple(xhci_trb_ring_t *ring, xhci_trb_t *first_trb,
     174        size_t trbs, uintptr_t *phys)
     175{
     176        assert(trbs > 0);
    174177        fibril_mutex_lock(&ring->guard);
    175178
     
    183186         * be full anytime during the transaction.
    184187         */
    185         xhci_trb_t *trb = td;
    186         do {
     188        xhci_trb_t *trb = first_trb;
     189        for (size_t i = 0; i < trbs; ++i, ++trb) {
    187190                ring->enqueue_trb++;
    188191
     
    192195                if (trb_ring_enqueue_phys(ring) == ring->dequeue)
    193196                        goto err_again;
    194         } while (xhci_trb_is_chained(trb++));
     197        }
    195198
    196199        ring->enqueue_segment = saved_enqueue_segment;
    197200        ring->enqueue_trb = saved_enqueue_trb;
    198         if (phys)
    199                 *phys = trb_ring_enqueue_phys(ring);
    200201
    201202        /*
    202203         * Now, copy the TRBs without further checking.
    203204         */
    204         trb = td;
    205         do {
     205        trb = first_trb;
     206        for (size_t i = 0; i < trbs; ++i, ++trb) {
     207                if (phys && i == trbs - 1)
     208                        *phys = trb_ring_enqueue_phys(ring);
     209
    206210                xhci_trb_set_cycle(trb, ring->pcs);
    207211                xhci_trb_copy(ring->enqueue_trb, trb);
     
    221225                        trb_ring_resolve_link(ring);
    222226                }
    223         } while (xhci_trb_is_chained(trb++));
     227        }
    224228
    225229        fibril_mutex_unlock(&ring->guard);
     
    234238
    235239/**
     240 * Enqueue TD composed of a single TRB. See: `xhci_trb_ring_enqueue_multiple`
     241 */
     242int xhci_trb_ring_enqueue(xhci_trb_ring_t *ring, xhci_trb_t *td, uintptr_t *phys)
     243{
     244        return xhci_trb_ring_enqueue_multiple(ring, td, 1, phys);
     245}
     246
     247/**
    236248 * Initializes an event ring.
    237249 * Even when it fails, the structure needs to be finalized.
Note: See TracChangeset for help on using the changeset viewer.