aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-3.10/0088-dwc_otg-prevent-crashes-on-host-port-disconnects.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm2708/patches-3.10/0088-dwc_otg-prevent-crashes-on-host-port-disconnects.patch')
-rw-r--r--target/linux/brcm2708/patches-3.10/0088-dwc_otg-prevent-crashes-on-host-port-disconnects.patch160
1 files changed, 0 insertions, 160 deletions
diff --git a/target/linux/brcm2708/patches-3.10/0088-dwc_otg-prevent-crashes-on-host-port-disconnects.patch b/target/linux/brcm2708/patches-3.10/0088-dwc_otg-prevent-crashes-on-host-port-disconnects.patch
deleted file mode 100644
index 217136a38e..0000000000
--- a/target/linux/brcm2708/patches-3.10/0088-dwc_otg-prevent-crashes-on-host-port-disconnects.patch
+++ /dev/null
@@ -1,160 +0,0 @@
-From 53e5476701371e6f8b85cdeeb6099cdaea3872ce Mon Sep 17 00:00:00 2001
-From: P33M <P33M@github.com>
-Date: Mon, 5 Aug 2013 11:47:12 +0100
-Subject: [PATCH 088/196] dwc_otg: prevent crashes on host port disconnects
-
-Fix several issues resulting in crashes or inconsistent state
-if a Model A root port was disconnected.
-
-- Clean up queue heads properly in kill_urbs_in_qh_list by
- removing the empty QHs from the schedule lists
-- Set the halt status properly to prevent IRQ handlers from
- using freed memory
-- Add fiq_split related cleanup for saved registers
-- Make microframe scheduling reclaim host channels if
- active during a disconnect
-- Abort URBs with -ESHUTDOWN status response, informing
- device drivers so they respond in a more correct fashion
- and don't try to resubmit URBs
-- Prevent IRQ handlers from attempting to handle channel
- interrupts if the associated URB was dequeued (and the
- driver state was cleared)
----
- drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 44 ++++++++++++++++++++++++----
- drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 7 +++++
- drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 3 ++
- 3 files changed, 48 insertions(+), 6 deletions(-)
-
-diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
-index c42172f..be1d25b 100644
---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
-+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
-@@ -59,6 +59,11 @@ static int last_sel_trans_num_avail_hc_at_end = 0;
-
- extern int g_next_sched_frame, g_np_count, g_np_sent;
-
-+extern haint_data_t haint_saved;
-+extern hcintmsk_data_t hcintmsk_saved[MAX_EPS_CHANNELS];
-+extern hcint_data_t hcint_saved[MAX_EPS_CHANNELS];
-+extern gintsts_data_t ginsts_saved;
-+
- dwc_otg_hcd_t *dwc_otg_hcd_alloc_hcd(void)
- {
- return DWC_ALLOC(sizeof(dwc_otg_hcd_t));
-@@ -168,31 +173,43 @@ static void del_timers(dwc_otg_hcd_t * hcd)
-
- /**
- * Processes all the URBs in a single list of QHs. Completes them with
-- * -ETIMEDOUT and frees the QTD.
-+ * -ESHUTDOWN and frees the QTD.
- */
- static void kill_urbs_in_qh_list(dwc_otg_hcd_t * hcd, dwc_list_link_t * qh_list)
- {
-- dwc_list_link_t *qh_item;
-+ dwc_list_link_t *qh_item, *qh_tmp;
- dwc_otg_qh_t *qh;
- dwc_otg_qtd_t *qtd, *qtd_tmp;
-
-- DWC_LIST_FOREACH(qh_item, qh_list) {
-+ DWC_LIST_FOREACH_SAFE(qh_item, qh_tmp, qh_list) {
- qh = DWC_LIST_ENTRY(qh_item, dwc_otg_qh_t, qh_list_entry);
- DWC_CIRCLEQ_FOREACH_SAFE(qtd, qtd_tmp,
- &qh->qtd_list, qtd_list_entry) {
- qtd = DWC_CIRCLEQ_FIRST(&qh->qtd_list);
- if (qtd->urb != NULL) {
- hcd->fops->complete(hcd, qtd->urb->priv,
-- qtd->urb, -DWC_E_TIMEOUT);
-+ qtd->urb, -DWC_E_SHUTDOWN);
- dwc_otg_hcd_qtd_remove_and_free(hcd, qtd, qh);
- }
-
- }
-+ if(qh->channel) {
-+ /* Using hcchar.chen == 1 is not a reliable test.
-+ * It is possible that the channel has already halted
-+ * but not yet been through the IRQ handler.
-+ */
-+ dwc_otg_hc_halt(hcd->core_if, qh->channel,
-+ DWC_OTG_HC_XFER_URB_DEQUEUE);
-+ if(microframe_schedule)
-+ hcd->available_host_channels++;
-+ qh->channel = NULL;
-+ }
-+ dwc_otg_hcd_qh_remove(hcd, qh);
- }
- }
-
- /**
-- * Responds with an error status of ETIMEDOUT to all URBs in the non-periodic
-+ * Responds with an error status of ESHUTDOWN to all URBs in the non-periodic
- * and periodic schedules. The QTD associated with each URB is removed from
- * the schedule and freed. This function may be called when a disconnect is
- * detected or when the HCD is being stopped.
-@@ -278,7 +295,8 @@ static int32_t dwc_otg_hcd_disconnect_cb(void *p)
- */
- dwc_otg_hcd->flags.b.port_connect_status_change = 1;
- dwc_otg_hcd->flags.b.port_connect_status = 0;
--
-+ if(fiq_fix_enable)
-+ local_fiq_disable();
- /*
- * Shutdown any transfers in process by clearing the Tx FIFO Empty
- * interrupt mask and status bits and disabling subsequent host
-@@ -374,8 +392,22 @@ static int32_t dwc_otg_hcd_disconnect_cb(void *p)
- channel->qh = NULL;
- }
- }
-+ if(fiq_split_enable) {
-+ for(i=0; i < 128; i++) {
-+ dwc_otg_hcd->hub_port[i] = 0;
-+ }
-+ haint_saved.d32 = 0;
-+ for(i=0; i < MAX_EPS_CHANNELS; i++) {
-+ hcint_saved[i].d32 = 0;
-+ hcintmsk_saved[i].d32 = 0;
-+ }
-+ }
-+
- }
-
-+ if(fiq_fix_enable)
-+ local_fiq_enable();
-+
- if (dwc_otg_hcd->fops->disconnect) {
- dwc_otg_hcd->fops->disconnect(dwc_otg_hcd);
- }
-diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
-index 7d521d9..19abea0 100644
---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
-+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
-@@ -2660,6 +2660,13 @@ int32_t dwc_otg_hcd_handle_hc_n_intr(dwc_otg_hcd_t * dwc_otg_hcd, uint32_t num)
-
- hc = dwc_otg_hcd->hc_ptr_array[num];
- hc_regs = dwc_otg_hcd->core_if->host_if->hc_regs[num];
-+ if(hc->halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE) {
-+ /* We are responding to a channel disable. Driver
-+ * state is cleared - our qtd has gone away.
-+ */
-+ release_channel(dwc_otg_hcd, hc, NULL, hc->halt_status);
-+ return 1;
-+ }
- qtd = DWC_CIRCLEQ_FIRST(&hc->qh->qtd_list);
-
- hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
-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 80690f9..0d49b50 100644
---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
-+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
-@@ -309,6 +309,9 @@ static int _complete(dwc_otg_hcd_t * hcd, void *urb_handle,
- case -DWC_E_OVERFLOW:
- status = -EOVERFLOW;
- break;
-+ case -DWC_E_SHUTDOWN:
-+ status = -ESHUTDOWN;
-+ break;
- default:
- if (status) {
- DWC_PRINTF("Uknown urb status %d\n", status);
---
-1.9.1
-