diff options
| author | Xun Luo <xunl@qca.qualcomm.com> | 2015-05-08 12:42:23 -0700 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2015-09-15 14:49:22 +0530 |
| commit | 22765b701feef2dfbe42c9ffb458a9c58beec86b (patch) | |
| tree | 0349e52dcbddeaa09b9af556ed53aa3103242838 | |
| parent | 90ed2ba0ad532c2f2b5a8636cbeb70cc91e6b6af (diff) | |
qca-cld: clear WMI work queue before bus context destruction
All WMI work queue should be cleared and processing stopped before
bus context destruction. This change enforces this rule.
Change-Id: I2e12f3f08424f718ec66fe257060ce13de17ee4e
CRs-Fixed: 840422
| -rw-r--r-- | CORE/SERVICES/COMMON/wma_api.h | 2 | ||||
| -rw-r--r-- | CORE/SERVICES/COMMON/wmi_unified_api.h | 3 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.c | 37 | ||||
| -rw-r--r-- | CORE/SERVICES/WMI/wmi_unified.c | 30 | ||||
| -rw-r--r-- | CORE/VOSS/src/vos_api.c | 13 |
5 files changed, 85 insertions, 0 deletions
diff --git a/CORE/SERVICES/COMMON/wma_api.h b/CORE/SERVICES/COMMON/wma_api.h index 48cd36b58170..4b748c04400d 100644 --- a/CORE/SERVICES/COMMON/wma_api.h +++ b/CORE/SERVICES/COMMON/wma_api.h @@ -101,6 +101,8 @@ VOS_STATUS wma_close(v_VOID_t *vos_context); VOS_STATUS wma_wmi_service_close(v_VOID_t *vos_context); +VOS_STATUS wma_wmi_work_close(v_VOID_t *vos_context); + v_VOID_t wma_rx_ready_event(WMA_HANDLE handle, v_VOID_t *ev); v_VOID_t wma_rx_service_ready_event(WMA_HANDLE handle, diff --git a/CORE/SERVICES/COMMON/wmi_unified_api.h b/CORE/SERVICES/COMMON/wmi_unified_api.h index efb062958ad8..3a1ee3137ac3 100644 --- a/CORE/SERVICES/COMMON/wmi_unified_api.h +++ b/CORE/SERVICES/COMMON/wmi_unified_api.h @@ -58,6 +58,9 @@ wmi_unified_attach(void *scn_handle, void (*func) (void*)); void wmi_unified_detach(struct wmi_unified* wmi_handle); +void +wmi_unified_remove_work(struct wmi_unified* wmi_handle); + /** * generic function to allocate WMI buffer * diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 29ce2b6b44f1..f5a7bc08c418 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -28417,6 +28417,43 @@ VOS_STATUS wma_wmi_service_close(v_VOID_t *vos_ctx) return VOS_STATUS_SUCCESS; } +/** + * wma_wmi_work_close() - close the work queue items associated with WMI + * @vos_ctx: Pointer to vos context + * + * This function closes work queue items associated with WMI, but not fully + * closes WMI service. + * + * Return: VOS_STATUS_SUCCESS if work close is successful. Otherwise + * proper error codes. + */ +VOS_STATUS wma_wmi_work_close(v_VOID_t *vos_ctx) +{ + tp_wma_handle wma_handle; + + WMA_LOGD("%s: Enter", __func__); + + wma_handle = vos_get_context(VOS_MODULE_ID_WDA, vos_ctx); + + /* validate the wma_handle */ + if (NULL == wma_handle) { + WMA_LOGE("%s: Invalid wma handle", __func__); + return VOS_STATUS_E_INVAL; + } + + /* validate the wmi handle */ + if (NULL == wma_handle->wmi_handle) { + WMA_LOGE("%s: Invalid wmi handle", __func__); + return VOS_STATUS_E_INVAL; + } + + /* remove the wmi work */ + WMA_LOGD("calling wmi_unified_remove_work"); + wmi_unified_remove_work(wma_handle->wmi_handle); + + return VOS_STATUS_SUCCESS; +} + /* * Detach DFS methods */ diff --git a/CORE/SERVICES/WMI/wmi_unified.c b/CORE/SERVICES/WMI/wmi_unified.c index 5dd290244a91..9e097e54f594 100644 --- a/CORE/SERVICES/WMI/wmi_unified.c +++ b/CORE/SERVICES/WMI/wmi_unified.c @@ -1080,6 +1080,36 @@ wmi_unified_detach(struct wmi_unified* wmi_handle) } } +/** + * wmi_unified_remove_work() - detach for WMI work + * @wmi_handle: handle to WMI + * + * A function that does not fully detach WMI, but just remove work + * queue items associated with it. This is used to make sure that + * before any other processing code that may destroy related contexts + * (HTC, etc), work queue processing on WMI has already been stopped. + * + * Return: void. + */ +void +wmi_unified_remove_work(struct wmi_unified* wmi_handle) +{ + wmi_buf_t buf; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Enter: %s", __func__); + vos_flush_work(&wmi_handle->rx_event_work); + adf_os_spin_lock_bh(&wmi_handle->eventq_lock); + buf = adf_nbuf_queue_remove(&wmi_handle->event_queue); + while (buf) { + adf_nbuf_free(buf); + buf = adf_nbuf_queue_remove(&wmi_handle->event_queue); + } + adf_os_spin_unlock_bh(&wmi_handle->eventq_lock); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Done: %s", __func__); +} + void wmi_htc_tx_complete(void *ctx, HTC_PACKET *htc_pkt) { struct wmi_unified *wmi_handle = (struct wmi_unified *)ctx; diff --git a/CORE/VOSS/src/vos_api.c b/CORE/VOSS/src/vos_api.c index d39d057bcd91..25078bb93113 100644 --- a/CORE/VOSS/src/vos_api.c +++ b/CORE/VOSS/src/vos_api.c @@ -993,6 +993,12 @@ VOS_STATUS vos_close( v_CONTEXT_t vosContext ) { VOS_STATUS vosStatus; + vosStatus = wma_wmi_work_close( vosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close wma_wmi_work", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } if (gpVosContext->htc_ctx) { @@ -2147,6 +2153,13 @@ VOS_STATUS vos_shutdown(v_CONTEXT_t vosContext) } } + vosStatus = wma_wmi_work_close(vosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close wma_wmi_work!", __func__); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus)); + } + if (gpVosContext->htc_ctx) { HTCStop(gpVosContext->htc_ctx); |
