reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, 1<<d->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)
{
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 */
v.channel);
}
- if (copy_to_user((void *)arg, &v, sizeof(v)))
+ if (copy_to_user(argp, &v, sizeof(v)))
return -EFAULT;
return 0;
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)) {
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);
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);
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;
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);
}
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);
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);
}
}
}
- if (qv.packet_sizes)
- kfree(qv.packet_sizes);
+ if (psizes)
+ kfree(psizes);
return 0;
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);
}
}
+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 ... :-(
*/
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
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;
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);
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;
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);
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);
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;
}