X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fieee1394%2Fvideo1394.c;h=3acc962296b13a4bb725a9a814944ad4fc3b13fd;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=7a757fc43f1d90082428b2e8004dc1d4938196e3;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c index 7a757fc43..3acc96229 100644 --- a/drivers/ieee1394/video1394.c +++ b/drivers/ieee1394/video1394.c @@ -699,12 +699,13 @@ static void initialize_dma_it_ctx(struct dma_iso_ctx *d, int sync_tag, reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, 1<ctx); } -static int video1394_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static int __video1394_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) { struct file_ctx *ctx = (struct file_ctx *)file->private_data; struct ti_ohci *ohci = ctx->ohci; unsigned long flags; + void __user *argp = (void __user *)arg; switch(cmd) { @@ -716,7 +717,7 @@ static int video1394_ioctl(struct inode *inode, struct file *file, struct dma_iso_ctx *d; int i; - if (copy_from_user(&v, (void *)arg, sizeof(v))) + if (copy_from_user(&v, argp, sizeof(v))) return -EFAULT; /* if channel < 0, find lowest available one */ @@ -813,7 +814,7 @@ static int video1394_ioctl(struct inode *inode, struct file *file, v.channel); } - if (copy_to_user((void *)arg, &v, sizeof(v))) + if (copy_to_user(argp, &v, sizeof(v))) return -EFAULT; return 0; @@ -825,7 +826,7 @@ static int video1394_ioctl(struct inode *inode, struct file *file, u64 mask; struct dma_iso_ctx *d; - if (copy_from_user(&channel, (void *)arg, sizeof(int))) + if (copy_from_user(&channel, argp, sizeof(int))) return -EFAULT; if (channel<0 || channel>(ISO_CHANNELS-1)) { @@ -860,7 +861,7 @@ static int video1394_ioctl(struct inode *inode, struct file *file, struct video1394_wait v; struct dma_iso_ctx *d; - if (copy_from_user(&v, (void *)arg, sizeof(v))) + if (copy_from_user(&v, argp, sizeof(v))) return -EFAULT; d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); @@ -923,7 +924,7 @@ static int video1394_ioctl(struct inode *inode, struct file *file, struct dma_iso_ctx *d; int i; - if (copy_from_user(&v, (void *)arg, sizeof(v))) + if (copy_from_user(&v, argp, sizeof(v))) return -EFAULT; d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); @@ -994,7 +995,7 @@ static int video1394_ioctl(struct inode *inode, struct file *file, spin_unlock_irqrestore(&d->lock, flags); v.buffer=i; - if (copy_to_user((void *)arg, &v, sizeof(v))) + if (copy_to_user(argp, &v, sizeof(v))) return -EFAULT; return 0; @@ -1002,12 +1003,10 @@ static int video1394_ioctl(struct inode *inode, struct file *file, case VIDEO1394_IOC_TALK_QUEUE_BUFFER: { struct video1394_wait v; - struct video1394_queue_variable qv; + unsigned int *psizes = NULL; struct dma_iso_ctx *d; - qv.packet_sizes = NULL; - - if (copy_from_user(&v, (void *)arg, sizeof(v))) + if (copy_from_user(&v, argp, sizeof(v))) return -EFAULT; d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); @@ -1020,22 +1019,21 @@ static int video1394_ioctl(struct inode *inode, struct file *file, } if (d->flags & VIDEO1394_VARIABLE_PACKET_SIZE) { - unsigned int *psizes; int buf_size = d->nb_cmd * sizeof(unsigned int); + struct video1394_queue_variable __user *p = argp; + unsigned int __user *qv; - if (copy_from_user(&qv, (void *)arg, sizeof(qv))) + if (get_user(qv, &p->packet_sizes)) return -EFAULT; psizes = kmalloc(buf_size, GFP_KERNEL); if (!psizes) return -ENOMEM; - if (copy_from_user(psizes, qv.packet_sizes, buf_size)) { + if (copy_from_user(psizes, qv, buf_size)) { kfree(psizes); return -EFAULT; } - - qv.packet_sizes = psizes; } spin_lock_irqsave(&d->lock,flags); @@ -1044,14 +1042,14 @@ static int video1394_ioctl(struct inode *inode, struct file *file, PRINT(KERN_ERR, ohci->host->id, "Buffer %d is already used",v.buffer); spin_unlock_irqrestore(&d->lock,flags); - if (qv.packet_sizes) - kfree(qv.packet_sizes); + if (psizes) + kfree(psizes); return -EFAULT; } if (d->flags & VIDEO1394_VARIABLE_PACKET_SIZE) { initialize_dma_it_prg_var_packet_queue( - d, v.buffer, qv.packet_sizes, + d, v.buffer, psizes, ohci); } @@ -1100,8 +1098,8 @@ static int video1394_ioctl(struct inode *inode, struct file *file, } } - if (qv.packet_sizes) - kfree(qv.packet_sizes); + if (psizes) + kfree(psizes); return 0; @@ -1111,7 +1109,7 @@ static int video1394_ioctl(struct inode *inode, struct file *file, struct video1394_wait v; struct dma_iso_ctx *d; - if (copy_from_user(&v, (void *)arg, sizeof(v))) + if (copy_from_user(&v, argp, sizeof(v))) return -EFAULT; d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); @@ -1154,12 +1152,21 @@ static int video1394_ioctl(struct inode *inode, struct file *file, } } +static long video1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int err; + lock_kernel(); + err = __video1394_ioctl(file, cmd, arg); + unlock_kernel(); + return err; +} + /* * This maps the vmalloced and reserved buffer to user space. * * FIXME: * - PAGE_READONLY should suffice!? - * - remap_page_range is kind of inefficient for page by page remapping. + * - remap_pfn_range is kind of inefficient for page by page remapping. * But e.g. pte_alloc() does not work in modules ... :-( */ @@ -1235,11 +1242,18 @@ static int video1394_release(struct inode *inode, struct file *file) return 0; } +#ifdef CONFIG_COMPAT +static long video1394_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg); +#endif + static struct cdev video1394_cdev; static struct file_operations video1394_fops= { .owner = THIS_MODULE, - .ioctl = video1394_ioctl, + .unlocked_ioctl = video1394_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = video1394_compat_ioctl, +#endif .mmap = video1394_mmap, .open = video1394_open, .release = video1394_release @@ -1335,18 +1349,15 @@ struct video1394_wait32 { struct compat_timeval filltime; }; -static int video1394_wr_wait32(unsigned int fd, unsigned int cmd, unsigned long arg, - struct file *file) +static int video1394_wr_wait32(struct file *file, unsigned int cmd, unsigned long arg) { + struct video1394_wait32 __user *argp = (void __user *)arg; struct video1394_wait32 wait32; struct video1394_wait wait; mm_segment_t old_fs; int ret; - if (file->f_op->ioctl != video1394_ioctl) - return -EFAULT; - - if (copy_from_user(&wait32, (void *)arg, sizeof(wait32))) + if (copy_from_user(&wait32, argp, sizeof(wait32))) return -EFAULT; wait.channel = wait32.channel; @@ -1357,11 +1368,11 @@ static int video1394_wr_wait32(unsigned int fd, unsigned int cmd, unsigned long old_fs = get_fs(); set_fs(KERNEL_DS); if (cmd == VIDEO1394_IOC32_LISTEN_WAIT_BUFFER) - ret = video1394_ioctl(file->f_dentry->d_inode, file, + ret = video1394_ioctl(file, VIDEO1394_IOC_LISTEN_WAIT_BUFFER, (unsigned long) &wait); else - ret = video1394_ioctl(file->f_dentry->d_inode, file, + ret = video1394_ioctl(file, VIDEO1394_IOC_LISTEN_POLL_BUFFER, (unsigned long) &wait); set_fs(old_fs); @@ -1372,25 +1383,21 @@ static int video1394_wr_wait32(unsigned int fd, unsigned int cmd, unsigned long wait32.filltime.tv_sec = (int)wait.filltime.tv_sec; wait32.filltime.tv_usec = (int)wait.filltime.tv_usec; - if (copy_to_user((struct video1394_wait32 *)arg, &wait32, sizeof(wait32))) + if (copy_to_user(argp, &wait32, sizeof(wait32))) ret = -EFAULT; } return ret; } -static int video1394_w_wait32(unsigned int fd, unsigned int cmd, unsigned long arg, - struct file *file) +static int video1394_w_wait32(struct file *file, unsigned int cmd, unsigned long arg) { struct video1394_wait32 wait32; struct video1394_wait wait; mm_segment_t old_fs; int ret; - if (file->f_op->ioctl != video1394_ioctl) - return -EFAULT; - - if (copy_from_user(&wait32, (void *)arg, sizeof(wait32))) + if (copy_from_user(&wait32, (void __user *)arg, sizeof(wait32))) return -EFAULT; wait.channel = wait32.channel; @@ -1401,11 +1408,11 @@ static int video1394_w_wait32(unsigned int fd, unsigned int cmd, unsigned long a old_fs = get_fs(); set_fs(KERNEL_DS); if (cmd == VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER) - ret = video1394_ioctl(file->f_dentry->d_inode, file, + ret = video1394_ioctl(file, VIDEO1394_IOC_LISTEN_QUEUE_BUFFER, (unsigned long) &wait); else - ret = video1394_ioctl(file->f_dentry->d_inode, file, + ret = video1394_ioctl(file, VIDEO1394_IOC_TALK_WAIT_BUFFER, (unsigned long) &wait); set_fs(old_fs); @@ -1413,38 +1420,42 @@ static int video1394_w_wait32(unsigned int fd, unsigned int cmd, unsigned long a return ret; } -static int video1394_queue_buf32(unsigned int fd, unsigned int cmd, unsigned long arg, - struct file *file) +static int video1394_queue_buf32(struct file *file, unsigned int cmd, unsigned long arg) { - if (file->f_op->ioctl != video1394_ioctl) - return -EFAULT; + return -EFAULT; /* ??? was there before. */ - return -EFAULT; - - return video1394_ioctl(file->f_dentry->d_inode, file, + return video1394_ioctl(file, VIDEO1394_IOC_TALK_QUEUE_BUFFER, arg); } +static long video1394_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg) +{ + switch (cmd) { + case VIDEO1394_IOC_LISTEN_CHANNEL: + case VIDEO1394_IOC_UNLISTEN_CHANNEL: + case VIDEO1394_IOC_TALK_CHANNEL: + case VIDEO1394_IOC_UNTALK_CHANNEL: + return video1394_ioctl(f, cmd, arg); + + case VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER: + return video1394_w_wait32(f, cmd, arg); + case VIDEO1394_IOC32_LISTEN_WAIT_BUFFER: + return video1394_wr_wait32(f, cmd, arg); + case VIDEO1394_IOC_TALK_QUEUE_BUFFER: + return video1394_queue_buf32(f, cmd, arg); + case VIDEO1394_IOC32_TALK_WAIT_BUFFER: + return video1394_w_wait32(f, cmd, arg); + case VIDEO1394_IOC32_LISTEN_POLL_BUFFER: + return video1394_wr_wait32(f, cmd, arg); + default: + return -ENOIOCTLCMD; + } +} + #endif /* CONFIG_COMPAT */ static void __exit video1394_exit_module (void) { -#ifdef CONFIG_COMPAT - int ret; - - ret = unregister_ioctl32_conversion(VIDEO1394_IOC_LISTEN_CHANNEL); - ret |= unregister_ioctl32_conversion(VIDEO1394_IOC_UNLISTEN_CHANNEL); - ret |= unregister_ioctl32_conversion(VIDEO1394_IOC_TALK_CHANNEL); - ret |= unregister_ioctl32_conversion(VIDEO1394_IOC_UNTALK_CHANNEL); - ret |= unregister_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER); - ret |= unregister_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_WAIT_BUFFER); - ret |= unregister_ioctl32_conversion(VIDEO1394_IOC_TALK_QUEUE_BUFFER); - ret |= unregister_ioctl32_conversion(VIDEO1394_IOC32_TALK_WAIT_BUFFER); - ret |= unregister_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_POLL_BUFFER); - if (ret) - PRINT_G(KERN_CRIT, "Error unregistering ioctl32 translations"); -#endif - hpsb_unregister_protocol(&video1394_driver); hpsb_unregister_highlevel(&video1394_highlevel); @@ -1481,30 +1492,6 @@ static int __init video1394_init_module (void) return ret; } -#ifdef CONFIG_COMPAT - { - /* First the compatible ones */ - ret = register_ioctl32_conversion(VIDEO1394_IOC_LISTEN_CHANNEL, NULL); - ret |= register_ioctl32_conversion(VIDEO1394_IOC_UNLISTEN_CHANNEL, NULL); - ret |= register_ioctl32_conversion(VIDEO1394_IOC_TALK_CHANNEL, NULL); - ret |= register_ioctl32_conversion(VIDEO1394_IOC_UNTALK_CHANNEL, NULL); - - /* These need translation */ - ret |= register_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER, - video1394_w_wait32); - ret |= register_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_WAIT_BUFFER, - video1394_wr_wait32); - ret |= register_ioctl32_conversion(VIDEO1394_IOC_TALK_QUEUE_BUFFER, - video1394_queue_buf32); - ret |= register_ioctl32_conversion(VIDEO1394_IOC32_TALK_WAIT_BUFFER, - video1394_w_wait32); - ret |= register_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_POLL_BUFFER, - video1394_wr_wait32); - if (ret) - PRINT_G(KERN_INFO, "Error registering ioctl32 translations"); - } -#endif - PRINT_G(KERN_INFO, "Installed " VIDEO1394_DRIVER_NAME " module"); return 0; }