VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / drivers / media / dvb / dvb-core / dvb_functions.c
1 #include <linux/errno.h>
2 #include <linux/fs.h>
3 #include <linux/string.h>
4 #include <linux/module.h>
5 #include <linux/ioctl.h>
6 #include <linux/slab.h>
7 #include <linux/smp_lock.h>
8 #include <asm/uaccess.h>
9
10 void dvb_kernel_thread_setup (const char *thread_name)
11 {
12         lock_kernel ();
13
14         daemonize (thread_name);
15
16         sigfillset (&current->blocked);
17
18         unlock_kernel ();
19 }
20
21 /* if the miracle happens and "generic_usercopy()" is included into
22    the kernel, then this can vanish. please don't make the mistake and
23    define this as video_usercopy(). this will introduce a dependecy
24    to the v4l "videodev.o" module, which is unnecessary for some
25    cards (ie. the budget dvb-cards don't need the v4l module...) */
26 int dvb_usercopy(struct inode *inode, struct file *file,
27                      unsigned int cmd, unsigned long arg,
28                      int (*func)(struct inode *inode, struct file *file,
29                      unsigned int cmd, void *arg))
30 {
31         char    sbuf[128];
32         void    *mbuf = NULL;
33         void    *parg = NULL;
34         int     err  = -EINVAL;
35
36         /*  Copy arguments into temp kernel buffer  */
37         switch (_IOC_DIR(cmd)) {
38         case _IOC_NONE:
39                 /*
40                  * For this command, the pointer is actually an integer
41                  * argument.
42                  */
43                 parg = (void *) arg;
44                 break;
45         case _IOC_READ: /* some v4l ioctls are marked wrong ... */
46         case _IOC_WRITE:
47         case (_IOC_WRITE | _IOC_READ):
48                 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
49                         parg = sbuf;
50                 } else {
51                         /* too big to allocate from stack */
52                         mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
53                         if (NULL == mbuf)
54                                 return -ENOMEM;
55                         parg = mbuf;
56                 }
57
58                 err = -EFAULT;
59                 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
60                         goto out;
61                 break;
62         }
63
64         /* call driver */
65         if ((err = func(inode, file, cmd, parg)) == -ENOIOCTLCMD)
66                 err = -EINVAL;
67
68         if (err < 0)
69                 goto out;
70
71         /*  Copy results into user buffer  */
72         switch (_IOC_DIR(cmd))
73         {
74         case _IOC_READ:
75         case (_IOC_WRITE | _IOC_READ):
76                 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
77                         err = -EFAULT;
78                 break;
79         }
80
81 out:
82         if (mbuf)
83                 kfree(mbuf);
84
85         return err;
86 }
87
88 EXPORT_SYMBOL(dvb_usercopy);
89 EXPORT_SYMBOL(dvb_kernel_thread_setup);