diff options
author | Gregory Herrero <gregory.herrero@intel.com> | 2015-11-05 03:41:45 -0500 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2015-12-15 10:12:41 -0500 |
commit | 762d3a1a9cd7438a8453e005ee5b2bab3203d9c3 (patch) | |
tree | 7f16548ef3473edc61050031b65d23addee54872 | |
parent | 3f808bdae75eaf464b1b2710894950772a3784f8 (diff) |
usb: dwc2: host: process all completed urbs
Process all completed urbs, if more urbs are complete by the time
driver processes completion interrupt.
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r-- | drivers/usb/dwc2/hcd_ddma.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/drivers/usb/dwc2/hcd_ddma.c b/drivers/usb/dwc2/hcd_ddma.c index edccac662d74..f98c7e91f6bc 100644 --- a/drivers/usb/dwc2/hcd_ddma.c +++ b/drivers/usb/dwc2/hcd_ddma.c | |||
@@ -940,17 +940,51 @@ static void dwc2_complete_isoc_xfer_ddma(struct dwc2_hsotg *hsotg, | |||
940 | list_for_each_entry_safe(qtd, qtd_tmp, &qh->qtd_list, qtd_list_entry) { | 940 | list_for_each_entry_safe(qtd, qtd_tmp, &qh->qtd_list, qtd_list_entry) { |
941 | if (!qtd->in_process) | 941 | if (!qtd->in_process) |
942 | break; | 942 | break; |
943 | |||
944 | /* | ||
945 | * Ensure idx corresponds to descriptor where first urb of this | ||
946 | * qtd was added. In fact, during isoc desc init, dwc2 may skip | ||
947 | * an index if current frame number is already over this index. | ||
948 | */ | ||
949 | if (idx != qtd->isoc_td_first) { | ||
950 | dev_vdbg(hsotg->dev, | ||
951 | "try to complete %d instead of %d\n", | ||
952 | idx, qtd->isoc_td_first); | ||
953 | idx = qtd->isoc_td_first; | ||
954 | } | ||
955 | |||
943 | do { | 956 | do { |
957 | struct dwc2_qtd *qtd_next; | ||
958 | u16 cur_idx; | ||
959 | |||
944 | rc = dwc2_cmpl_host_isoc_dma_desc(hsotg, chan, qtd, qh, | 960 | rc = dwc2_cmpl_host_isoc_dma_desc(hsotg, chan, qtd, qh, |
945 | idx); | 961 | idx); |
946 | if (rc < 0) | 962 | if (rc < 0) |
947 | return; | 963 | return; |
948 | idx = dwc2_desclist_idx_inc(idx, qh->interval, | 964 | idx = dwc2_desclist_idx_inc(idx, qh->interval, |
949 | chan->speed); | 965 | chan->speed); |
950 | if (rc == DWC2_CMPL_STOP) | 966 | if (!rc) |
951 | goto stop_scan; | 967 | continue; |
968 | |||
952 | if (rc == DWC2_CMPL_DONE) | 969 | if (rc == DWC2_CMPL_DONE) |
953 | break; | 970 | break; |
971 | |||
972 | /* rc == DWC2_CMPL_STOP */ | ||
973 | |||
974 | if (qh->interval >= 32) | ||
975 | goto stop_scan; | ||
976 | |||
977 | qh->td_first = idx; | ||
978 | cur_idx = dwc2_frame_list_idx(hsotg->frame_number); | ||
979 | qtd_next = list_first_entry(&qh->qtd_list, | ||
980 | struct dwc2_qtd, | ||
981 | qtd_list_entry); | ||
982 | if (dwc2_frame_idx_num_gt(cur_idx, | ||
983 | qtd_next->isoc_td_last)) | ||
984 | break; | ||
985 | |||
986 | goto stop_scan; | ||
987 | |||
954 | } while (idx != qh->td_first); | 988 | } while (idx != qh->td_first); |
955 | } | 989 | } |
956 | 990 | ||