上一篇讲到usb_register将uvc_driver.driver注册进去,今天咱们来梳理下uvc_driver.driver中最重要的函数probe(即uvc_probe)。
uvc_probe会传入2组参数,分别是struct usb_interface *intf和const struct usb_device_id *id。
经过intf咱们能够获取usb最重要的结构体struct usb_device,经过id咱们能够获得挂载uvc驱动的usb设备的PID和VID。
在uvc_probe中主要是构建了struct uvc_deviceide
struct uvc_device { struct usb_device *udev; struct usb_interface *intf; unsigned long warnings; __u32 quirks; int intfnum; char name[32]; enum uvc_device_state state; struct list_head list; atomic_t users; /* Video control interface */ __u16 uvc_version; __u32 clock_frequency; struct list_head entities; struct list_head chains; /* Video Streaming interfaces */ struct list_head streams; atomic_t nstreams; /* Status Interrupt Endpoint */ struct usb_host_endpoint *int_ep; struct urb *int_urb; __u8 *status; struct input_dev *input; char input_phys[64]; };
下面咱们介绍下几个在probe函数中比较重要的函数函数
主要做用是解析uvc设备的usb描述符ui
将以前uvc_drive中controls队列中的uvc控制参数添加到struct uvc_device的entities队列里,最后atom
list_add_tail(&dev->list, &uvc_driver.devices);
将uvc_device挂接到uvc_drive中,实现设备和驱动的挂载过程spa
uvc_scan_device&uvc_register_terms
将video设备注册到uvc链中,最后经过uvc_register_video将全部video设备都注册成支持v4l2接口的uvc设备
让咱们看下v4l2的ops结构体内容code
const struct v4l2_file_operations uvc_fops = { .owner = THIS_MODULE, .open = uvc_v4l2_open, .release = uvc_v4l2_release, .ioctl = uvc_v4l2_ioctl, .read = uvc_v4l2_read, .mmap = uvc_v4l2_mmap, .poll = uvc_v4l2_poll, };
经过这种方式咱们的uvc设备就能提供给上层v4l2的接口了接口
若是你的uvc设备还支持input的话,就须要单独为它注册input device节点(input_register_device),除此以外该函数还初始化中了中断urb,当你进行中断传输完成时会待用uvc_status_complete返回urb的提交状态,咱们通常看到Non-zero status (-71) in status completion handler这种错误就是在这个函数返回的。队列