qcacld-3.0: clear WMI work queue before bus context destruction

qcacld-2.0 to qcacld-3.0 propagation

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
This commit is contained in:
Xun Luo 2015-11-10 08:24:45 -08:00 • committed by Satish Singh
commit a858a47ead
5 changed files with 85 additions and 0 deletions

View file

@ -827,6 +827,13 @@ CDF_STATUS cds_close(v_CONTEXT_t cds_context)
{
CDF_STATUS cdf_status;
cdf_status = wma_wmi_work_close(cds_context);
if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
"%s: Failed to close wma_wmi_work", __func__);
CDF_ASSERT(0);
}
if (gp_cds_context->htc_ctx) {
htc_stop(gp_cds_context->htc_ctx);
htc_destroy(gp_cds_context->htc_ctx);
@ -1534,6 +1541,13 @@ CDF_STATUS cds_shutdown(v_CONTEXT_t cds_context)
}
}
cdf_status = wma_wmi_work_close(cds_context);
if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
"%s: Failed to close wma_wmi_work!", __func__);
CDF_ASSERT(0);
}
if (gp_cds_context->htc_ctx) {
htc_stop(gp_cds_context->htc_ctx);
htc_destroy(gp_cds_context->htc_ctx);

View file

@ -90,6 +90,8 @@ CDF_STATUS wma_close(void *cds_context);
CDF_STATUS wma_wmi_service_close(void *cds_context);
CDF_STATUS wma_wmi_work_close(void *cds_context);
void wma_rx_ready_event(WMA_HANDLE handle, void *ev);
void wma_rx_service_ready_event(WMA_HANDLE handle, void *ev);

View file

@ -2929,6 +2929,42 @@ CDF_STATUS wma_wmi_service_close(void *cds_ctx)
return CDF_STATUS_SUCCESS;
}
/**
* wma_wmi_work_close() - close the work queue items associated with WMI
* @cds_ctx: Pointer to cds context
*
* This function closes work queue items associated with WMI, but not fully
* closes WMI service.
*
* Return: CDF_STATUS_SUCCESS if work close is successful. Otherwise
* proper error codes.
*/
CDF_STATUS wma_wmi_work_close(void *cds_ctx)
{
tp_wma_handle wma_handle;
WMA_LOGD("%s: Enter", __func__);
wma_handle = cds_get_context(CDF_MODULE_ID_WMA);
/* validate the wma_handle */
if (NULL == wma_handle) {
WMA_LOGE("%s: Invalid wma handle", __func__);
return CDF_STATUS_E_INVAL;
}
/* validate the wmi handle */
if (NULL == wma_handle->wmi_handle) {
WMA_LOGE("%s: Invalid wmi handle", __func__);
return CDF_STATUS_E_INVAL;
}
/* remove the wmi work */
WMA_LOGD("calling wmi_unified_remove_work");
wmi_unified_remove_work(wma_handle->wmi_handle);
return CDF_STATUS_SUCCESS;
}
/**

View file

@ -1128,6 +1128,36 @@ void 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: None
*/
void
wmi_unified_remove_work(struct wmi_unified *wmi_handle)
{
wmi_buf_t buf;
CDF_TRACE(CDF_MODULE_ID_WMI, CDF_TRACE_LEVEL_INFO,
"Enter: %s", __func__);
cds_flush_work(&wmi_handle->rx_event_work);
cdf_spin_lock_bh(&wmi_handle->eventq_lock);
buf = cdf_nbuf_queue_remove(&wmi_handle->event_queue);
while (buf) {
cdf_nbuf_free(buf);
buf = cdf_nbuf_queue_remove(&wmi_handle->event_queue);
}
cdf_spin_unlock_bh(&wmi_handle->eventq_lock);
CDF_TRACE(CDF_MODULE_ID_WMA, CDF_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;

View file

@ -57,6 +57,9 @@ void *wmi_unified_attach(void *scn_handle,
*/
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
*