aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPetr Vandrovec <petr@vandrovec.name>2007-05-06 22:14:47 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2007-07-09 18:07:38 -0400
commit650c12c528d3e0ac69405dd35d3bc8a7228e49f2 (patch)
treef968e1e6fea9ee93b5fc06fadbbd128a1e58a6e7 /drivers
parent883b97eaf2a3fba7628f9f78ca7dc422aaf9728b (diff)
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 <petr@vandrovec.name> Acked-by: Dan Dennedy <dan@dennedy.org> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (split into 3 patches)
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ieee1394/raw1394.c97
1 files changed, 96 insertions, 1 deletions
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 94a3b6db589c..151a48f41c8f 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,
2805 return -EINVAL; 2805 return -EINVAL;
2806} 2806}
2807 2807
2808#ifdef CONFIG_COMPAT
2809struct raw1394_iso_packets32 {
2810 __u32 n_packets;
2811 compat_uptr_t infos;
2812} __attribute__((packed));
2813
2814struct raw1394_cycle_timer32 {
2815 __u32 cycle_timer;
2816 __u64 local_time;
2817} __attribute__((packed));
2818
2819#define RAW1394_IOC_ISO_RECV_PACKETS32 \
2820 _IOW ('#', 0x25, struct raw1394_iso_packets32)
2821#define RAW1394_IOC_ISO_XMIT_PACKETS32 \
2822 _IOW ('#', 0x27, struct raw1394_iso_packets32)
2823#define RAW1394_IOC_GET_CYCLE_TIMER32 \
2824 _IOR ('#', 0x30, struct raw1394_cycle_timer32)
2825
2826static long raw1394_iso_xmit_recv_packets32(struct file *file, unsigned int cmd,
2827 struct raw1394_iso_packets32 __user *arg)
2828{
2829 compat_uptr_t infos32;
2830 void *infos;
2831 long err = -EFAULT;
2832 struct raw1394_iso_packets __user *dst = compat_alloc_user_space(sizeof(struct raw1394_iso_packets));
2833
2834 if (!copy_in_user(&dst->n_packets, &arg->n_packets, sizeof arg->n_packets) &&
2835 !copy_from_user(&infos32, &arg->infos, sizeof infos32)) {
2836 infos = compat_ptr(infos32);
2837 if (!copy_to_user(&dst->infos, &infos, sizeof infos))
2838 err = raw1394_ioctl(NULL, file, cmd, (unsigned long)dst);
2839 }
2840 return err;
2841}
2842
2843static long raw1394_read_cycle_timer32(struct file_info *fi, void __user * uaddr)
2844{
2845 struct raw1394_cycle_timer32 ct;
2846 int err;
2847
2848 err = hpsb_read_cycle_timer(fi->host, &ct.cycle_timer, &ct.local_time);
2849 if (!err)
2850 if (copy_to_user(uaddr, &ct, sizeof(ct)))
2851 err = -EFAULT;
2852 return err;
2853}
2854
2855static long raw1394_compat_ioctl(struct file *file,
2856 unsigned int cmd, unsigned long arg)
2857{
2858 struct file_info *fi = file->private_data;
2859 void __user *argp = (void __user *)arg;
2860 long err;
2861
2862 lock_kernel();
2863 switch (cmd) {
2864 /* These requests have same format as long as 'int' has same size. */
2865 case RAW1394_IOC_ISO_RECV_INIT:
2866 case RAW1394_IOC_ISO_RECV_START:
2867 case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL:
2868 case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL:
2869 case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK:
2870 case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS:
2871 case RAW1394_IOC_ISO_RECV_FLUSH:
2872 case RAW1394_IOC_ISO_XMIT_RECV_STOP:
2873 case RAW1394_IOC_ISO_XMIT_INIT:
2874 case RAW1394_IOC_ISO_XMIT_START:
2875 case RAW1394_IOC_ISO_XMIT_SYNC:
2876 case RAW1394_IOC_ISO_GET_STATUS:
2877 case RAW1394_IOC_ISO_SHUTDOWN:
2878 case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
2879 err = raw1394_ioctl(NULL, file, cmd, arg);
2880 break;
2881 /* These request have different format. */
2882 case RAW1394_IOC_ISO_RECV_PACKETS32:
2883 err = raw1394_iso_xmit_recv_packets32(file, RAW1394_IOC_ISO_RECV_PACKETS, argp);
2884 break;
2885 case RAW1394_IOC_ISO_XMIT_PACKETS32:
2886 err = raw1394_iso_xmit_recv_packets32(file, RAW1394_IOC_ISO_XMIT_PACKETS, argp);
2887 break;
2888 case RAW1394_IOC_GET_CYCLE_TIMER32:
2889 err = raw1394_read_cycle_timer32(fi, argp);
2890 break;
2891 default:
2892 err = -EINVAL;
2893 break;
2894 }
2895 unlock_kernel();
2896
2897 return err;
2898}
2899#endif
2900
2808static unsigned int raw1394_poll(struct file *file, poll_table * pt) 2901static unsigned int raw1394_poll(struct file *file, poll_table * pt)
2809{ 2902{
2810 struct file_info *fi = file->private_data; 2903 struct file_info *fi = file->private_data;
@@ -3044,7 +3137,9 @@ static const struct file_operations raw1394_fops = {
3044 .write = raw1394_write, 3137 .write = raw1394_write,
3045 .mmap = raw1394_mmap, 3138 .mmap = raw1394_mmap,
3046 .ioctl = raw1394_ioctl, 3139 .ioctl = raw1394_ioctl,
3047 // .compat_ioctl = ... someone needs to do this 3140#ifdef CONFIG_COMPAT
3141 .compat_ioctl = raw1394_compat_ioctl,
3142#endif
3048 .poll = raw1394_poll, 3143 .poll = raw1394_poll,
3049 .open = raw1394_open, 3144 .open = raw1394_open,
3050 .release = raw1394_release, 3145 .release = raw1394_release,