Lines 2465-2470
ehci_device_isoc_fs_enter(struct usb_xfer *xfer)
Link Here
|
2465 |
uint32_t *plen; |
2465 |
uint32_t *plen; |
2466 |
uint32_t buf_offset; |
2466 |
uint32_t buf_offset; |
2467 |
uint32_t nframes; |
2467 |
uint32_t nframes; |
|
|
2468 |
uint32_t startframe; |
2468 |
uint32_t temp; |
2469 |
uint32_t temp; |
2469 |
uint32_t sitd_mask; |
2470 |
uint32_t sitd_mask; |
2470 |
uint16_t tlen; |
2471 |
uint16_t tlen; |
Lines 2483-2521
ehci_device_isoc_fs_enter(struct usb_xfer *xfer)
Link Here
|
2483 |
|
2484 |
|
2484 |
nframes = EOREAD4(sc, EHCI_FRINDEX) / 8; |
2485 |
nframes = EOREAD4(sc, EHCI_FRINDEX) / 8; |
2485 |
|
2486 |
|
2486 |
/* |
2487 |
if (usbd_xfer_get_isochronous_start_frame( |
2487 |
* check if the frame index is within the window where the frames |
2488 |
xfer, nframes, 0, 1, EHCI_VIRTUAL_FRAMELIST_COUNT - 1, &startframe)) |
2488 |
* will be inserted |
2489 |
DPRINTFN(3, "start next=%d\n", startframe); |
2489 |
*/ |
|
|
2490 |
buf_offset = (nframes - xfer->endpoint->isoc_next) & |
2491 |
(EHCI_VIRTUAL_FRAMELIST_COUNT - 1); |
2492 |
|
2493 |
if ((xfer->endpoint->is_synced == 0) || |
2494 |
(buf_offset < xfer->nframes)) { |
2495 |
/* |
2496 |
* If there is data underflow or the pipe queue is empty we |
2497 |
* schedule the transfer a few frames ahead of the current |
2498 |
* frame position. Else two isochronous transfers might |
2499 |
* overlap. |
2500 |
*/ |
2501 |
xfer->endpoint->isoc_next = (nframes + 3) & |
2502 |
(EHCI_VIRTUAL_FRAMELIST_COUNT - 1); |
2503 |
xfer->endpoint->is_synced = 1; |
2504 |
DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next); |
2505 |
} |
2506 |
/* |
2507 |
* compute how many milliseconds the insertion is ahead of the |
2508 |
* current frame position: |
2509 |
*/ |
2510 |
buf_offset = (xfer->endpoint->isoc_next - nframes) & |
2511 |
(EHCI_VIRTUAL_FRAMELIST_COUNT - 1); |
2512 |
|
2513 |
/* |
2514 |
* pre-compute when the isochronous transfer will be finished: |
2515 |
*/ |
2516 |
xfer->isoc_time_complete = |
2517 |
usb_isoc_time_expand(&sc->sc_bus, nframes) + |
2518 |
buf_offset + xfer->nframes; |
2519 |
|
2490 |
|
2520 |
/* get the real number of frames */ |
2491 |
/* get the real number of frames */ |
2521 |
|
2492 |
|
Lines 2532-2542
ehci_device_isoc_fs_enter(struct usb_xfer *xfer)
Link Here
|
2532 |
td = xfer->td_start[xfer->flags_int.curr_dma_set]; |
2503 |
td = xfer->td_start[xfer->flags_int.curr_dma_set]; |
2533 |
xfer->td_transfer_first = td; |
2504 |
xfer->td_transfer_first = td; |
2534 |
|
2505 |
|
2535 |
pp_last = &sc->sc_isoc_fs_p_last[xfer->endpoint->isoc_next]; |
2506 |
pp_last = &sc->sc_isoc_fs_p_last[startframe]; |
2536 |
|
2507 |
|
2537 |
/* store starting position */ |
2508 |
/* store starting position */ |
2538 |
|
2509 |
|
2539 |
xfer->qh_pos = xfer->endpoint->isoc_next; |
2510 |
xfer->qh_pos = startframe; |
2540 |
|
2511 |
|
2541 |
while (nframes--) { |
2512 |
while (nframes--) { |
2542 |
if (td == NULL) { |
2513 |
if (td == NULL) { |
Lines 2658-2667
ehci_device_isoc_fs_enter(struct usb_xfer *xfer)
Link Here
|
2658 |
|
2629 |
|
2659 |
xfer->td_transfer_last = td_last; |
2630 |
xfer->td_transfer_last = td_last; |
2660 |
|
2631 |
|
2661 |
/* update isoc_next */ |
|
|
2662 |
xfer->endpoint->isoc_next = (pp_last - &sc->sc_isoc_fs_p_last[0]) & |
2663 |
(EHCI_VIRTUAL_FRAMELIST_COUNT - 1); |
2664 |
|
2665 |
/* |
2632 |
/* |
2666 |
* We don't allow cancelling of the SPLIT transaction USB FULL |
2633 |
* We don't allow cancelling of the SPLIT transaction USB FULL |
2667 |
* speed transfer, because it disturbs the bandwidth |
2634 |
* speed transfer, because it disturbs the bandwidth |
Lines 2770-2780
ehci_device_isoc_hs_enter(struct usb_xfer *xfer)
Link Here
|
2770 |
uint32_t status; |
2737 |
uint32_t status; |
2771 |
uint32_t buf_offset; |
2738 |
uint32_t buf_offset; |
2772 |
uint32_t nframes; |
2739 |
uint32_t nframes; |
|
|
2740 |
uint32_t startframe; |
2773 |
uint32_t itd_offset[8 + 1]; |
2741 |
uint32_t itd_offset[8 + 1]; |
2774 |
uint8_t x; |
2742 |
uint8_t x; |
2775 |
uint8_t td_no; |
2743 |
uint8_t td_no; |
2776 |
uint8_t page_no; |
2744 |
uint8_t page_no; |
2777 |
uint8_t shift = usbd_xfer_get_fps_shift(xfer); |
|
|
2778 |
|
2745 |
|
2779 |
#ifdef USB_DEBUG |
2746 |
#ifdef USB_DEBUG |
2780 |
uint8_t once = 1; |
2747 |
uint8_t once = 1; |
Lines 2782-2828
ehci_device_isoc_hs_enter(struct usb_xfer *xfer)
Link Here
|
2782 |
#endif |
2749 |
#endif |
2783 |
|
2750 |
|
2784 |
DPRINTFN(6, "xfer=%p next=%d nframes=%d shift=%d\n", |
2751 |
DPRINTFN(6, "xfer=%p next=%d nframes=%d shift=%d\n", |
2785 |
xfer, xfer->endpoint->isoc_next, xfer->nframes, (int)shift); |
2752 |
xfer, xfer->endpoint->isoc_next, xfer->nframes, |
|
|
2753 |
usbd_xfer_get_fps_shift(xfer)); |
2786 |
|
2754 |
|
2787 |
/* get the current frame index */ |
2755 |
/* get the current frame index */ |
2788 |
|
2756 |
|
2789 |
nframes = EOREAD4(sc, EHCI_FRINDEX) / 8; |
2757 |
nframes = EOREAD4(sc, EHCI_FRINDEX) / 8; |
2790 |
|
2758 |
|
2791 |
/* |
2759 |
if (usbd_xfer_get_isochronous_start_frame( |
2792 |
* check if the frame index is within the window where the frames |
2760 |
xfer, nframes, 0, 1, EHCI_VIRTUAL_FRAMELIST_COUNT - 1, &startframe)) |
2793 |
* will be inserted |
2761 |
DPRINTFN(3, "start next=%d\n", startframe); |
2794 |
*/ |
|
|
2795 |
buf_offset = (nframes - xfer->endpoint->isoc_next) & |
2796 |
(EHCI_VIRTUAL_FRAMELIST_COUNT - 1); |
2797 |
|
2798 |
if ((xfer->endpoint->is_synced == 0) || |
2799 |
(buf_offset < (((xfer->nframes << shift) + 7) / 8))) { |
2800 |
/* |
2801 |
* If there is data underflow or the pipe queue is empty we |
2802 |
* schedule the transfer a few frames ahead of the current |
2803 |
* frame position. Else two isochronous transfers might |
2804 |
* overlap. |
2805 |
*/ |
2806 |
xfer->endpoint->isoc_next = (nframes + 3) & |
2807 |
(EHCI_VIRTUAL_FRAMELIST_COUNT - 1); |
2808 |
xfer->endpoint->is_synced = 1; |
2809 |
DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next); |
2810 |
} |
2811 |
/* |
2812 |
* compute how many milliseconds the insertion is ahead of the |
2813 |
* current frame position: |
2814 |
*/ |
2815 |
buf_offset = (xfer->endpoint->isoc_next - nframes) & |
2816 |
(EHCI_VIRTUAL_FRAMELIST_COUNT - 1); |
2817 |
|
2818 |
/* |
2819 |
* pre-compute when the isochronous transfer will be finished: |
2820 |
*/ |
2821 |
xfer->isoc_time_complete = |
2822 |
usb_isoc_time_expand(&sc->sc_bus, nframes) + buf_offset + |
2823 |
(((xfer->nframes << shift) + 7) / 8); |
2824 |
|
2825 |
/* get the real number of frames */ |
2826 |
|
2762 |
|
2827 |
nframes = xfer->nframes; |
2763 |
nframes = xfer->nframes; |
2828 |
|
2764 |
|
Lines 2838-2848
ehci_device_isoc_hs_enter(struct usb_xfer *xfer)
Link Here
|
2838 |
td = xfer->td_start[xfer->flags_int.curr_dma_set]; |
2774 |
td = xfer->td_start[xfer->flags_int.curr_dma_set]; |
2839 |
xfer->td_transfer_first = td; |
2775 |
xfer->td_transfer_first = td; |
2840 |
|
2776 |
|
2841 |
pp_last = &sc->sc_isoc_hs_p_last[xfer->endpoint->isoc_next]; |
2777 |
pp_last = &sc->sc_isoc_hs_p_last[startframe]; |
2842 |
|
2778 |
|
2843 |
/* store starting position */ |
2779 |
/* store starting position */ |
2844 |
|
2780 |
|
2845 |
xfer->qh_pos = xfer->endpoint->isoc_next; |
2781 |
xfer->qh_pos = startframe; |
2846 |
|
2782 |
|
2847 |
while (nframes) { |
2783 |
while (nframes) { |
2848 |
if (td == NULL) { |
2784 |
if (td == NULL) { |
Lines 2955-2964
ehci_device_isoc_hs_enter(struct usb_xfer *xfer)
Link Here
|
2955 |
} |
2891 |
} |
2956 |
|
2892 |
|
2957 |
xfer->td_transfer_last = td_last; |
2893 |
xfer->td_transfer_last = td_last; |
2958 |
|
|
|
2959 |
/* update isoc_next */ |
2960 |
xfer->endpoint->isoc_next = (pp_last - &sc->sc_isoc_hs_p_last[0]) & |
2961 |
(EHCI_VIRTUAL_FRAMELIST_COUNT - 1); |
2962 |
} |
2894 |
} |
2963 |
|
2895 |
|
2964 |
static void |
2896 |
static void |