diff options
| author | Mingcheng Zhu <mingchen@qca.qualcomm.com> | 2014-12-22 16:24:03 -0800 |
|---|---|---|
| committer | AnjaneeDevi Kapparapu <c_akappa@qti.qualcomm.com> | 2015-01-12 15:24:04 +0530 |
| commit | 3ff5878ca65bcd95fceefe8aa839e36d71e475dc (patch) | |
| tree | 4922b3a9c76232442ec4d659ce1167cbee5a3eef | |
| parent | a01047ee7e69245071f4cc1971752750b1108a86 (diff) | |
QCACLD2.0: Fix the startup error handling issue
wlan_hdd_startup has issue in error handling. This causes HIF crash
when wma_prestart returns failure. To make the minimum change a
hdd_start_reinit_flag is introduced in HIF so that HIF will ignore
the HIFStop called from wlan_hdd_startup. After wlan_hdd_startup
returned, The HIFStop is called by HIF in error return cases.
The same logic is implemented in wlan_hdd_reinit path.
Change-Id: Ic77114fbfa95676eed88da54b0091b0d71b0abaf
CRs-Fixed: 774560
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/hif_pci.c | 5 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/if_pci.c | 24 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/if_pci.h | 3 |
3 files changed, 27 insertions, 5 deletions
diff --git a/CORE/SERVICES/HIF/PCIe/hif_pci.c b/CORE/SERVICES/HIF/PCIe/hif_pci.c index fd2fd5fb057c..96db6a829aaa 100644 --- a/CORE/SERVICES/HIF/PCIe/hif_pci.c +++ b/CORE/SERVICES/HIF/PCIe/hif_pci.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1715,6 +1715,9 @@ HIFStop(HIF_DEVICE *hif_device) return; /* already stopped or stopping */ } + if (sc->hdd_startup_reinit_flag == TRUE) + return; /* If still in wlan_hdd_startup or wlan_hdd_reinit nop. */ + sc->hif_init_done = FALSE; if (hif_state->started) { diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.c b/CORE/SERVICES/HIF/PCIe/if_pci.c index 271a7d830ad8..1f5c4fe02be2 100644 --- a/CORE/SERVICES/HIF/PCIe/if_pci.c +++ b/CORE/SERVICES/HIF/PCIe/if_pci.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -976,8 +976,11 @@ again: init_waitqueue_head(&ol_sc->sc_osdev->event_queue); ret = hif_init_adf_ctx(ol_sc); - if (ret == 0) + if (ret == 0) { + sc->hdd_startup_reinit_flag = true; ret = hdd_wlan_startup(&pdev->dev, ol_sc); + sc->hdd_startup_reinit_flag = false; + } if (ret) { hif_disable_isr(ol_sc); @@ -1316,8 +1319,10 @@ again: ret = hif_init_adf_ctx(ol_sc); if (ret == 0) { + sc->hdd_startup_reinit_flag = true; if (VOS_STATUS_SUCCESS == hdd_wlan_re_init(ol_sc)) ret = 0; + sc->hdd_startup_reinit_flag = false; } /* Re-enable ASPM after firmware/OTP download is complete */ @@ -1404,6 +1409,15 @@ hif_nointrs(struct hif_pci_softc *sc) { int i; + if (sc->hdd_startup_reinit_flag) { + pr_err("%s: WARN: In HDD startup or reinit\n", __func__); + return; + } + + if (!sc->pdev) { + pr_err("%s: pdev is NULL\n", __func__); + return; + } if (sc->num_msi_intrs > 0) { /* MSI interrupt(s) */ for (i = 0; i < sc->num_msi_intrs; i++) { @@ -2134,7 +2148,11 @@ void hif_disable_isr(void *ol_sc) struct ol_softc *sc = (struct ol_softc *)ol_sc; struct hif_pci_softc *hif_sc = sc->hif_sc; struct ol_softc *scn; - + if (hif_sc->hdd_startup_reinit_flag) { + pr_err("%s: WARN: in HDD starrtup or reinit function\n", + __func__); + return; + } scn = hif_sc->ol_sc; hif_nointrs(hif_sc); #if CONFIG_PCIE_64BIT_MSI diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.h b/CORE/SERVICES/HIF/PCIe/if_pci.h index 66980697fb32..a4d0e3416f26 100644 --- a/CORE/SERVICES/HIF/PCIe/if_pci.h +++ b/CORE/SERVICES/HIF/PCIe/if_pci.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -89,6 +89,7 @@ struct hif_pci_softc { atomic_t pci_link_suspended; bool hif_init_done; bool recovery; + bool hdd_startup_reinit_flag; int htc_endpoint; }; #define TARGID(sc) ((A_target_id_t)(&(sc)->mem)) |
