diff options
Diffstat (limited to 'drivers/media/video/uvc/uvc_video.c')
-rw-r--r-- | drivers/media/video/uvc/uvc_video.c | 33 |
1 files changed, 22 insertions, 11 deletions
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, | |||
90 | static int uvc_get_video_ctrl(struct uvc_video_device *video, | 90 | static 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; | 142 | out: |
143 | kfree(data); | ||
144 | return ret; | ||
140 | } | 145 | } |
141 | 146 | ||
142 | int uvc_set_video_ctrl(struct uvc_video_device *video, | 147 | int 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 | ||
183 | int uvc_probe_video(struct uvc_video_device *video, | 194 | int uvc_probe_video(struct uvc_video_device *video, |