分析android的gadget:
gadget部分的UDC和API基本上弄懂了,现在开始研究android上的USB-gadget实现,开始读代码
1:首先从init开始。
static int __init init(void)
{
struct android_dev *dev;
printk(KERN_INFO "android init\n");
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
/* set default values, which should be overridden by platform data */
dev->product_id = PRODUCT_ID;
_android_dev = dev;
return platform_driver_register(&android_platform_driver);
}
它申请了一个dev空间,然后返回platform_driver_register(&android_platform_driver)。
platform_driver_register在drivers/base/platform.c中定义,如下:
int platform_driver_register(struct platform_driver *drv)
{
drv->driver.bus = &platform_bus_type;
if (drv->probe)
drv->driver.probe = platform_drv_probe;
if (drv->remove)
drv->driver.remove = platform_drv_remove;
if (drv->shutdown)
drv->driver.shutdown = platform_drv_shutdown;
return driver_register(&drv->driver);
}其含义是注册平台上某个控制器驱动。
而android_platform_driver的定义在android.c中,如下:
static struct platform_driver android_platform_driver = {
.driver = { .name = "android_usb", },
.probe = android_probe,
};
它只是定义了驱动的名字和探测程序。
2:接下来看android_probe,(android.c)
static int __init android_probe(struct platform_device *pdev)
{
struct android_usb_platform_data *pdata = pdev->dev.platform_data;
struct android_dev *dev = _android_dev;
printk(KERN_INFO "android_probe pdata: %p\n", pdata);
if (pdata) {
dev->products = pdata->products;
dev->num_products = pdata->num_products;
dev->functions = pdata->functions;
dev->num_functions = pdata->num_functions;
if (pdata->vendor_id)
device_desc.idVendor =
__constant_cpu_to_le16(pdata->vendor_id);
if (pdata->product_id) {
dev->product_id = pdata->product_id;
device_desc.idProduct =
__constant_cpu_to_le16(pdata->product_id);
}
if (pdata->version)
dev->version = pdata->version;
if (pdata->product_name)
strings_dev[STRING_PRODUCT_IDX].s = pdata->product_name;
if (pdata->manufacturer_name)
strings_dev[STRING_MANUFACTURER_IDX].s =
pdata->manufacturer_name;
if (pdata->serial_number)
strings_dev[STRING_SERIAL_IDX].s = pdata->serial_number;
}
return usb_composite_register(&android_usb_driver);
}
这个函数初始化了android_dev *dev,并在最后调用了usb_composite_register,
在include/linux/platform_device.h中,有platform_device的定义:
struct platform_device {
const char * name;
int id;
struct device dev;
u32 num_resources;
struct resource * resource;
struct platform_device_id *id_entry;
/* arch specific additions */
struct pdev_archdata archdata;
};
在探测程序中,大部分工作都是初始化一些数据,或者是数据转换吧,但是最后调用了return usb_composite_register(&android_usb_driver);,即将android_usb_driver注册了。
在android.c文件中,android_usb_driver的定义如下:
static struct usb_composite_driver android_usb_driver = {
.name = "android_usb",
.dev = &device_desc,
.strings = dev_strings,
.bind = android_bind,
.enable_function = android_enable_function,
};
3:usb_composite_register函数定义在drivers/usb/gadget/composite.c中:
int __init usb_composite_register(struct usb_composite_driver *driver)
{
if (!driver || !driver->dev || !driver->bind || composite)
return -EINVAL;
if (!driver->name)
driver->name = "composite";
composite_driver.function = (char *) driver->name;
composite_driver.driver.name = driver->name;
composite = driver;
driver->class = class_create(THIS_MODULE, "usb_composite");
if (IS_ERR(driver->class))
return PTR_ERR(driver->class);
driver->class->dev_uevent = composite_uevent;
return usb_gadget_register_driver(&composite_driver);
}
这个函数也很简单,就是使用usb_gadget_register_driver注册而已,至此,就算到了UDC层了。
4:我们再回头看看android_usb_driver。重点看下面三行代码。
.dev = &device_desc,
.bind = android_bind,
.enable_function = android_enable_function,
先看device_desc,在android.c中:
static struct usb_device_descriptor device_desc = {
.bLength = sizeof(device_desc),
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = __constant_cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_PER_INTERFACE,
.idVendor = __constant_cpu_to_le16(VENDOR_ID),
.idProduct = __constant_cpu_to_le16(PRODUCT_ID),
.bcdDevice = __constant_cpu_to_le16(0xffff),
.bNumConfigurations = 1,
};
没什么可说的,都是比较底层的描述性定义。
再看android_bind,在android.c中定义,比较长,重要的如下:
static int __init android_bind(struct usb_composite_dev *cdev)
{
struct android_dev *dev = _android_dev;
struct usb_gadget *gadget = cdev->gadget;
if (gadget->ops->wakeup)
android_config_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
/* register our configuration */
ret = usb_add_config(cdev, &android_config_driver);
if (ret) {
printk(KERN_ERR "usb_add_config failed\n");
return ret;
}
usb_gadget_set_selfpowered(gadget);
dev->cdev = cdev;
。。。。
}
函数bind负责完成Gadget驱动和下层设备控
制器的关联,并开启设备的功能
最后看看android_enable_function,在android.c中定义,
if (!strcmp(f->name, "rndis")) {
struct usb_function *func;
/* We need to specify the COMM class in the device descriptor
* if we are using RNDIS.
*/
if (enable)
list_for_each_entry(func, &android_config_driver.functions, list) {
if (!strcmp(func->name, "usb_mass_storage")) {
usb_function_set_enabled(func, !enable);
break;
}
}
usb_composite_force_reset(dev->cdev);
将列表中的所有功能全部开启,除了usb_mass_storage。
在composite.c中定义了usb_function_set_enabled函数。
void usb_function_set_enabled(struct usb_function *f, int enabled)
{
f->disabled = !enabled;
kobject_uevent(&f->dev->kobj, KOBJ_CHANGE);
}
这里涉及两个概念,一个是usb_function,一个是android_config_driver(usb_configuration)
static struct usb_configuration android_config_driver = {
.label = "android",
.bind = android_bind_config,
.setup = android_setup_config,
.bConfigurationValue = 1,
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
.bMaxPower = 0xFA, /* 500ma */
};
先看看usb_configuration,在include/linux/usb/composite.h中,
struct usb_configuration {
const char *label;
struct usb_gadget_strings **strings;
const struct usb_descriptor_header **descriptors;
/* REVISIT: bind() functions can be marked __init, which
* makes trouble for section mismatch analysis. See if
* we can't restructure things to avoid mismatching...
*/
/* configuration management: bind/unbind */
int (*bind)(struct usb_configuration *);
void (*unbind)(struct usb_configuration *);
int (*setup)(struct usb_configuration *,
const struct usb_ctrlrequest *);
/* fields in the config descriptor */
u8 bConfigurationValue;
u8 iConfiguration;
u8 bmAttributes;
u8 bMaxPower;
struct usb_composite_dev *cdev;
/* private: */
/* internals */
struct list_head list;
struct list_head functions;
u8 next_interface_id;
unsigned highspeed:1;
unsigned fullspeed:1;
struct usb_function *interface[MAX_CONFIG_INTERFACES];
};
再看看usb_function,在include/linux/usb/composite.h中
struct usb_function {
const char *name;
struct usb_gadget_strings **strings;
struct usb_descriptor_header **descriptors;
struct usb_descriptor_header **hs_descriptors;
struct usb_configuration *config;
/* disabled is zero if the function is enabled */
int disabled;
/* REVISIT: bind() functions can be marked __init, which
* makes trouble for section mismatch analysis. See if
* we can't restructure things to avoid mismatching.
* Related: unbind() may kfree() but bind() won't...
*/
/* configuration management: bind/unbind */
int (*bind)(struct usb_configuration *,
struct usb_function *);
void (*unbind)(struct usb_configuration *,
struct usb_function *);
/* runtime state management */
int (*set_alt)(struct usb_function *,
unsigned interface, unsigned alt);
int (*get_alt)(struct usb_function *,
unsigned interface);
void (*disable)(struct usb_function *);
int (*setup)(struct usb_function *,
const struct usb_ctrlrequest *);
void (*suspend)(struct usb_function *);
void (*resume)(struct usb_function *);
/* private: */
/* internals */
struct list_head list;
struct device *dev;
};
我没看出个所以然来,只知道这里有复杂的链表关系,不明白,于是回头看看,在android_config_driver中,注意这两个函数:
.bind = android_bind_config,
.setup = android_setup_config,
他们都在android.c文件中。
static int __init android_bind_config(struct usb_configuration *c)
{
struct android_dev *dev = _android_dev;
printk(KERN_DEBUG "android_bind_config\n");
dev->config = c;
/* bind our functions if they have all registered */
if (_registered_function_count == dev->num_functions)
bind_functions(dev);
return 0;
}
static int android_setup_config(struct usb_configuration *c,
const struct usb_ctrlrequest *ctrl)
{
int i;
int ret = -EOPNOTSUPP;
for (i = 0; i < android_config_driver.next_interface_id; i++) {
if (android_config_driver.interface[i]->setup) {
ret = android_config_driver.interface[i]->setup(
android_config_driver.interface[i], ctrl);
if (ret >= 0)
return ret;
}
}
return ret;
}
看下bind_functions
static void bind_functions(struct android_dev *dev)
{
struct android_usb_function *f;
char **functions = dev->functions;
int i;
for (i = 0; i < dev->num_functions; i++) {
char *name = *functions++;
f = get_function(name);
if (f)
f->bind_config(dev->config);
else
printk(KERN_ERR "function %s not found in bind_functions\n", name);
}
}
再看get_function。
static struct android_usb_function *get_function(const char *name)
{
struct android_usb_function *f;
list_for_each_entry(f, &_functions, list) {
if (!strcmp(name, f->name))
return f;
}
return 0;
}
到此为止,没有什么思路了,我察看了下android.c,大部分函数都用到了,唯有android_usb_set_connected没有使用 ,经搜索,在arch/arm/mach-omap2/board-sholes.c中使用了这个函数。
static int cpcap_usb_connected_probe(struct platform_device *pdev)
{
/* Wake up MUSB from lowpower state */
musb_disable_idle(1);
android_usb_set_connected(1);
return 0;
}
static int cpcap_usb_connected_remove(struct platform_device *pdev)
{
/* Enable low power state for MUSB */
musb_disable_idle(0);
android_usb_set_connected(0);
return 0;
}
终于知道function是哪来的了。
注意android_register_function,它在arch/arm/mach-omap2/board-sholes-usbnet.c,drivers/usb/gadget/f_acm.c,drivers/usb/gadget/f_adb.c:,drivers/usb/gadget/f_rndis.c,drivers/usb/gadget/f_mass_storage.c,中调用过,也就是说,总共就有这么几个function.简单查看了一下f_adb.c,看到了关于gadget的内容,哦也!!!终于弄通了!!!!!!!!!
(上面那句话是最后写的,下面的内容为设备与驱动的关联部分)
昨天基本上没有什么线索了,不知道android.c是怎么与gadget联系上的,不知道那些function是怎样关联,定义的。今天早上重新看,注意了一下最开始的platform_driver_register(&android_platform_driver);
int platform_driver_register(struct platform_driver *drv)
{
drv->driver.bus = &platform_bus_type;
if (drv->probe)
drv->driver.probe = platform_drv_probe;
if (drv->remove)
drv->driver.remove = platform_drv_remove;
if (drv->shutdown)
drv->driver.shutdown = platform_drv_shutdown;
return driver_register(&drv->driver);
}其含义是注册平台上某个控制器驱动。
platform_driver定义在include/linux/platform_device.h里:
struct platform_driver {
int (*probe)(struct platform_device *);
int (*remove)(struct platform_device *);
void (*shutdown)(struct platform_device *);
int (*suspend)(struct platform_device *, pm_message_t state);
int (*resume)(struct platform_device *);
struct device_driver driver;
struct platform_device_id *id_table;
};
device_driver定义在include/linux/device.h中
struct device_driver {
const char *name;
struct bus_type *bus;
struct module *owner;
const char *mod_name; /* used for built-in modules */
bool suppress_bind_attrs; /* disables bind/unbind via sysfs */
int (*probe) (struct device *dev);
int (*remove) (struct device *dev);
void (*shutdown) (struct device *dev);
int (*suspend) (struct device *dev, pm_message_t state);
int (*resume) (struct device *dev);
const struct attribute_group **groups;
const struct dev_pm_ops *pm;
struct driver_private *p;
};
platform_drv_probe定义在drivers/base/platform.c中定义,如下:
static int platform_drv_probe(struct device *_dev)
{
struct platform_driver *drv = to_platform_driver(_dev->driver);
struct platform_device *dev = to_platform_device(_dev);
return drv->probe(dev);
}
在这里,to_platform_driver是一个宏
#define to_platform_driver(drv) (container_of((drv), struct platform_driver, \
driver))
to_platform_device也是一个宏(定义在include/linux/platform_device.h)
#define to_platform_device(x) container_of((x), struct platform_device, dev)
现在的关键就是怎么确定使用哪个device呢?即struct device *_dev。
看了些资料,现在重点看一下driver_register,
platform_driver_register()函数
在文件drivers/base/platform.c中,实现并导出了platform_driver_register()函数,以便使其他模块中的函数可以调用此函数。它在完成简单的包装后,调用了driver_register()函数,完成了从平台实现到Linux内核实现的过渡。
在此,我们需要关注一下platform_match()和platform_drv_probe()函数。platform_match() 函数确定驱动与设备的关联,而platform_drv_probe()函数会在随后介绍的函数中被调用。
driver_register()函数定义在drivers/base/driver.c中。
int driver_register(struct device_driver *drv)
{
int ret;
struct device_driver *other;
BUG_ON(!drv->bus->p);
if ((drv->bus->probe && drv->probe) ||
(drv->bus->remove && drv->remove) ||
(drv->bus->shutdown && drv->shutdown))
printk(KERN_WARNING "Driver '%s' needs updating - please use "
"bus_type methods\n", drv->name);
other = driver_find(drv->name, drv->bus);
if (other) {
put_driver(other);
printk(KERN_ERR "Error: Driver '%s' is already registered, "
"aborting...\n", drv->name);
return -EBUSY;
}
ret = bus_add_driver(drv);
if (ret)
return ret;
ret = driver_add_groups(drv, drv->groups);
if (ret)
bus_remove_driver(drv);
return ret;
}
再看bus_add_driver。drivers/base/bus.c中。
int bus_add_driver(struct device_driver *drv)
{
struct bus_type *bus;
struct driver_private *priv;
int error = 0;
bus = bus_get(drv->bus);
if (!bus)
return -EINVAL;
pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name);
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv) {
error = -ENOMEM;
goto out_put_bus;
}
klist_init(&priv->klist_devices, NULL, NULL);
priv->driver = drv;
drv->p = priv;
priv->kobj.kset = bus->p->drivers_kset;
error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,
"%s", drv->name);
if (error)
goto out_unregister;
if (drv->bus->p->drivers_autoprobe) {
error = driver_attach(drv);
if (error)
goto out_unregister;
}
klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
module_add_driver(drv->owner, drv);
error = driver_create_file(drv, &driver_attr_uevent);
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
}
error = driver_add_attrs(bus, drv);
if (error) {
/* How the hell do we get out of this pickle? Give up */
printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
__func__, drv->name);
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
/* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
}
}
kobject_uevent(&priv->kobj, KOBJ_ADD);
return 0;
out_unregister:
kfree(drv->p);
drv->p = NULL;
kobject_put(&priv->kobj);
out_put_bus:
bus_put(bus);
return error;
}
1.5 dd.c文件
在文件drivers/base/dd.c中,实现了设备与驱动交互的核心函数。
1.5.1 driver_attach()函数
函数driver_attach()返回bus_for_each_dev()函数的运行结果。bus_for_each_dev()函数的原型如下:
int bus_for_each_dev(struct bus_type *bus, struct device *start, void *data,
int (*fn) (struct device *, void *));
该函数迭代了在总线上的每个设备,将相关的device结构传递给fn,同时传递data值。如果start是NULL,将从总线上的第一个设备开始迭代;否则将从start后的第一个设备开始迭代。如果fn返回一个非零值,将停止迭代,而这个值也会从该函数返回(摘自<<Linux设备驱动程序>>第三版)。
该函数是如何知道总线上的每个设备的呢?在设备注册过程中,我会详细介绍。
/*
* drivers/base/dd.c - The core device/driver interactions.
*
* This file contains the (sometimes tricky) code that controls the
* interactions between devices and drivers, which primarily includes
* driver binding and unbinding.
*/
/**
* driver_attach - try to bind driver to devices.
* @drv: driver.
*
* Walk the list of devices that the bus has on it and try to
* match the driver with each one. If driver_probe_device()
* returns 0 and the @dev->driver is set, we've found a
* compatible pair.
*/
int driver_attach(struct device_driver * drv)
{
return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
}
1.5.2 __driver_attach()函数
函数__driver_attach()在调用driver_probe_device()函数前,需要进行线程间的互斥处理。
static int __driver_attach(struct device * dev, void * data)
{
struct device_driver * drv = data;
/*
* Lock device and try to bind to it. We drop the error
* here and always return 0, because we need to keep trying
* to bind to devices and some drivers will return an error
* simply if it didn't support the device.
*
* driver_probe_device() will spit a warning if there
* is an error.
*/
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
down(&dev->sem);
if (!dev->driver)
driver_probe_device(drv, dev);
up(&dev->sem);
if (dev->parent)
up(&dev->parent->sem);
return 0;
}
1.5.3 driver_probe_device()函数
在driver_probe_device()函数中,调用了device_is_registered,如果它返回0,表示驱动与设备不一致,函数返回;否则,调用really_probe()函数。
/**
* driver_probe_device - attempt to bind device & driver together
* @drv: driver to bind a device to
* @dev: device to try to bind to the driver
*
* This function returns -ENODEV if the device is not registered,
* 1 if the device is bound sucessfully and 0 otherwise.
*
* This function must be called with @dev->sem held. When called for a
* USB interface, @dev->parent->sem must be held as well.
*/
int driver_probe_device(struct device_driver *drv, struct device *dev)
{
int ret = 0;
if (!device_is_registered(dev))
return -ENODEV;
pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
drv->bus->name, __func__, dev_name(dev), drv->name);
pm_runtime_get_noresume(dev);
pm_runtime_barrier(dev);
ret = really_probe(dev, drv);
pm_runtime_put_sync(dev);
return ret;
}
在文件include/linux/device.h中定义device_is_registered
static inline int device_is_registered(struct device *dev)
{
return dev->kobj.state_in_sysfs;
}
really_probe()函数
在really_probe()函数中,实现了设备与驱动的绑定。语句如下:dev->driver = drv;和
ret = drv->probe(dev); probe()函数的实现如下:
static int really_probe(struct device *dev, struct device_driver *drv)
{
int ret = 0;
atomic_inc(&probe_count);
pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
drv->bus->name, __func__, drv->name, dev_name(dev));
WARN_ON(!list_empty(&dev->devres_head));
dev->driver = drv;
if (driver_sysfs_add(dev)) {
printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
__func__, dev_name(dev));
goto probe_failed;
}
if (dev->bus->probe) {
ret = dev->bus->probe(dev);
if (ret)
goto probe_failed;
} else if (drv->probe) {
ret = drv->probe(dev);
if (ret)
goto probe_failed;
}
driver_bound(dev);
ret = 1;
pr_debug("bus: '%s': %s: bound device %s to driver %s\n",
drv->bus->name, __func__, dev_name(dev), drv->name);
goto done;
probe_failed:
devres_release_all(dev);
driver_sysfs_remove(dev);
dev->driver = NULL;
if (ret != -ENODEV && ret != -ENXIO) {
/* driver matched but the probe failed */
printk(KERN_WARNING
"%s: probe of %s failed with error %d\n",
drv->name, dev_name(dev), ret);
}
/*
* Ignore errors returned by ->probe so that the next driver can try
* its luck.
*/
ret = 0;
done:
atomic_dec(&probe_count);
wake_up(&probe_waitqueue);
return ret;
}