Linux uvc驅動分析
一、ioctl調用流程
1.common/drivers/media/video/uvc/uvc_driver.c
module_init(uvc_init);
static int __init uvc_init(void){
result = usb_register(&uvc_driver.driver);
}
struct uvc_driver uvc_driver = {
.driver = {
.name = "uvcvideo",
.probe = uvc_probe,
.disconnect = uvc_disconnect,
.suspend = uvc_suspend,
.resume = uvc_resume,
.reset_resume = uvc_reset_resume,
.id_table = uvc_ids,
.supports_autosuspend = 1,
},
};
static int uvc_probe(struct usb_interface *intf, const struct usb_device_id *id){
uvc_register_chains(dev)
}
static int uvc_register_chains(struct uvc_device *dev){
ret = uvc_register_terms(dev, chain);
}
static int uvc_register_terms(struct uvc_device *dev, struct uvc_video_chain *chain){
ret = uvc_register_video(dev, stream);
}
static int uvc_register_video(struct uvc_device *dev,struct uvc_streaming *stream){
ret = uvc_video_init(stream);
vdev = video_device_alloc();
vdev->v4l2_dev = &dev->vdev;
vdev->fops = &uvc_fops;
vdev->release = uvc_release;
strlcpy(vdev->name, dev->name, sizeof vdev->name);
stream->vdev = vdev;
video_set_drvdata(vdev, stream);
ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
}
2.common/drivers/media/video/uvc/uvc_v4l2.c
const struct v4l2_file_operations uvc_fops = {
.owner = THIS_MODULE,
.open = uvc_v4l2_open,
.release = uvc_v4l2_release,
.unlocked_ioctl = uvc_v4l2_ioctl,
.read = uvc_v4l2_read,
.mmap = uvc_v4l2_mmap,
.poll = uvc_v4l2_poll,
#ifndef CONFIG_MMU
.get_unmapped_area = uvc_v4l2_get_unmapped_area,
#endif
};
static long uvc_v4l2_ioctl(struct file *file, unsigned int cmd, unsigned long arg){
return video_usercopy(file, cmd, arg, uvc_v4l2_do_ioctl);
}
static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg){
return uvc_query_v4l2_ctrl(chain, arg);
}
3.common/drivers/media/video/uvc/uvc_ctrl.c
int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,struct v4l2_queryctrl *v4l2_ctrl){
}