diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-13 22:22:22 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-13 22:22:22 -0500 |
commit | d8c532c40721f7507896d202b8cae3b3642d2b0d (patch) | |
tree | 42b1ce76671eb85324281ed93491432f4523f983 /drivers/media/usb/uvc | |
parent | e777d192ffb9f2929d547a2f8a5f65b7db7a9552 (diff) | |
parent | 77c53d0b56264a8fc5844e087ad15fffe20c299d (diff) |
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab:
- Missing MAINTAINERS entries were added for several drivers
- Adds V4L2 support for DMABUF handling, allowing zero-copy buffer
sharing between V4L2 devices and GPU
- Got rid of all warnings when compiling with W=1 on x86
- Add a new driver for Exynos hardware (s3c-camif)
- Several bug fixes, cleanups and driver improvements
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (243 commits)
[media] omap3isp: Replace cpu_is_omap3630() with ISP revision check
[media] omap3isp: Prepare/unprepare clocks before/after enable/disable
[media] omap3isp: preview: Add support for 8-bit formats at the sink pad
[media] omap3isp: Replace printk with dev_*
[media] omap3isp: Find source pad from external entity
[media] omap3isp: Configure CSI-2 phy based on platform data
[media] omap3isp: Add PHY routing configuration
[media] omap3isp: Add CSI configuration registers from control block to ISP resources
[media] omap3isp: Remove unneeded module memory address definitions
[media] omap3isp: Use monotonic timestamps for statistics buffers
[media] uvcvideo: Fix control value clamping for unsigned integer controls
[media] uvcvideo: Mark first output terminal as default video node
[media] uvcvideo: Add VIDIOC_[GS]_PRIORITY support
[media] uvcvideo: Return -ENOTTY for unsupported ioctls
[media] uvcvideo: Set device_caps in VIDIOC_QUERYCAP
[media] uvcvideo: Don't fail when an unsupported format is requested
[media] uvcvideo: Return -EACCES when trying to access a read/write-only control
[media] uvcvideo: Set error_idx properly for extended controls API failures
[media] rtl28xxu: add NOXON DAB/DAB+ USB dongle rev 2
[media] fc2580: write some registers conditionally
...
Diffstat (limited to 'drivers/media/usb/uvc')
-rw-r--r-- | drivers/media/usb/uvc/uvc_ctrl.c | 29 | ||||
-rw-r--r-- | drivers/media/usb/uvc/uvc_driver.c | 10 | ||||
-rw-r--r-- | drivers/media/usb/uvc/uvc_entity.c | 2 | ||||
-rw-r--r-- | drivers/media/usb/uvc/uvc_queue.c | 2 | ||||
-rw-r--r-- | drivers/media/usb/uvc/uvc_v4l2.c | 89 | ||||
-rw-r--r-- | drivers/media/usb/uvc/uvc_video.c | 1 | ||||
-rw-r--r-- | drivers/media/usb/uvc/uvcvideo.h | 8 |
7 files changed, 111 insertions, 30 deletions
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index f7061a5ef1d2..516a5b188ea5 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c | |||
@@ -927,7 +927,7 @@ static int __uvc_ctrl_get(struct uvc_video_chain *chain, | |||
927 | int ret; | 927 | int ret; |
928 | 928 | ||
929 | if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) | 929 | if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) |
930 | return -EINVAL; | 930 | return -EACCES; |
931 | 931 | ||
932 | if (!ctrl->loaded) { | 932 | if (!ctrl->loaded) { |
933 | ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ctrl->entity->id, | 933 | ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ctrl->entity->id, |
@@ -1061,7 +1061,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | |||
1061 | 1061 | ||
1062 | ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping); | 1062 | ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping); |
1063 | if (ctrl == NULL) { | 1063 | if (ctrl == NULL) { |
1064 | ret = -EINVAL; | 1064 | ret = -ENOENT; |
1065 | goto done; | 1065 | goto done; |
1066 | } | 1066 | } |
1067 | 1067 | ||
@@ -1099,12 +1099,13 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain, | |||
1099 | return -ERESTARTSYS; | 1099 | return -ERESTARTSYS; |
1100 | 1100 | ||
1101 | ctrl = uvc_find_control(chain, query_menu->id, &mapping); | 1101 | ctrl = uvc_find_control(chain, query_menu->id, &mapping); |
1102 | if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) { | 1102 | if (ctrl == NULL) { |
1103 | ret = -EINVAL; | 1103 | ret = -ENOENT; |
1104 | goto done; | 1104 | goto done; |
1105 | } | 1105 | } |
1106 | 1106 | ||
1107 | if (query_menu->index >= mapping->menu_count) { | 1107 | if (mapping->v4l2_type != V4L2_CTRL_TYPE_MENU || |
1108 | query_menu->index >= mapping->menu_count) { | ||
1108 | ret = -EINVAL; | 1109 | ret = -EINVAL; |
1109 | goto done; | 1110 | goto done; |
1110 | } | 1111 | } |
@@ -1263,7 +1264,7 @@ static int uvc_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems) | |||
1263 | 1264 | ||
1264 | ctrl = uvc_find_control(handle->chain, sev->id, &mapping); | 1265 | ctrl = uvc_find_control(handle->chain, sev->id, &mapping); |
1265 | if (ctrl == NULL) { | 1266 | if (ctrl == NULL) { |
1266 | ret = -EINVAL; | 1267 | ret = -ENOENT; |
1267 | goto done; | 1268 | goto done; |
1268 | } | 1269 | } |
1269 | 1270 | ||
@@ -1414,7 +1415,7 @@ int uvc_ctrl_get(struct uvc_video_chain *chain, | |||
1414 | 1415 | ||
1415 | ctrl = uvc_find_control(chain, xctrl->id, &mapping); | 1416 | ctrl = uvc_find_control(chain, xctrl->id, &mapping); |
1416 | if (ctrl == NULL) | 1417 | if (ctrl == NULL) |
1417 | return -EINVAL; | 1418 | return -ENOENT; |
1418 | 1419 | ||
1419 | return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value); | 1420 | return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value); |
1420 | } | 1421 | } |
@@ -1431,8 +1432,10 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, | |||
1431 | int ret; | 1432 | int ret; |
1432 | 1433 | ||
1433 | ctrl = uvc_find_control(chain, xctrl->id, &mapping); | 1434 | ctrl = uvc_find_control(chain, xctrl->id, &mapping); |
1434 | if (ctrl == NULL || (ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR) == 0) | 1435 | if (ctrl == NULL) |
1435 | return -EINVAL; | 1436 | return -ENOENT; |
1437 | if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR)) | ||
1438 | return -EACCES; | ||
1436 | 1439 | ||
1437 | /* Clamp out of range values. */ | 1440 | /* Clamp out of range values. */ |
1438 | switch (mapping->v4l2_type) { | 1441 | switch (mapping->v4l2_type) { |
@@ -1452,8 +1455,12 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, | |||
1452 | if (step == 0) | 1455 | if (step == 0) |
1453 | step = 1; | 1456 | step = 1; |
1454 | 1457 | ||
1455 | xctrl->value = min + (xctrl->value - min + step/2) / step * step; | 1458 | xctrl->value = min + ((u32)(xctrl->value - min) + step / 2) |
1456 | xctrl->value = clamp(xctrl->value, min, max); | 1459 | / step * step; |
1460 | if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED) | ||
1461 | xctrl->value = clamp(xctrl->value, min, max); | ||
1462 | else | ||
1463 | xctrl->value = clamp_t(u32, xctrl->value, min, max); | ||
1457 | value = xctrl->value; | 1464 | value = xctrl->value; |
1458 | break; | 1465 | break; |
1459 | 1466 | ||
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 5967081747ce..5dbefa68b1d2 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c | |||
@@ -1562,6 +1562,9 @@ static int uvc_scan_device(struct uvc_device *dev) | |||
1562 | INIT_LIST_HEAD(&chain->entities); | 1562 | INIT_LIST_HEAD(&chain->entities); |
1563 | mutex_init(&chain->ctrl_mutex); | 1563 | mutex_init(&chain->ctrl_mutex); |
1564 | chain->dev = dev; | 1564 | chain->dev = dev; |
1565 | v4l2_prio_init(&chain->prio); | ||
1566 | |||
1567 | term->flags |= UVC_ENTITY_FLAG_DEFAULT; | ||
1565 | 1568 | ||
1566 | if (uvc_scan_chain(chain, term) < 0) { | 1569 | if (uvc_scan_chain(chain, term) < 0) { |
1567 | kfree(chain); | 1570 | kfree(chain); |
@@ -1722,6 +1725,8 @@ static int uvc_register_video(struct uvc_device *dev, | |||
1722 | vdev->v4l2_dev = &dev->vdev; | 1725 | vdev->v4l2_dev = &dev->vdev; |
1723 | vdev->fops = &uvc_fops; | 1726 | vdev->fops = &uvc_fops; |
1724 | vdev->release = uvc_release; | 1727 | vdev->release = uvc_release; |
1728 | vdev->prio = &stream->chain->prio; | ||
1729 | set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags); | ||
1725 | if (stream->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) | 1730 | if (stream->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) |
1726 | vdev->vfl_dir = VFL_DIR_TX; | 1731 | vdev->vfl_dir = VFL_DIR_TX; |
1727 | strlcpy(vdev->name, dev->name, sizeof vdev->name); | 1732 | strlcpy(vdev->name, dev->name, sizeof vdev->name); |
@@ -1741,6 +1746,11 @@ static int uvc_register_video(struct uvc_device *dev, | |||
1741 | return ret; | 1746 | return ret; |
1742 | } | 1747 | } |
1743 | 1748 | ||
1749 | if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1750 | stream->chain->caps |= V4L2_CAP_VIDEO_CAPTURE; | ||
1751 | else | ||
1752 | stream->chain->caps |= V4L2_CAP_VIDEO_OUTPUT; | ||
1753 | |||
1744 | atomic_inc(&dev->nstreams); | 1754 | atomic_inc(&dev->nstreams); |
1745 | return 0; | 1755 | return 0; |
1746 | } | 1756 | } |
diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c index 29e239911d0e..dc56a59ecadc 100644 --- a/drivers/media/usb/uvc/uvc_entity.c +++ b/drivers/media/usb/uvc/uvc_entity.c | |||
@@ -93,6 +93,8 @@ static int uvc_mc_init_entity(struct uvc_entity *entity) | |||
93 | } else if (entity->vdev != NULL) { | 93 | } else if (entity->vdev != NULL) { |
94 | ret = media_entity_init(&entity->vdev->entity, | 94 | ret = media_entity_init(&entity->vdev->entity, |
95 | entity->num_pads, entity->pads, 0); | 95 | entity->num_pads, entity->pads, 0); |
96 | if (entity->flags & UVC_ENTITY_FLAG_DEFAULT) | ||
97 | entity->vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT; | ||
96 | } else | 98 | } else |
97 | ret = 0; | 99 | ret = 0; |
98 | 100 | ||
diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c index 18a91fae6bc1..778addc5caff 100644 --- a/drivers/media/usb/uvc/uvc_queue.c +++ b/drivers/media/usb/uvc/uvc_queue.c | |||
@@ -128,7 +128,7 @@ int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, | |||
128 | int ret; | 128 | int ret; |
129 | 129 | ||
130 | queue->queue.type = type; | 130 | queue->queue.type = type; |
131 | queue->queue.io_modes = VB2_MMAP | VB2_USERPTR; | 131 | queue->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; |
132 | queue->queue.drv_priv = queue; | 132 | queue->queue.drv_priv = queue; |
133 | queue->queue.buf_struct_size = sizeof(struct uvc_buffer); | 133 | queue->queue.buf_struct_size = sizeof(struct uvc_buffer); |
134 | queue->queue.ops = &uvc_queue_qops; | 134 | queue->queue.ops = &uvc_queue_qops; |
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index f00db3060e0e..8e056046bc20 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c | |||
@@ -165,17 +165,18 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream, | |||
165 | fcc[0], fcc[1], fcc[2], fcc[3], | 165 | fcc[0], fcc[1], fcc[2], fcc[3], |
166 | fmt->fmt.pix.width, fmt->fmt.pix.height); | 166 | fmt->fmt.pix.width, fmt->fmt.pix.height); |
167 | 167 | ||
168 | /* Check if the hardware supports the requested format. */ | 168 | /* Check if the hardware supports the requested format, use the default |
169 | * format otherwise. | ||
170 | */ | ||
169 | for (i = 0; i < stream->nformats; ++i) { | 171 | for (i = 0; i < stream->nformats; ++i) { |
170 | format = &stream->format[i]; | 172 | format = &stream->format[i]; |
171 | if (format->fcc == fmt->fmt.pix.pixelformat) | 173 | if (format->fcc == fmt->fmt.pix.pixelformat) |
172 | break; | 174 | break; |
173 | } | 175 | } |
174 | 176 | ||
175 | if (format == NULL || format->fcc != fmt->fmt.pix.pixelformat) { | 177 | if (i == stream->nformats) { |
176 | uvc_trace(UVC_TRACE_FORMAT, "Unsupported format 0x%08x.\n", | 178 | format = stream->def_format; |
177 | fmt->fmt.pix.pixelformat); | 179 | fmt->fmt.pix.pixelformat = format->fcc; |
178 | return -EINVAL; | ||
179 | } | 180 | } |
180 | 181 | ||
181 | /* Find the closest image size. The distance between image sizes is | 182 | /* Find the closest image size. The distance between image sizes is |
@@ -564,15 +565,30 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
564 | usb_make_path(stream->dev->udev, | 565 | usb_make_path(stream->dev->udev, |
565 | cap->bus_info, sizeof(cap->bus_info)); | 566 | cap->bus_info, sizeof(cap->bus_info)); |
566 | cap->version = LINUX_VERSION_CODE; | 567 | cap->version = LINUX_VERSION_CODE; |
568 | cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING | ||
569 | | chain->caps; | ||
567 | if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | 570 | if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
568 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | 571 | cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
569 | | V4L2_CAP_STREAMING; | 572 | | V4L2_CAP_STREAMING; |
570 | else | 573 | else |
571 | cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | 574 | cap->device_caps = V4L2_CAP_VIDEO_OUTPUT |
572 | | V4L2_CAP_STREAMING; | 575 | | V4L2_CAP_STREAMING; |
573 | break; | 576 | break; |
574 | } | 577 | } |
575 | 578 | ||
579 | /* Priority */ | ||
580 | case VIDIOC_G_PRIORITY: | ||
581 | *(u32 *)arg = v4l2_prio_max(vdev->prio); | ||
582 | break; | ||
583 | |||
584 | case VIDIOC_S_PRIORITY: | ||
585 | ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); | ||
586 | if (ret < 0) | ||
587 | return ret; | ||
588 | |||
589 | return v4l2_prio_change(vdev->prio, &handle->vfh.prio, | ||
590 | *(u32 *)arg); | ||
591 | |||
576 | /* Get, Set & Query control */ | 592 | /* Get, Set & Query control */ |
577 | case VIDIOC_QUERYCTRL: | 593 | case VIDIOC_QUERYCTRL: |
578 | return uvc_query_v4l2_ctrl(chain, arg); | 594 | return uvc_query_v4l2_ctrl(chain, arg); |
@@ -591,8 +607,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
591 | 607 | ||
592 | ret = uvc_ctrl_get(chain, &xctrl); | 608 | ret = uvc_ctrl_get(chain, &xctrl); |
593 | uvc_ctrl_rollback(handle); | 609 | uvc_ctrl_rollback(handle); |
594 | if (ret >= 0) | 610 | if (ret < 0) |
595 | ctrl->value = xctrl.value; | 611 | return ret == -ENOENT ? -EINVAL : ret; |
612 | |||
613 | ctrl->value = xctrl.value; | ||
596 | break; | 614 | break; |
597 | } | 615 | } |
598 | 616 | ||
@@ -601,6 +619,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
601 | struct v4l2_control *ctrl = arg; | 619 | struct v4l2_control *ctrl = arg; |
602 | struct v4l2_ext_control xctrl; | 620 | struct v4l2_ext_control xctrl; |
603 | 621 | ||
622 | ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); | ||
623 | if (ret < 0) | ||
624 | return ret; | ||
625 | |||
604 | memset(&xctrl, 0, sizeof xctrl); | 626 | memset(&xctrl, 0, sizeof xctrl); |
605 | xctrl.id = ctrl->id; | 627 | xctrl.id = ctrl->id; |
606 | xctrl.value = ctrl->value; | 628 | xctrl.value = ctrl->value; |
@@ -612,7 +634,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
612 | ret = uvc_ctrl_set(chain, &xctrl); | 634 | ret = uvc_ctrl_set(chain, &xctrl); |
613 | if (ret < 0) { | 635 | if (ret < 0) { |
614 | uvc_ctrl_rollback(handle); | 636 | uvc_ctrl_rollback(handle); |
615 | return ret; | 637 | return ret == -ENOENT ? -EINVAL : ret; |
616 | } | 638 | } |
617 | ret = uvc_ctrl_commit(handle, &xctrl, 1); | 639 | ret = uvc_ctrl_commit(handle, &xctrl, 1); |
618 | if (ret == 0) | 640 | if (ret == 0) |
@@ -637,8 +659,9 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
637 | ret = uvc_ctrl_get(chain, ctrl); | 659 | ret = uvc_ctrl_get(chain, ctrl); |
638 | if (ret < 0) { | 660 | if (ret < 0) { |
639 | uvc_ctrl_rollback(handle); | 661 | uvc_ctrl_rollback(handle); |
640 | ctrls->error_idx = i; | 662 | ctrls->error_idx = ret == -ENOENT |
641 | return ret; | 663 | ? ctrls->count : i; |
664 | return ret == -ENOENT ? -EINVAL : ret; | ||
642 | } | 665 | } |
643 | } | 666 | } |
644 | ctrls->error_idx = 0; | 667 | ctrls->error_idx = 0; |
@@ -647,6 +670,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
647 | } | 670 | } |
648 | 671 | ||
649 | case VIDIOC_S_EXT_CTRLS: | 672 | case VIDIOC_S_EXT_CTRLS: |
673 | ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); | ||
674 | if (ret < 0) | ||
675 | return ret; | ||
676 | /* Fall through */ | ||
650 | case VIDIOC_TRY_EXT_CTRLS: | 677 | case VIDIOC_TRY_EXT_CTRLS: |
651 | { | 678 | { |
652 | struct v4l2_ext_controls *ctrls = arg; | 679 | struct v4l2_ext_controls *ctrls = arg; |
@@ -661,8 +688,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
661 | ret = uvc_ctrl_set(chain, ctrl); | 688 | ret = uvc_ctrl_set(chain, ctrl); |
662 | if (ret < 0) { | 689 | if (ret < 0) { |
663 | uvc_ctrl_rollback(handle); | 690 | uvc_ctrl_rollback(handle); |
664 | ctrls->error_idx = i; | 691 | ctrls->error_idx = (ret == -ENOENT && |
665 | return ret; | 692 | cmd == VIDIOC_S_EXT_CTRLS) |
693 | ? ctrls->count : i; | ||
694 | return ret == -ENOENT ? -EINVAL : ret; | ||
666 | } | 695 | } |
667 | } | 696 | } |
668 | 697 | ||
@@ -739,6 +768,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
739 | { | 768 | { |
740 | u32 input = *(u32 *)arg + 1; | 769 | u32 input = *(u32 *)arg + 1; |
741 | 770 | ||
771 | ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); | ||
772 | if (ret < 0) | ||
773 | return ret; | ||
774 | |||
742 | if ((ret = uvc_acquire_privileges(handle)) < 0) | 775 | if ((ret = uvc_acquire_privileges(handle)) < 0) |
743 | return ret; | 776 | return ret; |
744 | 777 | ||
@@ -792,6 +825,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
792 | } | 825 | } |
793 | 826 | ||
794 | case VIDIOC_S_FMT: | 827 | case VIDIOC_S_FMT: |
828 | ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); | ||
829 | if (ret < 0) | ||
830 | return ret; | ||
831 | |||
795 | if ((ret = uvc_acquire_privileges(handle)) < 0) | 832 | if ((ret = uvc_acquire_privileges(handle)) < 0) |
796 | return ret; | 833 | return ret; |
797 | 834 | ||
@@ -894,6 +931,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
894 | return uvc_v4l2_get_streamparm(stream, arg); | 931 | return uvc_v4l2_get_streamparm(stream, arg); |
895 | 932 | ||
896 | case VIDIOC_S_PARM: | 933 | case VIDIOC_S_PARM: |
934 | ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); | ||
935 | if (ret < 0) | ||
936 | return ret; | ||
937 | |||
897 | if ((ret = uvc_acquire_privileges(handle)) < 0) | 938 | if ((ret = uvc_acquire_privileges(handle)) < 0) |
898 | return ret; | 939 | return ret; |
899 | 940 | ||
@@ -924,10 +965,14 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
924 | 965 | ||
925 | case VIDIOC_G_CROP: | 966 | case VIDIOC_G_CROP: |
926 | case VIDIOC_S_CROP: | 967 | case VIDIOC_S_CROP: |
927 | return -EINVAL; | 968 | return -ENOTTY; |
928 | 969 | ||
929 | /* Buffers & streaming */ | 970 | /* Buffers & streaming */ |
930 | case VIDIOC_REQBUFS: | 971 | case VIDIOC_REQBUFS: |
972 | ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); | ||
973 | if (ret < 0) | ||
974 | return ret; | ||
975 | |||
931 | if ((ret = uvc_acquire_privileges(handle)) < 0) | 976 | if ((ret = uvc_acquire_privileges(handle)) < 0) |
932 | return ret; | 977 | return ret; |
933 | 978 | ||
@@ -973,6 +1018,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
973 | if (*type != stream->type) | 1018 | if (*type != stream->type) |
974 | return -EINVAL; | 1019 | return -EINVAL; |
975 | 1020 | ||
1021 | ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); | ||
1022 | if (ret < 0) | ||
1023 | return ret; | ||
1024 | |||
976 | if (!uvc_has_privileges(handle)) | 1025 | if (!uvc_has_privileges(handle)) |
977 | return -EBUSY; | 1026 | return -EBUSY; |
978 | 1027 | ||
@@ -991,6 +1040,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
991 | if (*type != stream->type) | 1040 | if (*type != stream->type) |
992 | return -EINVAL; | 1041 | return -EINVAL; |
993 | 1042 | ||
1043 | ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); | ||
1044 | if (ret < 0) | ||
1045 | return ret; | ||
1046 | |||
994 | if (!uvc_has_privileges(handle)) | 1047 | if (!uvc_has_privileges(handle)) |
995 | return -EBUSY; | 1048 | return -EBUSY; |
996 | 1049 | ||
@@ -1030,7 +1083,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1030 | 1083 | ||
1031 | case VIDIOC_ENUMOUTPUT: | 1084 | case VIDIOC_ENUMOUTPUT: |
1032 | uvc_trace(UVC_TRACE_IOCTL, "Unsupported ioctl 0x%08x\n", cmd); | 1085 | uvc_trace(UVC_TRACE_IOCTL, "Unsupported ioctl 0x%08x\n", cmd); |
1033 | return -EINVAL; | 1086 | return -ENOTTY; |
1034 | 1087 | ||
1035 | case UVCIOC_CTRL_MAP: | 1088 | case UVCIOC_CTRL_MAP: |
1036 | return uvc_ioctl_ctrl_map(chain, arg); | 1089 | return uvc_ioctl_ctrl_map(chain, arg); |
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index 57c3076a4625..3394c3432011 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c | |||
@@ -1812,6 +1812,7 @@ int uvc_video_init(struct uvc_streaming *stream) | |||
1812 | probe->bFormatIndex = format->index; | 1812 | probe->bFormatIndex = format->index; |
1813 | probe->bFrameIndex = frame->bFrameIndex; | 1813 | probe->bFrameIndex = frame->bFrameIndex; |
1814 | 1814 | ||
1815 | stream->def_format = format; | ||
1815 | stream->cur_format = format; | 1816 | stream->cur_format = format; |
1816 | stream->cur_frame = frame; | 1817 | stream->cur_frame = frame; |
1817 | 1818 | ||
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index af216ec45e39..af505fdd9b3f 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h | |||
@@ -225,10 +225,14 @@ struct uvc_format_desc { | |||
225 | * always be accessed with the UVC_ENTITY_* macros and never directly. | 225 | * always be accessed with the UVC_ENTITY_* macros and never directly. |
226 | */ | 226 | */ |
227 | 227 | ||
228 | #define UVC_ENTITY_FLAG_DEFAULT (1 << 0) | ||
229 | |||
228 | struct uvc_entity { | 230 | struct uvc_entity { |
229 | struct list_head list; /* Entity as part of a UVC device. */ | 231 | struct list_head list; /* Entity as part of a UVC device. */ |
230 | struct list_head chain; /* Entity as part of a video device | 232 | struct list_head chain; /* Entity as part of a video device |
231 | * chain. */ | 233 | * chain. */ |
234 | unsigned int flags; | ||
235 | |||
232 | __u8 id; | 236 | __u8 id; |
233 | __u16 type; | 237 | __u16 type; |
234 | char name[64]; | 238 | char name[64]; |
@@ -371,6 +375,9 @@ struct uvc_video_chain { | |||
371 | struct uvc_entity *selector; /* Selector unit */ | 375 | struct uvc_entity *selector; /* Selector unit */ |
372 | 376 | ||
373 | struct mutex ctrl_mutex; /* Protects ctrl.info */ | 377 | struct mutex ctrl_mutex; /* Protects ctrl.info */ |
378 | |||
379 | struct v4l2_prio_state prio; /* V4L2 priority state */ | ||
380 | u32 caps; /* V4L2 chain-wide caps */ | ||
374 | }; | 381 | }; |
375 | 382 | ||
376 | struct uvc_stats_frame { | 383 | struct uvc_stats_frame { |
@@ -436,6 +443,7 @@ struct uvc_streaming { | |||
436 | struct uvc_format *format; | 443 | struct uvc_format *format; |
437 | 444 | ||
438 | struct uvc_streaming_control ctrl; | 445 | struct uvc_streaming_control ctrl; |
446 | struct uvc_format *def_format; | ||
439 | struct uvc_format *cur_format; | 447 | struct uvc_format *cur_format; |
440 | struct uvc_frame *cur_frame; | 448 | struct uvc_frame *cur_frame; |
441 | /* Protect access to ctrl, cur_format, cur_frame and hardware video | 449 | /* Protect access to ctrl, cur_format, cur_frame and hardware video |