1. platform_device
In 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,};
In 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;}
During kernel initialization, a device named android_usb is registered first.
2. platform_driver
In Drivers/USB/gadget/Android. C:
static struct platform_driver android_platform_driver = {.driver = { .name = "android_usb"},};
Register the paltform_driver named android_usb. However, unlike other hardware drivers, the. probe function is used to match the driver. Don't worry. Take a look.
3. module_init
In fact, Android. c uses module_init:
Static int _ init Init (void) {struct android_dev * dev; int err; android_class = class_create (this_module, "android_usb "); // create the android_usb directory if (is_err (android_class) under sys/class // return ptr_err (android_class) for error handling; Dev = kzarloc (sizeof (* Dev), gfp_kernel ); if (! Dev) Return-enomem; Dev-> Functions = supported_funmem; // some features supported by the device, feature list/** 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 ); // It should be added to the queue to enable these functions init_work (& Dev-> Work, android_work); err = android_create_device (Dev); // create Dev, according to the kernel directory:/** localhost android_usb # ls * android0 f_diag f_rmnet ready * f_accessory f_mass_storage ready f_serial * f_adb f_mtp ready * f_ccid f_ptp ready * localhost android_usb # */if) {class_destroy (android_class); kfree (Dev); Return err;} _ android_dev = dev;/* override composite driver functions */composite_driver.setup = android_setup; identifier = android_disconnect; inline (& android_platform_driver, android_probe); // The driver is matched using the inline method. The matched function bit android_probe:/** static int _ devinit android_probe (struct platform_device * pdev) * {* struct android_usb_platform_data * pdata = pdev-> Dev. platform_data; // see @ 1 * struct android_dev * Dev = _ android_dev; ** Dev-> pdata = pdata; ** return 0; *} */return usb_composite_probe (& android_usb_driver, android_bind); // universal USB driver, bound with android_bind} module_init (init); static void _ exit cleanup (void) {category (& android_usb_driver); class_destroy (android_class ); kfree (_ android_dev); _ android_dev = NULL;} module_exit (cleanup );
I think there are two key points: supported_functions and android_bind. Continue to analyze the next blog.