diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2013-05-29 13:20:00 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-05-30 08:34:30 -0400 |
commit | 9db33f317432d1a9e22116092c6455ae71bf73fc (patch) | |
tree | 955504b8b7659bf2a9c912d7add3b10da2e7e543 /drivers/usb/host/imx21-hcd.c | |
parent | 8a1ea51f87a6149c3263a63e9c60d852bedbecd7 (diff) |
USB: IMX21: upgrade the isochronous API
This patch attempts to update the imx21-hcd driver to the current
standard for the isochronous API. Firstly, urb->start_frame should
always be set by the driver; it is not an input parameter. Secondly,
the URB_ISO_ASAP flag matters only when an URB is submitted to a
stream that has gotten an underrun. It causes the URB to be scheduled
for the next available slot in the future, rather than the earliest
unused (and expired) slot.
Unfortunately, I don't have any way to test these changes.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: Sascha Hauer <kernel@pengutronix.de>
CC: Martin Fuzzey <mfuzzey@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/imx21-hcd.c')
-rw-r--r-- | drivers/usb/host/imx21-hcd.c | 43 |
1 files changed, 26 insertions, 17 deletions
diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index f0ebe8e7c58b..03dc4d9cbeca 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c | |||
@@ -809,26 +809,36 @@ static int imx21_hc_urb_enqueue_isoc(struct usb_hcd *hcd, | |||
809 | 809 | ||
810 | /* calculate frame */ | 810 | /* calculate frame */ |
811 | cur_frame = imx21_hc_get_frame(hcd); | 811 | cur_frame = imx21_hc_get_frame(hcd); |
812 | if (urb->transfer_flags & URB_ISO_ASAP) { | 812 | i = 0; |
813 | if (list_empty(&ep_priv->td_list)) | 813 | if (list_empty(&ep_priv->td_list)) { |
814 | urb->start_frame = cur_frame + 5; | 814 | urb->start_frame = wrap_frame(cur_frame + 5); |
815 | else | 815 | } else { |
816 | urb->start_frame = list_entry( | 816 | urb->start_frame = wrap_frame(list_entry(ep_priv->td_list.prev, |
817 | ep_priv->td_list.prev, | 817 | struct td, list)->frame + urb->interval); |
818 | struct td, list)->frame + urb->interval; | 818 | |
819 | } | 819 | if (frame_after(cur_frame, urb->start_frame)) { |
820 | urb->start_frame = wrap_frame(urb->start_frame); | 820 | dev_dbg(imx21->dev, |
821 | if (frame_after(cur_frame, urb->start_frame)) { | 821 | "enqueue: adjusting iso start %d (cur=%d) asap=%d\n", |
822 | dev_dbg(imx21->dev, | 822 | urb->start_frame, cur_frame, |
823 | "enqueue: adjusting iso start %d (cur=%d) asap=%d\n", | 823 | (urb->transfer_flags & URB_ISO_ASAP) != 0); |
824 | urb->start_frame, cur_frame, | 824 | i = DIV_ROUND_UP(wrap_frame( |
825 | (urb->transfer_flags & URB_ISO_ASAP) != 0); | 825 | cur_frame - urb->start_frame), |
826 | urb->start_frame = wrap_frame(cur_frame + 1); | 826 | urb->interval); |
827 | if (urb->transfer_flags & URB_ISO_ASAP) { | ||
828 | urb->start_frame = wrap_frame(urb->start_frame | ||
829 | + i * urb->interval); | ||
830 | i = 0; | ||
831 | } else if (i >= urb->number_of_packets) { | ||
832 | ret = -EXDEV; | ||
833 | goto alloc_dmem_failed; | ||
834 | } | ||
835 | } | ||
827 | } | 836 | } |
828 | 837 | ||
829 | /* set up transfers */ | 838 | /* set up transfers */ |
839 | urb_priv->isoc_remaining = urb->number_of_packets - i; | ||
830 | td = urb_priv->isoc_td; | 840 | td = urb_priv->isoc_td; |
831 | for (i = 0; i < urb->number_of_packets; i++, td++) { | 841 | for (; i < urb->number_of_packets; i++, td++) { |
832 | unsigned int offset = urb->iso_frame_desc[i].offset; | 842 | unsigned int offset = urb->iso_frame_desc[i].offset; |
833 | td->ep = ep; | 843 | td->ep = ep; |
834 | td->urb = urb; | 844 | td->urb = urb; |
@@ -840,7 +850,6 @@ static int imx21_hc_urb_enqueue_isoc(struct usb_hcd *hcd, | |||
840 | list_add_tail(&td->list, &ep_priv->td_list); | 850 | list_add_tail(&td->list, &ep_priv->td_list); |
841 | } | 851 | } |
842 | 852 | ||
843 | urb_priv->isoc_remaining = urb->number_of_packets; | ||
844 | dev_vdbg(imx21->dev, "setup %d packets for iso frame %d->%d\n", | 853 | dev_vdbg(imx21->dev, "setup %d packets for iso frame %d->%d\n", |
845 | urb->number_of_packets, urb->start_frame, td->frame); | 854 | urb->number_of_packets, urb->start_frame, td->frame); |
846 | 855 | ||