ieee1394: raw1394: Add ioctl() for 32bit userland on 64bit kernel

2007-07-09 Thread Linux Kernel Mailing List
Gitweb: 
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=650c12c528d3e0ac69405dd35d3bc8a7228e49f2
Commit: 650c12c528d3e0ac69405dd35d3bc8a7228e49f2
Parent: 883b97eaf2a3fba7628f9f78ca7dc422aaf9728b
Author: Petr Vandrovec <[EMAIL PROTECTED]>
AuthorDate: Mon May 7 04:14:47 2007 +0200
Committer:  Stefan Richter <[EMAIL PROTECTED]>
CommitDate: Tue Jul 10 00:07:38 2007 +0200

    ieee1394: raw1394: Add ioctl() for 32bit userland on 64bit kernel

Add compat_ioctl.  Although all structures are more or less same,
raw1394_iso_packets got pointer inside, and raw1394_cycle_timer got unwanted
padding in the middle.  I did not add any translation for ioctls passing 
array
of integers around as integers seem to have same size (32 bits) on all
architectures supported by Linux.

Signed-off-by: Petr Vandrovec <[EMAIL PROTECTED]>
Acked-by: Dan Dennedy <[EMAIL PROTECTED]>
Signed-off-by: Stefan Richter <[EMAIL PROTECTED]> (split into 3 patches)
---
 drivers/ieee1394/raw1394.c |   97 +++-
 1 files changed, 96 insertions(+), 1 deletions(-)

diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 94a3b6d..151a48f 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -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;

ieee1394: raw1394: Add ioctl() for 32bit userland on 64bit kernel, amendment

2007-07-09 Thread Linux Kernel Mailing List
Gitweb: 
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=19f00e66f8aa7ee581c6d003fd68ee9f9dee4057
Commit: 19f00e66f8aa7ee581c6d003fd68ee9f9dee4057
Parent: 650c12c528d3e0ac69405dd35d3bc8a7228e49f2
Author: Stefan Richter <[EMAIL PROTECTED]>
AuthorDate: Mon May 21 18:52:06 2007 +0200
Committer:  Stefan Richter <[EMAIL PROTECTED]>
CommitDate: Tue Jul 10 00:07:38 2007 +0200

    ieee1394: raw1394: Add ioctl() for 32bit userland on 64bit kernel, amendment

Pointed out by Arnd Bergmann:  PPC32 aligns this at 64bit, IA32 packs
it.  A kernel-wide available __compat_u64 which is 4-byte aligned on
AMD64 and IA64 would be nicer though.

Signed-off-by: Stefan Richter <[EMAIL PROTECTED]>
---
 drivers/ieee1394/raw1394.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 151a48f..7b5aeb3 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -2814,7 +2814,11 @@ struct raw1394_iso_packets32 {
 struct raw1394_cycle_timer32 {
 __u32 cycle_timer;
 __u64 local_time;
-} __attribute__((packed));
+}
+#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
+__attribute__((packed))
+#endif
+;
 
 #define RAW1394_IOC_ISO_RECV_PACKETS32  \
 _IOW ('#', 0x25, struct raw1394_iso_packets32)
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html