Changeset 5c75456 in mainline
- Timestamp:
- 2017-12-29T17:11:14Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- bf7b747
- Parents:
- 5dfb70c9
- git-author:
- Salmelu <salmelu@…> (2017-12-29 17:10:05)
- git-committer:
- Salmelu <salmelu@…> (2017-12-29 17:11:14)
- Location:
- uspace
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/endpoint.c
r5dfb70c9 r5c75456 64 64 xhci_ep->mult = desc->usb3.mult; 65 65 66 // TODO: process according to 6.2.3.6 of XHCI specification; hardcoded for HS/SS EPs 67 xhci_ep->interval = desc->interval - 1; 68 66 69 if (xhci_ep->base.transfer_type == USB_TRANSFER_ISOCHRONOUS) { 67 70 xhci_ep->isoch_max_size = desc->usb3.bytes_per_interval … … 72 75 /* Allocate and setup isochronous-specific structures. */ 73 76 xhci_ep->isoch_enqueue = 0; 74 xhci_ep->isoch_dequeue = XHCI_ISOCH_BUFFER_COUNT - 1;77 xhci_ep->isoch_dequeue = 0; 75 78 xhci_ep->isoch_started = false; 76 79 … … 402 405 XHCI_EP_TR_DPTR_SET(*ctx, ep->ring.dequeue); 403 406 XHCI_EP_DCS_SET(*ctx, 1); 407 XHCI_EP_INTERVAL_SET(*ctx, ep->interval); 404 408 405 409 XHCI_EP_MAX_ESIT_PAYLOAD_LO_SET(*ctx, ep->isoch_max_size & 0xFFFF); … … 420 424 XHCI_EP_TR_DPTR_SET(*ctx, ep->ring.dequeue); 421 425 XHCI_EP_DCS_SET(*ctx, 1); 426 427 XHCI_EP_INTERVAL_SET(*ctx, ep->interval); 422 428 // TODO: max ESIT payload 423 429 } -
uspace/drv/bus/usb/xhci/endpoint.h
r5dfb70c9 r5c75456 89 89 /** Maximum number of bursts within an interval that this endpoint supports */ 90 90 uint8_t mult; 91 92 /** Scheduling interval for periodic endpoints */ 93 size_t interval; 91 94 92 95 /** The maximum size of an isochronous transfer and therefore the size of buffers */ -
uspace/drv/bus/usb/xhci/transfers.c
r5dfb70c9 r5c75456 234 234 235 235 static xhci_isoch_transfer_t* isoch_transfer_get_enqueue(xhci_endpoint_t *ep) { 236 if (( ep->isoch_enqueue% XHCI_ISOCH_BUFFER_COUNT) == ep->isoch_dequeue) {236 if (((ep->isoch_enqueue + 1) % XHCI_ISOCH_BUFFER_COUNT) == ep->isoch_dequeue) { 237 237 /* None ready */ 238 238 return NULL; … … 303 303 304 304 /* If not yet started, start the isochronous endpoint transfers - after buffer count - 1 writes */ 305 /* The - 2is there because of the enqueue != dequeue check. The buffer must have at least 2 transfers. */306 if ( xhci_ep->isoch_enqueue == XHCI_ISOCH_BUFFER_COUNT - 2&& !xhci_ep->isoch_started) {305 /* The -1 is there because of the enqueue != dequeue check. The buffer must have at least 2 transfers. */ 306 if (((xhci_ep->isoch_enqueue + 1) % XHCI_ISOCH_BUFFER_COUNT) == xhci_ep->isoch_dequeue && !xhci_ep->isoch_started) { 307 307 const uint8_t slot_id = xhci_dev->slot_id; 308 308 const uint8_t target = xhci_endpoint_index(xhci_ep) + 1; /* EP Doorbells start at 1 */ … … 322 322 } 323 323 324 static int schedule_isochronous_in_trbs(xhci_endpoint_t *xhci_ep, xhci_trb_ring_t *ring) { 325 xhci_trb_t trb; 326 xhci_isoch_transfer_t *isoch_transfer; 327 while ((isoch_transfer = isoch_transfer_get_enqueue(xhci_ep)) != NULL) { 328 xhci_trb_clean(&trb); 329 trb.parameter = isoch_transfer->data.phys; 330 isoch_transfer->size = xhci_ep->isoch_max_size; 331 332 int err = schedule_isochronous_trb(ring, xhci_ep, &trb, isoch_transfer->size, 333 &isoch_transfer->interrupt_trb_phys); 334 if (err) 335 return err; 336 } 337 return EOK; 338 } 339 324 340 static int schedule_isochronous_in(xhci_hc_t* hc, xhci_transfer_t* transfer, xhci_endpoint_t *xhci_ep, 325 341 xhci_device_t *xhci_dev) … … 328 344 /* If not yet started, start the isochronous endpoint transfers - before first read */ 329 345 if (!xhci_ep->isoch_started) { 346 xhci_trb_ring_t *ring = get_ring(hc, transfer); 347 /* Fill the TRB ring. */ 348 int err = schedule_isochronous_in_trbs(xhci_ep, ring); 349 if (err) { 350 fibril_mutex_unlock(&xhci_ep->isoch_guard); 351 return err; 352 } 353 /* Ring the doorbell to start it. */ 330 354 const uint8_t slot_id = xhci_dev->slot_id; 331 355 const uint8_t target = xhci_endpoint_index(xhci_ep) + 1; /* EP Doorbells start at 1 */ 332 interr = hc_ring_doorbell(hc, slot_id, target);356 err = hc_ring_doorbell(hc, slot_id, target); 333 357 if (err) { 334 358 fibril_mutex_unlock(&xhci_ep->isoch_guard); … … 406 430 case XHCI_TRBC_RING_OVERRUN: 407 431 case XHCI_TRBC_RING_UNDERRUN: 408 / / TODO: abort the phone; rings are unscheduled by xHC by now432 /* Rings are unscheduled by xHC now */ 409 433 ep->isoch_started = false; 434 /* For OUT, there was nothing to process */ 435 /* For IN, the buffer has overfilled, we empty the buffers and readd TRBs */ 436 ep->isoch_enqueue = ep->isoch_dequeue = 0; 410 437 err = EIO; 411 438 break; -
uspace/lib/drv/include/usb_iface.h
r5dfb70c9 r5c75456 115 115 size_t max_packet_size; 116 116 117 /** Scheduling interval for HC. Only valid for interrupt/isoch transfer. */ 118 size_t interval; 119 117 120 /** Number of packets per frame/uframe. 118 121 * Only valid for HS INT and ISO transfers. All others should set to 1*/ -
uspace/lib/usbdev/src/pipes.c
r5dfb70c9 r5c75456 299 299 pipe->bus_session = bus_session; 300 300 301 // TODO: hardcoded, remake to receive from device descriptors 302 pipe->desc.interval = 14; 303 301 304 if (transfer_type == USB_TRANSFER_ISOCHRONOUS) { 302 305 ret = usb_isoch_session_initialize(pipe);
Note:
See TracChangeset
for help on using the changeset viewer.