Changeset 998773d in mainline
- Timestamp:
- 2018-01-22T14:27:24Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- effbef3
- Parents:
- db51a6a6
- git-author:
- Ondřej Hlavatý <aearsis@…> (2018-01-22 14:11:42)
- git-committer:
- Ondřej Hlavatý <aearsis@…> (2018-01-22 14:27:24)
- Location:
- uspace/drv/bus/usb/xhci
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/commands.c
rdb51a6a6 r998773d 77 77 int err; 78 78 79 if ((err = xhci_trb_ring_init(&cr->trb_ring )))79 if ((err = xhci_trb_ring_init(&cr->trb_ring, 0))) 80 80 return err; 81 81 -
uspace/drv/bus/usb/xhci/endpoint.c
rdb51a6a6 r998773d 285 285 286 286 int err; 287 if ((err = xhci_trb_ring_init(&xhci_ep->ring ))) {287 if ((err = xhci_trb_ring_init(&xhci_ep->ring, 0))) { 288 288 return err; 289 289 } -
uspace/drv/bus/usb/xhci/hc.c
rdb51a6a6 r998773d 262 262 hc->dcbaa = hc->dcbaa_dma.virt; 263 263 264 if ((err = xhci_event_ring_init(&hc->event_ring )))264 if ((err = xhci_event_ring_init(&hc->event_ring, 1))) 265 265 goto err_dcbaa; 266 266 … … 494 494 XHCI_REG_WR(intr0, XHCI_INTR_ERSTBA_HI, UPPER32(erstptr)); 495 495 496 497 496 if (irq) { 498 497 XHCI_REG_SET(intr0, XHCI_INTR_IE, 1); -
uspace/drv/bus/usb/xhci/streams.c
rdb51a6a6 r998773d 154 154 155 155 /* Init and register TRB ring for the primary stream */ 156 if ((err = xhci_trb_ring_init(&data->ring ))) {156 if ((err = xhci_trb_ring_init(&data->ring, 0))) { 157 157 return err; 158 158 } … … 233 233 xhci_stream_data_t *secondary_data = &data->secondary_data[index]; 234 234 /* Init and register TRB ring for every secondary stream */ 235 if ((err = xhci_trb_ring_init(&secondary_data->ring ))) {235 if ((err = xhci_trb_ring_init(&secondary_data->ring, 0))) { 236 236 goto err_init; 237 237 } … … 332 332 /* Streams are now removed, proceed with reconfiguring endpoint. */ 333 333 int err; 334 if ((err = xhci_trb_ring_init(&xhci_ep->ring ))) {334 if ((err = xhci_trb_ring_init(&xhci_ep->ring, 0))) { 335 335 usb_log_error("Failed to initialize a transfer ring."); 336 336 return err; -
uspace/drv/bus/usb/xhci/trb_ring.c
rdb51a6a6 r998773d 37 37 #include "trb_ring.h" 38 38 39 #define SEGMENT_HEADER_SIZE (sizeof(link_t) + sizeof(uintptr_t)) 40 41 /** 42 * Number of TRBs in a segment (with our header). 43 */ 44 #define SEGMENT_TRB_COUNT ((PAGE_SIZE - SEGMENT_HEADER_SIZE) / sizeof(xhci_trb_t)) 39 /** 40 * A structure representing a segment of a TRB ring. 41 */ 42 43 #define SEGMENT_FOOTER_SIZE (sizeof(link_t) + sizeof(uintptr_t)) 44 45 #define SEGMENT_TRB_COUNT ((PAGE_SIZE - SEGMENT_FOOTER_SIZE) / sizeof(xhci_trb_t)) 46 #define SEGMENT_TRB_USEFUL_COUNT (SEGMENT_TRB_COUNT - 1) 45 47 46 48 struct trb_segment { … … 51 53 } __attribute__((aligned(PAGE_SIZE))); 52 54 55 static_assert(sizeof(trb_segment_t) == PAGE_SIZE); 56 53 57 54 58 /** … … 66 70 { 67 71 return segment_begin(segment) + SEGMENT_TRB_COUNT; 72 } 73 74 /** 75 * Return a first segment of a list of segments. 76 */ 77 static inline trb_segment_t *get_first_segment(list_t *segments) 78 { 79 return list_get_instance(list_first(segments), trb_segment_t, segments_link); 80 68 81 } 69 82 … … 97 110 /** 98 111 * Initializes the ring with one segment. 99 */ 100 int xhci_trb_ring_init(xhci_trb_ring_t *ring) 101 { 102 struct trb_segment *segment; 112 * 113 * @param[in] initial_size A number of free slots on the ring, 0 leaves the 114 * choice on a reasonable default (one page-sized segment). 115 */ 116 int xhci_trb_ring_init(xhci_trb_ring_t *ring, size_t initial_size) 117 { 103 118 int err; 119 if (initial_size == 0) 120 initial_size = SEGMENT_TRB_USEFUL_COUNT; 104 121 105 122 list_initialize(&ring->segments); 106 107 if ((err = trb_segment_alloc(&segment)) != EOK) 108 return err; 109 110 list_append(&segment->segments_link, &ring->segments); 111 ring->segment_count = 1; 112 123 size_t segment_count = (initial_size + SEGMENT_TRB_USEFUL_COUNT - 1) 124 / SEGMENT_TRB_USEFUL_COUNT; 125 126 for (size_t i = 0; i < segment_count; ++i) { 127 struct trb_segment *segment; 128 if ((err = trb_segment_alloc(&segment)) != EOK) 129 return err; 130 131 list_append(&segment->segments_link, &ring->segments); 132 ring->segment_count = i + 1; 133 } 134 135 trb_segment_t * const segment = get_first_segment(&ring->segments); 113 136 xhci_trb_t *last = segment_end(segment) - 1; 114 137 xhci_trb_link_fill(last, segment->phys); … … 284 307 /** 285 308 * Initializes an event ring. 286 */ 287 int xhci_event_ring_init(xhci_event_ring_t *ring) 288 { 289 struct trb_segment *segment; 309 * 310 * @param[in] initial_size A number of free slots on the ring, 0 leaves the 311 * choice on a reasonable default (one page-sized segment). 312 */ 313 int xhci_event_ring_init(xhci_event_ring_t *ring, size_t initial_size) 314 { 290 315 int err; 316 if (initial_size == 0) 317 initial_size = SEGMENT_TRB_COUNT; 291 318 292 319 list_initialize(&ring->segments); 293 320 294 if ((err = trb_segment_alloc(&segment)) != EOK) 295 return err; 296 297 list_append(&segment->segments_link, &ring->segments); 298 ring->segment_count = 1; 299 321 size_t segment_count = (initial_size + SEGMENT_TRB_COUNT - 1) / SEGMENT_TRB_COUNT; 322 size_t erst_size = segment_count * sizeof(xhci_erst_entry_t); 323 324 if (dma_buffer_alloc(&ring->erst, erst_size)) { 325 xhci_event_ring_fini(ring); 326 return ENOMEM; 327 } 328 329 xhci_erst_entry_t *erst = ring->erst.virt; 330 memset(erst, 0, erst_size); 331 332 for (size_t i = 0; i < segment_count; i++) { 333 trb_segment_t *segment; 334 if ((err = trb_segment_alloc(&segment)) != EOK) { 335 xhci_event_ring_fini(ring); 336 return err; 337 } 338 339 list_append(&segment->segments_link, &ring->segments); 340 ring->segment_count = i + 1; 341 xhci_fill_erst_entry(&erst[i], segment->phys, SEGMENT_TRB_COUNT); 342 } 343 344 trb_segment_t * const segment = get_first_segment(&ring->segments); 300 345 ring->dequeue_segment = segment; 301 346 ring->dequeue_trb = segment_begin(segment); 302 347 ring->dequeue_ptr = segment->phys; 303 304 if (dma_buffer_alloc(&ring->erst, PAGE_SIZE)) {305 xhci_event_ring_fini(ring);306 return ENOMEM;307 }308 xhci_erst_entry_t *erst = ring->erst.virt;309 310 memset(erst, 0, PAGE_SIZE);311 xhci_fill_erst_entry(&erst[0], segment->phys, SEGMENT_TRB_COUNT);312 313 348 ring->ccs = 1; 314 349 … … 316 351 317 352 usb_log_debug("Initialized event ring."); 318 319 353 return EOK; 320 354 } … … 324 358 list_foreach_safe(ring->segments, cur, next) { 325 359 trb_segment_t *segment = list_get_instance(cur, trb_segment_t, segments_link); 326 dmamem_unmap_anonymous(segment);360 trb_segment_free(segment); 327 361 } 328 362 -
uspace/drv/bus/usb/xhci/trb_ring.h
rdb51a6a6 r998773d 74 74 } xhci_trb_ring_t; 75 75 76 int xhci_trb_ring_init(xhci_trb_ring_t * );76 int xhci_trb_ring_init(xhci_trb_ring_t *, size_t); 77 77 void xhci_trb_ring_fini(xhci_trb_ring_t *); 78 78 int xhci_trb_ring_enqueue(xhci_trb_ring_t *, xhci_trb_t *, uintptr_t *); … … 107 107 } xhci_event_ring_t; 108 108 109 int xhci_event_ring_init(xhci_event_ring_t * );109 int xhci_event_ring_init(xhci_event_ring_t *, size_t); 110 110 void xhci_event_ring_fini(xhci_event_ring_t *); 111 111 int xhci_event_ring_dequeue(xhci_event_ring_t *, xhci_trb_t *);
Note:
See TracChangeset
for help on using the changeset viewer.