diff options
Diffstat (limited to 'drivers/media/video/v4l2-ioctl.c')
| -rw-r--r-- | drivers/media/video/v4l2-ioctl.c | 559 |
1 files changed, 238 insertions, 321 deletions
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 002ce1363443..e1da8fc9dd2f 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c | |||
| @@ -55,6 +55,19 @@ | |||
| 55 | memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \ | 55 | memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \ |
| 56 | 0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field)) | 56 | 0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field)) |
| 57 | 57 | ||
| 58 | #define have_fmt_ops(foo) ( \ | ||
| 59 | ops->vidioc_##foo##_fmt_vid_cap || \ | ||
| 60 | ops->vidioc_##foo##_fmt_vid_out || \ | ||
| 61 | ops->vidioc_##foo##_fmt_vid_cap_mplane || \ | ||
| 62 | ops->vidioc_##foo##_fmt_vid_out_mplane || \ | ||
| 63 | ops->vidioc_##foo##_fmt_vid_overlay || \ | ||
| 64 | ops->vidioc_##foo##_fmt_vbi_cap || \ | ||
| 65 | ops->vidioc_##foo##_fmt_vid_out_overlay || \ | ||
| 66 | ops->vidioc_##foo##_fmt_vbi_out || \ | ||
| 67 | ops->vidioc_##foo##_fmt_sliced_vbi_cap || \ | ||
| 68 | ops->vidioc_##foo##_fmt_sliced_vbi_out || \ | ||
| 69 | ops->vidioc_##foo##_fmt_type_private) | ||
| 70 | |||
| 58 | struct std_descr { | 71 | struct std_descr { |
| 59 | v4l2_std_id std; | 72 | v4l2_std_id std; |
| 60 | const char *descr; | 73 | const char *descr; |
| @@ -260,6 +273,8 @@ static const char *v4l2_ioctls[] = { | |||
| 260 | [_IOC_NR(VIDIOC_DQEVENT)] = "VIDIOC_DQEVENT", | 273 | [_IOC_NR(VIDIOC_DQEVENT)] = "VIDIOC_DQEVENT", |
| 261 | [_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)] = "VIDIOC_SUBSCRIBE_EVENT", | 274 | [_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)] = "VIDIOC_SUBSCRIBE_EVENT", |
| 262 | [_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT", | 275 | [_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT", |
| 276 | [_IOC_NR(VIDIOC_CREATE_BUFS)] = "VIDIOC_CREATE_BUFS", | ||
| 277 | [_IOC_NR(VIDIOC_PREPARE_BUF)] = "VIDIOC_PREPARE_BUF", | ||
| 263 | }; | 278 | }; |
| 264 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) | 279 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) |
| 265 | 280 | ||
| @@ -477,63 +492,6 @@ static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type) | |||
| 477 | return -EINVAL; | 492 | return -EINVAL; |
| 478 | } | 493 | } |
| 479 | 494 | ||
| 480 | /** | ||
| 481 | * fmt_sp_to_mp() - Convert a single-plane format to its multi-planar 1-plane | ||
| 482 | * equivalent | ||
| 483 | */ | ||
| 484 | static int fmt_sp_to_mp(const struct v4l2_format *f_sp, | ||
| 485 | struct v4l2_format *f_mp) | ||
| 486 | { | ||
| 487 | struct v4l2_pix_format_mplane *pix_mp = &f_mp->fmt.pix_mp; | ||
| 488 | const struct v4l2_pix_format *pix = &f_sp->fmt.pix; | ||
| 489 | |||
| 490 | if (f_sp->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
| 491 | f_mp->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | ||
| 492 | else if (f_sp->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) | ||
| 493 | f_mp->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | ||
| 494 | else | ||
| 495 | return -EINVAL; | ||
| 496 | |||
| 497 | pix_mp->width = pix->width; | ||
| 498 | pix_mp->height = pix->height; | ||
| 499 | pix_mp->pixelformat = pix->pixelformat; | ||
| 500 | pix_mp->field = pix->field; | ||
| 501 | pix_mp->colorspace = pix->colorspace; | ||
| 502 | pix_mp->num_planes = 1; | ||
| 503 | pix_mp->plane_fmt[0].sizeimage = pix->sizeimage; | ||
| 504 | pix_mp->plane_fmt[0].bytesperline = pix->bytesperline; | ||
| 505 | |||
| 506 | return 0; | ||
| 507 | } | ||
| 508 | |||
| 509 | /** | ||
| 510 | * fmt_mp_to_sp() - Convert a multi-planar 1-plane format to its single-planar | ||
| 511 | * equivalent | ||
| 512 | */ | ||
| 513 | static int fmt_mp_to_sp(const struct v4l2_format *f_mp, | ||
| 514 | struct v4l2_format *f_sp) | ||
| 515 | { | ||
| 516 | const struct v4l2_pix_format_mplane *pix_mp = &f_mp->fmt.pix_mp; | ||
| 517 | struct v4l2_pix_format *pix = &f_sp->fmt.pix; | ||
| 518 | |||
| 519 | if (f_mp->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) | ||
| 520 | f_sp->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
| 521 | else if (f_mp->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) | ||
| 522 | f_sp->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; | ||
| 523 | else | ||
| 524 | return -EINVAL; | ||
| 525 | |||
| 526 | pix->width = pix_mp->width; | ||
| 527 | pix->height = pix_mp->height; | ||
| 528 | pix->pixelformat = pix_mp->pixelformat; | ||
| 529 | pix->field = pix_mp->field; | ||
| 530 | pix->colorspace = pix_mp->colorspace; | ||
| 531 | pix->sizeimage = pix_mp->plane_fmt[0].sizeimage; | ||
| 532 | pix->bytesperline = pix_mp->plane_fmt[0].bytesperline; | ||
| 533 | |||
| 534 | return 0; | ||
| 535 | } | ||
| 536 | |||
| 537 | static long __video_do_ioctl(struct file *file, | 495 | static long __video_do_ioctl(struct file *file, |
| 538 | unsigned int cmd, void *arg) | 496 | unsigned int cmd, void *arg) |
| 539 | { | 497 | { |
| @@ -541,8 +499,8 @@ static long __video_do_ioctl(struct file *file, | |||
| 541 | const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; | 499 | const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; |
| 542 | void *fh = file->private_data; | 500 | void *fh = file->private_data; |
| 543 | struct v4l2_fh *vfh = NULL; | 501 | struct v4l2_fh *vfh = NULL; |
| 544 | struct v4l2_format f_copy; | ||
| 545 | int use_fh_prio = 0; | 502 | int use_fh_prio = 0; |
| 503 | long ret_prio = 0; | ||
| 546 | long ret = -ENOTTY; | 504 | long ret = -ENOTTY; |
| 547 | 505 | ||
| 548 | if (ops == NULL) { | 506 | if (ops == NULL) { |
| @@ -562,39 +520,8 @@ static long __video_do_ioctl(struct file *file, | |||
| 562 | use_fh_prio = test_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); | 520 | use_fh_prio = test_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); |
| 563 | } | 521 | } |
| 564 | 522 | ||
| 565 | if (use_fh_prio) { | 523 | if (use_fh_prio) |
| 566 | switch (cmd) { | 524 | ret_prio = v4l2_prio_check(vfd->prio, vfh->prio); |
| 567 | case VIDIOC_S_CTRL: | ||
| 568 | case VIDIOC_S_STD: | ||
| 569 | case VIDIOC_S_INPUT: | ||
| 570 | case VIDIOC_S_OUTPUT: | ||
| 571 | case VIDIOC_S_TUNER: | ||
| 572 | case VIDIOC_S_FREQUENCY: | ||
| 573 | case VIDIOC_S_FMT: | ||
| 574 | case VIDIOC_S_CROP: | ||
| 575 | case VIDIOC_S_AUDIO: | ||
| 576 | case VIDIOC_S_AUDOUT: | ||
| 577 | case VIDIOC_S_EXT_CTRLS: | ||
| 578 | case VIDIOC_S_FBUF: | ||
| 579 | case VIDIOC_S_PRIORITY: | ||
| 580 | case VIDIOC_S_DV_PRESET: | ||
| 581 | case VIDIOC_S_DV_TIMINGS: | ||
| 582 | case VIDIOC_S_JPEGCOMP: | ||
| 583 | case VIDIOC_S_MODULATOR: | ||
| 584 | case VIDIOC_S_PARM: | ||
| 585 | case VIDIOC_S_HW_FREQ_SEEK: | ||
| 586 | case VIDIOC_ENCODER_CMD: | ||
| 587 | case VIDIOC_OVERLAY: | ||
| 588 | case VIDIOC_REQBUFS: | ||
| 589 | case VIDIOC_STREAMON: | ||
| 590 | case VIDIOC_STREAMOFF: | ||
| 591 | ret = v4l2_prio_check(vfd->prio, vfh->prio); | ||
| 592 | if (ret) | ||
| 593 | goto exit_prio; | ||
| 594 | ret = -EINVAL; | ||
| 595 | break; | ||
| 596 | } | ||
| 597 | } | ||
| 598 | 525 | ||
| 599 | switch (cmd) { | 526 | switch (cmd) { |
| 600 | 527 | ||
| @@ -638,12 +565,14 @@ static long __video_do_ioctl(struct file *file, | |||
| 638 | enum v4l2_priority *p = arg; | 565 | enum v4l2_priority *p = arg; |
| 639 | 566 | ||
| 640 | if (!ops->vidioc_s_priority && !use_fh_prio) | 567 | if (!ops->vidioc_s_priority && !use_fh_prio) |
| 641 | break; | 568 | break; |
| 642 | dbgarg(cmd, "setting priority to %d\n", *p); | 569 | dbgarg(cmd, "setting priority to %d\n", *p); |
| 643 | if (ops->vidioc_s_priority) | 570 | if (ops->vidioc_s_priority) |
| 644 | ret = ops->vidioc_s_priority(file, fh, *p); | 571 | ret = ops->vidioc_s_priority(file, fh, *p); |
| 645 | else | 572 | else |
| 646 | ret = v4l2_prio_change(&vfd->v4l2_dev->prio, &vfh->prio, *p); | 573 | ret = ret_prio ? ret_prio : |
| 574 | v4l2_prio_change(&vfd->v4l2_dev->prio, | ||
| 575 | &vfh->prio, *p); | ||
| 647 | break; | 576 | break; |
| 648 | } | 577 | } |
| 649 | 578 | ||
| @@ -654,37 +583,37 @@ static long __video_do_ioctl(struct file *file, | |||
| 654 | 583 | ||
| 655 | switch (f->type) { | 584 | switch (f->type) { |
| 656 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 585 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
| 657 | if (ops->vidioc_enum_fmt_vid_cap) | 586 | if (likely(ops->vidioc_enum_fmt_vid_cap)) |
| 658 | ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f); | 587 | ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f); |
| 659 | break; | 588 | break; |
| 660 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: | 589 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
| 661 | if (ops->vidioc_enum_fmt_vid_cap_mplane) | 590 | if (likely(ops->vidioc_enum_fmt_vid_cap_mplane)) |
| 662 | ret = ops->vidioc_enum_fmt_vid_cap_mplane(file, | 591 | ret = ops->vidioc_enum_fmt_vid_cap_mplane(file, |
| 663 | fh, f); | 592 | fh, f); |
| 664 | break; | 593 | break; |
| 665 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 594 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
| 666 | if (ops->vidioc_enum_fmt_vid_overlay) | 595 | if (likely(ops->vidioc_enum_fmt_vid_overlay)) |
| 667 | ret = ops->vidioc_enum_fmt_vid_overlay(file, | 596 | ret = ops->vidioc_enum_fmt_vid_overlay(file, |
| 668 | fh, f); | 597 | fh, f); |
| 669 | break; | 598 | break; |
| 670 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | 599 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
| 671 | if (ops->vidioc_enum_fmt_vid_out) | 600 | if (likely(ops->vidioc_enum_fmt_vid_out)) |
| 672 | ret = ops->vidioc_enum_fmt_vid_out(file, fh, f); | 601 | ret = ops->vidioc_enum_fmt_vid_out(file, fh, f); |
| 673 | break; | 602 | break; |
| 674 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: | 603 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
| 675 | if (ops->vidioc_enum_fmt_vid_out_mplane) | 604 | if (likely(ops->vidioc_enum_fmt_vid_out_mplane)) |
| 676 | ret = ops->vidioc_enum_fmt_vid_out_mplane(file, | 605 | ret = ops->vidioc_enum_fmt_vid_out_mplane(file, |
| 677 | fh, f); | 606 | fh, f); |
| 678 | break; | 607 | break; |
| 679 | case V4L2_BUF_TYPE_PRIVATE: | 608 | case V4L2_BUF_TYPE_PRIVATE: |
| 680 | if (ops->vidioc_enum_fmt_type_private) | 609 | if (likely(ops->vidioc_enum_fmt_type_private)) |
| 681 | ret = ops->vidioc_enum_fmt_type_private(file, | 610 | ret = ops->vidioc_enum_fmt_type_private(file, |
| 682 | fh, f); | 611 | fh, f); |
| 683 | break; | 612 | break; |
| 684 | default: | 613 | default: |
| 685 | break; | 614 | break; |
| 686 | } | 615 | } |
| 687 | if (!ret) | 616 | if (likely (!ret)) |
| 688 | dbgarg(cmd, "index=%d, type=%d, flags=%d, " | 617 | dbgarg(cmd, "index=%d, type=%d, flags=%d, " |
| 689 | "pixelformat=%c%c%c%c, description='%s'\n", | 618 | "pixelformat=%c%c%c%c, description='%s'\n", |
| 690 | f->index, f->type, f->flags, | 619 | f->index, f->type, f->flags, |
| @@ -693,6 +622,14 @@ static long __video_do_ioctl(struct file *file, | |||
| 693 | (f->pixelformat >> 16) & 0xff, | 622 | (f->pixelformat >> 16) & 0xff, |
| 694 | (f->pixelformat >> 24) & 0xff, | 623 | (f->pixelformat >> 24) & 0xff, |
| 695 | f->description); | 624 | f->description); |
| 625 | else if (ret == -ENOTTY && | ||
| 626 | (ops->vidioc_enum_fmt_vid_cap || | ||
| 627 | ops->vidioc_enum_fmt_vid_out || | ||
| 628 | ops->vidioc_enum_fmt_vid_cap_mplane || | ||
| 629 | ops->vidioc_enum_fmt_vid_out_mplane || | ||
| 630 | ops->vidioc_enum_fmt_vid_overlay || | ||
| 631 | ops->vidioc_enum_fmt_type_private)) | ||
| 632 | ret = -EINVAL; | ||
| 696 | break; | 633 | break; |
| 697 | } | 634 | } |
| 698 | case VIDIOC_G_FMT: | 635 | case VIDIOC_G_FMT: |
| @@ -704,119 +641,67 @@ static long __video_do_ioctl(struct file *file, | |||
| 704 | 641 | ||
| 705 | switch (f->type) { | 642 | switch (f->type) { |
| 706 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 643 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
| 707 | if (ops->vidioc_g_fmt_vid_cap) { | 644 | if (ops->vidioc_g_fmt_vid_cap) |
| 708 | ret = ops->vidioc_g_fmt_vid_cap(file, fh, f); | 645 | ret = ops->vidioc_g_fmt_vid_cap(file, fh, f); |
| 709 | } else if (ops->vidioc_g_fmt_vid_cap_mplane) { | ||
| 710 | if (fmt_sp_to_mp(f, &f_copy)) | ||
| 711 | break; | ||
| 712 | ret = ops->vidioc_g_fmt_vid_cap_mplane(file, fh, | ||
| 713 | &f_copy); | ||
| 714 | if (ret) | ||
| 715 | break; | ||
| 716 | |||
| 717 | /* Driver is currently in multi-planar format, | ||
| 718 | * we can't return it in single-planar API*/ | ||
| 719 | if (f_copy.fmt.pix_mp.num_planes > 1) { | ||
| 720 | ret = -EBUSY; | ||
| 721 | break; | ||
| 722 | } | ||
| 723 | |||
| 724 | ret = fmt_mp_to_sp(&f_copy, f); | ||
| 725 | } | ||
| 726 | if (!ret) | 646 | if (!ret) |
| 727 | v4l_print_pix_fmt(vfd, &f->fmt.pix); | 647 | v4l_print_pix_fmt(vfd, &f->fmt.pix); |
| 728 | break; | 648 | break; |
| 729 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: | 649 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
| 730 | if (ops->vidioc_g_fmt_vid_cap_mplane) { | 650 | if (ops->vidioc_g_fmt_vid_cap_mplane) |
| 731 | ret = ops->vidioc_g_fmt_vid_cap_mplane(file, | 651 | ret = ops->vidioc_g_fmt_vid_cap_mplane(file, |
| 732 | fh, f); | 652 | fh, f); |
| 733 | } else if (ops->vidioc_g_fmt_vid_cap) { | ||
| 734 | if (fmt_mp_to_sp(f, &f_copy)) | ||
| 735 | break; | ||
| 736 | ret = ops->vidioc_g_fmt_vid_cap(file, | ||
| 737 | fh, &f_copy); | ||
| 738 | if (ret) | ||
| 739 | break; | ||
| 740 | |||
| 741 | ret = fmt_sp_to_mp(&f_copy, f); | ||
| 742 | } | ||
| 743 | if (!ret) | 653 | if (!ret) |
| 744 | v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp); | 654 | v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp); |
| 745 | break; | 655 | break; |
| 746 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 656 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
| 747 | if (ops->vidioc_g_fmt_vid_overlay) | 657 | if (likely(ops->vidioc_g_fmt_vid_overlay)) |
| 748 | ret = ops->vidioc_g_fmt_vid_overlay(file, | 658 | ret = ops->vidioc_g_fmt_vid_overlay(file, |
| 749 | fh, f); | 659 | fh, f); |
| 750 | break; | 660 | break; |
| 751 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | 661 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
| 752 | if (ops->vidioc_g_fmt_vid_out) { | 662 | if (ops->vidioc_g_fmt_vid_out) |
| 753 | ret = ops->vidioc_g_fmt_vid_out(file, fh, f); | 663 | ret = ops->vidioc_g_fmt_vid_out(file, fh, f); |
| 754 | } else if (ops->vidioc_g_fmt_vid_out_mplane) { | ||
| 755 | if (fmt_sp_to_mp(f, &f_copy)) | ||
| 756 | break; | ||
| 757 | ret = ops->vidioc_g_fmt_vid_out_mplane(file, fh, | ||
| 758 | &f_copy); | ||
| 759 | if (ret) | ||
| 760 | break; | ||
| 761 | |||
| 762 | /* Driver is currently in multi-planar format, | ||
| 763 | * we can't return it in single-planar API*/ | ||
| 764 | if (f_copy.fmt.pix_mp.num_planes > 1) { | ||
| 765 | ret = -EBUSY; | ||
| 766 | break; | ||
| 767 | } | ||
| 768 | |||
| 769 | ret = fmt_mp_to_sp(&f_copy, f); | ||
| 770 | } | ||
| 771 | if (!ret) | 664 | if (!ret) |
| 772 | v4l_print_pix_fmt(vfd, &f->fmt.pix); | 665 | v4l_print_pix_fmt(vfd, &f->fmt.pix); |
| 773 | break; | 666 | break; |
| 774 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: | 667 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
| 775 | if (ops->vidioc_g_fmt_vid_out_mplane) { | 668 | if (ops->vidioc_g_fmt_vid_out_mplane) |
| 776 | ret = ops->vidioc_g_fmt_vid_out_mplane(file, | 669 | ret = ops->vidioc_g_fmt_vid_out_mplane(file, |
| 777 | fh, f); | 670 | fh, f); |
| 778 | } else if (ops->vidioc_g_fmt_vid_out) { | ||
| 779 | if (fmt_mp_to_sp(f, &f_copy)) | ||
| 780 | break; | ||
| 781 | ret = ops->vidioc_g_fmt_vid_out(file, | ||
| 782 | fh, &f_copy); | ||
| 783 | if (ret) | ||
| 784 | break; | ||
| 785 | |||
| 786 | ret = fmt_sp_to_mp(&f_copy, f); | ||
| 787 | } | ||
| 788 | if (!ret) | 671 | if (!ret) |
| 789 | v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp); | 672 | v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp); |
| 790 | break; | 673 | break; |
| 791 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: | 674 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: |
| 792 | if (ops->vidioc_g_fmt_vid_out_overlay) | 675 | if (likely(ops->vidioc_g_fmt_vid_out_overlay)) |
| 793 | ret = ops->vidioc_g_fmt_vid_out_overlay(file, | 676 | ret = ops->vidioc_g_fmt_vid_out_overlay(file, |
| 794 | fh, f); | 677 | fh, f); |
| 795 | break; | 678 | break; |
| 796 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 679 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
| 797 | if (ops->vidioc_g_fmt_vbi_cap) | 680 | if (likely(ops->vidioc_g_fmt_vbi_cap)) |
| 798 | ret = ops->vidioc_g_fmt_vbi_cap(file, fh, f); | 681 | ret = ops->vidioc_g_fmt_vbi_cap(file, fh, f); |
| 799 | break; | 682 | break; |
| 800 | case V4L2_BUF_TYPE_VBI_OUTPUT: | 683 | case V4L2_BUF_TYPE_VBI_OUTPUT: |
| 801 | if (ops->vidioc_g_fmt_vbi_out) | 684 | if (likely(ops->vidioc_g_fmt_vbi_out)) |
| 802 | ret = ops->vidioc_g_fmt_vbi_out(file, fh, f); | 685 | ret = ops->vidioc_g_fmt_vbi_out(file, fh, f); |
| 803 | break; | 686 | break; |
| 804 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | 687 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: |
| 805 | if (ops->vidioc_g_fmt_sliced_vbi_cap) | 688 | if (likely(ops->vidioc_g_fmt_sliced_vbi_cap)) |
| 806 | ret = ops->vidioc_g_fmt_sliced_vbi_cap(file, | 689 | ret = ops->vidioc_g_fmt_sliced_vbi_cap(file, |
| 807 | fh, f); | 690 | fh, f); |
| 808 | break; | 691 | break; |
| 809 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: | 692 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: |
| 810 | if (ops->vidioc_g_fmt_sliced_vbi_out) | 693 | if (likely(ops->vidioc_g_fmt_sliced_vbi_out)) |
| 811 | ret = ops->vidioc_g_fmt_sliced_vbi_out(file, | 694 | ret = ops->vidioc_g_fmt_sliced_vbi_out(file, |
| 812 | fh, f); | 695 | fh, f); |
| 813 | break; | 696 | break; |
| 814 | case V4L2_BUF_TYPE_PRIVATE: | 697 | case V4L2_BUF_TYPE_PRIVATE: |
| 815 | if (ops->vidioc_g_fmt_type_private) | 698 | if (likely(ops->vidioc_g_fmt_type_private)) |
| 816 | ret = ops->vidioc_g_fmt_type_private(file, | 699 | ret = ops->vidioc_g_fmt_type_private(file, |
| 817 | fh, f); | 700 | fh, f); |
| 818 | break; | 701 | break; |
| 819 | } | 702 | } |
| 703 | if (unlikely(ret == -ENOTTY && have_fmt_ops(g))) | ||
| 704 | ret = -EINVAL; | ||
| 820 | 705 | ||
| 821 | break; | 706 | break; |
| 822 | } | 707 | } |
| @@ -824,6 +709,14 @@ static long __video_do_ioctl(struct file *file, | |||
| 824 | { | 709 | { |
| 825 | struct v4l2_format *f = (struct v4l2_format *)arg; | 710 | struct v4l2_format *f = (struct v4l2_format *)arg; |
| 826 | 711 | ||
| 712 | if (!have_fmt_ops(s)) | ||
| 713 | break; | ||
| 714 | if (ret_prio) { | ||
| 715 | ret = ret_prio; | ||
| 716 | break; | ||
| 717 | } | ||
| 718 | ret = -EINVAL; | ||
| 719 | |||
| 827 | /* FIXME: Should be one dump per type */ | 720 | /* FIXME: Should be one dump per type */ |
| 828 | dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names)); | 721 | dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names)); |
| 829 | 722 | ||
| @@ -831,44 +724,15 @@ static long __video_do_ioctl(struct file *file, | |||
| 831 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 724 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
| 832 | CLEAR_AFTER_FIELD(f, fmt.pix); | 725 | CLEAR_AFTER_FIELD(f, fmt.pix); |
| 833 | v4l_print_pix_fmt(vfd, &f->fmt.pix); | 726 | v4l_print_pix_fmt(vfd, &f->fmt.pix); |
| 834 | if (ops->vidioc_s_fmt_vid_cap) { | 727 | if (ops->vidioc_s_fmt_vid_cap) |
| 835 | ret = ops->vidioc_s_fmt_vid_cap(file, fh, f); | 728 | ret = ops->vidioc_s_fmt_vid_cap(file, fh, f); |
| 836 | } else if (ops->vidioc_s_fmt_vid_cap_mplane) { | ||
| 837 | if (fmt_sp_to_mp(f, &f_copy)) | ||
| 838 | break; | ||
| 839 | ret = ops->vidioc_s_fmt_vid_cap_mplane(file, fh, | ||
| 840 | &f_copy); | ||
| 841 | if (ret) | ||
| 842 | break; | ||
| 843 | |||
| 844 | if (f_copy.fmt.pix_mp.num_planes > 1) { | ||
| 845 | /* Drivers shouldn't adjust from 1-plane | ||
| 846 | * to more than 1-plane formats */ | ||
| 847 | ret = -EBUSY; | ||
| 848 | WARN_ON(1); | ||
| 849 | break; | ||
| 850 | } | ||
| 851 | |||
| 852 | ret = fmt_mp_to_sp(&f_copy, f); | ||
| 853 | } | ||
| 854 | break; | 729 | break; |
| 855 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: | 730 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
| 856 | CLEAR_AFTER_FIELD(f, fmt.pix_mp); | 731 | CLEAR_AFTER_FIELD(f, fmt.pix_mp); |
| 857 | v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp); | 732 | v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp); |
| 858 | if (ops->vidioc_s_fmt_vid_cap_mplane) { | 733 | if (ops->vidioc_s_fmt_vid_cap_mplane) |
| 859 | ret = ops->vidioc_s_fmt_vid_cap_mplane(file, | 734 | ret = ops->vidioc_s_fmt_vid_cap_mplane(file, |
| 860 | fh, f); | 735 | fh, f); |
| 861 | } else if (ops->vidioc_s_fmt_vid_cap && | ||
| 862 | f->fmt.pix_mp.num_planes == 1) { | ||
| 863 | if (fmt_mp_to_sp(f, &f_copy)) | ||
| 864 | break; | ||
| 865 | ret = ops->vidioc_s_fmt_vid_cap(file, | ||
| 866 | fh, &f_copy); | ||
| 867 | if (ret) | ||
| 868 | break; | ||
| 869 | |||
| 870 | ret = fmt_sp_to_mp(&f_copy, f); | ||
| 871 | } | ||
| 872 | break; | 736 | break; |
| 873 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 737 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
| 874 | CLEAR_AFTER_FIELD(f, fmt.win); | 738 | CLEAR_AFTER_FIELD(f, fmt.win); |
| @@ -879,44 +743,15 @@ static long __video_do_ioctl(struct file *file, | |||
| 879 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | 743 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
| 880 | CLEAR_AFTER_FIELD(f, fmt.pix); | 744 | CLEAR_AFTER_FIELD(f, fmt.pix); |
| 881 | v4l_print_pix_fmt(vfd, &f->fmt.pix); | 745 | v4l_print_pix_fmt(vfd, &f->fmt.pix); |
| 882 | if (ops->vidioc_s_fmt_vid_out) { | 746 | if (ops->vidioc_s_fmt_vid_out) |
| 883 | ret = ops->vidioc_s_fmt_vid_out(file, fh, f); | 747 | ret = ops->vidioc_s_fmt_vid_out(file, fh, f); |
| 884 | } else if (ops->vidioc_s_fmt_vid_out_mplane) { | ||
| 885 | if (fmt_sp_to_mp(f, &f_copy)) | ||
| 886 | break; | ||
| 887 | ret = ops->vidioc_s_fmt_vid_out_mplane(file, fh, | ||
| 888 | &f_copy); | ||
| 889 | if (ret) | ||
| 890 | break; | ||
| 891 | |||
| 892 | if (f_copy.fmt.pix_mp.num_planes > 1) { | ||
| 893 | /* Drivers shouldn't adjust from 1-plane | ||
| 894 | * to more than 1-plane formats */ | ||
| 895 | ret = -EBUSY; | ||
| 896 | WARN_ON(1); | ||
| 897 | break; | ||
| 898 | } | ||
| 899 | |||
| 900 | ret = fmt_mp_to_sp(&f_copy, f); | ||
| 901 | } | ||
| 902 | break; | 748 | break; |
| 903 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: | 749 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
| 904 | CLEAR_AFTER_FIELD(f, fmt.pix_mp); | 750 | CLEAR_AFTER_FIELD(f, fmt.pix_mp); |
| 905 | v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp); | 751 | v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp); |
| 906 | if (ops->vidioc_s_fmt_vid_out_mplane) { | 752 | if (ops->vidioc_s_fmt_vid_out_mplane) |
| 907 | ret = ops->vidioc_s_fmt_vid_out_mplane(file, | 753 | ret = ops->vidioc_s_fmt_vid_out_mplane(file, |
| 908 | fh, f); | 754 | fh, f); |
| 909 | } else if (ops->vidioc_s_fmt_vid_out && | ||
| 910 | f->fmt.pix_mp.num_planes == 1) { | ||
| 911 | if (fmt_mp_to_sp(f, &f_copy)) | ||
| 912 | break; | ||
| 913 | ret = ops->vidioc_s_fmt_vid_out(file, | ||
| 914 | fh, &f_copy); | ||
| 915 | if (ret) | ||
| 916 | break; | ||
| 917 | |||
| 918 | ret = fmt_mp_to_sp(&f_copy, f); | ||
| 919 | } | ||
| 920 | break; | 755 | break; |
| 921 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: | 756 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: |
| 922 | CLEAR_AFTER_FIELD(f, fmt.win); | 757 | CLEAR_AFTER_FIELD(f, fmt.win); |
| @@ -926,29 +761,30 @@ static long __video_do_ioctl(struct file *file, | |||
| 926 | break; | 761 | break; |
| 927 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 762 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
| 928 | CLEAR_AFTER_FIELD(f, fmt.vbi); | 763 | CLEAR_AFTER_FIELD(f, fmt.vbi); |
| 929 | if (ops->vidioc_s_fmt_vbi_cap) | 764 | if (likely(ops->vidioc_s_fmt_vbi_cap)) |
| 930 | ret = ops->vidioc_s_fmt_vbi_cap(file, fh, f); | 765 | ret = ops->vidioc_s_fmt_vbi_cap(file, fh, f); |
| 931 | break; | 766 | break; |
| 932 | case V4L2_BUF_TYPE_VBI_OUTPUT: | 767 | case V4L2_BUF_TYPE_VBI_OUTPUT: |
| 933 | CLEAR_AFTER_FIELD(f, fmt.vbi); | 768 | CLEAR_AFTER_FIELD(f, fmt.vbi); |
| 934 | if (ops->vidioc_s_fmt_vbi_out) | 769 | if (likely(ops->vidioc_s_fmt_vbi_out)) |
| 935 | ret = ops->vidioc_s_fmt_vbi_out(file, fh, f); | 770 | ret = ops->vidioc_s_fmt_vbi_out(file, fh, f); |
| 936 | break; | 771 | break; |
| 937 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | 772 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: |
| 938 | CLEAR_AFTER_FIELD(f, fmt.sliced); | 773 | CLEAR_AFTER_FIELD(f, fmt.sliced); |
| 939 | if (ops->vidioc_s_fmt_sliced_vbi_cap) | 774 | if (likely(ops->vidioc_s_fmt_sliced_vbi_cap)) |
| 940 | ret = ops->vidioc_s_fmt_sliced_vbi_cap(file, | 775 | ret = ops->vidioc_s_fmt_sliced_vbi_cap(file, |
| 941 | fh, f); | 776 | fh, f); |
| 942 | break; | 777 | break; |
| 943 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: | 778 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: |
| 944 | CLEAR_AFTER_FIELD(f, fmt.sliced); | 779 | CLEAR_AFTER_FIELD(f, fmt.sliced); |
| 945 | if (ops->vidioc_s_fmt_sliced_vbi_out) | 780 | if (likely(ops->vidioc_s_fmt_sliced_vbi_out)) |
| 946 | ret = ops->vidioc_s_fmt_sliced_vbi_out(file, | 781 | ret = ops->vidioc_s_fmt_sliced_vbi_out(file, |
| 947 | fh, f); | 782 | fh, f); |
| 783 | |||
| 948 | break; | 784 | break; |
| 949 | case V4L2_BUF_TYPE_PRIVATE: | 785 | case V4L2_BUF_TYPE_PRIVATE: |
| 950 | /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */ | 786 | /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */ |
| 951 | if (ops->vidioc_s_fmt_type_private) | 787 | if (likely(ops->vidioc_s_fmt_type_private)) |
| 952 | ret = ops->vidioc_s_fmt_type_private(file, | 788 | ret = ops->vidioc_s_fmt_type_private(file, |
| 953 | fh, f); | 789 | fh, f); |
| 954 | break; | 790 | break; |
| @@ -965,132 +801,77 @@ static long __video_do_ioctl(struct file *file, | |||
| 965 | switch (f->type) { | 801 | switch (f->type) { |
| 966 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 802 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
| 967 | CLEAR_AFTER_FIELD(f, fmt.pix); | 803 | CLEAR_AFTER_FIELD(f, fmt.pix); |
| 968 | if (ops->vidioc_try_fmt_vid_cap) { | 804 | if (ops->vidioc_try_fmt_vid_cap) |
| 969 | ret = ops->vidioc_try_fmt_vid_cap(file, fh, f); | 805 | ret = ops->vidioc_try_fmt_vid_cap(file, fh, f); |
| 970 | } else if (ops->vidioc_try_fmt_vid_cap_mplane) { | ||
| 971 | if (fmt_sp_to_mp(f, &f_copy)) | ||
| 972 | break; | ||
| 973 | ret = ops->vidioc_try_fmt_vid_cap_mplane(file, | ||
| 974 | fh, &f_copy); | ||
| 975 | if (ret) | ||
| 976 | break; | ||
| 977 | |||
| 978 | if (f_copy.fmt.pix_mp.num_planes > 1) { | ||
| 979 | /* Drivers shouldn't adjust from 1-plane | ||
| 980 | * to more than 1-plane formats */ | ||
| 981 | ret = -EBUSY; | ||
| 982 | WARN_ON(1); | ||
| 983 | break; | ||
| 984 | } | ||
| 985 | ret = fmt_mp_to_sp(&f_copy, f); | ||
| 986 | } | ||
| 987 | if (!ret) | 806 | if (!ret) |
| 988 | v4l_print_pix_fmt(vfd, &f->fmt.pix); | 807 | v4l_print_pix_fmt(vfd, &f->fmt.pix); |
| 989 | break; | 808 | break; |
| 990 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: | 809 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
| 991 | CLEAR_AFTER_FIELD(f, fmt.pix_mp); | 810 | CLEAR_AFTER_FIELD(f, fmt.pix_mp); |
| 992 | if (ops->vidioc_try_fmt_vid_cap_mplane) { | 811 | if (ops->vidioc_try_fmt_vid_cap_mplane) |
| 993 | ret = ops->vidioc_try_fmt_vid_cap_mplane(file, | 812 | ret = ops->vidioc_try_fmt_vid_cap_mplane(file, |
| 994 | fh, f); | 813 | fh, f); |
| 995 | } else if (ops->vidioc_try_fmt_vid_cap && | ||
| 996 | f->fmt.pix_mp.num_planes == 1) { | ||
| 997 | if (fmt_mp_to_sp(f, &f_copy)) | ||
| 998 | break; | ||
| 999 | ret = ops->vidioc_try_fmt_vid_cap(file, | ||
| 1000 | fh, &f_copy); | ||
| 1001 | if (ret) | ||
| 1002 | break; | ||
| 1003 | |||
| 1004 | ret = fmt_sp_to_mp(&f_copy, f); | ||
| 1005 | } | ||
| 1006 | if (!ret) | 814 | if (!ret) |
| 1007 | v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp); | 815 | v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp); |
| 1008 | break; | 816 | break; |
| 1009 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 817 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
| 1010 | CLEAR_AFTER_FIELD(f, fmt.win); | 818 | CLEAR_AFTER_FIELD(f, fmt.win); |
| 1011 | if (ops->vidioc_try_fmt_vid_overlay) | 819 | if (likely(ops->vidioc_try_fmt_vid_overlay)) |
| 1012 | ret = ops->vidioc_try_fmt_vid_overlay(file, | 820 | ret = ops->vidioc_try_fmt_vid_overlay(file, |
| 1013 | fh, f); | 821 | fh, f); |
| 1014 | break; | 822 | break; |
| 1015 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | 823 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
| 1016 | CLEAR_AFTER_FIELD(f, fmt.pix); | 824 | CLEAR_AFTER_FIELD(f, fmt.pix); |
| 1017 | if (ops->vidioc_try_fmt_vid_out) { | 825 | if (ops->vidioc_try_fmt_vid_out) |
| 1018 | ret = ops->vidioc_try_fmt_vid_out(file, fh, f); | 826 | ret = ops->vidioc_try_fmt_vid_out(file, fh, f); |
| 1019 | } else if (ops->vidioc_try_fmt_vid_out_mplane) { | ||
| 1020 | if (fmt_sp_to_mp(f, &f_copy)) | ||
| 1021 | break; | ||
| 1022 | ret = ops->vidioc_try_fmt_vid_out_mplane(file, | ||
| 1023 | fh, &f_copy); | ||
| 1024 | if (ret) | ||
| 1025 | break; | ||
| 1026 | |||
| 1027 | if (f_copy.fmt.pix_mp.num_planes > 1) { | ||
| 1028 | /* Drivers shouldn't adjust from 1-plane | ||
| 1029 | * to more than 1-plane formats */ | ||
| 1030 | ret = -EBUSY; | ||
| 1031 | WARN_ON(1); | ||
| 1032 | break; | ||
| 1033 | } | ||
| 1034 | ret = fmt_mp_to_sp(&f_copy, f); | ||
| 1035 | } | ||
| 1036 | if (!ret) | 827 | if (!ret) |
| 1037 | v4l_print_pix_fmt(vfd, &f->fmt.pix); | 828 | v4l_print_pix_fmt(vfd, &f->fmt.pix); |
| 1038 | break; | 829 | break; |
| 1039 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: | 830 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
| 1040 | CLEAR_AFTER_FIELD(f, fmt.pix_mp); | 831 | CLEAR_AFTER_FIELD(f, fmt.pix_mp); |
| 1041 | if (ops->vidioc_try_fmt_vid_out_mplane) { | 832 | if (ops->vidioc_try_fmt_vid_out_mplane) |
| 1042 | ret = ops->vidioc_try_fmt_vid_out_mplane(file, | 833 | ret = ops->vidioc_try_fmt_vid_out_mplane(file, |
| 1043 | fh, f); | 834 | fh, f); |
| 1044 | } else if (ops->vidioc_try_fmt_vid_out && | ||
| 1045 | f->fmt.pix_mp.num_planes == 1) { | ||
| 1046 | if (fmt_mp_to_sp(f, &f_copy)) | ||
| 1047 | break; | ||
| 1048 | ret = ops->vidioc_try_fmt_vid_out(file, | ||
| 1049 | fh, &f_copy); | ||
| 1050 | if (ret) | ||
| 1051 | break; | ||
| 1052 | |||
| 1053 | ret = fmt_sp_to_mp(&f_copy, f); | ||
| 1054 | } | ||
| 1055 | if (!ret) | 835 | if (!ret) |
| 1056 | v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp); | 836 | v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp); |
| 1057 | break; | 837 | break; |
| 1058 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: | 838 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: |
| 1059 | CLEAR_AFTER_FIELD(f, fmt.win); | 839 | CLEAR_AFTER_FIELD(f, fmt.win); |
| 1060 | if (ops->vidioc_try_fmt_vid_out_overlay) | 840 | if (likely(ops->vidioc_try_fmt_vid_out_overlay)) |
| 1061 | ret = ops->vidioc_try_fmt_vid_out_overlay(file, | 841 | ret = ops->vidioc_try_fmt_vid_out_overlay(file, |
| 1062 | fh, f); | 842 | fh, f); |
| 1063 | break; | 843 | break; |
| 1064 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 844 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
| 1065 | CLEAR_AFTER_FIELD(f, fmt.vbi); | 845 | CLEAR_AFTER_FIELD(f, fmt.vbi); |
| 1066 | if (ops->vidioc_try_fmt_vbi_cap) | 846 | if (likely(ops->vidioc_try_fmt_vbi_cap)) |
| 1067 | ret = ops->vidioc_try_fmt_vbi_cap(file, fh, f); | 847 | ret = ops->vidioc_try_fmt_vbi_cap(file, fh, f); |
| 1068 | break; | 848 | break; |
| 1069 | case V4L2_BUF_TYPE_VBI_OUTPUT: | 849 | case V4L2_BUF_TYPE_VBI_OUTPUT: |
| 1070 | CLEAR_AFTER_FIELD(f, fmt.vbi); | 850 | CLEAR_AFTER_FIELD(f, fmt.vbi); |
| 1071 | if (ops->vidioc_try_fmt_vbi_out) | 851 | if (likely(ops->vidioc_try_fmt_vbi_out)) |
| 1072 | ret = ops->vidioc_try_fmt_vbi_out(file, fh, f); | 852 | ret = ops->vidioc_try_fmt_vbi_out(file, fh, f); |
| 1073 | break; | 853 | break; |
| 1074 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | 854 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: |
| 1075 | CLEAR_AFTER_FIELD(f, fmt.sliced); | 855 | CLEAR_AFTER_FIELD(f, fmt.sliced); |
| 1076 | if (ops->vidioc_try_fmt_sliced_vbi_cap) | 856 | if (likely(ops->vidioc_try_fmt_sliced_vbi_cap)) |
| 1077 | ret = ops->vidioc_try_fmt_sliced_vbi_cap(file, | 857 | ret = ops->vidioc_try_fmt_sliced_vbi_cap(file, |
| 1078 | fh, f); | 858 | fh, f); |
| 1079 | break; | 859 | break; |
| 1080 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: | 860 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: |
| 1081 | CLEAR_AFTER_FIELD(f, fmt.sliced); | 861 | CLEAR_AFTER_FIELD(f, fmt.sliced); |
| 1082 | if (ops->vidioc_try_fmt_sliced_vbi_out) | 862 | if (likely(ops->vidioc_try_fmt_sliced_vbi_out)) |
| 1083 | ret = ops->vidioc_try_fmt_sliced_vbi_out(file, | 863 | ret = ops->vidioc_try_fmt_sliced_vbi_out(file, |
| 1084 | fh, f); | 864 | fh, f); |
| 1085 | break; | 865 | break; |
| 1086 | case V4L2_BUF_TYPE_PRIVATE: | 866 | case V4L2_BUF_TYPE_PRIVATE: |
| 1087 | /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */ | 867 | /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */ |
| 1088 | if (ops->vidioc_try_fmt_type_private) | 868 | if (likely(ops->vidioc_try_fmt_type_private)) |
| 1089 | ret = ops->vidioc_try_fmt_type_private(file, | 869 | ret = ops->vidioc_try_fmt_type_private(file, |
| 1090 | fh, f); | 870 | fh, f); |
| 1091 | break; | 871 | break; |
| 1092 | } | 872 | } |
| 1093 | 873 | if (unlikely(ret == -ENOTTY && have_fmt_ops(try))) | |
| 874 | ret = -EINVAL; | ||
| 1094 | break; | 875 | break; |
| 1095 | } | 876 | } |
| 1096 | /* FIXME: Those buf reqs could be handled here, | 877 | /* FIXME: Those buf reqs could be handled here, |
| @@ -1103,6 +884,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 1103 | 884 | ||
| 1104 | if (!ops->vidioc_reqbufs) | 885 | if (!ops->vidioc_reqbufs) |
| 1105 | break; | 886 | break; |
| 887 | if (ret_prio) { | ||
| 888 | ret = ret_prio; | ||
| 889 | break; | ||
| 890 | } | ||
| 1106 | ret = check_fmt(ops, p->type); | 891 | ret = check_fmt(ops, p->type); |
| 1107 | if (ret) | 892 | if (ret) |
| 1108 | break; | 893 | break; |
| @@ -1168,6 +953,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 1168 | 953 | ||
| 1169 | if (!ops->vidioc_overlay) | 954 | if (!ops->vidioc_overlay) |
| 1170 | break; | 955 | break; |
| 956 | if (ret_prio) { | ||
| 957 | ret = ret_prio; | ||
| 958 | break; | ||
| 959 | } | ||
| 1171 | dbgarg(cmd, "value=%d\n", *i); | 960 | dbgarg(cmd, "value=%d\n", *i); |
| 1172 | ret = ops->vidioc_overlay(file, fh, *i); | 961 | ret = ops->vidioc_overlay(file, fh, *i); |
| 1173 | break; | 962 | break; |
| @@ -1193,6 +982,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 1193 | 982 | ||
| 1194 | if (!ops->vidioc_s_fbuf) | 983 | if (!ops->vidioc_s_fbuf) |
| 1195 | break; | 984 | break; |
| 985 | if (ret_prio) { | ||
| 986 | ret = ret_prio; | ||
| 987 | break; | ||
| 988 | } | ||
| 1196 | dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n", | 989 | dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n", |
| 1197 | p->capability, p->flags, (unsigned long)p->base); | 990 | p->capability, p->flags, (unsigned long)p->base); |
| 1198 | v4l_print_pix_fmt(vfd, &p->fmt); | 991 | v4l_print_pix_fmt(vfd, &p->fmt); |
| @@ -1205,6 +998,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 1205 | 998 | ||
| 1206 | if (!ops->vidioc_streamon) | 999 | if (!ops->vidioc_streamon) |
| 1207 | break; | 1000 | break; |
| 1001 | if (ret_prio) { | ||
| 1002 | ret = ret_prio; | ||
| 1003 | break; | ||
| 1004 | } | ||
| 1208 | dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); | 1005 | dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); |
| 1209 | ret = ops->vidioc_streamon(file, fh, i); | 1006 | ret = ops->vidioc_streamon(file, fh, i); |
| 1210 | break; | 1007 | break; |
| @@ -1215,6 +1012,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 1215 | 1012 | ||
| 1216 | if (!ops->vidioc_streamoff) | 1013 | if (!ops->vidioc_streamoff) |
| 1217 | break; | 1014 | break; |
| 1015 | if (ret_prio) { | ||
| 1016 | ret = ret_prio; | ||
| 1017 | break; | ||
| 1018 | } | ||
| 1218 | dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); | 1019 | dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); |
| 1219 | ret = ops->vidioc_streamoff(file, fh, i); | 1020 | ret = ops->vidioc_streamoff(file, fh, i); |
| 1220 | break; | 1021 | break; |
| @@ -1227,6 +1028,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 1227 | unsigned int index = p->index, i, j = 0; | 1028 | unsigned int index = p->index, i, j = 0; |
| 1228 | const char *descr = ""; | 1029 | const char *descr = ""; |
| 1229 | 1030 | ||
| 1031 | if (id == 0) | ||
| 1032 | break; | ||
| 1033 | ret = -EINVAL; | ||
| 1034 | |||
| 1230 | /* Return norm array in a canonical way */ | 1035 | /* Return norm array in a canonical way */ |
| 1231 | for (i = 0; i <= index && id; i++) { | 1036 | for (i = 0; i <= index && id; i++) { |
| 1232 | /* last std value in the standards array is 0, so this | 1037 | /* last std value in the standards array is 0, so this |
| @@ -1262,16 +1067,15 @@ static long __video_do_ioctl(struct file *file, | |||
| 1262 | { | 1067 | { |
| 1263 | v4l2_std_id *id = arg; | 1068 | v4l2_std_id *id = arg; |
| 1264 | 1069 | ||
| 1265 | ret = 0; | ||
| 1266 | /* Calls the specific handler */ | 1070 | /* Calls the specific handler */ |
| 1267 | if (ops->vidioc_g_std) | 1071 | if (ops->vidioc_g_std) |
| 1268 | ret = ops->vidioc_g_std(file, fh, id); | 1072 | ret = ops->vidioc_g_std(file, fh, id); |
| 1269 | else if (vfd->current_norm) | 1073 | else if (vfd->current_norm) { |
| 1074 | ret = 0; | ||
| 1270 | *id = vfd->current_norm; | 1075 | *id = vfd->current_norm; |
| 1271 | else | 1076 | } |
| 1272 | ret = -EINVAL; | ||
| 1273 | 1077 | ||
| 1274 | if (!ret) | 1078 | if (likely(!ret)) |
| 1275 | dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id); | 1079 | dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id); |
| 1276 | break; | 1080 | break; |
| 1277 | } | 1081 | } |
| @@ -1281,15 +1085,20 @@ static long __video_do_ioctl(struct file *file, | |||
| 1281 | 1085 | ||
| 1282 | dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id); | 1086 | dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id); |
| 1283 | 1087 | ||
| 1088 | if (!ops->vidioc_s_std) | ||
| 1089 | break; | ||
| 1090 | |||
| 1091 | if (ret_prio) { | ||
| 1092 | ret = ret_prio; | ||
| 1093 | break; | ||
| 1094 | } | ||
| 1095 | ret = -EINVAL; | ||
| 1284 | norm = (*id) & vfd->tvnorms; | 1096 | norm = (*id) & vfd->tvnorms; |
| 1285 | if (vfd->tvnorms && !norm) /* Check if std is supported */ | 1097 | if (vfd->tvnorms && !norm) /* Check if std is supported */ |
| 1286 | break; | 1098 | break; |
| 1287 | 1099 | ||
| 1288 | /* Calls the specific handler */ | 1100 | /* Calls the specific handler */ |
| 1289 | if (ops->vidioc_s_std) | 1101 | ret = ops->vidioc_s_std(file, fh, &norm); |
| 1290 | ret = ops->vidioc_s_std(file, fh, &norm); | ||
| 1291 | else | ||
| 1292 | ret = -EINVAL; | ||
| 1293 | 1102 | ||
| 1294 | /* Updates standard information */ | 1103 | /* Updates standard information */ |
| 1295 | if (ret >= 0) | 1104 | if (ret >= 0) |
| @@ -1302,6 +1111,14 @@ static long __video_do_ioctl(struct file *file, | |||
| 1302 | 1111 | ||
| 1303 | if (!ops->vidioc_querystd) | 1112 | if (!ops->vidioc_querystd) |
| 1304 | break; | 1113 | break; |
| 1114 | /* | ||
| 1115 | * If nothing detected, it should return all supported | ||
| 1116 | * Drivers just need to mask the std argument, in order | ||
| 1117 | * to remove the standards that don't apply from the mask. | ||
| 1118 | * This means that tuners, audio and video decoders can join | ||
| 1119 | * their efforts to improve the standards detection | ||
| 1120 | */ | ||
| 1121 | *p = vfd->tvnorms; | ||
| 1305 | ret = ops->vidioc_querystd(file, fh, arg); | 1122 | ret = ops->vidioc_querystd(file, fh, arg); |
| 1306 | if (!ret) | 1123 | if (!ret) |
| 1307 | dbgarg(cmd, "detected std=%08Lx\n", | 1124 | dbgarg(cmd, "detected std=%08Lx\n", |
| @@ -1358,6 +1175,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 1358 | 1175 | ||
| 1359 | if (!ops->vidioc_s_input) | 1176 | if (!ops->vidioc_s_input) |
| 1360 | break; | 1177 | break; |
| 1178 | if (ret_prio) { | ||
| 1179 | ret = ret_prio; | ||
| 1180 | break; | ||
| 1181 | } | ||
| 1361 | dbgarg(cmd, "value=%d\n", *i); | 1182 | dbgarg(cmd, "value=%d\n", *i); |
| 1362 | ret = ops->vidioc_s_input(file, fh, *i); | 1183 | ret = ops->vidioc_s_input(file, fh, *i); |
| 1363 | break; | 1184 | break; |
| @@ -1410,6 +1231,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 1410 | 1231 | ||
| 1411 | if (!ops->vidioc_s_output) | 1232 | if (!ops->vidioc_s_output) |
| 1412 | break; | 1233 | break; |
| 1234 | if (ret_prio) { | ||
| 1235 | ret = ret_prio; | ||
| 1236 | break; | ||
| 1237 | } | ||
| 1413 | dbgarg(cmd, "value=%d\n", *i); | 1238 | dbgarg(cmd, "value=%d\n", *i); |
| 1414 | ret = ops->vidioc_s_output(file, fh, *i); | 1239 | ret = ops->vidioc_s_output(file, fh, *i); |
| 1415 | break; | 1240 | break; |
| @@ -1479,6 +1304,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 1479 | if (!(vfh && vfh->ctrl_handler) && !vfd->ctrl_handler && | 1304 | if (!(vfh && vfh->ctrl_handler) && !vfd->ctrl_handler && |
| 1480 | !ops->vidioc_s_ctrl && !ops->vidioc_s_ext_ctrls) | 1305 | !ops->vidioc_s_ctrl && !ops->vidioc_s_ext_ctrls) |
| 1481 | break; | 1306 | break; |
| 1307 | if (ret_prio) { | ||
| 1308 | ret = ret_prio; | ||
| 1309 | break; | ||
| 1310 | } | ||
| 1482 | 1311 | ||
| 1483 | dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value); | 1312 | dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value); |
| 1484 | 1313 | ||
| @@ -1504,6 +1333,8 @@ static long __video_do_ioctl(struct file *file, | |||
| 1504 | ctrl.value = p->value; | 1333 | ctrl.value = p->value; |
| 1505 | if (check_ext_ctrls(&ctrls, 1)) | 1334 | if (check_ext_ctrls(&ctrls, 1)) |
| 1506 | ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls); | 1335 | ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls); |
| 1336 | else | ||
| 1337 | ret = -EINVAL; | ||
| 1507 | break; | 1338 | break; |
| 1508 | } | 1339 | } |
| 1509 | case VIDIOC_G_EXT_CTRLS: | 1340 | case VIDIOC_G_EXT_CTRLS: |
| @@ -1515,8 +1346,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 1515 | ret = v4l2_g_ext_ctrls(vfh->ctrl_handler, p); | 1346 | ret = v4l2_g_ext_ctrls(vfh->ctrl_handler, p); |
| 1516 | else if (vfd->ctrl_handler) | 1347 | else if (vfd->ctrl_handler) |
| 1517 | ret = v4l2_g_ext_ctrls(vfd->ctrl_handler, p); | 1348 | ret = v4l2_g_ext_ctrls(vfd->ctrl_handler, p); |
| 1518 | else if (ops->vidioc_g_ext_ctrls && check_ext_ctrls(p, 0)) | 1349 | else if (ops->vidioc_g_ext_ctrls) |
| 1519 | ret = ops->vidioc_g_ext_ctrls(file, fh, p); | 1350 | ret = check_ext_ctrls(p, 0) ? |
| 1351 | ops->vidioc_g_ext_ctrls(file, fh, p) : | ||
| 1352 | -EINVAL; | ||
| 1520 | else | 1353 | else |
| 1521 | break; | 1354 | break; |
| 1522 | v4l_print_ext_ctrls(cmd, vfd, p, !ret); | 1355 | v4l_print_ext_ctrls(cmd, vfd, p, !ret); |
| @@ -1530,6 +1363,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 1530 | if (!(vfh && vfh->ctrl_handler) && !vfd->ctrl_handler && | 1363 | if (!(vfh && vfh->ctrl_handler) && !vfd->ctrl_handler && |
| 1531 | !ops->vidioc_s_ext_ctrls) | 1364 | !ops->vidioc_s_ext_ctrls) |
| 1532 | break; | 1365 | break; |
| 1366 | if (ret_prio) { | ||
| 1367 | ret = ret_prio; | ||
| 1368 | break; | ||
| 1369 | } | ||
| 1533 | v4l_print_ext_ctrls(cmd, vfd, p, 1); | 1370 | v4l_print_ext_ctrls(cmd, vfd, p, 1); |
| 1534 | if (vfh && vfh->ctrl_handler) | 1371 | if (vfh && vfh->ctrl_handler) |
| 1535 | ret = v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, p); | 1372 | ret = v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, p); |
| @@ -1537,6 +1374,8 @@ static long __video_do_ioctl(struct file *file, | |||
| 1537 | ret = v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler, p); | 1374 | ret = v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler, p); |
| 1538 | else if (check_ext_ctrls(p, 0)) | 1375 | else if (check_ext_ctrls(p, 0)) |
| 1539 | ret = ops->vidioc_s_ext_ctrls(file, fh, p); | 1376 | ret = ops->vidioc_s_ext_ctrls(file, fh, p); |
| 1377 | else | ||
| 1378 | ret = -EINVAL; | ||
| 1540 | break; | 1379 | break; |
| 1541 | } | 1380 | } |
| 1542 | case VIDIOC_TRY_EXT_CTRLS: | 1381 | case VIDIOC_TRY_EXT_CTRLS: |
| @@ -1554,6 +1393,8 @@ static long __video_do_ioctl(struct file *file, | |||
| 1554 | ret = v4l2_try_ext_ctrls(vfd->ctrl_handler, p); | 1393 | ret = v4l2_try_ext_ctrls(vfd->ctrl_handler, p); |
| 1555 | else if (check_ext_ctrls(p, 0)) | 1394 | else if (check_ext_ctrls(p, 0)) |
| 1556 | ret = ops->vidioc_try_ext_ctrls(file, fh, p); | 1395 | ret = ops->vidioc_try_ext_ctrls(file, fh, p); |
| 1396 | else | ||
| 1397 | ret = -EINVAL; | ||
| 1557 | break; | 1398 | break; |
| 1558 | } | 1399 | } |
| 1559 | case VIDIOC_QUERYMENU: | 1400 | case VIDIOC_QUERYMENU: |
| @@ -1614,6 +1455,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 1614 | 1455 | ||
| 1615 | if (!ops->vidioc_s_audio) | 1456 | if (!ops->vidioc_s_audio) |
| 1616 | break; | 1457 | break; |
| 1458 | if (ret_prio) { | ||
| 1459 | ret = ret_prio; | ||
| 1460 | break; | ||
| 1461 | } | ||
| 1617 | dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " | 1462 | dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " |
| 1618 | "mode=0x%x\n", p->index, p->name, | 1463 | "mode=0x%x\n", p->index, p->name, |
| 1619 | p->capability, p->mode); | 1464 | p->capability, p->mode); |
| @@ -1654,6 +1499,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 1654 | 1499 | ||
| 1655 | if (!ops->vidioc_s_audout) | 1500 | if (!ops->vidioc_s_audout) |
| 1656 | break; | 1501 | break; |
| 1502 | if (ret_prio) { | ||
| 1503 | ret = ret_prio; | ||
| 1504 | break; | ||
| 1505 | } | ||
| 1657 | dbgarg(cmd, "index=%d, name=%s, capability=%d, " | 1506 | dbgarg(cmd, "index=%d, name=%s, capability=%d, " |
| 1658 | "mode=%d\n", p->index, p->name, | 1507 | "mode=%d\n", p->index, p->name, |
| 1659 | p->capability, p->mode); | 1508 | p->capability, p->mode); |
| @@ -1683,6 +1532,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 1683 | 1532 | ||
| 1684 | if (!ops->vidioc_s_modulator) | 1533 | if (!ops->vidioc_s_modulator) |
| 1685 | break; | 1534 | break; |
| 1535 | if (ret_prio) { | ||
| 1536 | ret = ret_prio; | ||
| 1537 | break; | ||
| 1538 | } | ||
| 1686 | dbgarg(cmd, "index=%d, name=%s, capability=%d, " | 1539 | dbgarg(cmd, "index=%d, name=%s, capability=%d, " |
| 1687 | "rangelow=%d, rangehigh=%d, txsubchans=%d\n", | 1540 | "rangelow=%d, rangehigh=%d, txsubchans=%d\n", |
| 1688 | p->index, p->name, p->capability, p->rangelow, | 1541 | p->index, p->name, p->capability, p->rangelow, |
| @@ -1709,6 +1562,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 1709 | 1562 | ||
| 1710 | if (!ops->vidioc_s_crop) | 1563 | if (!ops->vidioc_s_crop) |
| 1711 | break; | 1564 | break; |
| 1565 | if (ret_prio) { | ||
| 1566 | ret = ret_prio; | ||
| 1567 | break; | ||
| 1568 | } | ||
| 1712 | dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); | 1569 | dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); |
| 1713 | dbgrect(vfd, "", &p->c); | 1570 | dbgrect(vfd, "", &p->c); |
| 1714 | ret = ops->vidioc_s_crop(file, fh, p); | 1571 | ret = ops->vidioc_s_crop(file, fh, p); |
| @@ -1752,11 +1609,15 @@ static long __video_do_ioctl(struct file *file, | |||
| 1752 | 1609 | ||
| 1753 | if (!ops->vidioc_g_jpegcomp) | 1610 | if (!ops->vidioc_g_jpegcomp) |
| 1754 | break; | 1611 | break; |
| 1612 | if (ret_prio) { | ||
| 1613 | ret = ret_prio; | ||
| 1614 | break; | ||
| 1615 | } | ||
| 1755 | dbgarg(cmd, "quality=%d, APPn=%d, APP_len=%d, " | 1616 | dbgarg(cmd, "quality=%d, APPn=%d, APP_len=%d, " |
| 1756 | "COM_len=%d, jpeg_markers=%d\n", | 1617 | "COM_len=%d, jpeg_markers=%d\n", |
| 1757 | p->quality, p->APPn, p->APP_len, | 1618 | p->quality, p->APPn, p->APP_len, |
| 1758 | p->COM_len, p->jpeg_markers); | 1619 | p->COM_len, p->jpeg_markers); |
| 1759 | ret = ops->vidioc_s_jpegcomp(file, fh, p); | 1620 | ret = ops->vidioc_s_jpegcomp(file, fh, p); |
| 1760 | break; | 1621 | break; |
| 1761 | } | 1622 | } |
| 1762 | case VIDIOC_G_ENC_INDEX: | 1623 | case VIDIOC_G_ENC_INDEX: |
| @@ -1777,6 +1638,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 1777 | 1638 | ||
| 1778 | if (!ops->vidioc_encoder_cmd) | 1639 | if (!ops->vidioc_encoder_cmd) |
| 1779 | break; | 1640 | break; |
| 1641 | if (ret_prio) { | ||
| 1642 | ret = ret_prio; | ||
| 1643 | break; | ||
| 1644 | } | ||
| 1780 | ret = ops->vidioc_encoder_cmd(file, fh, p); | 1645 | ret = ops->vidioc_encoder_cmd(file, fh, p); |
| 1781 | if (!ret) | 1646 | if (!ret) |
| 1782 | dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); | 1647 | dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); |
| @@ -1797,6 +1662,8 @@ static long __video_do_ioctl(struct file *file, | |||
| 1797 | { | 1662 | { |
| 1798 | struct v4l2_streamparm *p = arg; | 1663 | struct v4l2_streamparm *p = arg; |
| 1799 | 1664 | ||
| 1665 | if (!ops->vidioc_g_parm && !vfd->current_norm) | ||
| 1666 | break; | ||
| 1800 | if (ops->vidioc_g_parm) { | 1667 | if (ops->vidioc_g_parm) { |
| 1801 | ret = check_fmt(ops, p->type); | 1668 | ret = check_fmt(ops, p->type); |
| 1802 | if (ret) | 1669 | if (ret) |
| @@ -1805,14 +1672,13 @@ static long __video_do_ioctl(struct file *file, | |||
| 1805 | } else { | 1672 | } else { |
| 1806 | v4l2_std_id std = vfd->current_norm; | 1673 | v4l2_std_id std = vfd->current_norm; |
| 1807 | 1674 | ||
| 1675 | ret = -EINVAL; | ||
| 1808 | if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1676 | if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
| 1809 | break; | 1677 | break; |
| 1810 | 1678 | ||
| 1811 | ret = 0; | 1679 | ret = 0; |
| 1812 | if (ops->vidioc_g_std) | 1680 | if (ops->vidioc_g_std) |
| 1813 | ret = ops->vidioc_g_std(file, fh, &std); | 1681 | ret = ops->vidioc_g_std(file, fh, &std); |
| 1814 | else if (std == 0) | ||
| 1815 | ret = -EINVAL; | ||
| 1816 | if (ret == 0) | 1682 | if (ret == 0) |
| 1817 | v4l2_video_std_frame_period(std, | 1683 | v4l2_video_std_frame_period(std, |
| 1818 | &p->parm.capture.timeperframe); | 1684 | &p->parm.capture.timeperframe); |
| @@ -1827,6 +1693,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 1827 | 1693 | ||
| 1828 | if (!ops->vidioc_s_parm) | 1694 | if (!ops->vidioc_s_parm) |
| 1829 | break; | 1695 | break; |
| 1696 | if (ret_prio) { | ||
| 1697 | ret = ret_prio; | ||
| 1698 | break; | ||
| 1699 | } | ||
| 1830 | ret = check_fmt(ops, p->type); | 1700 | ret = check_fmt(ops, p->type); |
| 1831 | if (ret) | 1701 | if (ret) |
| 1832 | break; | 1702 | break; |
| @@ -1862,6 +1732,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 1862 | 1732 | ||
| 1863 | if (!ops->vidioc_s_tuner) | 1733 | if (!ops->vidioc_s_tuner) |
| 1864 | break; | 1734 | break; |
| 1735 | if (ret_prio) { | ||
| 1736 | ret = ret_prio; | ||
| 1737 | break; | ||
| 1738 | } | ||
| 1865 | p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? | 1739 | p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? |
| 1866 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | 1740 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; |
| 1867 | dbgarg(cmd, "index=%d, name=%s, type=%d, " | 1741 | dbgarg(cmd, "index=%d, name=%s, type=%d, " |
| @@ -1896,6 +1770,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 1896 | 1770 | ||
| 1897 | if (!ops->vidioc_s_frequency) | 1771 | if (!ops->vidioc_s_frequency) |
| 1898 | break; | 1772 | break; |
| 1773 | if (ret_prio) { | ||
| 1774 | ret = ret_prio; | ||
| 1775 | break; | ||
| 1776 | } | ||
| 1899 | dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", | 1777 | dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", |
| 1900 | p->tuner, p->type, p->frequency); | 1778 | p->tuner, p->type, p->frequency); |
| 1901 | ret = ops->vidioc_s_frequency(file, fh, p); | 1779 | ret = ops->vidioc_s_frequency(file, fh, p); |
| @@ -1970,6 +1848,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 1970 | 1848 | ||
| 1971 | if (!ops->vidioc_s_hw_freq_seek) | 1849 | if (!ops->vidioc_s_hw_freq_seek) |
| 1972 | break; | 1850 | break; |
| 1851 | if (ret_prio) { | ||
| 1852 | ret = ret_prio; | ||
| 1853 | break; | ||
| 1854 | } | ||
| 1973 | type = (vfd->vfl_type == VFL_TYPE_RADIO) ? | 1855 | type = (vfd->vfl_type == VFL_TYPE_RADIO) ? |
| 1974 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | 1856 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; |
| 1975 | dbgarg(cmd, | 1857 | dbgarg(cmd, |
| @@ -2074,6 +1956,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 2074 | 1956 | ||
| 2075 | if (!ops->vidioc_s_dv_preset) | 1957 | if (!ops->vidioc_s_dv_preset) |
| 2076 | break; | 1958 | break; |
| 1959 | if (ret_prio) { | ||
| 1960 | ret = ret_prio; | ||
| 1961 | break; | ||
| 1962 | } | ||
| 2077 | 1963 | ||
| 2078 | dbgarg(cmd, "preset=%d\n", p->preset); | 1964 | dbgarg(cmd, "preset=%d\n", p->preset); |
| 2079 | ret = ops->vidioc_s_dv_preset(file, fh, p); | 1965 | ret = ops->vidioc_s_dv_preset(file, fh, p); |
| @@ -2109,6 +1995,10 @@ static long __video_do_ioctl(struct file *file, | |||
| 2109 | 1995 | ||
| 2110 | if (!ops->vidioc_s_dv_timings) | 1996 | if (!ops->vidioc_s_dv_timings) |
| 2111 | break; | 1997 | break; |
| 1998 | if (ret_prio) { | ||
| 1999 | ret = ret_prio; | ||
| 2000 | break; | ||
| 2001 | } | ||
| 2112 | 2002 | ||
| 2113 | switch (p->type) { | 2003 | switch (p->type) { |
| 2114 | case V4L2_DV_BT_656_1120: | 2004 | case V4L2_DV_BT_656_1120: |
| @@ -2216,20 +2106,47 @@ static long __video_do_ioctl(struct file *file, | |||
| 2216 | dbgarg(cmd, "type=0x%8.8x", sub->type); | 2106 | dbgarg(cmd, "type=0x%8.8x", sub->type); |
| 2217 | break; | 2107 | break; |
| 2218 | } | 2108 | } |
| 2219 | default: | 2109 | case VIDIOC_CREATE_BUFS: |
| 2220 | { | 2110 | { |
| 2221 | bool valid_prio = true; | 2111 | struct v4l2_create_buffers *create = arg; |
| 2222 | 2112 | ||
| 2223 | if (!ops->vidioc_default) | 2113 | if (!ops->vidioc_create_bufs) |
| 2114 | break; | ||
| 2115 | if (ret_prio) { | ||
| 2116 | ret = ret_prio; | ||
| 2117 | break; | ||
| 2118 | } | ||
| 2119 | ret = check_fmt(ops, create->format.type); | ||
| 2120 | if (ret) | ||
| 2224 | break; | 2121 | break; |
| 2225 | if (use_fh_prio) | 2122 | |
| 2226 | valid_prio = v4l2_prio_check(vfd->prio, vfh->prio) >= 0; | 2123 | ret = ops->vidioc_create_bufs(file, fh, create); |
| 2227 | ret = ops->vidioc_default(file, fh, valid_prio, cmd, arg); | 2124 | |
| 2125 | dbgarg(cmd, "count=%d @ %d\n", create->count, create->index); | ||
| 2228 | break; | 2126 | break; |
| 2229 | } | 2127 | } |
| 2128 | case VIDIOC_PREPARE_BUF: | ||
| 2129 | { | ||
| 2130 | struct v4l2_buffer *b = arg; | ||
| 2131 | |||
| 2132 | if (!ops->vidioc_prepare_buf) | ||
| 2133 | break; | ||
| 2134 | ret = check_fmt(ops, b->type); | ||
| 2135 | if (ret) | ||
| 2136 | break; | ||
| 2137 | |||
| 2138 | ret = ops->vidioc_prepare_buf(file, fh, b); | ||
| 2139 | |||
| 2140 | dbgarg(cmd, "index=%d", b->index); | ||
| 2141 | break; | ||
| 2142 | } | ||
| 2143 | default: | ||
| 2144 | if (!ops->vidioc_default) | ||
| 2145 | break; | ||
| 2146 | ret = ops->vidioc_default(file, fh, ret_prio >= 0, cmd, arg); | ||
| 2147 | break; | ||
| 2230 | } /* switch */ | 2148 | } /* switch */ |
| 2231 | 2149 | ||
| 2232 | exit_prio: | ||
| 2233 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { | 2150 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { |
| 2234 | if (ret < 0) { | 2151 | if (ret < 0) { |
| 2235 | v4l_print_ioctl(vfd->name, cmd); | 2152 | v4l_print_ioctl(vfd->name, cmd); |
