参考文献:《Linux 设备驱动开发详解:基于最新的Linux4.0内核》
其他参考: 文中引用的代码版本为 Linux Kernel 4.9 (高通SDM670平台)
USB Gadget设备端驱动架构总目录
一、Gadget基本架构分层
从USB设备侧角度来看,分为三个层次:底层:UDC(USB Device Controller)驱动,中间层:Gadget Function API接口以及实现具体功能的上层:Gadget Function驱动程序。
UDC直接访问底层硬件设备控制器,向上层提供硬件相关的API回调函数,Gadget Function API对UDC的回调函数进行简单的包装,这层API可以看做是中间层,将下层的UDC驱动与上层的Function隔离,从而将功能实现与底层通信分开。最上层的Gadget Function具体控制USB设备的功能,使设备表现出具体的功能,如UVC,MTP等。
二、USB设备描述符
USB设备分为设备(Device),配置(Configuration),接口(Interface),端点(Endpoint)四个层次。
Device可以包含一个多多个配置,配置由多个接口组成,依次类推接口最终具体到USB的端点。接口代表基本的功能。一个配置中的所有接口可以同时有效。
端点是最基本的通信形式,USB设备接口本质上是端点的集合,主机只能通过端点与设备进行通信,来使用设备的功能。每个端点是单向的PIPE,端点0为控制端点,用于设备初始化参数等。端点1,2一般为数据端点。
(1)设备描述符
描述设备通用信息,如USB版本号,供应商,PID,等
内核代码中定义如下 (include/uapi/linux/usb/ch9.h)
282 /* USB_DT_DEVICE: Device descriptor */
283 struct usb_device_descriptor {
284 __u8 bLength; //描述符长度
285 __u8 bDescriptorType; //描述符类型编号
286
287 __le16 bcdUSB; //USB版本号
288 __u8 bDeviceClass; //设备类
289 __u8 bDeviceSubClass; //设备子类
290 __u8 bDeviceProtocol; //协议
291 __u8 bMaxPacketSize0; //端点0 最大包大小
292 __le16 idVendor; //VID
293 __le16 idProduct; //PID
294 __le16 bcdDevice; //出厂编号
295 __u8 iManufacturer; //供应商
296 __u8 iProduct; //产品名称
297 __u8 iSerialNumber; //序列号
298 __u8 bNumConfigurations; //可能的配置数量
299 } __attribute__ ((packed));
例如高通目标设备的设备描述符为:
可以看到当前的信息如下USB版本为2.1, 端点0支持64 byte的数据长度,厂商为高通,供应商为Pico等。
(2)配置描述符
描述配置所需要的接口数量,功耗要求,内核中的代码定义为: (include/uapi/linux/usb/ch9.h)
339 struct usb_config_descriptor {
340 __u8 bLength; //描述符长度
341 __u8 bDescriptorType; //描述符类型
342
343 __le16 wTotalLength; //配置所返回的所有数据的总长度,即各个描述符长度之和
344 __u8 bNumInterfaces; //配置所支持的接口数量
345 __u8 bConfigurationValue; //设置此配置需要的参数
346 __u8 iConfiguration; //描述该配置的字符串的索引值
347 __u8 bmAttributes; //供电模式
348 __u8 bMaxPower; //最大电流
349 } __attribute__ ((packed));
(3)接口描述符
接口类,子类适用的协议,USB接口内核中适用usb_interface结构体描述,而USB接口描述符定义如下(include/uapi/linux/usb/ch9.h)
376 struct usb_interface_descriptor {
377 __u8 bLength; //描述符长度
378 __u8 bDescriptorType; //描述符类型
379
380 __u8 bInterfaceNumber; //描述符编号
381 __u8 bAlternateSetting; //备用的接口描述符编号
382 __u8 bNumEndpoints; //接口使用的端点数,不包括端点0
383 __u8 bInterfaceClass; //接口类型
384 __u8 bInterfaceSubClass; //子类
385 __u8 bInterfaceProtocol; //协议
386 __u8 iInterface; //接口的字符串索引值
387 } __attribute__ ((packed));
(4)端点描述符
端点地址,方向类型支持的最大包大小,中断类型包含轮询频率,内核中定义为:(include/uapi/linux/usb/ch9.h)
394 struct usb_endpoint_descriptor {
395 __u8 bLength;
396 __u8 bDescriptorType;
397
398 __u8 bEndpointAddress;//端点地址,0-3是断点号,7位是方向(0输入,1输出)
399 __u8 bmAttributes; //端点属性 bit0-1, 00控制,01同步 02批量 03中断
400 __le16 wMaxPacketSize;//包长度
401 __u8 bInterval;//轮询数据时间间隔,同步为1,中断为1-255 其他忽略
402
403 /* NOTE: these two are _only_ in audio endpoints. */
404 /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
405 __u8 bRefresh;
406 __u8 bSynchAddress;
407 } __attribute__ ((packed));
三、Gadget的核心数据结构
USB设备控制器usb_gadget,UDC操作usb_gadget_ops, 描述一个端点的usb_ep以及描述端点操作的usb_ep_ops
(1)USB设备控制器描述 usb_gadget (include/linux/usb/gadget.h)
504 struct usb_gadget {
505 struct work_struct work;
506 struct usb_udc *udc;
507 /* readonly to gadget driver */
508 const struct usb_gadget_ops *ops;
509 struct usb_ep *ep0;
510 struct list_head ep_list; /* of usb_ep */
511 enum usb_device_speed speed;
512 enum usb_device_speed max_speed;
513 enum usb_device_state state;
514 const char *name;
515 struct device dev;
516 unsigned out_epnum;
517 unsigned in_epnum;
518 unsigned mA;
519 struct usb_otg_caps *otg_caps;
520
521 unsigned sg_supported:1;
522 unsigned is_otg:1;
523 unsigned is_a_peripheral:1;
524 unsigned b_hnp_enable:1;
525 unsigned a_hnp_support:1;
526 unsigned a_alt_hnp_support:1;
527 unsigned hnp_polling_support:1;
528 unsigned host_request_flag:1;
529 unsigned quirk_ep_out_aligned_size:1;
530 unsigned quirk_altset_not_supp:1;
531 unsigned quirk_stall_not_supp:1;
532 unsigned quirk_zlp_not_supp:1;
533 unsigned quirk_avoids_skb_reserve:1;
534 unsigned is_selfpowered:1;
535 unsigned deactivated:1;
536 unsigned connected:1;
537 bool remote_wakeup;
538 bool bam2bam_func_enabled;
539 u32 extra_buf_alloc;
540 bool l1_supported;
541 bool is_chipidea;
542 };
(2)USB设备控制器的操作函数 (include/linux/usb/gadget.h)
418 struct usb_gadget_ops {
419 int (*get_frame)(struct usb_gadget *);
420 int (*wakeup)(struct usb_gadget *);
421 int (*func_wakeup)(struct usb_gadget *, int interface_id);
422 int (*set_selfpowered) (struct usb_gadget *, int is_selfpowered);
423 int (*vbus_session) (struct usb_gadget *, int is_active);
424 int (*vbus_draw) (struct usb_gadget *, unsigned mA);
425 int (*pullup) (struct usb_gadget *, int is_on);
426 int (*ioctl)(struct usb_gadget *,
427 unsigned code, unsigned long param);
428 void (*get_config_params)(struct usb_dcd_config_params *);
429 int (*udc_start)(struct usb_gadget *,
430 struct usb_gadget_driver *);
431 int (*udc_stop)(struct usb_gadget *);
432 struct usb_ep *(*match_ep)(struct usb_gadget *,
433 struct usb_endpoint_descriptor *,
434 struct usb_ss_ep_comp_descriptor *);
435 int (*restart)(struct usb_gadget *);
436 };
(3)USB端点描述 (include/linux/usb/gadget.h)
321 struct usb_ep {
322 void *driver_data;
323
324 const char *name;
325 const struct usb_ep_ops *ops;
326 struct list_head ep_list;
327 struct usb_ep_caps caps;
328 bool claimed;
329 bool enabled;
330 unsigned maxpacket:16;
331 unsigned maxpacket_limit:16;
332 unsigned max_streams:16;
333 unsigned mult:2;
334 unsigned maxburst:5;
335 u8 address;
336 const struct usb_endpoint_descriptor *desc;
337 const struct usb_ss_ep_comp_descriptor *comp_desc;
338 enum ep_type ep_type;
339 u8 ep_num;
340 u8 ep_intr_num;
341 bool endless;
342 };
(4)USB端点操作 (include/linux/usb/gadget.h)
226 struct usb_ep_ops {
227 int (*enable) (struct usb_ep *ep,
228 const struct usb_endpoint_descriptor *desc);
229 int (*disable) (struct usb_ep *ep);
230
231 struct usb_request *(*alloc_request) (struct usb_ep *ep,
232 gfp_t gfp_flags);
233 void (*free_request) (struct usb_ep *ep, struct usb_request *req);
234
235 int (*queue) (struct usb_ep *ep, struct usb_request *req,
236 gfp_t gfp_flags);
237 int (*dequeue) (struct usb_ep *ep, struct usb_request *req);
238
239 int (*set_halt) (struct usb_ep *ep, int value);
240 int (*set_wedge) (struct usb_ep *ep);
241
242 int (*fifo_status) (struct usb_ep *ep);
243 void (*fifo_flush) (struct usb_ep *ep);
244 int (*gsi_ep_op)(struct usb_ep *ep, void *op_data,
245 enum gsi_ep_op op);
246
247 };
在UDC驱动中,封装并实现上述的四个描述和操作的结构体,通过usb_add_gadget_udc()来注册UDC(drivers/usb/gadget/udc/core.c)
1278 int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget)
1279 {
1280 return usb_add_gadget_udc_release(parent, gadget, NULL);
1281 }
1162 int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
1163 void (*release)(struct device *dev))
在function中需要填充usb_interface_descriptor , usb_endpoint_descriptor, 合成usb_descriptor_header,实现usb_function的成员函数
这些描述符以UVC为例,都在f_uvc.c中定义,按照第二部分USB描述符的结构编辑。
例如:
79 static struct usb_interface_descriptor uvc_control_intf = {
80 .bLength = USB_DT_INTERFACE_SIZE,
81 .bDescriptorType = USB_DT_INTERFACE,
82 .bInterfaceNumber = UVC_INTF_VIDEO_CONTROL,
83 .bAlternateSetting = 0,
84 .bNumEndpoints = 1,
85 .bInterfaceClass = USB_CLASS_VIDEO,
86 .bInterfaceSubClass = UVC_SC_VIDEOCONTROL,
87 .bInterfaceProtocol = 0x01,
88 .iInterface = 0,
89 };
同时需要实现usb_function结构体的成员函数,usb_function结构体定义于(include/linux/usb/composite.h)
199 struct usb_function {
200 const char *name;
201 int intf_id;
202 struct usb_gadget_strings **strings;
203 struct usb_descriptor_header **fs_descriptors;//全速低俗描述符表
204 struct usb_descriptor_header **hs_descriptors;//高速描述符表
205 struct usb_descriptor_header **ss_descriptors;//超高速描述符表
206 struct usb_descriptor_header **ssp_descriptors;
207
208 struct usb_configuration *config;
209
210 struct usb_os_desc_table *os_desc_table;
211 unsigned os_desc_n;
212
213 /* REVISIT: bind() functions can be marked __init, which
214 * makes trouble for section mismatch analysis. See if
215 * we can't restructure things to avoid mismatching.
216 * Related: unbind() may kfree() but bind() won't...
217 */
218
219 /* configuration management: bind/unbind */
220 int (*bind)(struct usb_configuration *,
221 struct usb_function *);//获取IO缓冲端点等资源
222 void (*unbind)(struct usb_configuration *,
223 struct usb_function *);
224 void (*free_func)(struct usb_function *f);
225 struct module *mod;
226
227 /* runtime state management */
228 int (*set_alt)(struct usb_function *,
229 unsigned interface, unsigned alt);
230 int (*get_alt)(struct usb_function *,
231 unsigned interface);
232 void (*disable)(struct usb_function *);
233 int (*setup)(struct usb_function *,
234 const struct usb_ctrlrequest *);
235 bool (*req_match)(struct usb_function *,
236 const struct usb_ctrlrequest *,
237 bool config0);
238 void (*suspend)(struct usb_function *);
239 void (*resume)(struct usb_function *);
240
241 /* USB 3.0 additions */
242 int (*get_status)(struct usb_function *);
243 int (*func_suspend)(struct usb_function *,
244 u8 suspend_opt);
245 unsigned func_is_suspended:1;
246 unsigned func_wakeup_allowed:1;
247 unsigned func_wakeup_pending:1;
248 /* private: */
249 /* internals */
250 struct list_head list;
251 DECLARE_BITMAP(endpoints, 32);
252 const struct usb_function_instance *fi;
253
254 unsigned int bind_deactivated:1;
255 };
以UVC为例挂载时需要执行的流程为
uvc_init
uvc_alloc_inst
uvcg_attach_configfs
uvc_alloc
uvc_function_bind
uvc_copy_descriptors
uvc_copy_descriptors
uvc_copy_descriptors
uvc_register_video
上述的描述符以及usb_function成员函数填充好以后,内核通过下面这个API来完成function的注册(drivers/usb/gadget/function.c)
int usb_function_register(struct usb_function_driver *newf);
90 int usb_function_register(struct usb_function_driver *newf)
91 {
92 struct usb_function_driver *fd;
93 int ret;
94 pr_err("SOLEN in %s",__func__);
95 ret = -EEXIST;
96 mutex_lock(&func_lock);
97 list_for_each_entry(fd, &func_list, list) {
98 if (!strcmp(fd->name, newf->name))
99 {
100 pr_err("SOLEN in %s go to out",__func__);
101 goto out;
102 }
103 }
104 ret = 0;
105 list_add_tail(&newf->list, &func_list);
106 pr_err("SOLEN in list_add_tail \n");
107 out:
108 mutex_unlock(&func_lock);
109 return ret;
110 }
四、端口通讯
(一)USB_REQUEST
Gadget使用usb_request来描述传输请求,(include/linux/usb/gadget.h)
193 struct usb_request {
194 void *buf;
195 unsigned length;
196 dma_addr_t dma;
197
198 struct scatterlist *sg;
199 unsigned num_sgs;
200 unsigned num_mapped_sgs;
201
202 unsigned stream_id:16;
203 unsigned no_interrupt:1;
204 unsigned zero:1;
205 unsigned short_not_ok:1;
206
207 void (*complete)(struct usb_ep *ep,
208 struct usb_request *req);
209 void *context;
210 struct list_head list;
211
212 int status;
213 unsigned actual;
214 unsigned int udc_priv;
215 };