ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[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                 parg = (void *)arg;
40                 break;
41         case _IOC_READ: /* some v4l ioctls are marked wrong ... */
42         case _IOC_WRITE:
43         case (_IOC_WRITE | _IOC_READ):
44                 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
45                         parg = sbuf;
46                 } else {
47                         /* too big to allocate from stack */
48                         mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
49                         if (NULL == mbuf)
50                                 return -ENOMEM;
51                         parg = mbuf;
52                 }
53
54                 err = -EFAULT;
55                 if (copy_from_user(parg, (void *)arg, _IOC_SIZE(cmd)))
56                         goto out;
57                 break;
58         }
59
60         /* call driver */
61         if ((err = func(inode, file, cmd, parg)) == -ENOIOCTLCMD)
62                 err = -EINVAL;
63
64         if (err < 0)
65                 goto out;
66
67         /*  Copy results into user buffer  */
68         switch (_IOC_DIR(cmd))
69         {
70         case _IOC_READ:
71         case (_IOC_WRITE | _IOC_READ):
72                 if (copy_to_user((void *)arg, parg, _IOC_SIZE(cmd)))
73                         err = -EFAULT;
74                 break;
75         }
76
77 out:
78         if (mbuf)
79                 kfree(mbuf);
80
81         return err;
82 }
83
84 EXPORT_SYMBOL(dvb_usercopy);
85 EXPORT_SYMBOL(dvb_kernel_thread_setup);