diff options
Diffstat (limited to 'target/linux/brcm2708/patches-3.10/0082-dwc_otg-prevent-OOPSes-during-device-disconnects.patch')
-rw-r--r-- | target/linux/brcm2708/patches-3.10/0082-dwc_otg-prevent-OOPSes-during-device-disconnects.patch | 143 |
1 files changed, 0 insertions, 143 deletions
diff --git a/target/linux/brcm2708/patches-3.10/0082-dwc_otg-prevent-OOPSes-during-device-disconnects.patch b/target/linux/brcm2708/patches-3.10/0082-dwc_otg-prevent-OOPSes-during-device-disconnects.patch deleted file mode 100644 index 129dc0894b..0000000000 --- a/target/linux/brcm2708/patches-3.10/0082-dwc_otg-prevent-OOPSes-during-device-disconnects.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 2e2f1ef719a2fa55fd1d95d9536fa8cca94459a4 Mon Sep 17 00:00:00 2001 -From: P33M <P33M@github.com> -Date: Thu, 18 Jul 2013 17:07:26 +0100 -Subject: [PATCH 082/196] dwc_otg: prevent OOPSes during device disconnects - -The dwc_otg_urb_enqueue function is thread-unsafe. In particular the -access of urb->hcpriv, usb_hcd_link_urb_to_ep, dwc_otg_urb->qtd and -friends does not occur within a critical section and so if a device -was unplugged during activity there was a high chance that the -usbcore hub_thread would try to disable the endpoint with partially- -formed entries in the URB queue. This would result in BUG() or null -pointer dereferences. - -Fix so that access of urb->hcpriv, enqueuing to the hardware and -adding to usbcore endpoint URB lists is contained within a single -critical section. ---- - drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 3 --- - drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 14 +++++--------- - drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 6 +----- - 3 files changed, 6 insertions(+), 17 deletions(-) - -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c -index af9108c..a1970dc 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c -@@ -464,7 +464,6 @@ int dwc_otg_hcd_urb_enqueue(dwc_otg_hcd_t * hcd, - dwc_otg_hcd_urb_t * dwc_otg_urb, void **ep_handle, - int atomic_alloc) - { -- dwc_irqflags_t flags; - int retval = 0; - uint8_t needs_scheduling = 0; - dwc_otg_transaction_type_e tr_type; -@@ -515,12 +514,10 @@ int dwc_otg_hcd_urb_enqueue(dwc_otg_hcd_t * hcd, - } - - if(needs_scheduling) { -- DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags); - tr_type = dwc_otg_hcd_select_transactions(hcd); - if (tr_type != DWC_OTG_TRANSACTION_NONE) { - dwc_otg_hcd_queue_transactions(hcd, tr_type); - } -- DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags); - } - return retval; - } -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -index 0f72bd5..ad03ff1 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -@@ -679,9 +679,7 @@ static int dwc_otg_urb_enqueue(struct usb_hcd *hcd, - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) - struct usb_host_endpoint *ep = urb->ep; - #endif --#if USB_URB_EP_LINKING - dwc_irqflags_t irqflags; --#endif - void **ref_ep_hcpriv = &ep->hcpriv; - dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); - dwc_otg_hcd_urb_t *dwc_otg_urb; -@@ -733,7 +731,6 @@ static int dwc_otg_urb_enqueue(struct usb_hcd *hcd, - if(dwc_otg_urb == NULL) - return -ENOMEM; - -- urb->hcpriv = dwc_otg_urb; - if (!dwc_otg_urb && urb->number_of_packets) - return -ENOMEM; - -@@ -775,10 +772,10 @@ static int dwc_otg_urb_enqueue(struct usb_hcd *hcd, - iso_frame_desc[i].length); - } - --#if USB_URB_EP_LINKING - DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &irqflags); -+ urb->hcpriv = dwc_otg_urb; -+#if USB_URB_EP_LINKING - retval = usb_hcd_link_urb_to_ep(hcd, urb); -- DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, irqflags); - if (0 == retval) - #endif - { -@@ -794,17 +791,16 @@ static int dwc_otg_urb_enqueue(struct usb_hcd *hcd, - urb); - } - } else { --#if USB_URB_EP_LINKING -- dwc_irqflags_t irqflags; - DWC_DEBUGPL(DBG_HCD, "DWC OTG dwc_otg_hcd_urb_enqueue failed rc %d\n", retval); -- DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &irqflags); -+#if USB_URB_EP_LINKING - usb_hcd_unlink_urb_from_ep(hcd, urb); -- DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, irqflags); - #endif -+ urb->hcpriv = NULL; - if (retval == -DWC_E_NO_DEVICE) - retval = -ENODEV; - } - } -+ DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, irqflags); - return retval; - } - -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c -index 8125307..5aed416 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c -@@ -919,6 +919,7 @@ void dwc_otg_hcd_qtd_init(dwc_otg_qtd_t * qtd, dwc_otg_hcd_urb_t * urb) - * QH to place the QTD into. If it does not find a QH, then it will create a - * new QH. If the QH to which the QTD is added is not currently scheduled, it - * is placed into the proper schedule based on its EP type. -+ * HCD lock must be held and interrupts must be disabled on entry - * - * @param[in] qtd The QTD to add - * @param[in] hcd The DWC HCD structure -@@ -931,8 +932,6 @@ int dwc_otg_hcd_qtd_add(dwc_otg_qtd_t * qtd, - dwc_otg_hcd_t * hcd, dwc_otg_qh_t ** qh, int atomic_alloc) - { - int retval = 0; -- dwc_irqflags_t flags; -- - dwc_otg_hcd_urb_t *urb = qtd->urb; - - /* -@@ -946,15 +945,12 @@ int dwc_otg_hcd_qtd_add(dwc_otg_qtd_t * qtd, - goto done; - } - } -- DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags); - retval = dwc_otg_hcd_qh_add(hcd, *qh); - if (retval == 0) { - DWC_CIRCLEQ_INSERT_TAIL(&((*qh)->qtd_list), qtd, - qtd_list_entry); - qtd->qh = *qh; - } -- DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags); -- - done: - - return retval; --- -1.9.1 - |