aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/dwc_otg/dwc_otg_hcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/dwc_otg/dwc_otg_hcd.c')
-rw-r--r--drivers/usb/gadget/dwc_otg/dwc_otg_hcd.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/drivers/usb/gadget/dwc_otg/dwc_otg_hcd.c b/drivers/usb/gadget/dwc_otg/dwc_otg_hcd.c
index 6b83ee46440..2fdf0ca99ea 100644
--- a/drivers/usb/gadget/dwc_otg/dwc_otg_hcd.c
+++ b/drivers/usb/gadget/dwc_otg/dwc_otg_hcd.c
@@ -273,6 +273,7 @@ static int32_t dwc_otg_hcd_disconnect_cb(void *_p)
dwc_hc_t * channel;
dwc_otg_hc_regs_t * hc_regs;
hcchar_data_t hcchar;
+ unsigned long flags;
num_channels = dwc_otg_hcd->core_if->core_params->host_channels;
if (!dwc_otg_hcd->core_if->dma_enable) {
/* Flush out any channel requests in slave mode. */
@@ -303,6 +304,10 @@ static int32_t dwc_otg_hcd_disconnect_cb(void *_p)
dwc_otg_hc_cleanup(dwc_otg_hcd->core_if,channel);
list_add_tail(&channel->hc_list_entry,
&dwc_otg_hcd->free_hc_list);
+ local_irq_save(flags);
+ dwc_otg_hcd->available_host_channels ++;
+ local_irq_restore(flags);
+
}
}
}
@@ -1042,23 +1047,38 @@ void dwc_otg_hcd_endpoint_disable(struct usb_hcd *_hcd,
{
dwc_otg_qh_t * qh;
dwc_otg_hcd_t * dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd);
+ unsigned long flags;
+ int retry = 0;
+
DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD EP DISABLE: _bEndpointAddress=0x%02x, "
"endpoint=%d\n", _ep->desc.bEndpointAddress,
dwc_ep_addr_to_endpoint(_ep->desc.bEndpointAddress));
+
+rescan:
+ local_irq_save(flags);
+
qh = (dwc_otg_qh_t *) (_ep->hcpriv);
if (qh != NULL) {
-#ifdef CONFIG_DWC_DEBUG
/** Check that the QTD list is really empty */
if (!list_empty(&qh->qtd_list)) {
+ if (retry++ < 250) {
+ local_irq_restore(flags);
+ schedule_timeout_uninterruptible(1);
+ goto rescan;
+ }
+#ifdef CONFIG_DWC_DEBUG
DWC_WARN("DWC OTG HCD EP DISABLE:"
" QTD List for this endpoint is not empty\n");
+#endif /* */
}
-#endif /* */
dwc_otg_hcd_qh_remove_and_free(dwc_otg_hcd, qh);
_ep->hcpriv = NULL;
}
+
+ local_irq_restore(flags);
+
return;
}