阅读:1379回复:0
Gadget Framework 代码分析(二) --- zero.c排版有些问题,请参考http://blog.csdn.net/zkami 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); } |
|