Changeset 2bff2cc2 in mainline
- Timestamp:
- 2018-01-18T14:00:57Z (7 years ago)
- 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)
- Location:
- uspace/drv/bus/usb/xhci
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/trb_ring.c
r0f79283b r2bff2cc2 376 376 return EOK; 377 377 } 378 379 void 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 393 int 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 412 int 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 431 void 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 438 void xhci_sw_ring_fini(xhci_sw_ring_t *ring) 439 { 440 free(ring->begin); 441 } 442 443 /** 444 * @} 445 */ -
uspace/drv/bus/usb/xhci/trb_ring.h
r0f79283b r2bff2cc2 119 119 int xhci_event_ring_dequeue(xhci_event_ring_t *, xhci_trb_t *); 120 120 121 /** 122 * A TRB ring of which the software is both consumer and provider. 123 */ 124 typedef struct xhci_sw_ring { 125 xhci_trb_t *begin, *end; 126 xhci_trb_t *enqueue, *dequeue; 127 128 fibril_mutex_t guard; 129 fibril_condvar_t enqueued_cv, dequeued_cv; 130 131 bool running; 132 } xhci_sw_ring_t; 133 134 void xhci_sw_ring_init(xhci_sw_ring_t *, size_t); 135 136 /* Both may block if the ring is full/empty. */ 137 int xhci_sw_ring_enqueue(xhci_sw_ring_t *, xhci_trb_t *); 138 int xhci_sw_ring_dequeue(xhci_sw_ring_t *, xhci_trb_t *); 139 140 void xhci_sw_ring_stop(xhci_sw_ring_t *); 141 void xhci_sw_ring_fini(xhci_sw_ring_t *); 142 121 143 #endif 144 145 /** 146 * @} 147 */
Note:
See TracChangeset
for help on using the changeset viewer.