aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/v4l2-ioctl.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2010-07-12 10:09:41 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-21 19:32:41 -0400
commitfc0a80798576f80ca10b3f6c9c7097f12fd1d64e (patch)
tree561546ada442b0fb9df166723d601b1587d3f6b0 /drivers/media/video/v4l2-ioctl.c
parent9f00edaef8a8741a2d5333676fe9aa23a2a3d2be (diff)
[media] v4l: Share code between video_usercopy and video_ioctl2
The two functions are mostly identical. They handle the copy_from_user and copy_to_user operations related with V4L2 ioctls and call the real ioctl handler. Create a __video_usercopy function that implements the core of video_usercopy and video_ioctl2, and call that function from both. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/v4l2-ioctl.c')
-rw-r--r--drivers/media/video/v4l2-ioctl.c109
1 files changed, 11 insertions, 98 deletions
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 7a720745c3fa..db6ec3868347 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -294,101 +294,6 @@ void v4l_printk_ioctl(unsigned int cmd)
294} 294}
295EXPORT_SYMBOL(v4l_printk_ioctl); 295EXPORT_SYMBOL(v4l_printk_ioctl);
296 296
297/*
298 * helper function -- handles userspace copying for ioctl arguments
299 * Obsolete usercopy function - Should be removed soon
300 */
301long
302video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
303 v4l2_kioctl func)
304{
305 char sbuf[128];
306 void *mbuf = NULL;
307 void *parg = NULL;
308 long err = -EINVAL;
309 int is_ext_ctrl;
310 size_t ctrls_size = 0;
311 void __user *user_ptr = NULL;
312
313 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
314 cmd == VIDIOC_TRY_EXT_CTRLS);
315
316 /* Copy arguments into temp kernel buffer */
317 switch (_IOC_DIR(cmd)) {
318 case _IOC_NONE:
319 parg = NULL;
320 break;
321 case _IOC_READ:
322 case _IOC_WRITE:
323 case (_IOC_WRITE | _IOC_READ):
324 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
325 parg = sbuf;
326 } else {
327 /* too big to allocate from stack */
328 mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
329 if (NULL == mbuf)
330 return -ENOMEM;
331 parg = mbuf;
332 }
333
334 err = -EFAULT;
335 if (_IOC_DIR(cmd) & _IOC_WRITE)
336 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
337 goto out;
338 break;
339 }
340 if (is_ext_ctrl) {
341 struct v4l2_ext_controls *p = parg;
342
343 /* In case of an error, tell the caller that it wasn't
344 a specific control that caused it. */
345 p->error_idx = p->count;
346 user_ptr = (void __user *)p->controls;
347 if (p->count) {
348 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
349 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
350 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
351 err = -ENOMEM;
352 if (NULL == mbuf)
353 goto out_ext_ctrl;
354 err = -EFAULT;
355 if (copy_from_user(mbuf, user_ptr, ctrls_size))
356 goto out_ext_ctrl;
357 p->controls = mbuf;
358 }
359 }
360
361 /* call driver */
362 err = func(file, cmd, parg);
363 if (err == -ENOIOCTLCMD)
364 err = -EINVAL;
365 if (is_ext_ctrl) {
366 struct v4l2_ext_controls *p = parg;
367
368 p->controls = (void *)user_ptr;
369 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
370 err = -EFAULT;
371 goto out_ext_ctrl;
372 }
373 if (err < 0)
374 goto out;
375
376out_ext_ctrl:
377 /* Copy results into user buffer */
378 switch (_IOC_DIR(cmd)) {
379 case _IOC_READ:
380 case (_IOC_WRITE | _IOC_READ):
381 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
382 err = -EFAULT;
383 break;
384 }
385
386out:
387 kfree(mbuf);
388 return err;
389}
390EXPORT_SYMBOL(video_usercopy);
391
392static void dbgbuf(unsigned int cmd, struct video_device *vfd, 297static void dbgbuf(unsigned int cmd, struct video_device *vfd,
393 struct v4l2_buffer *p) 298 struct v4l2_buffer *p)
394{ 299{
@@ -2332,8 +2237,9 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
2332 return ret; 2237 return ret;
2333} 2238}
2334 2239
2335long video_ioctl2(struct file *file, 2240long
2336 unsigned int cmd, unsigned long arg) 2241video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
2242 v4l2_kioctl func)
2337{ 2243{
2338 char sbuf[128]; 2244 char sbuf[128];
2339 void *mbuf = NULL; 2245 void *mbuf = NULL;
@@ -2395,7 +2301,7 @@ long video_ioctl2(struct file *file,
2395 } 2301 }
2396 2302
2397 /* Handles IOCTL */ 2303 /* Handles IOCTL */
2398 err = __video_do_ioctl(file, cmd, parg); 2304 err = func(file, cmd, parg);
2399 if (err == -ENOIOCTLCMD) 2305 if (err == -ENOIOCTLCMD)
2400 err = -EINVAL; 2306 err = -EINVAL;
2401 2307
@@ -2422,4 +2328,11 @@ out:
2422 kfree(mbuf); 2328 kfree(mbuf);
2423 return err; 2329 return err;
2424} 2330}
2331EXPORT_SYMBOL(video_usercopy);
2332
2333long video_ioctl2(struct file *file,
2334 unsigned int cmd, unsigned long arg)
2335{
2336 return video_usercopy(file, cmd, arg, __video_do_ioctl);
2337}
2425EXPORT_SYMBOL(video_ioctl2); 2338EXPORT_SYMBOL(video_ioctl2);