转眼间,看usb gadget代码看的有一段时间了,把其中的层次关系大致的理了一遍,就写出来和大家分享下,不对之处敬请指出,了解层次结构嘛,当然是代码越简单越好,俗话说“柿子专拣软的捏”,就拿最简单的zero.c开涮啦!
首先说下整体流程:
一个UDC(usb设备控制器)上面要挂一个usb_gadget_driver,usb_composite_dev挂到UDC的gadget上,usb_composite_driver挂到usb_composite_dev上,然后在usb_composite_dev上挂上一个usb_configuration配置,然后在usb_configuration的function链表中挂一个function,并且把function写入对应的config 的interface数组中。这就是整个流程。可能这么说有点晕,下面就看实际的代码分析吧!
首先把结构体老大贴出来,因为别人都依靠他呢!
首先你应该准备一个usb_gadget_driver,并把它挂到上述结构体的driver成员中。在zero.c中该结构为
-
struct s3c2410_udc {
- .........................
-
struct usb_gadget gadget;
-
struct usb_gadget_driver *driver;
- .....................
- };
首先你应该准备一个usb_gadget_driver,并把它挂到上述结构体的driver成员中。在zero.c中该结构为
-
static struct usb_gadget_driver composite_driver = {
-
.speed = USB_SPEED_HIGH,
-
-
.unbind = composite_unbind,
-
-
.setup = composite_setup,
-
.disconnect = composite_disconnect,
-
-
.suspend = composite_suspend,
-
.resume = composite_resume,
-
-
.driver = {
-
.owner = THIS_MODULE,
-
},
- };
这个结构是通用的结构。其中的composite_driver.function成员和composite_driver.driver.name被
usb_composite_driver中得成员给重新赋值了。
-
static struct usb_composite_driver zero_driver = {
-
.name = "zero",
-
.dev = &device_desc,
-
.strings = dev_strings,
-
.unbind = zero_unbind,
-
.suspend = zero_suspend,
-
.resume = zero_resume,
- };
然后分配一个usb_composite_dev,把该结构体挂到gadget上,现在结构体老大如下
- struct s3c2410_udc {
- .........................
- struct usb_gadget gadget;----------》cdev
-
struct usb_gadget_driver *driver;-------->composite_driver
..................... - };
- 然后在cdev上挂上usb_composite_driver,其定义如下:
-
-
static struct usb_composite_driver zero_driver = {
-
.name = "zero",
-
.dev = &device_desc,
-
.strings = dev_strings,
-
.unbind = zero_unbind,
-
.suspend = zero_suspend,
-
.resume = zero_resume,
- };
然后在cdev上绑定usb_configuration,usb_config的定义如下: -
static struct usb_composite_driver zero_driver = {
-
-
static struct usb_configuration loopback_driver = {
-
.label = "loopback",
-
.strings = loopback_strings,
-
.bConfigurationValue = 2,
-
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
-
/* .iConfiguration = DYNAMIC */
- };
-
static struct usb_configuration loopback_driver = {
-
-
loop = kzalloc(sizeof *loop, GFP_KERNEL);
-
loop->function.name = "loopback";
-
loop->function.descriptors = fs_loopback_descs;
-
loop->function.bind = loopback_bind;
-
loop->function.unbind = loopback_unbind;
-
loop->function.set_alt = loopback_set_alt;
- loop->function.disable = loopback_disable;
-
loop = kzalloc(sizeof *loop, GFP_KERNEL);