From: Andi Kleen Convert dv1394 driver to compat_ioctl Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton --- 25-akpm/drivers/ieee1394/dv1394.c | 99 +++++++++++++++++++------------------- 1 files changed, 51 insertions(+), 48 deletions(-) diff -puN drivers/ieee1394/dv1394.c~convert-dv1394-driver-to-compat_ioctl drivers/ieee1394/dv1394.c --- 25/drivers/ieee1394/dv1394.c~convert-dv1394-driver-to-compat_ioctl Tue Jan 18 15:45:23 2005 +++ 25-akpm/drivers/ieee1394/dv1394.c Tue Jan 18 15:45:23 2005 @@ -168,6 +168,11 @@ static inline void flush_pci_write(struc static void it_tasklet_func(unsigned long data); static void ir_tasklet_func(unsigned long data); +#ifdef CONFIG_COMPAT +static long dv1394_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg); +#endif + /* GLOBAL DATA */ /* list of all video_cards */ @@ -1540,26 +1545,29 @@ static ssize_t dv1394_read(struct file * /*** DEVICE IOCTL INTERFACE ************************************************/ -/* I *think* the VFS serializes ioctl() for us, so we don't have to worry - about situations like having two threads in here at once... */ - -static int dv1394_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long dv1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct video_card *video = file_to_video_card(file); + struct video_card *video; unsigned long flags; int ret = -EINVAL; void __user *argp = (void __user *)arg; DECLARE_WAITQUEUE(wait, current); + lock_kernel(); + video = file_to_video_card(file); + /* serialize this to prevent multi-threaded mayhem */ if (file->f_flags & O_NONBLOCK) { - if (down_trylock(&video->sem)) + if (down_trylock(&video->sem)) { + unlock_kernel(); return -EAGAIN; + } } else { - if (down_interruptible(&video->sem)) + if (down_interruptible(&video->sem)) { + unlock_kernel(); return -ERESTARTSYS; + } } switch(cmd) @@ -1783,11 +1791,10 @@ static int dv1394_ioctl(struct inode *in out: up(&video->sem); + unlock_kernel(); return ret; } - - /*** DEVICE FILE INTERFACE CONTINUED ***************************************/ static int dv1394_open(struct inode *inode, struct file *file) @@ -2165,7 +2172,10 @@ static struct file_operations dv1394_fop { .owner = THIS_MODULE, .poll = dv1394_poll, - .ioctl = dv1394_ioctl, + .unlocked_ioctl = dv1394_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = dv1394_compat_ioctl, +#endif .mmap = dv1394_mmap, .open = dv1394_open, .write = dv1394_write, @@ -2507,8 +2517,9 @@ struct dv1394_status32 { u32 dropped_frames; }; -static int handle_dv1394_init(unsigned int fd, unsigned int cmd, unsigned long arg, - struct file *file) +/* RED-PEN: this should use compat_alloc_userspace instead */ + +static int handle_dv1394_init(struct file *file, unsigned int cmd, unsigned long arg) { struct dv1394_init32 dv32; struct dv1394_init dv; @@ -2531,15 +2542,14 @@ static int handle_dv1394_init(unsigned i old_fs = get_fs(); set_fs(KERNEL_DS); - ret = dv1394_ioctl(file->f_dentry->d_inode, file, + ret = dv1394_ioctl(file, DV1394_IOC_INIT, (unsigned long)&dv); set_fs(old_fs); return ret; } -static int handle_dv1394_get_status(unsigned int fd, unsigned int cmd, unsigned long arg, - struct file *file) +static int handle_dv1394_get_status(struct file *file, unsigned int cmd, unsigned long arg) { struct dv1394_status32 dv32; struct dv1394_status dv; @@ -2551,7 +2561,7 @@ static int handle_dv1394_get_status(unsi old_fs = get_fs(); set_fs(KERNEL_DS); - ret = dv1394_ioctl(file->f_dentry->d_inode, file, + ret = dv1394_ioctl(file, DV1394_IOC_GET_STATUS, (unsigned long)&dv); set_fs(old_fs); @@ -2574,6 +2584,30 @@ static int handle_dv1394_get_status(unsi return ret; } + + + +static long dv1394_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + int err; + switch (cmd) { + case DV1394_IOC_SHUTDOWN: + case DV1394_IOC_SUBMIT_FRAMES: + case DV1394_IOC_WAIT_FRAMES: + case DV1394_IOC_RECEIVE_FRAMES: + case DV1394_IOC_START_RECEIVE: + return dv1394_ioctl(file, cmd, arg); + + case DV1394_IOC32_INIT: + return handle_dv1394_init(file, cmd, arg); + case DV1394_IOC32_GET_STATUS: + return handle_dv1394_get_status(file, cmd, arg); + default: + return -ENOIOCTLCMD; + } +} + #endif /* CONFIG_COMPAT */ @@ -2586,20 +2620,6 @@ MODULE_LICENSE("GPL"); static void __exit dv1394_exit_module(void) { -#ifdef CONFIG_COMPAT - int ret; - - ret = unregister_ioctl32_conversion(DV1394_IOC_SHUTDOWN); - ret |= unregister_ioctl32_conversion(DV1394_IOC_SUBMIT_FRAMES); - ret |= unregister_ioctl32_conversion(DV1394_IOC_WAIT_FRAMES); - ret |= unregister_ioctl32_conversion(DV1394_IOC_RECEIVE_FRAMES); - ret |= unregister_ioctl32_conversion(DV1394_IOC_START_RECEIVE); - ret |= unregister_ioctl32_conversion(DV1394_IOC32_INIT); - ret |= unregister_ioctl32_conversion(DV1394_IOC32_GET_STATUS); - if (ret) - printk(KERN_ERR "dv1394: Error unregistering ioctl32 translations\n"); -#endif - hpsb_unregister_protocol(&dv1394_driver); hpsb_unregister_highlevel(&dv1394_highlevel); @@ -2633,23 +2653,6 @@ static int __init dv1394_init_module(voi return ret; } -#ifdef CONFIG_COMPAT - { - /* First compatible ones */ - ret = register_ioctl32_conversion(DV1394_IOC_SHUTDOWN, NULL); - ret |= register_ioctl32_conversion(DV1394_IOC_SUBMIT_FRAMES, NULL); - ret |= register_ioctl32_conversion(DV1394_IOC_WAIT_FRAMES, NULL); - ret |= register_ioctl32_conversion(DV1394_IOC_RECEIVE_FRAMES, NULL); - ret |= register_ioctl32_conversion(DV1394_IOC_START_RECEIVE, NULL); - - /* These need to be handled by translation */ - ret |= register_ioctl32_conversion(DV1394_IOC32_INIT, handle_dv1394_init); - ret |= register_ioctl32_conversion(DV1394_IOC32_GET_STATUS, handle_dv1394_get_status); - if (ret) - printk(KERN_ERR "dv1394: Error registering ioctl32 translations\n"); - } -#endif - return 0; } _