|
@@ -2805,6 +2805,99 @@ static int raw1394_ioctl(struct inode *inode, struct file *file,
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_COMPAT
|
|
|
+struct raw1394_iso_packets32 {
|
|
|
+ __u32 n_packets;
|
|
|
+ compat_uptr_t infos;
|
|
|
+} __attribute__((packed));
|
|
|
+
|
|
|
+struct raw1394_cycle_timer32 {
|
|
|
+ __u32 cycle_timer;
|
|
|
+ __u64 local_time;
|
|
|
+} __attribute__((packed));
|
|
|
+
|
|
|
+#define RAW1394_IOC_ISO_RECV_PACKETS32 \
|
|
|
+ _IOW ('#', 0x25, struct raw1394_iso_packets32)
|
|
|
+#define RAW1394_IOC_ISO_XMIT_PACKETS32 \
|
|
|
+ _IOW ('#', 0x27, struct raw1394_iso_packets32)
|
|
|
+#define RAW1394_IOC_GET_CYCLE_TIMER32 \
|
|
|
+ _IOR ('#', 0x30, struct raw1394_cycle_timer32)
|
|
|
+
|
|
|
+static long raw1394_iso_xmit_recv_packets32(struct file *file, unsigned int cmd,
|
|
|
+ struct raw1394_iso_packets32 __user *arg)
|
|
|
+{
|
|
|
+ compat_uptr_t infos32;
|
|
|
+ void *infos;
|
|
|
+ long err = -EFAULT;
|
|
|
+ struct raw1394_iso_packets __user *dst = compat_alloc_user_space(sizeof(struct raw1394_iso_packets));
|
|
|
+
|
|
|
+ if (!copy_in_user(&dst->n_packets, &arg->n_packets, sizeof arg->n_packets) &&
|
|
|
+ !copy_from_user(&infos32, &arg->infos, sizeof infos32)) {
|
|
|
+ infos = compat_ptr(infos32);
|
|
|
+ if (!copy_to_user(&dst->infos, &infos, sizeof infos))
|
|
|
+ err = raw1394_ioctl(NULL, file, cmd, (unsigned long)dst);
|
|
|
+ }
|
|
|
+ return err;
|
|
|
+}
|
|
|
+
|
|
|
+static long raw1394_read_cycle_timer32(struct file_info *fi, void __user * uaddr)
|
|
|
+{
|
|
|
+ struct raw1394_cycle_timer32 ct;
|
|
|
+ int err;
|
|
|
+
|
|
|
+ err = hpsb_read_cycle_timer(fi->host, &ct.cycle_timer, &ct.local_time);
|
|
|
+ if (!err)
|
|
|
+ if (copy_to_user(uaddr, &ct, sizeof(ct)))
|
|
|
+ err = -EFAULT;
|
|
|
+ return err;
|
|
|
+}
|
|
|
+
|
|
|
+static long raw1394_compat_ioctl(struct file *file,
|
|
|
+ unsigned int cmd, unsigned long arg)
|
|
|
+{
|
|
|
+ struct file_info *fi = file->private_data;
|
|
|
+ void __user *argp = (void __user *)arg;
|
|
|
+ long err;
|
|
|
+
|
|
|
+ lock_kernel();
|
|
|
+ switch (cmd) {
|
|
|
+ /* These requests have same format as long as 'int' has same size. */
|
|
|
+ case RAW1394_IOC_ISO_RECV_INIT:
|
|
|
+ case RAW1394_IOC_ISO_RECV_START:
|
|
|
+ case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL:
|
|
|
+ case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL:
|
|
|
+ case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK:
|
|
|
+ case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS:
|
|
|
+ case RAW1394_IOC_ISO_RECV_FLUSH:
|
|
|
+ case RAW1394_IOC_ISO_XMIT_RECV_STOP:
|
|
|
+ case RAW1394_IOC_ISO_XMIT_INIT:
|
|
|
+ case RAW1394_IOC_ISO_XMIT_START:
|
|
|
+ case RAW1394_IOC_ISO_XMIT_SYNC:
|
|
|
+ case RAW1394_IOC_ISO_GET_STATUS:
|
|
|
+ case RAW1394_IOC_ISO_SHUTDOWN:
|
|
|
+ case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
|
|
|
+ err = raw1394_ioctl(NULL, file, cmd, arg);
|
|
|
+ break;
|
|
|
+ /* These request have different format. */
|
|
|
+ case RAW1394_IOC_ISO_RECV_PACKETS32:
|
|
|
+ err = raw1394_iso_xmit_recv_packets32(file, RAW1394_IOC_ISO_RECV_PACKETS, argp);
|
|
|
+ break;
|
|
|
+ case RAW1394_IOC_ISO_XMIT_PACKETS32:
|
|
|
+ err = raw1394_iso_xmit_recv_packets32(file, RAW1394_IOC_ISO_XMIT_PACKETS, argp);
|
|
|
+ break;
|
|
|
+ case RAW1394_IOC_GET_CYCLE_TIMER32:
|
|
|
+ err = raw1394_read_cycle_timer32(fi, argp);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ err = -EINVAL;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ unlock_kernel();
|
|
|
+
|
|
|
+ return err;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
static unsigned int raw1394_poll(struct file *file, poll_table * pt)
|
|
|
{
|
|
|
struct file_info *fi = file->private_data;
|
|
@@ -3044,7 +3137,9 @@ static const struct file_operations raw1394_fops = {
|
|
|
.write = raw1394_write,
|
|
|
.mmap = raw1394_mmap,
|
|
|
.ioctl = raw1394_ioctl,
|
|
|
- // .compat_ioctl = ... someone needs to do this
|
|
|
+#ifdef CONFIG_COMPAT
|
|
|
+ .compat_ioctl = raw1394_compat_ioctl,
|
|
|
+#endif
|
|
|
.poll = raw1394_poll,
|
|
|
.open = raw1394_open,
|
|
|
.release = raw1394_release,
|