一、Linux USB Gadget Driver功能
为了与主机端驱动设备的USB Device Driver概念进行区别,将在外围器件中运行的驱动程序称为USB Gadget Driver。其中,Host端驱动设备的驱动程序是master或者client driver,设备端gadget driver是slave或者function driver。
Gadget Driver和USB Host端驱动程序类似,都是使用请求队列来对I/O包进行缓冲,这些请求可以被提交和取消。它们的结构、消息和常量的定义也和USB技术规范第九章的内容一致。同时也是通过bind和unbind将driver与device建立关系。
二、Linux USB Gadget Driver核心数据结构
1. USB_Gadget对象
struct usb_gadget {
};
2. Gadget器件操作函数集
操作UDC硬件的API,但操作端点的函数由端点操作函数集完成
struct usb_gadget_ops {
};
3. USB Gadget driver对象
struct usb_gadget_driver {
};
4. 描述一个I/O请求
struct usb_request {
};
5. 端点
struct usb_ep {
};
6. 端点操作函数集
struct usb_ep_ops {
};
7. 字符串结构
struct usb_gadget_strings {
};
struct usb_string {
};
8. UDC驱动程序需要实现的上层调用接口
int usb_gadget_register_driver(struct usb_gadget_driver *driver);
int usb_gadget_unregister_driver(struct usb_gadget_driver *driver);
三、UDC驱动程序
1. UDC层主要数据结构,以S3C2410为例,在driver/usb/gadget/s3c2410_udc.c和s3c2410_udc.h文件中。
下面的结构基本上每个UDC驱动程序都会实现,但具体实现的细节又不太相同。但万变不离其宗,宗就是上面介绍的基本gadget驱动数据结构,基本上UDC驱动程序自己实现的数据结构都是都这些基本数据结构的二次封装。
a. 设备结构
struct s3c2410_udc {
spinlock_t lock;
struct s3c2410_ep ep[S3C2410_ENDPOINTS];
int address;
struct usb_gadget gadget;
struct usb_gadget_driver *driver;
struct s3c2410_request fifo_req;
u8 fifo_buf[EP_FIFO_SIZE];
u16 devstatus;
u32 port_status;
int ep0state;
unsigned got_irq : 1;
unsigned req_std : 1;
unsigned req_config : 1;
unsigned req_pending : 1;
u8 vbus;
struct dentry *regs_info;
};
程序中对这个结构的初始化:
static struct s3c2410_udc memory = {
.ep0 = &memory.ep[0].ep,
.name = gadget_name,
.dev = {
.init_name = "gadget",
},
/* control endpoint */
},
/* first group of endpoints */
},
};
不同的UDC,自定义的数据结构不同。但一般都有这样一个数据结构来表示UDC设备,对usb_gadget设备对象进行封装,并包含设备的所有端点。
b. 端点结构
struct s3c2410_ep {
};
对usb_ep结构进行封装,并有一个queue队列来对该端口上的request进行排队。
c. Request结构
struct s3c2410_request {
};
对usb_request进行封装,queue变量进行队列排队。