summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/target/arm/usb-drv-arc.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/firmware/target/arm/usb-drv-arc.c b/firmware/target/arm/usb-drv-arc.c
index 94dc9b7b5e..3b1146cc5c 100644
--- a/firmware/target/arm/usb-drv-arc.c
+++ b/firmware/target/arm/usb-drv-arc.c
@@ -917,20 +917,33 @@ static void transfer_completed(void)
917 int pipe = ep * 2 + dir; 917 int pipe = ep * 2 + dir;
918 if (mask & pipe2mask[pipe]) { 918 if (mask & pipe2mask[pipe]) {
919 struct queue_head* qh = &qh_array[pipe]; 919 struct queue_head* qh = &qh_array[pipe];
920 if(qh->wait) { 920
921 qh->wait=0;
922 wakeup_signal(&transfer_completion_signal[pipe]);
923 }
924 int length=0; 921 int length=0;
925 struct transfer_descriptor* td=&td_array[pipe*NUM_TDS_PER_EP]; 922 struct transfer_descriptor* td=&td_array[pipe*NUM_TDS_PER_EP];
926 while(td!=(struct transfer_descriptor*)DTD_NEXT_TERMINATE && td!=0) 923 while(td!=(struct transfer_descriptor*)DTD_NEXT_TERMINATE && td!=0)
927 { 924 {
925 /* It seems that the controller sets the pipe bit to one even if the TD
926 * dosn't have the IOC bit set. So we have the rely the active status bit
927 * to check that all the TDs of the transfer are really finished and let
928 * the transfer continue if it's no the case */
929 if(td->size_ioc_sts & DTD_STATUS_ACTIVE)
930 {
931 logf("skip half finished transfer");
932 goto Lskip;
933 }
928 length += ((td->reserved & DTD_RESERVED_LENGTH_MASK) - 934 length += ((td->reserved & DTD_RESERVED_LENGTH_MASK) -
929 ((td->size_ioc_sts & DTD_PACKET_SIZE) >> DTD_LENGTH_BIT_POS)); 935 ((td->size_ioc_sts & DTD_PACKET_SIZE) >> DTD_LENGTH_BIT_POS));
930 td=(struct transfer_descriptor*) td->next_td_ptr; 936 td=(struct transfer_descriptor*) td->next_td_ptr;
931 } 937 }
938 if(qh->wait) {
939 qh->wait=0;
940 wakeup_signal(&transfer_completion_signal[pipe]);
941 }
942
932 usb_core_transfer_complete(ep, dir?USB_DIR_IN:USB_DIR_OUT, 943 usb_core_transfer_complete(ep, dir?USB_DIR_IN:USB_DIR_OUT,
933 qh->status, length); 944 qh->status, length);
945 Lskip:
946 continue;
934 } 947 }
935 } 948 }
936 } 949 }