diff options
Diffstat (limited to 'drivers/media/video/gspca/gspca.c')
-rw-r--r-- | drivers/media/video/gspca/gspca.c | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 28842ed24c09..33161e1e0bcc 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -856,37 +856,44 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
856 | return 0; | 856 | return 0; |
857 | } | 857 | } |
858 | 858 | ||
859 | /* the use of V4L2_CTRL_FLAG_NEXT_CTRL asks for the controls to be sorted */ | ||
860 | static int vidioc_queryctrl(struct file *file, void *priv, | 859 | static int vidioc_queryctrl(struct file *file, void *priv, |
861 | struct v4l2_queryctrl *q_ctrl) | 860 | struct v4l2_queryctrl *q_ctrl) |
862 | { | 861 | { |
863 | struct gspca_dev *gspca_dev = priv; | 862 | struct gspca_dev *gspca_dev = priv; |
864 | int i; | 863 | int i, ix; |
865 | u32 id; | 864 | u32 id; |
866 | 865 | ||
866 | ix = -1; | ||
867 | id = q_ctrl->id; | 867 | id = q_ctrl->id; |
868 | if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { | 868 | if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { |
869 | id &= V4L2_CTRL_ID_MASK; | 869 | id &= V4L2_CTRL_ID_MASK; |
870 | id++; | 870 | id++; |
871 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { | 871 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { |
872 | if (id >= gspca_dev->sd_desc->ctrls[i].qctrl.id) { | 872 | if (id < gspca_dev->sd_desc->ctrls[i].qctrl.id) |
873 | memcpy(q_ctrl, | 873 | continue; |
874 | &gspca_dev->sd_desc->ctrls[i].qctrl, | 874 | if (ix < 0) { |
875 | sizeof *q_ctrl); | 875 | ix = i; |
876 | return 0; | 876 | continue; |
877 | } | 877 | } |
878 | if (gspca_dev->sd_desc->ctrls[i].qctrl.id | ||
879 | > gspca_dev->sd_desc->ctrls[ix].qctrl.id) | ||
880 | continue; | ||
881 | ix = i; | ||
878 | } | 882 | } |
879 | return -EINVAL; | ||
880 | } | 883 | } |
881 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { | 884 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { |
882 | if (id == gspca_dev->sd_desc->ctrls[i].qctrl.id) { | 885 | if (id == gspca_dev->sd_desc->ctrls[i].qctrl.id) { |
883 | memcpy(q_ctrl, | 886 | ix = i; |
884 | &gspca_dev->sd_desc->ctrls[i].qctrl, | 887 | break; |
885 | sizeof *q_ctrl); | ||
886 | return 0; | ||
887 | } | 888 | } |
888 | } | 889 | } |
889 | return -EINVAL; | 890 | if (ix < 0) |
891 | return -EINVAL; | ||
892 | memcpy(q_ctrl, &gspca_dev->sd_desc->ctrls[ix].qctrl, | ||
893 | sizeof *q_ctrl); | ||
894 | if (gspca_dev->ctrl_dis & (1 << ix)) | ||
895 | q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED; | ||
896 | return 0; | ||
890 | } | 897 | } |
891 | 898 | ||
892 | static int vidioc_s_ctrl(struct file *file, void *priv, | 899 | static int vidioc_s_ctrl(struct file *file, void *priv, |