diff options
author | Holger Waechtler <devnull@localhost> | 2002-11-07 19:40:48 +0000 |
---|---|---|
committer | Holger Waechtler <devnull@localhost> | 2002-11-07 19:40:48 +0000 |
commit | ecdaecc3faa0526b4c80c4f1759a3b1be04d2546 (patch) | |
tree | f9674a161dd99c8a4c2b266a5101695e954dcb4f /linux/drivers/media/dvb/dvb-core/compat.c | |
parent | 81e8895d0b64c877036853a5dbd8f9b1ba564364 (diff) | |
download | mediapointer-dvb-s2-ecdaecc3faa0526b4c80c4f1759a3b1be04d2546.tar.gz mediapointer-dvb-s2-ecdaecc3faa0526b4c80c4f1759a3b1be04d2546.tar.bz2 |
2.4 compatibility crap
Diffstat (limited to 'linux/drivers/media/dvb/dvb-core/compat.c')
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/compat.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/compat.c b/linux/drivers/media/dvb/dvb-core/compat.c new file mode 100644 index 000000000..af33c58b7 --- /dev/null +++ b/linux/drivers/media/dvb/dvb-core/compat.c @@ -0,0 +1,91 @@ +#include <linux/slab.h> +#include "compat.h" + +/** + * compatibility crap for old kernels. No guarantee for a working driver + * even when everything compiles. + */ + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,45)) || !CONFIG_VIDEO_DEV +int generic_usercopy(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg, + int (*func)(struct inode *inode, struct file *file, + unsigned int cmd, void *arg)) +{ + char sbuf[128]; + void *mbuf = NULL; + void *parg = NULL; + int err = -EINVAL; + + /* Copy arguments into temp kernel buffer */ + switch (_IOC_DIR(cmd)) { + case _IOC_NONE: + 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 *)arg, _IOC_SIZE(cmd))) + goto out; + break; + } + + /* call driver */ + if ((err = func(inode, file, cmd, parg)) == -ENOIOCTLCMD) + err = -EINVAL; + + if (err < 0) + goto out; + + /* Copy results into user buffer */ + switch (_IOC_DIR(cmd)) + { + case _IOC_READ: + case (_IOC_WRITE | _IOC_READ): + if (copy_to_user((void *)arg, parg, _IOC_SIZE(cmd))) + err = -EFAULT; + break; + } + +out: + if (mbuf) + kfree(mbuf); + + return err; +} +#endif + + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,45)) +struct page * vmalloc_to_page(void *vmalloc_addr) +{ + unsigned long addr = (unsigned long) vmalloc_addr; + struct page *page = NULL; + pgd_t *pgd = pgd_offset_k(addr); + pmd_t *pmd; + pte_t *ptep, pte; + + if (!pgd_none(*pgd)) { + pmd = pmd_offset(pgd, addr); + if (!pmd_none(*pmd)) { + ptep = pte_offset(pmd, addr); + pte = *ptep; + if (pte_present(pte)) + page = pte_page(pte); + } + } + return page; +} +#endif + |