Gadget Framework 代码分析(二) --- zero.c
struct zero_dev {
spinlock_t lock;
struct usb_gadget *gadget; //代表一个gadget设备
struct usb_request *req; /* for control responses */
/* when configured, we have one of two configs:
* - source data (in to host) and sink it (out from host)
* - or loop it back (out from host back in to host)
*/
u8 config;
struct usb_ep *in_ep, *out_ep;
/* autoresume timer */
struct timer_list resume;
};
以下定义了这个gadget设备的device, configure, interface...
其中的struct usb_device_descriptor,usb_config_descriptor,usb_otg_descriptor
usb_interface_descriptor,usb_endpoint_descriptor,usb_descriptor_header
定义在ch9.h,structure中的各字段与Spec相对应,忘记了同学最好复习一下USB2.0 Spec的第9章吧。
static struct usb_device_descriptor device_desc ------- device
static struct usb_config_descriptor source_sink_config
static struct usb_config_descriptor loopback_config ---device中包括2个config
static struct usb_otg_descriptor otg_descriptor --- OTG
static struct usb_interface_descriptor source_sink_intf
static struct usb_interface_descriptor loopback_intf ---每个config包括2个interface
static struct usb_endpoint_descriptor fs_source_desc
static struct usb_endpoint_descriptor fs_sink_desc ---2个full speed bull 端点
static struct usb_descriptor_header *fs_source_sink_function []
static struct usb_descriptor_header *fs_loopback_function []
static struct usb_endpoint_descriptor hs_source_desc
static struct usb_endpoint_descriptor hs_sink_desc ---2个high speed bulk 端点
static struct usb_qualifier_descriptor dev_qualifier
static struct usb_descriptor_header *hs_source_sink_function []
static struct usb_descriptor_header *hs_loopback_function []
static struct usb_gadget_driver zero_driver = {//这个gadget设备的driver
...
.function = (char *) longname,
.bind = zero_bind,
.unbind = __exit_p(zero_unbind),
.setup = zero_setup, //设备对host端setup()的response
.disconnect = zero_disconnect,
.suspend = zero_suspend,
.resume = zero_resume,
...
};
//处理ep0的控制请求
static int
zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
{
struct zero_dev *dev = get_gadget_data (gadget);
struct usb_request *req = dev->req;
u16 w_index = le16_to_cpu(ctrl->wIndex); //制定一个ep或interface
u16 w_value = le16_to_cpu(ctrl->wValue); //req的特定参数
u16 w_length = le16_to_cpu(ctrl->wLength); //data阶段的data长度
根据ctrl->bRequest(请求的类型):
USB_REQ_GET_DESCRIPTOR:
根据w_value>>8来判断要get的descriptor类型:
USB_DT_DEVICE: 把&device_desc的数据拷贝到req->buf
USB_DT_DEVICE_QUALIFIER: 把&device_qualifier的数据拷贝到req->buf
USB_DT_OTHER_SPEED_CONFIG:
USB_DT_CONFIG: 把该config下的所有interface, ep都拷贝到req->buf
USB_DT_STRING:
USB_REQ_SET_CONFIGURATION:
zero_set_config(dev, w_value); //w_value就是要set的config的value,即dev->config
USB_REQ_GET_CONFIGURATION:
*(u8 *)req->buf = dev->config; //返回当前config的value
USB_REQ_SET_INTERFACE:
zero_reset_config (dev);
zero_set_config(dev, config);
USB_REQ_GET_INTERFACE:
...
最后把ep的request放到queue中去,作为对host的应答
value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC);
}