Lines 2440-2445
ehci_device_isoc_fs_enter(struct usb_xfer *xfer)
Link Here
|
2440 |
uint32_t *plen; |
2440 |
uint32_t *plen; |
2441 |
uint32_t buf_offset; |
2441 |
uint32_t buf_offset; |
2442 |
uint32_t nframes; |
2442 |
uint32_t nframes; |
|
|
2443 |
uint32_t startframe; |
2443 |
uint32_t temp; |
2444 |
uint32_t temp; |
2444 |
uint32_t sitd_mask; |
2445 |
uint32_t sitd_mask; |
2445 |
uint16_t tlen; |
2446 |
uint16_t tlen; |
Lines 2458-2496
ehci_device_isoc_fs_enter(struct usb_xfer *xfer)
Link Here
|
2458 |
|
2459 |
|
2459 |
nframes = EOREAD4(sc, EHCI_FRINDEX) / 8; |
2460 |
nframes = EOREAD4(sc, EHCI_FRINDEX) / 8; |
2460 |
|
2461 |
|
2461 |
/* |
2462 |
if (usbd_xfer_get_isochronous_start_frame( |
2462 |
* check if the frame index is within the window where the frames |
2463 |
xfer, nframes, 1, EHCI_VIRTUAL_FRAMELIST_COUNT - 1, &startframe)) |
2463 |
* will be inserted |
2464 |
DPRINTFN(3, "start next=%d\n", startframe); |
2464 |
*/ |
|
|
2465 |
buf_offset = (nframes - xfer->endpoint->isoc_next) & |
2466 |
(EHCI_VIRTUAL_FRAMELIST_COUNT - 1); |
2467 |
|
2468 |
if ((xfer->endpoint->is_synced == 0) || |
2469 |
(buf_offset < xfer->nframes)) { |
2470 |
/* |
2471 |
* If there is data underflow or the pipe queue is empty we |
2472 |
* schedule the transfer a few frames ahead of the current |
2473 |
* frame position. Else two isochronous transfers might |
2474 |
* overlap. |
2475 |
*/ |
2476 |
xfer->endpoint->isoc_next = (nframes + 3) & |
2477 |
(EHCI_VIRTUAL_FRAMELIST_COUNT - 1); |
2478 |
xfer->endpoint->is_synced = 1; |
2479 |
DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next); |
2480 |
} |
2481 |
/* |
2482 |
* compute how many milliseconds the insertion is ahead of the |
2483 |
* current frame position: |
2484 |
*/ |
2485 |
buf_offset = (xfer->endpoint->isoc_next - nframes) & |
2486 |
(EHCI_VIRTUAL_FRAMELIST_COUNT - 1); |
2487 |
|
2488 |
/* |
2489 |
* pre-compute when the isochronous transfer will be finished: |
2490 |
*/ |
2491 |
xfer->isoc_time_complete = |
2492 |
usb_isoc_time_expand(&sc->sc_bus, nframes) + |
2493 |
buf_offset + xfer->nframes; |
2494 |
|
2465 |
|
2495 |
/* get the real number of frames */ |
2466 |
/* get the real number of frames */ |
2496 |
|
2467 |
|
Lines 2507-2517
ehci_device_isoc_fs_enter(struct usb_xfer *xfer)
Link Here
|
2507 |
td = xfer->td_start[xfer->flags_int.curr_dma_set]; |
2478 |
td = xfer->td_start[xfer->flags_int.curr_dma_set]; |
2508 |
xfer->td_transfer_first = td; |
2479 |
xfer->td_transfer_first = td; |
2509 |
|
2480 |
|
2510 |
pp_last = &sc->sc_isoc_fs_p_last[xfer->endpoint->isoc_next]; |
2481 |
pp_last = &sc->sc_isoc_fs_p_last[startframe]; |
2511 |
|
2482 |
|
2512 |
/* store starting position */ |
2483 |
/* store starting position */ |
2513 |
|
2484 |
|
2514 |
xfer->qh_pos = xfer->endpoint->isoc_next; |
2485 |
xfer->qh_pos = startframe; |
2515 |
|
2486 |
|
2516 |
while (nframes--) { |
2487 |
while (nframes--) { |
2517 |
if (td == NULL) { |
2488 |
if (td == NULL) { |
Lines 2633-2642
ehci_device_isoc_fs_enter(struct usb_xfer *xfer)
Link Here
|
2633 |
|
2604 |
|
2634 |
xfer->td_transfer_last = td_last; |
2605 |
xfer->td_transfer_last = td_last; |
2635 |
|
2606 |
|
2636 |
/* update isoc_next */ |
|
|
2637 |
xfer->endpoint->isoc_next = (pp_last - &sc->sc_isoc_fs_p_last[0]) & |
2638 |
(EHCI_VIRTUAL_FRAMELIST_COUNT - 1); |
2639 |
|
2640 |
/* |
2607 |
/* |
2641 |
* We don't allow cancelling of the SPLIT transaction USB FULL |
2608 |
* We don't allow cancelling of the SPLIT transaction USB FULL |
2642 |
* speed transfer, because it disturbs the bandwidth |
2609 |
* speed transfer, because it disturbs the bandwidth |
Lines 2743-2753
ehci_device_isoc_hs_enter(struct usb_xfer *xfer)
Link Here
|
2743 |
uint32_t status; |
2710 |
uint32_t status; |
2744 |
uint32_t buf_offset; |
2711 |
uint32_t buf_offset; |
2745 |
uint32_t nframes; |
2712 |
uint32_t nframes; |
|
|
2713 |
uint32_t startframe; |
2746 |
uint32_t itd_offset[8 + 1]; |
2714 |
uint32_t itd_offset[8 + 1]; |
2747 |
uint8_t x; |
2715 |
uint8_t x; |
2748 |
uint8_t td_no; |
2716 |
uint8_t td_no; |
2749 |
uint8_t page_no; |
2717 |
uint8_t page_no; |
2750 |
uint8_t shift = usbd_xfer_get_fps_shift(xfer); |
|
|
2751 |
|
2718 |
|
2752 |
#ifdef USB_DEBUG |
2719 |
#ifdef USB_DEBUG |
2753 |
uint8_t once = 1; |
2720 |
uint8_t once = 1; |
Lines 2755-2801
ehci_device_isoc_hs_enter(struct usb_xfer *xfer)
Link Here
|
2755 |
#endif |
2722 |
#endif |
2756 |
|
2723 |
|
2757 |
DPRINTFN(6, "xfer=%p next=%d nframes=%d shift=%d\n", |
2724 |
DPRINTFN(6, "xfer=%p next=%d nframes=%d shift=%d\n", |
2758 |
xfer, xfer->endpoint->isoc_next, xfer->nframes, (int)shift); |
2725 |
xfer, xfer->endpoint->isoc_next, xfer->nframes, |
|
|
2726 |
usbd_xfer_get_fps_shift(xfer)); |
2759 |
|
2727 |
|
2760 |
/* get the current frame index */ |
2728 |
/* get the current frame index */ |
2761 |
|
2729 |
|
2762 |
nframes = EOREAD4(sc, EHCI_FRINDEX) / 8; |
2730 |
nframes = EOREAD4(sc, EHCI_FRINDEX) / 8; |
2763 |
|
2731 |
|
2764 |
/* |
2732 |
if (usbd_xfer_get_isochronous_start_frame( |
2765 |
* check if the frame index is within the window where the frames |
2733 |
xfer, nframes, 1, EHCI_VIRTUAL_FRAMELIST_COUNT - 1, &startframe)) |
2766 |
* will be inserted |
2734 |
DPRINTFN(3, "start next=%d\n", startframe); |
2767 |
*/ |
|
|
2768 |
buf_offset = (nframes - xfer->endpoint->isoc_next) & |
2769 |
(EHCI_VIRTUAL_FRAMELIST_COUNT - 1); |
2770 |
|
2771 |
if ((xfer->endpoint->is_synced == 0) || |
2772 |
(buf_offset < (((xfer->nframes << shift) + 7) / 8))) { |
2773 |
/* |
2774 |
* If there is data underflow or the pipe queue is empty we |
2775 |
* schedule the transfer a few frames ahead of the current |
2776 |
* frame position. Else two isochronous transfers might |
2777 |
* overlap. |
2778 |
*/ |
2779 |
xfer->endpoint->isoc_next = (nframes + 3) & |
2780 |
(EHCI_VIRTUAL_FRAMELIST_COUNT - 1); |
2781 |
xfer->endpoint->is_synced = 1; |
2782 |
DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next); |
2783 |
} |
2784 |
/* |
2785 |
* compute how many milliseconds the insertion is ahead of the |
2786 |
* current frame position: |
2787 |
*/ |
2788 |
buf_offset = (xfer->endpoint->isoc_next - nframes) & |
2789 |
(EHCI_VIRTUAL_FRAMELIST_COUNT - 1); |
2790 |
|
2791 |
/* |
2792 |
* pre-compute when the isochronous transfer will be finished: |
2793 |
*/ |
2794 |
xfer->isoc_time_complete = |
2795 |
usb_isoc_time_expand(&sc->sc_bus, nframes) + buf_offset + |
2796 |
(((xfer->nframes << shift) + 7) / 8); |
2797 |
|
2798 |
/* get the real number of frames */ |
2799 |
|
2735 |
|
2800 |
nframes = xfer->nframes; |
2736 |
nframes = xfer->nframes; |
2801 |
|
2737 |
|
Lines 2811-2821
ehci_device_isoc_hs_enter(struct usb_xfer *xfer)
Link Here
|
2811 |
td = xfer->td_start[xfer->flags_int.curr_dma_set]; |
2747 |
td = xfer->td_start[xfer->flags_int.curr_dma_set]; |
2812 |
xfer->td_transfer_first = td; |
2748 |
xfer->td_transfer_first = td; |
2813 |
|
2749 |
|
2814 |
pp_last = &sc->sc_isoc_hs_p_last[xfer->endpoint->isoc_next]; |
2750 |
pp_last = &sc->sc_isoc_hs_p_last[startframe]; |
2815 |
|
2751 |
|
2816 |
/* store starting position */ |
2752 |
/* store starting position */ |
2817 |
|
2753 |
|
2818 |
xfer->qh_pos = xfer->endpoint->isoc_next; |
2754 |
xfer->qh_pos = startframe; |
2819 |
|
2755 |
|
2820 |
while (nframes) { |
2756 |
while (nframes) { |
2821 |
if (td == NULL) { |
2757 |
if (td == NULL) { |
Lines 2927-2936
ehci_device_isoc_hs_enter(struct usb_xfer *xfer)
Link Here
|
2927 |
} |
2863 |
} |
2928 |
|
2864 |
|
2929 |
xfer->td_transfer_last = td_last; |
2865 |
xfer->td_transfer_last = td_last; |
2930 |
|
|
|
2931 |
/* update isoc_next */ |
2932 |
xfer->endpoint->isoc_next = (pp_last - &sc->sc_isoc_hs_p_last[0]) & |
2933 |
(EHCI_VIRTUAL_FRAMELIST_COUNT - 1); |
2934 |
} |
2866 |
} |
2935 |
|
2867 |
|
2936 |
static void |
2868 |
static void |