summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/dwc3/debugfs.c2
-rw-r--r--drivers/usb/dwc3/gadget.c30
2 files changed, 19 insertions, 13 deletions
diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c
index 7a886714d72b..4312a8f86e57 100644
--- a/drivers/usb/dwc3/debugfs.c
+++ b/drivers/usb/dwc3/debugfs.c
@@ -738,8 +738,6 @@ static int dwc3_ep_trbs_show(struct seq_file *s, void *unused)
spin_lock_irqsave(&dwc->lock, flags);
dep = dwc->eps[ep_num];
- if (!dep->trb_pool)
- return 0;
seq_printf(s, "%s trb pool: flags:0x%x freeslot:%d busyslot:%d\n",
dep->name, dep->flags, dep->free_slot, dep->busy_slot);
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index c6eb5043a9a2..b7756a6bcb6d 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -386,7 +386,7 @@ static int dwc3_alloc_trb_pool(struct dwc3_ep *dep)
dep->trb_pool = dma_zalloc_coherent(dwc->dev,
sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
- &dep->trb_pool_dma, GFP_ATOMIC);
+ &dep->trb_pool_dma, GFP_KERNEL);
if (!dep->trb_pool) {
dev_err(dep->dwc->dev, "failed to allocate trb pool for %s\n",
dep->name);
@@ -668,6 +668,17 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
dep->number >> 1,
(dep->number & 1) ? "in" : "out");
+ /*
+ * Clean up ep ring of non-control endpoint to avoid getting xferInProgress
+ * due to stale trbs with HWO bit set from previous composition when update
+ * transfer cmd is issued.
+ */
+ if (dep->number > 1) {
+ memset(&dep->trb_pool[0], 0,
+ sizeof(struct dwc3_trb) * DWC3_TRB_NUM);
+ dbg_event(dep->number, "Clr_TRB", 0);
+ }
+
return 0;
}
@@ -714,12 +725,6 @@ static int dwc3_gadget_ep_enable(struct usb_ep *ep,
return 0;
}
- if (dep->number > 1) {
- ret = dwc3_alloc_trb_pool(dep);
- if (ret)
- return ret;
- }
-
spin_lock_irqsave(&dwc->lock, flags);
ret = __dwc3_gadget_ep_enable(dep, desc, ep->comp_desc, false, false);
dbg_event(dep->number, "ENABLE", ret);
@@ -754,8 +759,6 @@ static int dwc3_gadget_ep_disable(struct usb_ep *ep)
dbg_event(dep->number, "DISABLE", ret);
spin_unlock_irqrestore(&dwc->lock, flags);
- dwc3_free_trb_pool(dep);
-
return ret;
}
@@ -2162,11 +2165,17 @@ static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc,
if (!epnum)
dwc->gadget.ep0 = &dep->endpoint;
} else {
+ int ret;
+
usb_ep_set_maxpacket_limit(&dep->endpoint, 1024);
dep->endpoint.max_streams = 15;
dep->endpoint.ops = &dwc3_gadget_ep_ops;
list_add_tail(&dep->endpoint.ep_list,
&dwc->gadget.ep_list);
+
+ ret = dwc3_alloc_trb_pool(dep);
+ if (ret)
+ return ret;
}
if (epnum == 0 || epnum == 1) {
@@ -2229,8 +2238,7 @@ static void dwc3_gadget_free_endpoints(struct dwc3 *dwc)
* with all sorts of bugs when removing dwc3.ko.
*/
if (epnum != 0 && epnum != 1) {
- if (dep->trb_pool)
- dwc3_free_trb_pool(dep);
+ dwc3_free_trb_pool(dep);
list_del(&dep->endpoint.ep_list);
}