歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android 4.0 USB掛載內核驅動層流程分析

Android 4.0 USB掛載內核驅動層流程詳細分析。

1.platform_device
在arch/arm/mach-msm/Board-xx.c中

static struct platform_device android_usb_device = {
.name = "android_usb",
.id = -1,
.dev = {
.platform_data = &android_usb_pdata,  //@1
}

};
static struct android_usb_platform_data android_usb_pdata = {
.update_pid_and_serial_num = usb_diag_update_pid_and_serial_num,
};

在rpc_hsusb.c中:

int usb_diag_update_pid_and_serial_num(uint32_t pid, const char *snum)
{
int ret;

ret = msm_hsusb_send_productID(pid);
if (ret)
return ret;

if (!snum) {
ret = msm_hsusb_is_serial_num_null(1);
if (ret)
return ret;
return 0;
}

ret = msm_hsusb_is_serial_num_null(0);
if (ret)
return ret;
ret = msm_hsusb_send_serial_number(snum);
if (ret)
return ret;

return 0;
}

在內核初始化時,先注冊了名為android_usb的設備。

2.platform_driver

在drivers/usb/gadget/Android.c中:

static struct platform_driver android_platform_driver = {
.driver = { .name = "android_usb"},
};

注冊了名為android_usb的paltform_driver。但是並不像其他硬件驅動那樣,有.probe函數用來匹配驅動。不要著急,慢慢看。

3.module_init

其實Android.c用的是module_init的方式:

static int __init init(void)
{
struct android_dev *dev;
int err;

android_class = class_create(THIS_MODULE, "android_usb");    //在sys/class下創建android_usb目錄
if (IS_ERR(android_class))    //錯誤處理
return PTR_ERR(android_class);

dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;

dev->functions = supported_functions;    //設備支持的一些功能,功能列表
/*
*static struct android_usb_function *supported_functions[] = {
* &rmnet_smd_function,
* &rmnet_sdio_function,
* &rmnet_smd_sdio_function,
* &rmnet_function,
* &diag_function,
* &serial_function,
* &adb_function,
* &ccid_function,
*// &acm_function,
* &mtp_function,
* &ptp_function,
* &rndis_function,
* &mass_storage_function,
* &accessory_function,
* NULL
*};
*/
INIT_LIST_HEAD(&dev->enabled_functions);    //應該是加入到隊列裡的意思吧,使能這些功能
INIT_WORK(&dev->work, android_work);

err = android_create_device(dev);    //創建dev,按內核目錄來看:
/*
*localhost android_usb # ls                                                   
*android0          f_diag            f_rmnet          f_rndis
*f_accessory      f_mass_storage    f_rmnet_sdio      f_serial
*f_adb            f_mtp            f_rmnet_smd
*f_ccid            f_ptp            f_rmnet_smd_sdio
*localhost android_usb #
*/
if (err) {
class_destroy(android_class);
kfree(dev);
return err;
}

_android_dev = dev;

/* Override composite driver functions */
composite_driver.setup = android_setup;
composite_driver.disconnect = android_disconnect;

platform_driver_probe(&android_platform_driver, android_probe);    //驅動是通過platform_driver_probe方式進行匹配的,匹配函數位android_probe:
/*
*static int __devinit android_probe(struct platform_device *pdev)
*{
* struct android_usb_platform_data *pdata = pdev->dev.platform_data;    //見@1
* struct android_dev *dev = _android_dev;
*
* dev->pdata = pdata;
*
* return 0;
*}
*/

return usb_composite_probe(&android_usb_driver, android_bind);    //萬能USB驅動,用android_bind進行綁定
}
module_init(init);

static void __exit cleanup(void)
{
usb_composite_unregister(&android_usb_driver);
class_destroy(android_class);
kfree(_android_dev);
_android_dev = NULL;
}
module_exit(cleanup);

我認為是有兩個重點,一個是supported_functions,另一個是android_bind。下一篇繼續分析 http://www.linuxidc.com/Linux/2013-02/80000p2.htm。

Copyright © Linux教程網 All Rights Reserved