Newer
Older
honey-os / src / userland / usb / xhci / trbRing.c
  1. #include "xhci.h"
  2. #include <usb.h>
  3.  
  4. XHCITRB *enqueueCommand(TrbRing *ring, XHCITRB *trb) {
  5. trb->control |= ring->cycle;
  6. memcpy((void *)trb, (void *)&ring->trbs[ring->enqueue], sizeof(XHCITRB));
  7. XHCITRB *result = &ring->physical[ring->enqueue];
  8. ring->enqueue++;
  9. if (ring->enqueue == ring->size - 1) {
  10. ring->trbs[ring->enqueue].control = 1 ^ ring->trbs[ring->enqueue].control;
  11. ring->cycle ^= 1;
  12. ring->enqueue = 0;
  13. }
  14. return result;
  15. }
  16.  
  17. XHCITRB *trbRingFetch(TrbRing *ring, uint32_t *index) {
  18. if ((ring->trbs[ring->dequeue].control & 1) != ring->cycle) {
  19. return NULL;
  20. }
  21. if (index) {
  22. *index = ring->dequeue;
  23. }
  24. XHCITRB *result = &ring->trbs[ring->dequeue];
  25. ring->dequeue++;
  26. if (ring->dequeue == ring->size - 1) {
  27. ring->dequeue = 0;
  28. ring->cycle ^= 1;
  29. }
  30. return result;
  31. }
  32.  
  33. void setupTrbRing(TrbRing *ring, uint32_t size) {
  34. ring->trbs = malloc(sizeof(XHCITRB) * (size + 1));
  35. ring->physical = getPhysicalAddress((void *)ring->trbs);
  36. ring->cycle = true;
  37. ring->enqueue = 0;
  38. ring->dequeue = 0;
  39. ring->size = size;
  40. // define link to beginning
  41. ring->trbs[ring->size - 1].dataLow = U32(ring->physical);
  42. ring->trbs[ring->size - 1].dataHigh = 0;
  43. ring->trbs[ring->size - 1].control = 1 << 1 | COMMAND_TYPE(6);
  44. }
  45.  
  46. TrbRing *createSlotTRB(SlotXHCI *slot) {
  47. TrbRing *ring = malloc(sizeof(TrbRing));
  48. setupTrbRing(ring, 255);
  49. slot->inputContext->deviceContext.endpoints[0].transferDequeuePointerLow =
  50. U32(ring->physical) | 1;
  51. slot->inputContext->deviceContext.endpoints[0].transferDequeuePointerHigh =
  52. 0;
  53. return ring;
  54. }