aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/dwc3/gadget.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-29 10:07:59 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-29 10:07:59 -0700
commit9af6f26a1a7f152f7736c0c20247eef0ab3df190 (patch)
tree6cbf30a8a08bae27bc17a0a4dcee72f15a11b6c7 /drivers/usb/dwc3/gadget.c
parentc067affcd316a36a28beaf8ea8c39db22a88c778 (diff)
parentc1aa67729a1d94373fb9826fef97b8a2b7f2e00f (diff)
Merge tag 'usb-4.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB fixes from Greg KH: "Here are a number of small USB driver fixes for 4.9-rc3. There is the usual number of gadget and xhci patches in here to resolved reported issues, as well as some usb-serial driver fixes and new device ids. All have been in linux-next with no reported issues" * tag 'usb-4.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (26 commits) usb: chipidea: host: fix NULL ptr dereference during shutdown usb: renesas_usbhs: add wait after initialization for R-Car Gen3 usb: increase ohci watchdog delay to 275 msec usb: musb: Call pm_runtime from musb_gadget_queue usb: musb: Fix hardirq-safe hardirq-unsafe lock order error usb: ehci-platform: increase EHCI_MAX_RSTS to 4 usb: ohci-at91: Set RemoteWakeupConnected bit explicitly. USB: serial: fix potential NULL-dereference at probe xhci: use default USB_RESUME_TIMEOUT when resuming ports. xhci: workaround for hosts missing CAS bit xhci: add restart quirk for Intel Wildcatpoint PCH USB: serial: cp210x: fix tiocmget error handling wusb: fix error return code in wusb_prf() Revert "Documentation: devicetree: dwc2: Deprecate g-tx-fifo-size" Revert "usb: dwc2: gadget: fix TX FIFO size and address initialization" Revert "usb: dwc2: gadget: change variable name to more meaningful" USB: serial: ftdi_sio: add support for Infineon TriBoard TC2X7 wusb: Stop using the stack for sg crypto scratch space usb: dwc3: Fix size used in dma_free_coherent() usb: gadget: f_fs: stop sleeping in ffs_func_eps_disable ...
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
-rw-r--r--drivers/usb/dwc3/gadget.c26
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,
req->trb = trb;
req->trb_dma = dwc3_trb_dma_offset(dep, trb);
req->first_trb_index = dep->trb_enqueue;
+ dep->queued_requests++;
}
dwc3_ep_inc_enq(dep);
@@ -833,8 +834,6 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
trb->ctrl |= DWC3_TRB_CTRL_HWO;
- dep->queued_requests++;
-
trace_dwc3_prepare_trb(dep, trb);
}
@@ -1074,9 +1073,17 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
list_add_tail(&req->list, &dep->pending_list);
- if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
- dep->flags & DWC3_EP_PENDING_REQUEST) {
- if (list_empty(&dep->started_list)) {
+ /*
+ * NOTICE: Isochronous endpoints should NEVER be prestarted. We must
+ * wait for a XferNotReady event so we will know what's the current
+ * (micro-)frame number.
+ *
+ * Without this trick, we are very, very likely gonna get Bus Expiry
+ * errors which will force us issue EndTransfer command.
+ */
+ if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
+ if ((dep->flags & DWC3_EP_PENDING_REQUEST) &&
+ list_empty(&dep->started_list)) {
dwc3_stop_active_transfer(dwc, dep->number, true);
dep->flags = DWC3_EP_ENABLED;
}
@@ -1861,8 +1868,11 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep,
unsigned int s_pkt = 0;
unsigned int trb_status;
- dep->queued_requests--;
dwc3_ep_inc_deq(dep);
+
+ if (req->trb == trb)
+ dep->queued_requests--;
+
trace_dwc3_complete_trb(dep, trb);
/*
@@ -2980,7 +2990,7 @@ err3:
kfree(dwc->setup_buf);
err2:
- dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
+ dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb) * 2,
dwc->ep0_trb, dwc->ep0_trb_addr);
err1:
@@ -3005,7 +3015,7 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
kfree(dwc->setup_buf);
kfree(dwc->zlp_buf);
- dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
+ dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb) * 2,
dwc->ep0_trb, dwc->ep0_trb_addr);
dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),