Skip to content

Commit fc0a807

Browse files
pinchartlMauro Carvalho Chehab
authored and
Mauro Carvalho Chehab
committed
[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>
1 parent 9f00eda commit fc0a807

File tree

1 file changed

+11
-98
lines changed

1 file changed

+11
-98
lines changed

Diff for: drivers/media/video/v4l2-ioctl.c

+11-98
Original file line numberDiff line numberDiff line change
@@ -294,101 +294,6 @@ void v4l_printk_ioctl(unsigned int cmd)
294294
}
295295
EXPORT_SYMBOL(v4l_printk_ioctl);
296296

297-
/*
298-
* helper function -- handles userspace copying for ioctl arguments
299-
* Obsolete usercopy function - Should be removed soon
300-
*/
301-
long
302-
video_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-
376-
out_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-
386-
out:
387-
kfree(mbuf);
388-
return err;
389-
}
390-
EXPORT_SYMBOL(video_usercopy);
391-
392297
static void dbgbuf(unsigned int cmd, struct video_device *vfd,
393298
struct v4l2_buffer *p)
394299
{
@@ -2332,8 +2237,9 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
23322237
return ret;
23332238
}
23342239

2335-
long video_ioctl2(struct file *file,
2336-
unsigned int cmd, unsigned long arg)
2240+
long
2241+
video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
2242+
v4l2_kioctl func)
23372243
{
23382244
char sbuf[128];
23392245
void *mbuf = NULL;
@@ -2395,7 +2301,7 @@ long video_ioctl2(struct file *file,
23952301
}
23962302

23972303
/* Handles IOCTL */
2398-
err = __video_do_ioctl(file, cmd, parg);
2304+
err = func(file, cmd, parg);
23992305
if (err == -ENOIOCTLCMD)
24002306
err = -EINVAL;
24012307

@@ -2422,4 +2328,11 @@ long video_ioctl2(struct file *file,
24222328
kfree(mbuf);
24232329
return err;
24242330
}
2331+
EXPORT_SYMBOL(video_usercopy);
2332+
2333+
long video_ioctl2(struct file *file,
2334+
unsigned int cmd, unsigned long arg)
2335+
{
2336+
return video_usercopy(file, cmd, arg, __video_do_ioctl);
2337+
}
24252338
EXPORT_SYMBOL(video_ioctl2);

0 commit comments

Comments
 (0)