Skip to content

Commit

Permalink
Fix older kernels
Browse files Browse the repository at this point in the history
  • Loading branch information
bas-t committed Feb 28, 2015
1 parent 11c4899 commit 43120a0
Showing 1 changed file with 99 additions and 1 deletion.
100 changes: 99 additions & 1 deletion dvbloopback/module/dvb_loopback.c
Expand Up @@ -113,6 +113,104 @@ static void rvfree(void *mem, unsigned long size)
vfree(mem);
}

/* This is a copy of dvb_usercopy. We need to do this because it isn't exported
by dvbdev without the newest dvb-core patch
*/

#if LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0)
static int dvblb_usercopy(struct file *file,
unsigned int cmd, unsigned long arg,
int (*func)(struct file *file,
unsigned int cmd, void *arg))

{
char sbuf[128];
void *mbuf = NULL;
void *parg = NULL;
int err = -EINVAL;
struct dtv_properties *tvps = NULL;
struct dtv_property *tvp = NULL;

/* Copy arguments into temp kernel buffer */
switch (_IOC_DIR(cmd)) {
case _IOC_NONE:
/*
* For this command, the pointer is actually an integer
* argument.
*/
parg = (void *) arg;
break;
case _IOC_READ: /* some v4l ioctls are marked wrong ... */
case _IOC_WRITE:
case (_IOC_WRITE | _IOC_READ):
if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
parg = sbuf;
} else {
/* too big to allocate from stack */
mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
if (NULL == mbuf)
return -ENOMEM;
parg = mbuf;
}

err = -EFAULT;
if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
goto out;
if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY)) {
tvps = (struct dtv_properties __user *)arg;
tvp = (struct dtv_property *) kmalloc(tvps->num *
sizeof(struct dtv_property), GFP_KERNEL);
if (!tvp){
err = -ENOMEM;
goto out;
}
if (copy_from_user(tvp, tvps->props,
(tvps->num) * sizeof(struct dtv_property))) {
err = -EFAULT;
goto out;
}
tvps = (struct dtv_properties __user *)parg;
tvps->props = tvp;
tvp = NULL;
}
break;
}

/* call driver */
if ((err = func(file, cmd, parg)) == -ENOIOCTLCMD)
err = -ENOTTY;

if (err < 0)
goto out;

/* Copy results into user buffer */
switch (_IOC_DIR(cmd))
{
case _IOC_READ:
case (_IOC_WRITE | _IOC_READ):
if ((cmd == FE_GET_PROPERTY) || (cmd == FE_SET_PROPERTY))
{
tvps = (struct dtv_properties __user *)arg;
tvp = tvps->props;
tvps = (struct dtv_properties __user *)parg;
if (copy_to_user(tvp, tvps->props, tvps->num *
sizeof(struct dtv_property))) {
err = -EFAULT;
goto out;
}
tvps->props = tvp;
}
if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
err = -EFAULT;
break;
}

out:
kfree(mbuf);
return err;
}
#endif

static int get_new_filemap(struct dvblb_devinfo *lbdev, int id) {
int i;
for(i = 0; i < DVBLB_MAXFD; i++)
Expand Down Expand Up @@ -609,7 +707,7 @@ static long dvblb_ioctl(struct file *f,
if (lbdev->forward_dev)
return dvblb_forward_ioctl(lbdev, f, cmd, arg);

return dvblb_usercopy (f, cmd, arg,
return dvb_usercopy (f, cmd, arg,
dvbdev->kernel_ioctl);
}
/* This is the userspace control device */
Expand Down

0 comments on commit 43120a0

Please sign in to comment.