diff options
| author | Chien-Ming Chen <mingc@qca.qualcomm.com> | 2014-11-25 17:44:53 +0800 |
|---|---|---|
| committer | AnjaneeDevi Kapparapu <c_akappa@qti.qualcomm.com> | 2014-12-01 16:19:24 +0530 |
| commit | 350abab61a9ddaba7d9e5e5bc705f752f0662e0d (patch) | |
| tree | 6be8b0c00631465bfb4a64cfdf3bab20ffbc5ce2 | |
| parent | d78975a6b4da8d8723690b433a7564730f115551 (diff) | |
qcacld: Fix USB SSR failure from target assertion
USB SSR uses uevent to trigger unloading/loading driver
again. It could meet the timing issue due to target's
cold reset. To prevent this race condition, issuing
the uevent in usb disconnect cb function. To ensure
that usb probe is completed after cold reset, adding
delay to check it in usb probe function.
Change-Id: I8c2acc05e0e367c073d7b27a5223d375b26724cb
CRs-Fixed: 762484
| -rw-r--r-- | CORE/SERVICES/BMI/ol_fw.c | 9 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/USB/if_usb.c | 17 |
2 files changed, 25 insertions, 1 deletions
diff --git a/CORE/SERVICES/BMI/ol_fw.c b/CORE/SERVICES/BMI/ol_fw.c index f32ba8f88619..6da6486006f9 100644 --- a/CORE/SERVICES/BMI/ol_fw.c +++ b/CORE/SERVICES/BMI/ol_fw.c @@ -1072,6 +1072,13 @@ void ol_ramdump_handler(struct ol_softc *scn) pr_err("Firmware crash detected...\n"); pr_err("Host SW version: %s\n", QWLAN_VERSIONSTR); pr_err("FW version: %d.%d.%d.%d", MSPId, mSPId, SIId, CRMId); + + if (vos_is_load_unload_in_progress(VOS_MODULE_ID_VOSS, NULL)) { + printk("%s: Loading/Unloading is in progress, ignore!\n", + __func__); + return; + } + reg = (A_UINT32 *) (data + 4); print_hex_dump(KERN_DEBUG, " ", DUMP_PREFIX_OFFSET, 16, 4, reg, min_t(A_UINT32, len - 4, FW_REG_DUMP_CNT * 4), @@ -1079,7 +1086,7 @@ void ol_ramdump_handler(struct ol_softc *scn) scn->fw_ram_dumping = 0; if (scn->enableFwSelfRecovery) - kobject_uevent(&scn->adf_dev->dev->kobj, KOBJ_OFFLINE); + vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE); } else if (pattern == FW_REG_PATTERN) { reg = (A_UINT32 *) (data + 4); diff --git a/CORE/SERVICES/HIF/USB/if_usb.c b/CORE/SERVICES/HIF/USB/if_usb.c index 6fde4c865e38..da81b57debdf 100644 --- a/CORE/SERVICES/HIF/USB/if_usb.c +++ b/CORE/SERVICES/HIF/USB/if_usb.c @@ -256,6 +256,15 @@ static void hif_usb_remove(struct usb_interface *interface) HIF_USB_UNLOAD_STATE_TARGET_RESET); scn = sc->ol_sc; + /* The logp is set by target failure's ol_ramdump_handler. + * Coldreset occurs and do this disconnect cb, try to issue + * offline uevent to restart driver. + */ + if (vos_is_logp_in_progress(VOS_MODULE_ID_VOSS, NULL)) { + /* dispatch 'offline' uevent to restart module */ + kobject_uevent(&scn->adf_dev->dev->kobj, KOBJ_OFFLINE); + vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE); + } if (atomic_inc_and_test(&usb_sc->hdd_removed)) { atomic_set(&usb_sc->hdd_removed_processing, 1); @@ -267,6 +276,7 @@ static void hif_usb_remove(struct usb_interface *interface) __hdd_wlan_exit(); atomic_set(&usb_sc->hdd_removed_processing, 0); } + hif_nointrs(sc); HIF_USBDeviceDetached(interface, 1); hif_deinit_adf_ctx(scn); @@ -462,12 +472,19 @@ static int is_usb_driver_register = 0; int hif_register_driver(void) { int status = 0; + int probe_wait_cnt = 0; is_usb_driver_register = 1; init_waitqueue_head(&hif_usb_unload_event_wq); atomic_set(&hif_usb_unload_state, HIF_USB_UNLOAD_STATE_NULL); usb_register_notify(&hif_usb_dev_nb); status = usb_register(&hif_usb_drv_id); + /* wait for usb probe done, 2s at most*/ + while(!usb_sc && probe_wait_cnt < 10) { + A_MSLEEP(200); + probe_wait_cnt++; + } + if (usb_sc && status == 0) return 0; else |
