summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXun Luo <xunl@qca.qualcomm.com>2015-05-08 12:42:23 -0700
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2015-09-15 14:49:22 +0530
commit22765b701feef2dfbe42c9ffb458a9c58beec86b (patch)
tree0349e52dcbddeaa09b9af556ed53aa3103242838
parent90ed2ba0ad532c2f2b5a8636cbeb70cc91e6b6af (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.h2
-rw-r--r--CORE/SERVICES/COMMON/wmi_unified_api.h3
-rw-r--r--CORE/SERVICES/WMA/wma.c37
-rw-r--r--CORE/SERVICES/WMI/wmi_unified.c30
-rw-r--r--CORE/VOSS/src/vos_api.c13
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);