qcacld-2.0是Qualcomm WLAN Driver。
分析开放的驱动代码:
https://github.com/myrom/opensource_wlan_qcacld-2.0.git
git得到源码。
根据__init
找到入口文件opensource_wlan_qcacld-2.0/CORE/HDD/src/wlan_hdd_main.c
static int __init hdd_module_init ( void)
{
return hdd_driver_init();
}
驱动初始化函数hdd_driver_init
/**---------------------------------------------------------------------------
\brief hdd_driver_init() - Core Driver Init Function
This is the driver entry point - called in different time line depending
on whether the driver is statically or dynamically linked
\param - None
\return - 0 for success, non zero for failure
--------------------------------------------------------------------------*/
static int hdd_driver_init( void)
{
VOS_STATUS status;
v_CONTEXT_t pVosContext = NULL;
int ret_status = 0;
unsigned long rc;
#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
wlan_logging_sock_init_svc();
#endif
ENTER();
#ifdef TIMER_MANAGER
vos_timer_manager_init();
#endif
#ifdef MEMORY_DEBUG
vos_mem_init();
#endif
vos_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);
vos_ssr_protect_init();
pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
do {
#ifndef MODULE
if (WLAN_IS_EPPING_ENABLED(con_mode)) {
ret_status = epping_driver_init(con_mode, &wlan_wake_lock,
WLAN_MODULE_NAME);
if (ret_status < 0) {
hdd_remove_pm_qos();
hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
vos_wake_lock_destroy(&wlan_wake_lock);
}
return ret_status;
}
#else
if (WLAN_IS_EPPING_ENABLED(hdd_get_conparam())) {
ret_status = epping_driver_init(hdd_get_conparam(),
&wlan_wake_lock, WLAN_MODULE_NAME);
if (ret_status < 0) {
hdd_remove_pm_qos();
hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
vos_wake_lock_destroy(&wlan_wake_lock);
}
return ret_status;
}
#endif
/* Preopen VOSS so that it is ready to start at least SAL */
status = vos_preOpen(&pVosContext);
if (!VOS_IS_STATUS_SUCCESS(status))
{
hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
ret_status = -1;
break;
}
#ifdef HDD_TRACE_RECORD
MTRACE(hddTraceInit());
#endif
#ifndef MODULE
/* For statically linked driver, call hdd_set_conparam to update curr_con_mode
*/
hdd_set_conparam((v_UINT_t)con_mode);
#endif
#define HDD_WLAN_START_WAIT_TIME VOS_WDA_TIMEOUT + 5000
init_completion(&wlan_start_comp);
ret_status = hif_register_driver();
if (!ret_status) {
rc = wait_for_completion_timeout(
&wlan_start_comp,
msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
if (!rc) {
hddLog(VOS_TRACE_LEVEL_FATAL,
"%s: timed-out waiting for hif_register_driver", __func__);
ret_status = -1;
} else
ret_status = 0;
}
hdd_remove_pm_qos();
hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
if (ret_status) {
hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN Driver Initialization failed",
__func__);
hif_unregister_driver();
vos_preClose( &pVosContext );
ret_status = -ENODEV;
break