From 3ff5878ca65bcd95fceefe8aa839e36d71e475dc Mon Sep 17 00:00:00 2001 From: Mingcheng Zhu Date: Mon, 22 Dec 2014 16:24:03 -0800 Subject: 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 --- CORE/SERVICES/HIF/PCIe/hif_pci.c | 5 ++++- CORE/SERVICES/HIF/PCIe/if_pci.c | 24 +++++++++++++++++++++--- 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)) -- cgit v1.2.3