qcacld-3.0: Clean-up module init and exit

In module init, bunch of initializations are done which are not
required till probe call back gets called. Also in module exit,
some clean-up done which should wait till remove call back gets
called. Move the initialization done in module init to probe call back and
clean-up done in module exit to remove call back.

Change-Id: Id4a0cb21300de1ceab8ed043638b735f31d516d4
CRs-fixed: 950170
Этот коммит содержится в:
Prashanth Bhatta
2015-11-30 14:28:52 -08:00
коммит произвёл Satish Singh
родитель 05aaf01126
Коммит 5da711e712
6 изменённых файлов: 294 добавлений и 292 удалений

Просмотреть файл

@@ -55,9 +55,8 @@
*/
#define CDS_WMA_TIMEOUT (15000)
CDF_STATUS cds_alloc_global_context(v_CONTEXT_t *p_cds_context);
CDF_STATUS cds_free_global_context(v_CONTEXT_t *p_cds_context);
v_CONTEXT_t cds_init(void);
void cds_deinit(void);
CDF_STATUS cds_pre_enable(v_CONTEXT_t cds_context);

Просмотреть файл

@@ -80,70 +80,51 @@ static uint8_t cds_multicast_logging;
void cds_sys_probe_thread_cback(void *pUserData);
/**
* cds_alloc_global_context() - allocate CDS global context
* @p_cds_context: A pointer to where to store the CDS Context
* cds_init() - Initialize CDS
*
* cds_alloc_global_context() function allocates the CDS global Context,
* but does not initialize all the members. This overal initialization will
* happen at cds_open().
* This function allocates the resource required for CDS, but does not
* initialize all the members. This overall initialization will happen at
* cds_open().
*
* Return: CDF status
* Return: Global context on success and NULL on failure.
*/
CDF_STATUS cds_alloc_global_context(v_CONTEXT_t *p_cds_context)
v_CONTEXT_t cds_init(void)
{
if (p_cds_context == NULL)
return CDF_STATUS_E_FAILURE;
cdf_mc_timer_manager_init();
cdf_mem_init();
/* allocate the CDS Context */
*p_cds_context = NULL;
gp_cds_context = &g_cds_context;
cdf_mem_zero(gp_cds_context, sizeof(cds_context_type));
*p_cds_context = gp_cds_context;
gp_cds_context->cdf_ctx = &g_cdf_ctx;
cdf_mem_zero(&g_cdf_ctx, sizeof(g_cdf_ctx));
/* initialize the spinlock */
cdf_trace_spin_lock_init();
/* it is the right time to initialize MTRACE structures */
#if defined(TRACE_RECORD)
cdf_trace_init();
#endif
cdf_dp_trace_init();
return CDF_STATUS_SUCCESS;
} /* cds_alloc_global_context() */
cds_ssr_protect_init();
return gp_cds_context;
}
/**
* cds_free_global_context() - free CDS global context
* @p_cds_context: A pointer to where the CDS Context was stored
* cds_deinit() - Deinitialize CDS
*
* cds_free_global_context() function frees the CDS Context.
*
* Return: CDF status
* This function frees the CDS resources
*/
CDF_STATUS cds_free_global_context(v_CONTEXT_t *p_cds_context)
void cds_deinit(void)
{
CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_INFO,
"%s: De-allocating the CDS Context", __func__);
if (gp_cds_context == NULL)
return;
if ((p_cds_context == NULL) || (*p_cds_context == NULL)) {
CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
"%s: vOS Context is Null", __func__);
return CDF_STATUS_E_FAILURE;
}
if (gp_cds_context != *p_cds_context) {
CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
"%s: Context mismatch", __func__);
return CDF_STATUS_E_FAILURE;
}
gp_cds_context->cdf_ctx = NULL;
*p_cds_context = gp_cds_context = NULL;
gp_cds_context = NULL;
return CDF_STATUS_SUCCESS;
} /* cds_free_global_context() */
return;
}
#ifdef WLAN_FEATURE_NAN
/**

Просмотреть файл

@@ -1425,6 +1425,9 @@ static inline void hdd_stop_bus_bw_computer_timer(hdd_adapter_t *pAdapter)
}
#endif
int hdd_init(void);
void hdd_deinit(void);
int hdd_wlan_startup(struct device *dev, void *hif_sc);
void __hdd_wlan_exit(void);
int hdd_wlan_notify_modem_power_state(int state);
@@ -1517,7 +1520,6 @@ void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter);
static inline void wlan_hdd_stop_sap(hdd_adapter_t *ap_adapter) {}
static inline void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter) {}
#endif
cdf_wake_lock_t *hdd_wlan_get_wake_lock_ptr(void);
#ifdef QCA_CONFIG_SMP
int wlan_hdd_get_cpu(void);

Просмотреть файл

@@ -47,6 +47,7 @@
#include "wma_api.h"
#include "wlan_hdd_napi.h"
#include "cds_concurrency.h"
#include "qwlan_version.h"
#ifdef MODULE
#define WLAN_MODULE_NAME module_name(THIS_MODULE)
@@ -72,6 +73,112 @@
#define WLAN_HDD_UNREGISTER_DRIVER(wlan_drv_ops) \
icnss_unregister_driver(wlan_drv_ops)
#endif /* HIF_PCI */
#define DISABLE_KRAIT_IDLE_PS_VAL 200
/*
* In BMI Phase we are only sending small chunk (256 bytes) of the FW image at
* a time, and wait for the completion interrupt to start the next transfer.
* During this phase, the KRAIT is entering IDLE/StandAlone(SA) Power Save(PS).
* The delay incurred for resuming from IDLE/SA PS is huge during driver load.
* So prevent APPS IDLE/SA PS durint driver load for reducing interrupt latency.
*/
#ifdef CONFIG_CNSS
static inline void hdd_request_pm_qos(int val)
{
cnss_request_pm_qos(val);
}
static inline void hdd_remove_pm_qos(void)
{
cnss_remove_pm_qos();
}
#else
static inline void hdd_request_pm_qos(int val)
{
}
static inline void hdd_remove_pm_qos(void)
{
}
#endif
/**
* hdd_hif_open() - HIF open helper
* @dev: wlan device structure
* @bdev: bus device structure
* @bid: bus identifier for shared busses
* @bus_type: underlying bus type
* @reinit: true if we are reinitializing the driver during recovery phase
*
* This function brings-up HIF layer during load/recovery phase.
*
* Return: 0 on success and errno on failure.
*/
static int hdd_hif_open(struct device *dev, void *bdev, const hif_bus_id *bid,
enum ath_hal_bus_type bus_type, bool reinit)
{
CDF_STATUS status;
int ret = 0;
void *hif_ctx;
status = hif_open();
if (!CDF_IS_STATUS_SUCCESS(status)) {
hdd_err("hif_open error = %d", status);
return cdf_status_to_os_return(status);
}
hif_ctx = cds_get_context(CDF_MODULE_ID_HIF);
ret = hdd_napi_create();
if (hdd_napi_enabled(HDD_NAPI_ANY)) {
hdd_info("hdd_napi_create returned: %d", status);
if (ret <= 0) {
hdd_err("NAPI creation error, rc: 0x%x, reinit = %d",
status, reinit);
ret = -EFAULT;
goto err_hif_close;
}
}
status = hif_enable(hif_ctx, dev, bdev, bid, bus_type,
(reinit == true) ? HIF_ENABLE_TYPE_REINIT :
HIF_ENABLE_TYPE_PROBE);
if (!CDF_IS_STATUS_SUCCESS(status)) {
hdd_err("hif_enable error = %d, reinit = %d",
status, reinit);
ret = cdf_status_to_os_return(status);
goto err_napi_destroy;
}
return 0;
err_napi_destroy:
hdd_napi_destroy(true);
err_hif_close:
hif_close(hif_ctx);
return ret;
}
/**
* hdd_hif_close() - HIF close helper
* @hif_ctx: HIF context
*
* Helper function to close HIF
*/
static void hdd_hif_close(void *hif_ctx)
{
if (hif_ctx == NULL)
return;
hif_disable(hif_ctx, HIF_DISABLE_TYPE_REMOVE);
hdd_napi_destroy(true);
hif_close(hif_ctx);
}
/**
* wlan_hdd_probe() - handles probe request
@@ -91,69 +198,68 @@ static int wlan_hdd_probe(struct device *dev, void *bdev, const hif_bus_id *bid,
{
void *hif_ctx;
CDF_STATUS status;
int ret;
int ret = 0;
pr_info("%s: %sprobing driver v%s\n", WLAN_MODULE_NAME,
reinit ? "re-" : "", QWLAN_VERSIONSTR);
hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
/*
* The Krait is going to Idle/Stand Alone Power Save
* more aggressively which is resulting in the longer driver load time.
* The Fix is to not allow Krait to enter Idle Power Save during driver
* load.
*/
hdd_request_pm_qos(DISABLE_KRAIT_IDLE_PS_VAL);
if (!reinit) {
ret = hdd_init();
if (ret)
goto out;
}
if (WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
status = epping_open();
if (status != CDF_STATUS_SUCCESS)
return status;
goto err_hdd_deinit;
}
status = hif_open();
if (status != CDF_STATUS_SUCCESS) {
hddLog(LOGE, FL("hif_open error = %d"), status);
return -EFAULT;
}
ret = hdd_hif_open(dev, bdev, bid, bus_type, reinit);
if (ret)
goto err_epping_close;
hif_ctx = cds_get_context(CDF_MODULE_ID_HIF);
if (reinit)
hdd_napi_destroy(true);
status = hdd_napi_create();
if (hdd_napi_enabled(HDD_NAPI_ANY)) {
hdd_info("hdd_napi_create returned: %d\n", status);
if (status <= 0) {
hdd_err("NAPI creation error, rc: 0x%x, reinit = %d",
status, reinit);
ret = -EFAULT;
goto end;
}
}
status = hif_enable(hif_ctx, dev, bdev, bid,
bus_type, (reinit == true) ?
HIF_ENABLE_TYPE_REINIT : HIF_ENABLE_TYPE_PROBE);
if (status != CDF_STATUS_SUCCESS) {
hdd_err("hif_enable error = %d, reinit = %d",
status, reinit);
ret = -EIO;
goto end;
}
if (reinit)
ret = hdd_wlan_re_init(hif_ctx);
else
ret = hdd_wlan_startup(dev, hif_ctx);
end:
if (ret) {
if (WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
hif_pktlogmod_exit(hif_ctx);
epping_disable();
htc_destroy(cds_get_context(CDF_MODULE_ID_HTC));
hif_disable(hif_ctx, (reinit == true) ?
HIF_ENABLE_TYPE_REINIT : HIF_ENABLE_TYPE_PROBE);
cds_free_context(NULL, CDF_MODULE_ID_HTC, NULL);
epping_close();
} else {
hif_pktlogmod_exit(hif_ctx);
__hdd_wlan_exit();
hif_disable(hif_ctx, HIF_DISABLE_TYPE_REMOVE);
}
hif_close(hif_ctx);
}
if (ret)
goto err_hif_close;
if (reinit)
cds_set_logp_in_progress(false);
hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
hdd_remove_pm_qos();
return 0;
err_hif_close:
hdd_hif_close(hif_ctx);
err_epping_close:
if (WLAN_IS_EPPING_ENABLED(cds_get_conparam()))
epping_close();
err_hdd_deinit:
hdd_deinit();
out:
hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
hdd_remove_pm_qos();
return ret;
}
@@ -168,38 +274,26 @@ end:
static void wlan_hdd_remove(void)
{
void *hif_ctx;
v_CONTEXT_t p_cds_context = NULL;
/* Get the global cds context */
p_cds_context = cds_get_global_context();
pr_info("%s: Removing driver v%s\n", WLAN_MODULE_NAME,
QWLAN_VERSIONSTR);
hif_ctx = cds_get_context(CDF_MODULE_ID_HIF);
hif_pktlogmod_exit(hif_ctx);
if (WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
hif_pktlogmod_exit(hif_ctx);
epping_disable();
htc_destroy(cds_get_context(CDF_MODULE_ID_HTC));
hif_disable(hif_ctx, HIF_DISABLE_TYPE_REMOVE);
cds_free_context(NULL, CDF_MODULE_ID_HTC, NULL);
epping_close();
} else {
hif_pktlogmod_exit(hif_ctx);
__hdd_wlan_exit();
hif_disable(hif_ctx, HIF_DISABLE_TYPE_REMOVE);
}
hdd_napi_destroy(true);
hif_close(hif_ctx);
hdd_hif_close(hif_ctx);
cds_free_global_context(&p_cds_context);
hdd_deinit();
#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
wlan_logging_sock_deinit_svc();
#endif
cdf_wake_lock_destroy(hdd_wlan_get_wake_lock_ptr());
pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
pr_info("%s: Driver Removed\n", WLAN_MODULE_NAME);
}
/**
@@ -235,8 +329,7 @@ static void wlan_hdd_shutdown(void)
hdd_wlan_shutdown();
}
hif_disable(hif_ctx, HIF_DISABLE_TYPE_SHUTDOWN);
hif_close(hif_ctx);
hdd_hif_close(hif_ctx);
}
/**

Просмотреть файл

@@ -123,7 +123,6 @@ extern int hdd_hostapd_stop(struct net_device *dev);
#define MEMORY_DEBUG_STR ""
#endif
#define DISABLE_KRAIT_IDLE_PS_VAL 1
/* the Android framework expects this param even though we don't use it */
#define BUF_LEN 20
static char fwpath_buffer[BUF_LEN];
@@ -3610,10 +3609,18 @@ void __hdd_wlan_exit(void)
cds_set_load_unload_in_progress(true);
/* Check IPA HW Pipe shutdown */
hdd_ipa_uc_force_pipe_shutdown(hdd_ctx);
#ifdef WLAN_FEATURE_LPSS
wlan_hdd_send_status_pkg(NULL, NULL, 0, 0);
#endif
memdump_deinit();
#ifdef QCA_PKT_PROTO_TRACE
cds_pkt_proto_trace_close();
#endif
/* Do all the cleanup before deregistering the driver */
hdd_wlan_exit(hdd_ctx);
EXIT();
@@ -5449,9 +5456,13 @@ ftm_processing:
}
hif_enable_power_gating(hif_sc);
memdump_init();
hdd_ctx->isLoadInProgress = false;
cds_set_load_unload_in_progress(false);
complete(&wlan_start_comp);
goto success;
err_nl_srv:
@@ -6378,18 +6389,6 @@ end:
}
#endif
/**
* hdd_wlan_get_wake_lock_ptr(): get HDD's wake lock pointer
*
* This function returns the wake lock pointer to the caller
*
* Return: cdf_wake_lock_t
*/
cdf_wake_lock_t *hdd_wlan_get_wake_lock_ptr(void)
{
return &wlan_wake_lock;
}
/**
* hdd_get_fw_version() - Get FW version
* @hdd_ctx: pointer to HDD context.
@@ -6440,85 +6439,52 @@ const char *hdd_get_fwpath(void)
return fwpath.string;
}
/*
* In BMI Phase we are only sending small chunk (256 bytes) of the FW image at
* a time, and wait for the completion interrupt to start the next transfer.
* During this phase, the KRAIT is entering IDLE/StandAlone(SA) Power Save(PS).
* The delay incurred for resuming from IDLE/SA PS is huge during driver load.
* So prevent APPS IDLE/SA PS durint driver load for reducing interrupt latency.
*/
#ifdef CONFIG_CNSS
static inline void hdd_request_pm_qos(int val)
{
cnss_request_pm_qos(val);
}
static inline void hdd_remove_pm_qos(void)
{
cnss_remove_pm_qos();
}
#else
static inline void hdd_request_pm_qos(int val)
{
}
static inline void hdd_remove_pm_qos(void)
{
}
#endif
/**
* hdd_driver_init() - Core Driver Init Function
* hdd_init() - Initialize Driver
*
* This is the driver entry point - called in different timeline depending
* on whether the driver is statically or dynamically linked
* This function initilizes CDS global context with the help of cds_init. This
* has to be the first function called after probe to get a valid global
* context.
*
* Return: 0 for success, non zero for failure
* Return: 0 for success, errno on failure
*/
static int hdd_driver_init(void)
int hdd_init(void)
{
CDF_STATUS status;
v_CONTEXT_t p_cds_context = NULL;
int ret_status = 0;
unsigned long rc;
int ret = 0;
#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
wlan_logging_sock_init_svc();
#endif
p_cds_context = cds_init();
ENTER();
if (p_cds_context == NULL) {
hdd_alert("Failed to allocate CDS context");
ret = -ENOMEM;
goto err_out;
}
cdf_wake_lock_init(&wlan_wake_lock, "wlan");
hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
/*
* The Krait is going to Idle/Stand Alone Power Save
* more aggressively which is resulting in the longer driver load time.
* The Fix is to not allow Krait to enter Idle Power Save during driver
* load.
*/
hdd_request_pm_qos(DISABLE_KRAIT_IDLE_PS_VAL);
cds_ssr_protect_init();
hdd_trace_init();
pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
err_out:
return ret;
}
do {
cdf_mc_timer_manager_init();
cdf_mem_init();
/* Allocate CDS global context */
status = cds_alloc_global_context(&p_cds_context);
/**
* hdd_deinit() - Deinitialize Driver
*
* This function frees CDS global context with the help of cds_deinit. This
* has to be the last function call in remove callback to free the global
* context.
*/
void hdd_deinit(void)
{
cds_deinit();
if (!CDF_IS_STATUS_SUCCESS(status)) {
hddLog(CDF_TRACE_LEVEL_FATAL,
FL("Failed to preOpen CDS"));
ret_status = -1;
break;
}
hdd_trace_init();
hdd_set_conparam((uint32_t) con_mode);
#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
wlan_logging_sock_deinit_svc();
#endif
}
#ifdef QCA_WIFI_3_0_ADRASTEA
#define HDD_WLAN_START_WAIT_TIME (3600 * 1000)
@@ -6526,54 +6492,64 @@ static int hdd_driver_init(void)
#define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000)
#endif
init_completion(&wlan_start_comp);
ret_status = wlan_hdd_register_driver();
if (!ret_status) {
rc = wait_for_completion_timeout(
&wlan_start_comp,
msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
if (!rc) {
hddLog(LOGP,
FL("timed-out waiting for wlan_hdd_register_driver"));
ret_status = -1;
} else
ret_status = 0;
}
/**
* __hdd_module_init - Module init helper
*
* Module init helper function used by both module and static driver.
*
* Return: 0 for success, errno on failure
*/
static int __hdd_module_init(void)
{
int ret = 0;
unsigned long rc;
hdd_remove_pm_qos();
hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
pr_info("%s: Loading driver v%s\n", WLAN_MODULE_NAME,
QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
if (ret_status) {
hddLog(LOGP, FL("WLAN Driver Initialization failed"));
wlan_hdd_unregister_driver();
cds_free_global_context(&p_cds_context);
ret_status = -ENODEV;
break;
} else {
pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
memdump_init();
return 0;
}
cdf_wake_lock_init(&wlan_wake_lock, "wlan");
} while (0);
hdd_set_conparam((uint32_t) con_mode);
if (0 != ret_status) {
cdf_mc_timer_exit();
cdf_mem_exit();
cdf_wake_lock_destroy(&wlan_wake_lock);
init_completion(&wlan_start_comp);
#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
wlan_logging_sock_deinit_svc();
#endif
memdump_deinit();
ret = wlan_hdd_register_driver();
if (ret) {
pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
} else {
pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
goto out;
}
EXIT();
rc = wait_for_completion_timeout(&wlan_start_comp,
msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
return ret_status;
if (!rc) {
hdd_alert("Timed-out waiting for wlan_hdd_register_driver");
goto out;
}
pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
return 0;
out:
cdf_wake_lock_destroy(&wlan_wake_lock);
return ret;
}
/**
* __hdd_module_exit - Module exit helper
*
* Module exit helper function used by both module and static driver.
*/
static void __hdd_module_exit(void)
{
pr_info("%s: Unloading driver v%s\n", WLAN_MODULE_NAME,
QWLAN_VERSIONSTR);
wlan_hdd_unregister_driver();
cdf_wake_lock_destroy(&wlan_wake_lock);
return;
}
/**
@@ -6586,7 +6562,7 @@ static int hdd_driver_init(void)
#ifdef MODULE
static int __init hdd_module_init(void)
{
return hdd_driver_init();
return __hdd_module_init();
}
#else /* #ifdef MODULE */
static int __init hdd_module_init(void)
@@ -6596,60 +6572,6 @@ static int __init hdd_module_init(void)
}
#endif /* #ifdef MODULE */
/**
* hdd_driver_exit() - Exit function
*
* This is the driver exit point (invoked when module is unloaded using rmmod
* or con_mode was changed by userspace)
*
* Return: None
*/
static void hdd_driver_exit(void)
{
hdd_context_t *hdd_ctx = NULL;
int retry = 0;
pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME,
QWLAN_VERSIONSTR);
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
hddLog(CDF_TRACE_LEVEL_FATAL,
FL("module exit called before probe"));
} else {
/* Check IPA HW Pipe shutdown */
hdd_ipa_uc_force_pipe_shutdown(hdd_ctx);
#ifdef QCA_PKT_PROTO_TRACE
cds_pkt_proto_trace_close();
#endif /* QCA_PKT_PROTO_TRACE */
while (hdd_ctx->isLogpInProgress ||
cds_is_logp_in_progress()) {
hddLog(CDF_TRACE_LEVEL_FATAL,
FL(
"SSR in Progress; block rmmod for 1 second!!!"
));
msleep(1000);
if (retry++ == HDD_MOD_EXIT_SSR_MAX_RETRIES) {
hddLog(CDF_TRACE_LEVEL_FATAL,
FL("SSR never completed, fatal error"));
CDF_BUG(0);
}
}
rtnl_lock();
hdd_ctx->isUnloadInProgress = true;
cds_set_load_unload_in_progress(true);
rtnl_unlock();
}
cds_wait_for_work_thread_completion(__func__);
memdump_deinit();
wlan_hdd_unregister_driver();
return;
}
/**
* hdd_module_exit() - Exit function
*
@@ -6659,7 +6581,7 @@ static void hdd_driver_exit(void)
*/
static void __exit hdd_module_exit(void)
{
hdd_driver_exit();
__hdd_module_exit();
}
#ifdef MODULE
@@ -6668,6 +6590,7 @@ static int fwpath_changed_handler(const char *kmessage, struct kernel_param *kp)
return param_set_copystring(kmessage, kp);
}
#else /* #ifdef MODULE */
/**
* kickstart_driver() - driver entry point
*
@@ -6681,21 +6604,24 @@ static int fwpath_changed_handler(const char *kmessage, struct kernel_param *kp)
*/
static int kickstart_driver(void)
{
int ret_status;
int ret = 0;
if (!wlan_hdd_inited) {
ret_status = hdd_driver_init();
wlan_hdd_inited = ret_status ? 0 : 1;
return ret_status;
ret = __hdd_module_init();
wlan_hdd_inited = ret ? 0 : 1;
return ret;
}
hdd_driver_exit();
__hdd_module_exit();
msleep(200);
ret_status = hdd_driver_init();
wlan_hdd_inited = ret_status ? 0 : 1;
return ret_status;
ret = __hdd_module_init();
wlan_hdd_inited = ret ? 0 : 1;
return ret;
}
/**

Просмотреть файл

@@ -128,6 +128,7 @@ void epping_disable(void)
hif_reset_soc(cds_get_context(CDF_MODULE_ID_HIF));
htc_stop(cds_get_context(CDF_MODULE_ID_HTC));
epping_cookie_cleanup(pEpping_ctx);
htc_destroy(cds_get_context(CDF_MODULE_ID_HTC));
}
/**