aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/v4l1-compat.c
diff options
context:
space:
mode:
authorTrent Piepho <xyzzy@speakeasy.org>2007-04-27 21:56:29 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-05-09 09:13:09 -0400
commitbbe2486fe3bd6c7cffaf4123b7e86a55c209ed44 (patch)
tree09520b7aaf5d491a0f954fc8f038d0806663ac5d /drivers/media/video/v4l1-compat.c
parent9d3eb99b36c73843cd73f45dad8ca9dde1ce3888 (diff)
V4L/DVB (5571): V4l1-compat: Make VIDIOCSPICT return errors in a useful way
Among other things, VIDIOCSPICT sets the pixel format. Some drivers don't support all formats, e.g. cx88 doesn't support the planar formats. The compat code that translates VIDIOCSPICT into V4L2 ioctls doesn't pass on any errors, so a userspace program doesn't know if it has selected an unsupported pixel format. VIDIOCSPICT sets both the memory capture and overlay formats, and it's possible that one will be set while the other will fail, e.g. cx88 doesn't even support overlay. Also, trying to set the overlay format will fail for non-root users. Signed-off-by: Trent Piepho <xyzzy@speakeasy.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/v4l1-compat.c')
-rw-r--r--drivers/media/video/v4l1-compat.c54
1 files changed, 41 insertions, 13 deletions
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index efb67d29fc0b..ede8543818bf 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -616,6 +616,8 @@ v4l_compat_translate_ioctl(struct inode *inode,
616 case VIDIOCSPICT: /* set tone controls & partial capture format */ 616 case VIDIOCSPICT: /* set tone controls & partial capture format */
617 { 617 {
618 struct video_picture *pict = arg; 618 struct video_picture *pict = arg;
619 int mem_err = 0, ovl_err = 0;
620
619 memset(&fbuf2, 0, sizeof(fbuf2)); 621 memset(&fbuf2, 0, sizeof(fbuf2));
620 622
621 set_v4l_control(inode, file, 623 set_v4l_control(inode, file,
@@ -628,33 +630,59 @@ v4l_compat_translate_ioctl(struct inode *inode,
628 V4L2_CID_SATURATION, pict->colour, drv); 630 V4L2_CID_SATURATION, pict->colour, drv);
629 set_v4l_control(inode, file, 631 set_v4l_control(inode, file,
630 V4L2_CID_WHITENESS, pict->whiteness, drv); 632 V4L2_CID_WHITENESS, pict->whiteness, drv);
633 /*
634 * V4L1 uses this ioctl to set both memory capture and overlay
635 * pixel format, while V4L2 has two different ioctls for this.
636 * Some cards may not support one or the other, and may support
637 * different pixel formats for memory vs overlay.
638 */
631 639
632 fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL); 640 fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
633 fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 641 fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
634 err = drv(inode, file, VIDIOC_G_FMT, fmt2); 642 err = drv(inode, file, VIDIOC_G_FMT, fmt2);
635 if (err < 0) 643 /* If VIDIOC_G_FMT failed, then the driver likely doesn't
644 support memory capture. Trying to set the memory capture
645 parameters would be pointless. */
646 if (err < 0) {
636 dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n",err); 647 dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n",err);
637 if (fmt2->fmt.pix.pixelformat != 648 mem_err = -1000; /* didn't even try */
638 palette_to_pixelformat(pict->palette)) { 649 } else if (fmt2->fmt.pix.pixelformat !=
650 palette_to_pixelformat(pict->palette)) {
639 fmt2->fmt.pix.pixelformat = palette_to_pixelformat( 651 fmt2->fmt.pix.pixelformat = palette_to_pixelformat(
640 pict->palette); 652 pict->palette);
641 err = drv(inode, file, VIDIOC_S_FMT, fmt2); 653 mem_err = drv(inode, file, VIDIOC_S_FMT, fmt2);
642 if (err < 0) 654 if (mem_err < 0)
643 dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",err); 655 dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",
656 mem_err);
644 } 657 }
645 658
646 err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2); 659 err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
647 if (err < 0) 660 /* If VIDIOC_G_FBUF failed, then the driver likely doesn't
661 support overlay. Trying to set the overlay parameters
662 would be quite pointless. */
663 if (err < 0) {
648 dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n",err); 664 dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n",err);
649 if (fbuf2.fmt.pixelformat != 665 ovl_err = -1000; /* didn't even try */
650 palette_to_pixelformat(pict->palette)) { 666 } else if (fbuf2.fmt.pixelformat !=
667 palette_to_pixelformat(pict->palette)) {
651 fbuf2.fmt.pixelformat = palette_to_pixelformat( 668 fbuf2.fmt.pixelformat = palette_to_pixelformat(
652 pict->palette); 669 pict->palette);
653 err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2); 670 ovl_err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2);
654 if (err < 0) 671 if (ovl_err < 0)
655 dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",err); 672 dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",
656 err = 0; /* likely fails for non-root */ 673 ovl_err);
657 } 674 }
675 if (ovl_err < 0 && mem_err < 0)
676 /* ioctl failed, couldn't set either parameter */
677 if (mem_err != -1000) {
678 err = mem_err;
679 } else if (ovl_err == -EPERM) {
680 err = 0;
681 } else {
682 err = ovl_err;
683 }
684 else
685 err = 0;
658 break; 686 break;
659 } 687 }
660 case VIDIOCGTUNER: /* get tuner information */ 688 case VIDIOCGTUNER: /* get tuner information */