diff options
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
-rw-r--r-- | drivers/usb/dwc3/gadget.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 07cc8929f271..1dfa56a5f1c5 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -783,6 +783,7 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, | |||
783 | req->trb = trb; | 783 | req->trb = trb; |
784 | req->trb_dma = dwc3_trb_dma_offset(dep, trb); | 784 | req->trb_dma = dwc3_trb_dma_offset(dep, trb); |
785 | req->first_trb_index = dep->trb_enqueue; | 785 | req->first_trb_index = dep->trb_enqueue; |
786 | dep->queued_requests++; | ||
786 | } | 787 | } |
787 | 788 | ||
788 | dwc3_ep_inc_enq(dep); | 789 | dwc3_ep_inc_enq(dep); |
@@ -833,8 +834,6 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, | |||
833 | 834 | ||
834 | trb->ctrl |= DWC3_TRB_CTRL_HWO; | 835 | trb->ctrl |= DWC3_TRB_CTRL_HWO; |
835 | 836 | ||
836 | dep->queued_requests++; | ||
837 | |||
838 | trace_dwc3_prepare_trb(dep, trb); | 837 | trace_dwc3_prepare_trb(dep, trb); |
839 | } | 838 | } |
840 | 839 | ||
@@ -1074,9 +1073,17 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | |||
1074 | 1073 | ||
1075 | list_add_tail(&req->list, &dep->pending_list); | 1074 | list_add_tail(&req->list, &dep->pending_list); |
1076 | 1075 | ||
1077 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && | 1076 | /* |
1078 | dep->flags & DWC3_EP_PENDING_REQUEST) { | 1077 | * NOTICE: Isochronous endpoints should NEVER be prestarted. We must |
1079 | if (list_empty(&dep->started_list)) { | 1078 | * wait for a XferNotReady event so we will know what's the current |
1079 | * (micro-)frame number. | ||
1080 | * | ||
1081 | * Without this trick, we are very, very likely gonna get Bus Expiry | ||
1082 | * errors which will force us issue EndTransfer command. | ||
1083 | */ | ||
1084 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { | ||
1085 | if ((dep->flags & DWC3_EP_PENDING_REQUEST) && | ||
1086 | list_empty(&dep->started_list)) { | ||
1080 | dwc3_stop_active_transfer(dwc, dep->number, true); | 1087 | dwc3_stop_active_transfer(dwc, dep->number, true); |
1081 | dep->flags = DWC3_EP_ENABLED; | 1088 | dep->flags = DWC3_EP_ENABLED; |
1082 | } | 1089 | } |
@@ -1861,8 +1868,11 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep, | |||
1861 | unsigned int s_pkt = 0; | 1868 | unsigned int s_pkt = 0; |
1862 | unsigned int trb_status; | 1869 | unsigned int trb_status; |
1863 | 1870 | ||
1864 | dep->queued_requests--; | ||
1865 | dwc3_ep_inc_deq(dep); | 1871 | dwc3_ep_inc_deq(dep); |
1872 | |||
1873 | if (req->trb == trb) | ||
1874 | dep->queued_requests--; | ||
1875 | |||
1866 | trace_dwc3_complete_trb(dep, trb); | 1876 | trace_dwc3_complete_trb(dep, trb); |
1867 | 1877 | ||
1868 | /* | 1878 | /* |
@@ -2980,7 +2990,7 @@ err3: | |||
2980 | kfree(dwc->setup_buf); | 2990 | kfree(dwc->setup_buf); |
2981 | 2991 | ||
2982 | err2: | 2992 | err2: |
2983 | dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb), | 2993 | dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb) * 2, |
2984 | dwc->ep0_trb, dwc->ep0_trb_addr); | 2994 | dwc->ep0_trb, dwc->ep0_trb_addr); |
2985 | 2995 | ||
2986 | err1: | 2996 | err1: |
@@ -3005,7 +3015,7 @@ void dwc3_gadget_exit(struct dwc3 *dwc) | |||
3005 | kfree(dwc->setup_buf); | 3015 | kfree(dwc->setup_buf); |
3006 | kfree(dwc->zlp_buf); | 3016 | kfree(dwc->zlp_buf); |
3007 | 3017 | ||
3008 | dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb), | 3018 | dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb) * 2, |
3009 | dwc->ep0_trb, dwc->ep0_trb_addr); | 3019 | dwc->ep0_trb, dwc->ep0_trb_addr); |
3010 | 3020 | ||
3011 | dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req), | 3021 | dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req), |