diff -uNrwB -x '.*' -x '*.o' -x '*.mod' --new-file linux-2.5.69/drivers/media/video/videodev.c linux-2.5.69.usercopy/drivers/media/video/videodev.c --- linux-2.5.69/drivers/media/video/videodev.c 2003-05-06 13:16:21.000000000 +0200 +++ linux-2.5.69.usercopy/drivers/media/video/videodev.c 2003-05-23 10:14:27.000000000 +0200 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -109,67 +109,6 @@ } /* - * helper function -- handles userspace copying for ioctl arguments - */ -int -video_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 */ - err = func(inode, file, cmd, parg); - if (err == -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; -} - -/* * open/release helper functions -- handle exclusive opens */ extern int video_exclusive_open(struct inode *inode, struct file *file) @@ -506,7 +445,6 @@ EXPORT_SYMBOL(video_register_device); EXPORT_SYMBOL(video_unregister_device); EXPORT_SYMBOL(video_devdata); -EXPORT_SYMBOL(video_usercopy); EXPORT_SYMBOL(video_exclusive_open); EXPORT_SYMBOL(video_exclusive_release); diff -uNrwB -x '.*' -x '*.o' -x '*.mod' --new-file linux-2.5.69/include/linux/usercopy.h linux-2.5.69.usercopy/include/linux/usercopy.h --- linux-2.5.69/include/linux/usercopy.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.5.69.usercopy/include/linux/usercopy.h 2003-05-23 09:55:17.000000000 +0200 @@ -0,0 +1,12 @@ +#ifndef _LINUX_USERCOPY_H +#define _LINUX_USERCOPY_H + +#include + +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 /* _LINUX_USERCOPY_H */ diff -uNrwB -x '.*' -x '*.o' -x '*.mod' --new-file linux-2.5.69/include/linux/videodev.h linux-2.5.69.usercopy/include/linux/videodev.h --- linux-2.5.69/include/linux/videodev.h 2003-05-06 13:16:43.000000000 +0200 +++ linux-2.5.69.usercopy/include/linux/videodev.h 2003-05-23 10:15:51.000000000 +0200 @@ -20,6 +20,7 @@ #include #include +#include struct video_device { diff -uNrwB -x '.*' -x '*.o' -x '*.mod' --new-file linux-2.5.69/lib/Kconfig linux-2.5.69.usercopy/lib/Kconfig --- linux-2.5.69/lib/Kconfig 2003-04-07 19:31:46.000000000 +0200 +++ linux-2.5.69.usercopy/lib/Kconfig 2003-05-23 09:58:53.000000000 +0200 @@ -12,6 +12,15 @@ kernel tree does. Such modules that use library CRC32 functions require M here. +config USERCOPY + tristate "Generic usercopy function" + help + This option is provided for the case where no in-kernel-tree + modules require the generic usercopy function for copying + ioctl arguments from user space to kernel space, but a module + built outside the kernel tree does. Such modules that use + this function require M here. + # # Do we need the compression support? # diff -uNrwB -x '.*' -x '*.o' -x '*.mod' --new-file linux-2.5.69/lib/Makefile linux-2.5.69.usercopy/lib/Makefile --- linux-2.5.69/lib/Makefile 2003-05-06 13:15:51.000000000 +0200 +++ linux-2.5.69.usercopy/lib/Makefile 2003-05-23 10:26:37.000000000 +0200 @@ -21,6 +21,7 @@ endif obj-$(CONFIG_CRC32) += crc32.o +obj-$(CONFIG_USERCOPY) += usercopy.o obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/ obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/ @@ -29,6 +30,9 @@ include $(TOPDIR)/drivers/usb/Makefile.lib include $(TOPDIR)/fs/Makefile.lib include $(TOPDIR)/net/bluetooth/bnep/Makefile.lib +include $(TOPDIR)/drivers/media/video/Makefile.lib +include $(TOPDIR)/drivers/media/common/Makefile.lib +include $(TOPDIR)/drivers/media/dvb/dvb-core/Makefile.lib host-progs := gen_crc32table clean-files := crc32table.h diff -uNrwB -x '.*' -x '*.o' -x '*.mod' --new-file linux-2.5.69/lib/usercopy.c linux-2.5.69.usercopy/lib/usercopy.c --- linux-2.5.69/lib/usercopy.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.5.69.usercopy/lib/usercopy.c 2003-05-23 10:46:43.000000000 +0200 @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include + +#include + +/* + * helper function -- handles userspace copying for ioctl arguments + */ + +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 */ + err = func(inode, file, cmd, parg); + if (err == -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; +} + +EXPORT_SYMBOL(generic_usercopy);