diff options
author | Florian Fainelli <florian@openwrt.org> | 2014-02-28 20:30:08 +0000 |
---|---|---|
committer | Florian Fainelli <florian@openwrt.org> | 2014-02-28 20:30:08 +0000 |
commit | 800930b924c19a56b3a6e94ad351cd0715fb410d (patch) | |
tree | 70158d97f68604d69da8da779507469cf930bf07 /target/linux/brcm2708/patches-3.10/0049-dwc_otg-Fix-unsafe-access-of-QTD-during-URB-enqueue.patch | |
parent | 68c939ba0b0a0dda84e7a2ae370155be9a5593bc (diff) | |
download | upstream-800930b924c19a56b3a6e94ad351cd0715fb410d.tar.gz upstream-800930b924c19a56b3a6e94ad351cd0715fb410d.tar.bz2 upstream-800930b924c19a56b3a6e94ad351cd0715fb410d.zip |
brcm2708: update against latest rpi-3.10.y branch
Update our copies of the brcm2708 patches to the latest rpi-3.10-y
rebased against linux-3.10.y stable (3.10.32). This should hopefully
make it easier for us in the future to leverage the raspberry/rpi-*
branches.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@39770 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/brcm2708/patches-3.10/0049-dwc_otg-Fix-unsafe-access-of-QTD-during-URB-enqueue.patch')
-rw-r--r-- | target/linux/brcm2708/patches-3.10/0049-dwc_otg-Fix-unsafe-access-of-QTD-during-URB-enqueue.patch | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/target/linux/brcm2708/patches-3.10/0049-dwc_otg-Fix-unsafe-access-of-QTD-during-URB-enqueue.patch b/target/linux/brcm2708/patches-3.10/0049-dwc_otg-Fix-unsafe-access-of-QTD-during-URB-enqueue.patch new file mode 100644 index 0000000000..089165341a --- /dev/null +++ b/target/linux/brcm2708/patches-3.10/0049-dwc_otg-Fix-unsafe-access-of-QTD-during-URB-enqueue.patch @@ -0,0 +1,82 @@ +From 08e3e98d28e32852e43bf25fb3e64bb3f5e6af4d Mon Sep 17 00:00:00 2001 +From: P33M <P33M@github.com> +Date: Fri, 15 Feb 2013 22:36:47 +0000 +Subject: [PATCH 049/174] dwc_otg: Fix unsafe access of QTD during URB enqueue + +In dwc_otg_hcd_urb_enqueue during qtd creation, it was possible that the +transaction could complete almost immediately after the qtd was assigned +to a host channel during URB enqueue, which meant the qtd pointer was no +longer valid having been completed and removed. Usually, this resulted in +an OOPS during URB submission. By predetermining whether transactions +need to be queued or not, this unsafe pointer access is avoided. + +This bug was only evident on the Pi model A where a device was attached +that had no periodic endpoints (e.g. USB pendrive or some wlan devices). +--- + drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 23 ++++++++++++----------- + drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 2 +- + 2 files changed, 13 insertions(+), 12 deletions(-) + +--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c +@@ -462,6 +462,8 @@ int dwc_otg_hcd_urb_enqueue(dwc_otg_hcd_ + { + dwc_irqflags_t flags; + int retval = 0; ++ uint8_t needs_scheduling = 0; ++ dwc_otg_transaction_type_e tr_type; + dwc_otg_qtd_t *qtd; + gintmsk_data_t intr_mask = {.d32 = 0 }; + +@@ -493,22 +495,22 @@ int dwc_otg_hcd_urb_enqueue(dwc_otg_hcd_ + return -DWC_E_NO_MEMORY; + } + #endif +- retval = +- dwc_otg_hcd_qtd_add(qtd, hcd, (dwc_otg_qh_t **) ep_handle, atomic_alloc); ++ intr_mask.d32 = DWC_READ_REG32(&hcd->core_if->core_global_regs->gintmsk); ++ if(!intr_mask.b.sofintr) needs_scheduling = 1; ++ if((((dwc_otg_qh_t *)ep_handle)->ep_type == UE_BULK) && !(qtd->urb->flags & URB_GIVEBACK_ASAP)) ++ /* Do not schedule SG transactions until qtd has URB_GIVEBACK_ASAP set */ ++ needs_scheduling = 0; ++ ++ retval = dwc_otg_hcd_qtd_add(qtd, hcd, (dwc_otg_qh_t **) ep_handle, atomic_alloc); + // creates a new queue in ep_handle if it doesn't exist already + if (retval < 0) { + DWC_ERROR("DWC OTG HCD URB Enqueue failed adding QTD. " + "Error status %d\n", retval); + dwc_otg_hcd_qtd_free(qtd); ++ return retval; + } +- intr_mask.d32 = DWC_READ_REG32(&hcd->core_if->core_global_regs->gintmsk); +- if (!intr_mask.b.sofintr && retval == 0) { +- dwc_otg_transaction_type_e tr_type; +- if ((qtd->qh->ep_type == UE_BULK) +- && !(qtd->urb->flags & URB_GIVEBACK_ASAP)) { +- /* Do not schedule SG transactions until qtd has URB_GIVEBACK_ASAP set */ +- return 0; +- } ++ ++ if(needs_scheduling) { + DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags); + tr_type = dwc_otg_hcd_select_transactions(hcd); + if (tr_type != DWC_OTG_TRANSACTION_NONE) { +@@ -516,7 +518,6 @@ int dwc_otg_hcd_urb_enqueue(dwc_otg_hcd_ + } + DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags); + } +- + return retval; + } + +--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c +@@ -937,7 +937,7 @@ int dwc_otg_hcd_qtd_add(dwc_otg_qtd_t * + if (*qh == NULL) { + *qh = dwc_otg_hcd_qh_create(hcd, urb, atomic_alloc); + if (*qh == NULL) { +- retval = -1; ++ retval = -DWC_E_NO_MEMORY; + goto done; + } + } |