diff options
Diffstat (limited to 'linux/drivers/media/dvb/dvb-core')
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/compat.c | 91 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/compat.h | 31 |
2 files changed, 122 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 + diff --git a/linux/drivers/media/dvb/dvb-core/compat.h b/linux/drivers/media/dvb/dvb-core/compat.h index 25af8145b..33f30145c 100644 --- a/linux/drivers/media/dvb/dvb-core/compat.h +++ b/linux/drivers/media/dvb/dvb-core/compat.h @@ -9,16 +9,47 @@ #include <linux/module.h> #include <linux/list.h> +#include <linux/videodev.h> + #ifndef MODULE_LICENSE #define MODULE_LICENSE(x) #endif + #ifndef list_for_each_safe #define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) #endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,45)) || !CONFIG_VIDEO_DEV +#define video_usercopy generic_usercopy + +extern 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)); +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,45) + +#define video_devdata(dev) (dev->priv) + +static inline +void cond_resched (void) +{ + if (current->need_resched) + schedule(); +} + +extern struct page * vmalloc_to_page(void *addr); + +#define remap_page_range(vma,from,to,size,prot) \ + remap_page_range(from,to,size,prot) + +#endif + #endif |