Loading drivers/media/video/pwc/pwc-if.c +2 −20 Original line number Diff line number Diff line Loading @@ -151,8 +151,6 @@ static int pwc_video_close(struct file *file); static ssize_t pwc_video_read(struct file *file, char __user *buf, size_t count, loff_t *ppos); static unsigned int pwc_video_poll(struct file *file, poll_table *wait); static long pwc_video_ioctl(struct file *file, unsigned int ioctlnr, unsigned long arg); static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma); static const struct v4l2_file_operations pwc_fops = { Loading @@ -162,7 +160,7 @@ static const struct v4l2_file_operations pwc_fops = { .read = pwc_video_read, .poll = pwc_video_poll, .mmap = pwc_video_mmap, .unlocked_ioctl = pwc_video_ioctl, .unlocked_ioctl = video_ioctl2, }; static struct video_device pwc_template = { .name = "Philips Webcam", /* Filled in later */ Loading Loading @@ -1378,23 +1376,6 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait) return 0; } static long pwc_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct video_device *vdev = file->private_data; struct pwc_device *pdev; long r = -ENODEV; if (!vdev) goto out; pdev = video_get_drvdata(vdev); if (!pdev->unplugged) r = video_usercopy(file, cmd, arg, pwc_video_do_ioctl); out: return r; } static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) { struct video_device *vdev = file->private_data; Loading Loading @@ -1744,6 +1725,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template)); pdev->vdev->parent = &intf->dev; pdev->vdev->lock = &pdev->modlock; pdev->vdev->ioctl_ops = &pwc_ioctl_ops; strcpy(pdev->vdev->name, name); video_set_drvdata(pdev->vdev, pdev); Loading drivers/media/video/pwc/pwc-v4l.c +491 −543 Original line number Diff line number Diff line Loading @@ -341,34 +341,11 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f) } long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) static int pwc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) { struct video_device *vdev = video_devdata(file); struct pwc_device *pdev; DECLARE_WAITQUEUE(wait, current); if (vdev == NULL) return -EFAULT; pdev = video_get_drvdata(vdev); if (pdev == NULL) return -EFAULT; #ifdef CONFIG_USB_PWC_DEBUG if (PWC_DEBUG_LEVEL_IOCTL & pwc_trace) { v4l_printk_ioctl(cmd); printk("\n"); } #endif struct pwc_device *pdev = video_drvdata(file); switch (cmd) { /* V4L2 Layer */ case VIDIOC_QUERYCAP: { struct v4l2_capability *cap = arg; PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCAP) This application "\ "try to use the v4l2 layer\n"); strcpy(cap->driver, PWC_NAME); strlcpy(cap->card, vdev->name, sizeof(cap->card)); usb_make_path(pdev->udev, cap->bus_info, sizeof(cap->bus_info)); Loading @@ -380,43 +357,30 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } case VIDIOC_ENUMINPUT: static int pwc_enum_input(struct file *file, void *fh, struct v4l2_input *i) { struct v4l2_input *i = arg; if (i->index) /* Only one INPUT is supported */ return -EINVAL; memset(i, 0, sizeof(struct v4l2_input)); strcpy(i->name, "usb"); return 0; } case VIDIOC_G_INPUT: static int pwc_g_input(struct file *file, void *fh, unsigned int *i) { int *i = arg; *i = 0; /* Only one INPUT is supported */ *i = 0; return 0; } case VIDIOC_S_INPUT: { int *i = arg; if ( *i ) { /* Only one INPUT is supported */ PWC_DEBUG_IOCTL("Only one input source is"\ " supported with this webcam.\n"); return -EINVAL; } return 0; static int pwc_s_input(struct file *file, void *fh, unsigned int i) { return i ? -EINVAL : 0; } /* TODO: */ case VIDIOC_QUERYCTRL: static int pwc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c) { struct v4l2_queryctrl *c = arg; int i; PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) query id=%d\n", c->id); for (i = 0; i < sizeof(pwc_controls) / sizeof(struct v4l2_queryctrl); i++) { if (pwc_controls[i].id == c->id) { PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) found\n"); Loading @@ -424,17 +388,15 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } } PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) not found\n"); return -EINVAL; } case VIDIOC_G_CTRL: static int pwc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c) { struct v4l2_control *c = arg; struct pwc_device *pdev = video_drvdata(file); int ret; switch (c->id) { switch (c->id) { case V4L2_CID_BRIGHTNESS: c->value = pwc_get_brightness(pdev); if (c->value < 0) Loading Loading @@ -531,13 +493,13 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) } return -EINVAL; } case VIDIOC_S_CTRL: static int pwc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) { struct v4l2_control *c = arg; struct pwc_device *pdev = video_drvdata(file); int ret; switch (c->id) { switch (c->id) { case V4L2_CID_BRIGHTNESS: c->value <<= 9; ret = pwc_set_brightness(pdev, c->value); Loading Loading @@ -647,21 +609,12 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) return -EINVAL; } case VIDIOC_ENUM_FMT: static int pwc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f) { struct v4l2_fmtdesc *f = arg; int index; if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; struct pwc_device *pdev = video_drvdata(file); /* We only support two format: the raw format, and YUV */ index = f->index; memset(f,0,sizeof(struct v4l2_fmtdesc)); f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; f->index = index; switch(index) { switch (f->index) { case 0: /* RAW format */ f->pixelformat = pdev->type <= 646 ? V4L2_PIX_FMT_PWC1 : V4L2_PIX_FMT_PWC2; Loading @@ -678,53 +631,32 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } case VIDIOC_G_FMT: static int pwc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) { struct v4l2_format *f = arg; PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n",pdev->image.x,pdev->image.y); if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; struct pwc_device *pdev = video_drvdata(file); PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n", pdev->image.x, pdev->image.y); pwc_vidioc_fill_fmt(pdev, f); return 0; } case VIDIOC_TRY_FMT: return pwc_vidioc_try_fmt(pdev, arg); case VIDIOC_S_FMT: return pwc_vidioc_set_fmt(pdev, arg); case VIDIOC_G_STD: static int pwc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) { v4l2_std_id *std = arg; *std = V4L2_STD_UNKNOWN; return 0; } struct pwc_device *pdev = video_drvdata(file); case VIDIOC_S_STD: { v4l2_std_id *std = arg; if (*std != V4L2_STD_UNKNOWN) return -EINVAL; return 0; return pwc_vidioc_try_fmt(pdev, f); } case VIDIOC_ENUMSTD: static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) { struct v4l2_standard *std = arg; if (std->index != 0) return -EINVAL; std->id = V4L2_STD_UNKNOWN; strlcpy(std->name, "webcam", sizeof(std->name)); return 0; struct pwc_device *pdev = video_drvdata(file); return pwc_vidioc_set_fmt(pdev, f); } case VIDIOC_REQBUFS: static int pwc_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *rb) { struct v4l2_requestbuffers *rb = arg; int nbuffers; PWC_DEBUG_IOCTL("ioctl(VIDIOC_REQBUFS) count=%d\n", rb->count); Loading @@ -743,9 +675,9 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } case VIDIOC_QUERYBUF: static int pwc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) { struct v4l2_buffer *buf = arg; struct pwc_device *pdev = video_drvdata(file); int index; PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) index=%d\n", buf->index); Loading @@ -753,19 +685,12 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad type\n"); return -EINVAL; } if (buf->memory != V4L2_MEMORY_MMAP) { PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad memory type\n"); return -EINVAL; } index = buf->index; if (index < 0 || index >= pwc_mbufs) { PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad index %d\n", buf->index); return -EINVAL; } memset(buf, 0, sizeof(struct v4l2_buffer)); buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf->index = index; buf->m.offset = index * pdev->len_per_image; if (pdev->pixfmt != V4L2_PIX_FMT_YUV420) buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame); Loading @@ -773,7 +698,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) buf->bytesused = pdev->view.size; buf->field = V4L2_FIELD_NONE; buf->memory = V4L2_MEMORY_MMAP; //buf->flags = V4L2_BUF_FLAG_MAPPED; /*buf->flags = V4L2_BUF_FLAG_MAPPED;*/ buf->length = pdev->len_per_image; PWC_DEBUG_READ("VIDIOC_QUERYBUF: index=%d\n", buf->index); Loading @@ -783,10 +708,8 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } case VIDIOC_QBUF: static int pwc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) { struct v4l2_buffer *buf = arg; PWC_DEBUG_IOCTL("ioctl(VIDIOC_QBUF) index=%d\n", buf->index); if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; Loading @@ -801,9 +724,10 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } case VIDIOC_DQBUF: static int pwc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) { struct v4l2_buffer *buf = arg; DECLARE_WAITQUEUE(wait, current); struct pwc_device *pdev = video_drvdata(file); int ret; PWC_DEBUG_IOCTL("ioctl(VIDIOC_DQBUF)\n"); Loading @@ -811,12 +735,6 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; /* Add ourselves to the frame wait-queue. FIXME: needs auditing for safety. QUESTION: In what respect? I think that using the frameq is safe now. */ add_wait_queue(&pdev->frameq, &wait); while (pdev->full_frames == NULL) { if (pdev->error_status) { Loading Loading @@ -868,20 +786,25 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) } case VIDIOC_STREAMON: static int pwc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) { struct pwc_device *pdev = video_drvdata(file); return pwc_isoc_init(pdev); } case VIDIOC_STREAMOFF: static int pwc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) { struct pwc_device *pdev = video_drvdata(file); pwc_isoc_cleanup(pdev); return 0; } case VIDIOC_ENUM_FRAMESIZES: static int pwc_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize) { struct v4l2_frmsizeenum *fsize = arg; struct pwc_device *pdev = video_drvdata(file); unsigned int i = 0, index = fsize->index; if (fsize->pixel_format == V4L2_PIX_FMT_YUV420) { Loading @@ -907,9 +830,10 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) return -EINVAL; } case VIDIOC_ENUM_FRAMEINTERVALS: static int pwc_enum_frameintervals(struct file *file, void *fh, struct v4l2_frmivalenum *fival) { struct v4l2_frmivalenum *fival = arg; struct pwc_device *pdev = video_drvdata(file); int size = -1; unsigned int i; Loading @@ -922,9 +846,8 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) } /* TODO: Support raw format */ if (size < 0 || fival->pixel_format != V4L2_PIX_FMT_YUV420) { if (size < 0 || fival->pixel_format != V4L2_PIX_FMT_YUV420) return -EINVAL; } i = pwc_get_fps(pdev, fival->index, size); if (!i) Loading @@ -937,10 +860,35 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } default: static long pwc_default(struct file *file, void *fh, int cmd, void *arg) { struct pwc_device *pdev = video_drvdata(file); return pwc_ioctl(pdev, cmd, arg); } /* ..switch */ return 0; } const struct v4l2_ioctl_ops pwc_ioctl_ops = { .vidioc_querycap = pwc_querycap, .vidioc_enum_input = pwc_enum_input, .vidioc_g_input = pwc_g_input, .vidioc_s_input = pwc_s_input, .vidioc_enum_fmt_vid_cap = pwc_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = pwc_g_fmt_vid_cap, .vidioc_s_fmt_vid_cap = pwc_s_fmt_vid_cap, .vidioc_try_fmt_vid_cap = pwc_try_fmt_vid_cap, .vidioc_queryctrl = pwc_queryctrl, .vidioc_g_ctrl = pwc_g_ctrl, .vidioc_s_ctrl = pwc_s_ctrl, .vidioc_reqbufs = pwc_reqbufs, .vidioc_querybuf = pwc_querybuf, .vidioc_qbuf = pwc_qbuf, .vidioc_dqbuf = pwc_dqbuf, .vidioc_streamon = pwc_streamon, .vidioc_streamoff = pwc_streamoff, .vidioc_enum_framesizes = pwc_enum_framesizes, .vidioc_enum_frameintervals = pwc_enum_frameintervals, .vidioc_default = pwc_default, }; /* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ drivers/media/video/pwc/pwc.h +1 −2 Original line number Diff line number Diff line Loading @@ -339,8 +339,7 @@ extern int pwc_camera_power(struct pwc_device *pdev, int power); /* Private ioctl()s; see pwc-ioctl.h */ extern long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg); /** Functions in pwc-v4l.c */ extern long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg); extern const struct v4l2_ioctl_ops pwc_ioctl_ops; /** pwc-uncompress.c */ /* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */ Loading Loading
drivers/media/video/pwc/pwc-if.c +2 −20 Original line number Diff line number Diff line Loading @@ -151,8 +151,6 @@ static int pwc_video_close(struct file *file); static ssize_t pwc_video_read(struct file *file, char __user *buf, size_t count, loff_t *ppos); static unsigned int pwc_video_poll(struct file *file, poll_table *wait); static long pwc_video_ioctl(struct file *file, unsigned int ioctlnr, unsigned long arg); static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma); static const struct v4l2_file_operations pwc_fops = { Loading @@ -162,7 +160,7 @@ static const struct v4l2_file_operations pwc_fops = { .read = pwc_video_read, .poll = pwc_video_poll, .mmap = pwc_video_mmap, .unlocked_ioctl = pwc_video_ioctl, .unlocked_ioctl = video_ioctl2, }; static struct video_device pwc_template = { .name = "Philips Webcam", /* Filled in later */ Loading Loading @@ -1378,23 +1376,6 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait) return 0; } static long pwc_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct video_device *vdev = file->private_data; struct pwc_device *pdev; long r = -ENODEV; if (!vdev) goto out; pdev = video_get_drvdata(vdev); if (!pdev->unplugged) r = video_usercopy(file, cmd, arg, pwc_video_do_ioctl); out: return r; } static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) { struct video_device *vdev = file->private_data; Loading Loading @@ -1744,6 +1725,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template)); pdev->vdev->parent = &intf->dev; pdev->vdev->lock = &pdev->modlock; pdev->vdev->ioctl_ops = &pwc_ioctl_ops; strcpy(pdev->vdev->name, name); video_set_drvdata(pdev->vdev, pdev); Loading
drivers/media/video/pwc/pwc-v4l.c +491 −543 Original line number Diff line number Diff line Loading @@ -341,34 +341,11 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f) } long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) static int pwc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) { struct video_device *vdev = video_devdata(file); struct pwc_device *pdev; DECLARE_WAITQUEUE(wait, current); if (vdev == NULL) return -EFAULT; pdev = video_get_drvdata(vdev); if (pdev == NULL) return -EFAULT; #ifdef CONFIG_USB_PWC_DEBUG if (PWC_DEBUG_LEVEL_IOCTL & pwc_trace) { v4l_printk_ioctl(cmd); printk("\n"); } #endif struct pwc_device *pdev = video_drvdata(file); switch (cmd) { /* V4L2 Layer */ case VIDIOC_QUERYCAP: { struct v4l2_capability *cap = arg; PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCAP) This application "\ "try to use the v4l2 layer\n"); strcpy(cap->driver, PWC_NAME); strlcpy(cap->card, vdev->name, sizeof(cap->card)); usb_make_path(pdev->udev, cap->bus_info, sizeof(cap->bus_info)); Loading @@ -380,43 +357,30 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } case VIDIOC_ENUMINPUT: static int pwc_enum_input(struct file *file, void *fh, struct v4l2_input *i) { struct v4l2_input *i = arg; if (i->index) /* Only one INPUT is supported */ return -EINVAL; memset(i, 0, sizeof(struct v4l2_input)); strcpy(i->name, "usb"); return 0; } case VIDIOC_G_INPUT: static int pwc_g_input(struct file *file, void *fh, unsigned int *i) { int *i = arg; *i = 0; /* Only one INPUT is supported */ *i = 0; return 0; } case VIDIOC_S_INPUT: { int *i = arg; if ( *i ) { /* Only one INPUT is supported */ PWC_DEBUG_IOCTL("Only one input source is"\ " supported with this webcam.\n"); return -EINVAL; } return 0; static int pwc_s_input(struct file *file, void *fh, unsigned int i) { return i ? -EINVAL : 0; } /* TODO: */ case VIDIOC_QUERYCTRL: static int pwc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c) { struct v4l2_queryctrl *c = arg; int i; PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) query id=%d\n", c->id); for (i = 0; i < sizeof(pwc_controls) / sizeof(struct v4l2_queryctrl); i++) { if (pwc_controls[i].id == c->id) { PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) found\n"); Loading @@ -424,17 +388,15 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } } PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) not found\n"); return -EINVAL; } case VIDIOC_G_CTRL: static int pwc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c) { struct v4l2_control *c = arg; struct pwc_device *pdev = video_drvdata(file); int ret; switch (c->id) { switch (c->id) { case V4L2_CID_BRIGHTNESS: c->value = pwc_get_brightness(pdev); if (c->value < 0) Loading Loading @@ -531,13 +493,13 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) } return -EINVAL; } case VIDIOC_S_CTRL: static int pwc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) { struct v4l2_control *c = arg; struct pwc_device *pdev = video_drvdata(file); int ret; switch (c->id) { switch (c->id) { case V4L2_CID_BRIGHTNESS: c->value <<= 9; ret = pwc_set_brightness(pdev, c->value); Loading Loading @@ -647,21 +609,12 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) return -EINVAL; } case VIDIOC_ENUM_FMT: static int pwc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f) { struct v4l2_fmtdesc *f = arg; int index; if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; struct pwc_device *pdev = video_drvdata(file); /* We only support two format: the raw format, and YUV */ index = f->index; memset(f,0,sizeof(struct v4l2_fmtdesc)); f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; f->index = index; switch(index) { switch (f->index) { case 0: /* RAW format */ f->pixelformat = pdev->type <= 646 ? V4L2_PIX_FMT_PWC1 : V4L2_PIX_FMT_PWC2; Loading @@ -678,53 +631,32 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } case VIDIOC_G_FMT: static int pwc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) { struct v4l2_format *f = arg; PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n",pdev->image.x,pdev->image.y); if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; struct pwc_device *pdev = video_drvdata(file); PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n", pdev->image.x, pdev->image.y); pwc_vidioc_fill_fmt(pdev, f); return 0; } case VIDIOC_TRY_FMT: return pwc_vidioc_try_fmt(pdev, arg); case VIDIOC_S_FMT: return pwc_vidioc_set_fmt(pdev, arg); case VIDIOC_G_STD: static int pwc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) { v4l2_std_id *std = arg; *std = V4L2_STD_UNKNOWN; return 0; } struct pwc_device *pdev = video_drvdata(file); case VIDIOC_S_STD: { v4l2_std_id *std = arg; if (*std != V4L2_STD_UNKNOWN) return -EINVAL; return 0; return pwc_vidioc_try_fmt(pdev, f); } case VIDIOC_ENUMSTD: static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) { struct v4l2_standard *std = arg; if (std->index != 0) return -EINVAL; std->id = V4L2_STD_UNKNOWN; strlcpy(std->name, "webcam", sizeof(std->name)); return 0; struct pwc_device *pdev = video_drvdata(file); return pwc_vidioc_set_fmt(pdev, f); } case VIDIOC_REQBUFS: static int pwc_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *rb) { struct v4l2_requestbuffers *rb = arg; int nbuffers; PWC_DEBUG_IOCTL("ioctl(VIDIOC_REQBUFS) count=%d\n", rb->count); Loading @@ -743,9 +675,9 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } case VIDIOC_QUERYBUF: static int pwc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) { struct v4l2_buffer *buf = arg; struct pwc_device *pdev = video_drvdata(file); int index; PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) index=%d\n", buf->index); Loading @@ -753,19 +685,12 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad type\n"); return -EINVAL; } if (buf->memory != V4L2_MEMORY_MMAP) { PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad memory type\n"); return -EINVAL; } index = buf->index; if (index < 0 || index >= pwc_mbufs) { PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad index %d\n", buf->index); return -EINVAL; } memset(buf, 0, sizeof(struct v4l2_buffer)); buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf->index = index; buf->m.offset = index * pdev->len_per_image; if (pdev->pixfmt != V4L2_PIX_FMT_YUV420) buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame); Loading @@ -773,7 +698,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) buf->bytesused = pdev->view.size; buf->field = V4L2_FIELD_NONE; buf->memory = V4L2_MEMORY_MMAP; //buf->flags = V4L2_BUF_FLAG_MAPPED; /*buf->flags = V4L2_BUF_FLAG_MAPPED;*/ buf->length = pdev->len_per_image; PWC_DEBUG_READ("VIDIOC_QUERYBUF: index=%d\n", buf->index); Loading @@ -783,10 +708,8 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } case VIDIOC_QBUF: static int pwc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) { struct v4l2_buffer *buf = arg; PWC_DEBUG_IOCTL("ioctl(VIDIOC_QBUF) index=%d\n", buf->index); if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; Loading @@ -801,9 +724,10 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } case VIDIOC_DQBUF: static int pwc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) { struct v4l2_buffer *buf = arg; DECLARE_WAITQUEUE(wait, current); struct pwc_device *pdev = video_drvdata(file); int ret; PWC_DEBUG_IOCTL("ioctl(VIDIOC_DQBUF)\n"); Loading @@ -811,12 +735,6 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; /* Add ourselves to the frame wait-queue. FIXME: needs auditing for safety. QUESTION: In what respect? I think that using the frameq is safe now. */ add_wait_queue(&pdev->frameq, &wait); while (pdev->full_frames == NULL) { if (pdev->error_status) { Loading Loading @@ -868,20 +786,25 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) } case VIDIOC_STREAMON: static int pwc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) { struct pwc_device *pdev = video_drvdata(file); return pwc_isoc_init(pdev); } case VIDIOC_STREAMOFF: static int pwc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) { struct pwc_device *pdev = video_drvdata(file); pwc_isoc_cleanup(pdev); return 0; } case VIDIOC_ENUM_FRAMESIZES: static int pwc_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize) { struct v4l2_frmsizeenum *fsize = arg; struct pwc_device *pdev = video_drvdata(file); unsigned int i = 0, index = fsize->index; if (fsize->pixel_format == V4L2_PIX_FMT_YUV420) { Loading @@ -907,9 +830,10 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) return -EINVAL; } case VIDIOC_ENUM_FRAMEINTERVALS: static int pwc_enum_frameintervals(struct file *file, void *fh, struct v4l2_frmivalenum *fival) { struct v4l2_frmivalenum *fival = arg; struct pwc_device *pdev = video_drvdata(file); int size = -1; unsigned int i; Loading @@ -922,9 +846,8 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) } /* TODO: Support raw format */ if (size < 0 || fival->pixel_format != V4L2_PIX_FMT_YUV420) { if (size < 0 || fival->pixel_format != V4L2_PIX_FMT_YUV420) return -EINVAL; } i = pwc_get_fps(pdev, fival->index, size); if (!i) Loading @@ -937,10 +860,35 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } default: static long pwc_default(struct file *file, void *fh, int cmd, void *arg) { struct pwc_device *pdev = video_drvdata(file); return pwc_ioctl(pdev, cmd, arg); } /* ..switch */ return 0; } const struct v4l2_ioctl_ops pwc_ioctl_ops = { .vidioc_querycap = pwc_querycap, .vidioc_enum_input = pwc_enum_input, .vidioc_g_input = pwc_g_input, .vidioc_s_input = pwc_s_input, .vidioc_enum_fmt_vid_cap = pwc_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = pwc_g_fmt_vid_cap, .vidioc_s_fmt_vid_cap = pwc_s_fmt_vid_cap, .vidioc_try_fmt_vid_cap = pwc_try_fmt_vid_cap, .vidioc_queryctrl = pwc_queryctrl, .vidioc_g_ctrl = pwc_g_ctrl, .vidioc_s_ctrl = pwc_s_ctrl, .vidioc_reqbufs = pwc_reqbufs, .vidioc_querybuf = pwc_querybuf, .vidioc_qbuf = pwc_qbuf, .vidioc_dqbuf = pwc_dqbuf, .vidioc_streamon = pwc_streamon, .vidioc_streamoff = pwc_streamoff, .vidioc_enum_framesizes = pwc_enum_framesizes, .vidioc_enum_frameintervals = pwc_enum_frameintervals, .vidioc_default = pwc_default, }; /* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
drivers/media/video/pwc/pwc.h +1 −2 Original line number Diff line number Diff line Loading @@ -339,8 +339,7 @@ extern int pwc_camera_power(struct pwc_device *pdev, int power); /* Private ioctl()s; see pwc-ioctl.h */ extern long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg); /** Functions in pwc-v4l.c */ extern long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg); extern const struct v4l2_ioctl_ops pwc_ioctl_ops; /** pwc-uncompress.c */ /* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */ Loading