aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/uvc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/uvc')
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c33
-rw-r--r--drivers/media/video/uvc/uvc_video.c33
2 files changed, 43 insertions, 23 deletions
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 626f4ad7e876..6ef3e5297de8 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -585,13 +585,17 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
585 struct uvc_control_mapping *mapping; 585 struct uvc_control_mapping *mapping;
586 struct uvc_menu_info *menu; 586 struct uvc_menu_info *menu;
587 unsigned int i; 587 unsigned int i;
588 __u8 data[8]; 588 __u8 *data;
589 int ret; 589 int ret;
590 590
591 ctrl = uvc_find_control(video, v4l2_ctrl->id, &mapping); 591 ctrl = uvc_find_control(video, v4l2_ctrl->id, &mapping);
592 if (ctrl == NULL) 592 if (ctrl == NULL)
593 return -EINVAL; 593 return -EINVAL;
594 594
595 data = kmalloc(8, GFP_KERNEL);
596 if (data == NULL)
597 return -ENOMEM;
598
595 memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); 599 memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl);
596 v4l2_ctrl->id = mapping->id; 600 v4l2_ctrl->id = mapping->id;
597 v4l2_ctrl->type = mapping->v4l2_type; 601 v4l2_ctrl->type = mapping->v4l2_type;
@@ -604,8 +608,8 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
604 if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { 608 if (ctrl->info->flags & UVC_CONTROL_GET_DEF) {
605 if ((ret = uvc_query_ctrl(video->dev, GET_DEF, ctrl->entity->id, 609 if ((ret = uvc_query_ctrl(video->dev, GET_DEF, ctrl->entity->id,
606 video->dev->intfnum, ctrl->info->selector, 610 video->dev->intfnum, ctrl->info->selector,
607 &data, ctrl->info->size)) < 0) 611 data, ctrl->info->size)) < 0)
608 return ret; 612 goto out;
609 v4l2_ctrl->default_value = uvc_get_le_value(data, mapping); 613 v4l2_ctrl->default_value = uvc_get_le_value(data, mapping);
610 } 614 }
611 615
@@ -623,13 +627,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
623 } 627 }
624 } 628 }
625 629
626 return 0; 630 ret = 0;
631 goto out;
627 632
628 case V4L2_CTRL_TYPE_BOOLEAN: 633 case V4L2_CTRL_TYPE_BOOLEAN:
629 v4l2_ctrl->minimum = 0; 634 v4l2_ctrl->minimum = 0;
630 v4l2_ctrl->maximum = 1; 635 v4l2_ctrl->maximum = 1;
631 v4l2_ctrl->step = 1; 636 v4l2_ctrl->step = 1;
632 return 0; 637 ret = 0;
638 goto out;
633 639
634 default: 640 default:
635 break; 641 break;
@@ -638,26 +644,29 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
638 if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { 644 if (ctrl->info->flags & UVC_CONTROL_GET_MIN) {
639 if ((ret = uvc_query_ctrl(video->dev, GET_MIN, ctrl->entity->id, 645 if ((ret = uvc_query_ctrl(video->dev, GET_MIN, ctrl->entity->id,
640 video->dev->intfnum, ctrl->info->selector, 646 video->dev->intfnum, ctrl->info->selector,
641 &data, ctrl->info->size)) < 0) 647 data, ctrl->info->size)) < 0)
642 return ret; 648 goto out;
643 v4l2_ctrl->minimum = uvc_get_le_value(data, mapping); 649 v4l2_ctrl->minimum = uvc_get_le_value(data, mapping);
644 } 650 }
645 if (ctrl->info->flags & UVC_CONTROL_GET_MAX) { 651 if (ctrl->info->flags & UVC_CONTROL_GET_MAX) {
646 if ((ret = uvc_query_ctrl(video->dev, GET_MAX, ctrl->entity->id, 652 if ((ret = uvc_query_ctrl(video->dev, GET_MAX, ctrl->entity->id,
647 video->dev->intfnum, ctrl->info->selector, 653 video->dev->intfnum, ctrl->info->selector,
648 &data, ctrl->info->size)) < 0) 654 data, ctrl->info->size)) < 0)
649 return ret; 655 goto out;
650 v4l2_ctrl->maximum = uvc_get_le_value(data, mapping); 656 v4l2_ctrl->maximum = uvc_get_le_value(data, mapping);
651 } 657 }
652 if (ctrl->info->flags & UVC_CONTROL_GET_RES) { 658 if (ctrl->info->flags & UVC_CONTROL_GET_RES) {
653 if ((ret = uvc_query_ctrl(video->dev, GET_RES, ctrl->entity->id, 659 if ((ret = uvc_query_ctrl(video->dev, GET_RES, ctrl->entity->id,
654 video->dev->intfnum, ctrl->info->selector, 660 video->dev->intfnum, ctrl->info->selector,
655 &data, ctrl->info->size)) < 0) 661 data, ctrl->info->size)) < 0)
656 return ret; 662 goto out;
657 v4l2_ctrl->step = uvc_get_le_value(data, mapping); 663 v4l2_ctrl->step = uvc_get_le_value(data, mapping);
658 } 664 }
659 665
660 return 0; 666 ret = 0;
667out:
668 kfree(data);
669 return ret;
661} 670}
662 671
663 672
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index ad63794fda77..6854ac78a161 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -90,17 +90,20 @@ static void uvc_fixup_buffer_size(struct uvc_video_device *video,
90static int uvc_get_video_ctrl(struct uvc_video_device *video, 90static int uvc_get_video_ctrl(struct uvc_video_device *video,
91 struct uvc_streaming_control *ctrl, int probe, __u8 query) 91 struct uvc_streaming_control *ctrl, int probe, __u8 query)
92{ 92{
93 __u8 data[34]; 93 __u8 *data;
94 __u8 size; 94 __u16 size;
95 int ret; 95 int ret;
96 96
97 size = video->dev->uvc_version >= 0x0110 ? 34 : 26; 97 size = video->dev->uvc_version >= 0x0110 ? 34 : 26;
98 data = kmalloc(size, GFP_KERNEL);
99 if (data == NULL)
100 return -ENOMEM;
101
98 ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum, 102 ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum,
99 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, &data, size, 103 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
100 UVC_CTRL_STREAMING_TIMEOUT); 104 UVC_CTRL_STREAMING_TIMEOUT);
101
102 if (ret < 0) 105 if (ret < 0)
103 return ret; 106 goto out;
104 107
105 ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]); 108 ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]);
106 ctrl->bFormatIndex = data[2]; 109 ctrl->bFormatIndex = data[2];
@@ -136,17 +139,22 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
136 */ 139 */
137 uvc_fixup_buffer_size(video, ctrl); 140 uvc_fixup_buffer_size(video, ctrl);
138 141
139 return 0; 142out:
143 kfree(data);
144 return ret;
140} 145}
141 146
142int uvc_set_video_ctrl(struct uvc_video_device *video, 147int uvc_set_video_ctrl(struct uvc_video_device *video,
143 struct uvc_streaming_control *ctrl, int probe) 148 struct uvc_streaming_control *ctrl, int probe)
144{ 149{
145 __u8 data[34]; 150 __u8 *data;
146 __u8 size; 151 __u16 size;
152 int ret;
147 153
148 size = video->dev->uvc_version >= 0x0110 ? 34 : 26; 154 size = video->dev->uvc_version >= 0x0110 ? 34 : 26;
149 memset(data, 0, sizeof data); 155 data = kzalloc(size, GFP_KERNEL);
156 if (data == NULL)
157 return -ENOMEM;
150 158
151 *(__le16 *)&data[0] = cpu_to_le16(ctrl->bmHint); 159 *(__le16 *)&data[0] = cpu_to_le16(ctrl->bmHint);
152 data[2] = ctrl->bFormatIndex; 160 data[2] = ctrl->bFormatIndex;
@@ -174,10 +182,13 @@ int uvc_set_video_ctrl(struct uvc_video_device *video,
174 data[33] = ctrl->bMaxVersion; 182 data[33] = ctrl->bMaxVersion;
175 } 183 }
176 184
177 return __uvc_query_ctrl(video->dev, SET_CUR, 0, 185 ret = __uvc_query_ctrl(video->dev, SET_CUR, 0,
178 video->streaming->intfnum, 186 video->streaming->intfnum,
179 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, &data, size, 187 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
180 UVC_CTRL_STREAMING_TIMEOUT); 188 UVC_CTRL_STREAMING_TIMEOUT);
189
190 kfree(data);
191 return ret;
181} 192}
182 193
183int uvc_probe_video(struct uvc_video_device *video, 194int uvc_probe_video(struct uvc_video_device *video,