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. if (ring->trbs[ring->enqueue].control & 1) {
  11. ring->trbs[ring->enqueue].control &= ~1;
  12. } else {
  13. ring->trbs[ring->enqueue].control |= 1;
  14. }
  15. if (ring->trbs[ring->enqueue].control & 1) {
  16. ring->cycle ^= 1;
  17. }
  18. ring->enqueue = 0;
  19. }
  20. return result;
  21. }
  22.  
  23. XHCITRB *trbRingFetch(TrbRing *ring, uint32_t *index) {
  24. if ((ring->trbs[ring->dequeue].control & 1) != ring->cycle) {
  25. return NULL;
  26. }
  27. if (index) {
  28. *index = ring->dequeue;
  29. }
  30. XHCITRB *result = &ring->trbs[ring->dequeue];
  31. ring->dequeue++;
  32. if (ring->dequeue == ring->size) {
  33. ring->dequeue = 0;
  34. ring->cycle ^= -1;
  35. }
  36. return result;
  37. }
  38.  
  39. void setupTrbRing(TrbRing *ring, uint32_t size) {
  40. ring->trbs = requestMemory(1, 0, 0);
  41. ring->physical = getPhysicalAddress((void *)ring->trbs);
  42. ring->cycle = true;
  43. ring->enqueue = 0;
  44. ring->dequeue = 0;
  45. ring->size = size;
  46. // define link to beginning
  47. ring->trbs[ring->size - 1].dataLow = U32(ring->physical);
  48. ring->trbs[ring->size - 1].control |= 1 << 1 | COMMAND_TYPE(6);
  49. }
  50.  
  51. TrbRing *createSlotTRB(SlotXHCI *slot) {
  52. TrbRing *ring = malloc(sizeof(TrbRing));
  53. setupTrbRing(ring, 256);
  54. slot->inputContext->deviceContext.endpoints[0].transferDequeuePointerLow =
  55. U32(ring->physical) | 1;
  56. slot->inputContext->deviceContext.endpoints[0].transferDequeuePointerHigh =
  57. 0;
  58. return ring;
  59. }