commented early_printk patch because of rejects.
[linux-flexiantxendom0-3.2.10.git] / arch / sparc64 / kernel / ioctl32.c
1 /* $Id: ioctl32.c,v 1.136 2002/01/14 09:49:52 davem Exp $
2  * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
3  *
4  * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
5  * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
6  * Copyright (C) 2003  Pavel Machek (pavel@suse.cz)
7  *
8  * These routines maintain argument size conversion between 32bit and 64bit
9  * ioctls.
10  */
11
12 #define INCLUDES
13 #include "compat_ioctl.c"
14 #include <linux/ncp_fs.h>
15 #include <asm/fbio.h>
16 #include <asm/kbio.h>
17 #include <asm/vuid_event.h>
18 #include <asm/envctrl.h>
19 #include <asm/display7seg.h>
20 #include <asm/openpromio.h>
21 #include <asm/audioio.h>
22 #include <asm/watchdog.h>
23
24 /* Use this to get at 32-bit user passed pointers. 
25  * See sys_sparc32.c for description about it.
26  */
27 #define A(__x) ((void __user *)(unsigned long)(__x))
28
29 static __inline__ void *alloc_user_space(long len)
30 {
31         struct pt_regs *regs = current_thread_info()->kregs;
32         unsigned long usp = regs->u_regs[UREG_I6];
33
34         if (!(test_thread_flag(TIF_32BIT)))
35                 usp += STACK_BIAS;
36
37         return (void *) (usp - len);
38 }
39
40 #define CODE
41 #include "compat_ioctl.c"
42
43 struct hd_big_geometry32 {
44         unsigned char heads;
45         unsigned char sectors;
46         unsigned int cylinders;
47         u32 start;
48 };
49                         
50 static int hdio_getgeo_big(unsigned int fd, unsigned int cmd, unsigned long arg)
51 {
52         mm_segment_t old_fs = get_fs();
53         struct hd_big_geometry geo;
54         int err;
55         
56         set_fs (KERNEL_DS);
57         err = sys_ioctl(fd, cmd, (unsigned long)&geo);
58         set_fs (old_fs);
59         if (!err) {
60                 struct hd_big_geometry32 *up = (struct hd_big_geometry32 *) arg;
61
62                 if (put_user(geo.heads, &up->heads) ||
63                     __put_user(geo.sectors, &up->sectors) ||
64                     __put_user(geo.cylinders, &up->cylinders) ||
65                     __put_user(((u32) geo.start), &up->start))
66                         err = -EFAULT;
67         }
68         return err;
69 }
70
71 struct  fbcmap32 {
72         int             index;          /* first element (0 origin) */
73         int             count;
74         u32             red;
75         u32             green;
76         u32             blue;
77 };
78
79 #define FBIOPUTCMAP32   _IOW('F', 3, struct fbcmap32)
80 #define FBIOGETCMAP32   _IOW('F', 4, struct fbcmap32)
81
82 static int fbiogetputcmap(unsigned int fd, unsigned int cmd, unsigned long arg)
83 {
84         struct fbcmap f;
85         int ret;
86         char red[256], green[256], blue[256];
87         u32 r, g, b;
88         mm_segment_t old_fs = get_fs();
89         
90         ret = get_user(f.index, &(((struct fbcmap32 *)arg)->index));
91         ret |= __get_user(f.count, &(((struct fbcmap32 *)arg)->count));
92         ret |= __get_user(r, &(((struct fbcmap32 *)arg)->red));
93         ret |= __get_user(g, &(((struct fbcmap32 *)arg)->green));
94         ret |= __get_user(b, &(((struct fbcmap32 *)arg)->blue));
95         if (ret)
96                 return -EFAULT;
97         if ((f.index < 0) || (f.index > 255)) return -EINVAL;
98         if (f.index + f.count > 256)
99                 f.count = 256 - f.index;
100         if (cmd == FBIOPUTCMAP32) {
101                 ret = copy_from_user (red, A(r), f.count);
102                 ret |= copy_from_user (green, A(g), f.count);
103                 ret |= copy_from_user (blue, A(b), f.count);
104                 if (ret)
105                         return -EFAULT;
106         }
107         f.red = red; f.green = green; f.blue = blue;
108         set_fs (KERNEL_DS);
109         ret = sys_ioctl (fd, (cmd == FBIOPUTCMAP32) ? FBIOPUTCMAP_SPARC : FBIOGETCMAP_SPARC, (long)&f);
110         set_fs (old_fs);
111         if (!ret && cmd == FBIOGETCMAP32) {
112                 ret = copy_to_user (A(r), red, f.count);
113                 ret |= copy_to_user (A(g), green, f.count);
114                 ret |= copy_to_user (A(b), blue, f.count);
115         }
116         return ret ? -EFAULT : 0;
117 }
118
119 struct fbcursor32 {
120         short set;              /* what to set, choose from the list above */
121         short enable;           /* cursor on/off */
122         struct fbcurpos pos;    /* cursor position */
123         struct fbcurpos hot;    /* cursor hot spot */
124         struct fbcmap32 cmap;   /* color map info */
125         struct fbcurpos size;   /* cursor bit map size */
126         u32     image;          /* cursor image bits */
127         u32     mask;           /* cursor mask bits */
128 };
129         
130 #define FBIOSCURSOR32   _IOW('F', 24, struct fbcursor32)
131 #define FBIOGCURSOR32   _IOW('F', 25, struct fbcursor32)
132
133 static int fbiogscursor(unsigned int fd, unsigned int cmd, unsigned long arg)
134 {
135         struct fbcursor f;
136         int ret;
137         char red[2], green[2], blue[2];
138         char image[128], mask[128];
139         u32 r, g, b;
140         u32 m, i;
141         mm_segment_t old_fs = get_fs();
142         
143         ret = copy_from_user (&f, (struct fbcursor32 *)arg, 2 * sizeof (short) + 2 * sizeof(struct fbcurpos));
144         ret |= __get_user(f.size.x, &(((struct fbcursor32 *)arg)->size.x));
145         ret |= __get_user(f.size.y, &(((struct fbcursor32 *)arg)->size.y));
146         ret |= __get_user(f.cmap.index, &(((struct fbcursor32 *)arg)->cmap.index));
147         ret |= __get_user(f.cmap.count, &(((struct fbcursor32 *)arg)->cmap.count));
148         ret |= __get_user(r, &(((struct fbcursor32 *)arg)->cmap.red));
149         ret |= __get_user(g, &(((struct fbcursor32 *)arg)->cmap.green));
150         ret |= __get_user(b, &(((struct fbcursor32 *)arg)->cmap.blue));
151         ret |= __get_user(m, &(((struct fbcursor32 *)arg)->mask));
152         ret |= __get_user(i, &(((struct fbcursor32 *)arg)->image));
153         if (ret)
154                 return -EFAULT;
155         if (f.set & FB_CUR_SETCMAP) {
156                 if ((uint) f.size.y > 32)
157                         return -EINVAL;
158                 ret = copy_from_user (mask, A(m), f.size.y * 4);
159                 ret |= copy_from_user (image, A(i), f.size.y * 4);
160                 if (ret)
161                         return -EFAULT;
162                 f.image = image; f.mask = mask;
163         }
164         if (f.set & FB_CUR_SETCMAP) {
165                 ret = copy_from_user (red, A(r), 2);
166                 ret |= copy_from_user (green, A(g), 2);
167                 ret |= copy_from_user (blue, A(b), 2);
168                 if (ret)
169                         return -EFAULT;
170                 f.cmap.red = red; f.cmap.green = green; f.cmap.blue = blue;
171         }
172         set_fs (KERNEL_DS);
173         ret = sys_ioctl (fd, FBIOSCURSOR, (long)&f);
174         set_fs (old_fs);
175         return ret;
176 }
177
178 struct ncp_ioctl_request_32 {
179         unsigned int function;
180         unsigned int size;
181         compat_caddr_t data;
182 };
183
184 struct ncp_fs_info_v2_32 {
185         int version;
186         unsigned int mounted_uid;
187         unsigned int connection;
188         unsigned int buffer_size;
189
190         unsigned int volume_number;
191         __u32 directory_id;
192
193         __u32 dummy1;
194         __u32 dummy2;
195         __u32 dummy3;
196 };
197
198 struct ncp_objectname_ioctl_32
199 {
200         int             auth_type;
201         unsigned int    object_name_len;
202         compat_caddr_t  object_name;    /* an userspace data, in most cases user name */
203 };
204
205 struct ncp_privatedata_ioctl_32
206 {
207         unsigned int    len;
208         compat_caddr_t  data;           /* ~1000 for NDS */
209 };
210
211 #define NCP_IOC_NCPREQUEST_32           _IOR('n', 1, struct ncp_ioctl_request_32)
212
213 #define NCP_IOC_GETMOUNTUID2_32         _IOW('n', 2, unsigned int)
214
215 #define NCP_IOC_GET_FS_INFO_V2_32       _IOWR('n', 4, struct ncp_fs_info_v2_32)
216
217 #define NCP_IOC_GETOBJECTNAME_32        _IOWR('n', 9, struct ncp_objectname_ioctl_32)
218 #define NCP_IOC_SETOBJECTNAME_32        _IOR('n', 9, struct ncp_objectname_ioctl_32)
219 #define NCP_IOC_GETPRIVATEDATA_32       _IOWR('n', 10, struct ncp_privatedata_ioctl_32)
220 #define NCP_IOC_SETPRIVATEDATA_32       _IOR('n', 10, struct ncp_privatedata_ioctl_32)
221
222 static int do_ncp_ncprequest(unsigned int fd, unsigned int cmd, unsigned long arg)
223 {
224         struct ncp_ioctl_request_32 n32;
225         struct ncp_ioctl_request n;
226         mm_segment_t old_fs;
227         int err;
228
229         if (copy_from_user(&n32, (struct ncp_ioctl_request_32*)arg,
230             sizeof(n32)))
231                 return -EFAULT;
232
233         n.function = n32.function;
234         n.size = n32.size;
235         if (n.size > 65536)
236                 return -EINVAL;
237         n.data = vmalloc(65536);        /* 65536 must be same as NCP_PACKET_SIZE_INTERNAL in ncpfs */
238         if (!n.data)
239                 return -ENOMEM;
240         err = -EFAULT;
241         if (copy_from_user(n.data, A(n32.data), n.size))
242                 goto out;
243
244         old_fs = get_fs(); set_fs (KERNEL_DS);
245         err = sys_ioctl (fd, NCP_IOC_NCPREQUEST, (unsigned long)&n);
246         set_fs (old_fs);
247         if(err <= 0)
248                 goto out;
249         if (err > 65536) {
250                 err = -EINVAL;
251                 goto out;
252         }
253         if (copy_to_user(A(n32.data), n.data, err)) {
254                 err = -EFAULT;
255                 goto out;
256         }
257  out:
258         vfree(n.data);
259         return err;
260 }
261
262 static int do_ncp_getmountuid2(unsigned int fd, unsigned int cmd, unsigned long arg)
263 {
264         mm_segment_t old_fs = get_fs();
265         __kernel_uid_t kuid;
266         int err;
267
268         cmd = NCP_IOC_GETMOUNTUID2;
269
270         set_fs(KERNEL_DS);
271         err = sys_ioctl(fd, cmd, (unsigned long)&kuid);
272         set_fs(old_fs);
273
274         if (!err)
275                 err = put_user(kuid, (unsigned int*)arg);
276
277         return err;
278 }
279
280 static int do_ncp_getfsinfo2(unsigned int fd, unsigned int cmd, unsigned long arg)
281 {
282         mm_segment_t old_fs = get_fs();
283         struct ncp_fs_info_v2_32 n32;
284         struct ncp_fs_info_v2 n;
285         int err;
286
287         if (copy_from_user(&n32, (struct ncp_fs_info_v2_32*)arg, sizeof(n32)))
288                 return -EFAULT;
289         if (n32.version != NCP_GET_FS_INFO_VERSION_V2)
290                 return -EINVAL;
291         n.version = NCP_GET_FS_INFO_VERSION_V2;
292
293         set_fs(KERNEL_DS);
294         err = sys_ioctl(fd, NCP_IOC_GET_FS_INFO_V2, (unsigned long)&n);
295         set_fs(old_fs);
296
297         if (!err) {
298                 n32.version = n.version;
299                 n32.mounted_uid = n.mounted_uid;
300                 n32.connection = n.connection;
301                 n32.buffer_size = n.buffer_size;
302                 n32.volume_number = n.volume_number;
303                 n32.directory_id = n.directory_id;
304                 n32.dummy1 = n.dummy1;
305                 n32.dummy2 = n.dummy2;
306                 n32.dummy3 = n.dummy3;
307                 err = copy_to_user((struct ncp_fs_info_v2_32*)arg, &n32, sizeof(n32)) ? -EFAULT : 0;
308         }
309         return err;
310 }
311
312 static int do_ncp_getobjectname(unsigned int fd, unsigned int cmd, unsigned long arg)
313 {
314         struct ncp_objectname_ioctl_32 n32;
315         struct ncp_objectname_ioctl n;
316         mm_segment_t old_fs;
317         int err;
318         size_t tl;
319
320         if (copy_from_user(&n32, (struct ncp_objectname_ioctl_32*)arg,
321             sizeof(n32)))
322                 return -EFAULT;
323
324         n.object_name_len = tl = n32.object_name_len;
325         if (tl) {
326                 n.object_name = kmalloc(tl, GFP_KERNEL);
327                 if (!n.object_name)
328                         return -ENOMEM;
329         } else {
330                 n.object_name = NULL;
331         }
332
333         old_fs = get_fs(); set_fs (KERNEL_DS);
334         err = sys_ioctl (fd, NCP_IOC_GETOBJECTNAME, (unsigned long)&n);
335         set_fs (old_fs);
336         if(err)
337                 goto out;
338                 
339         if (tl > n.object_name_len)
340                 tl = n.object_name_len;
341
342         err = -EFAULT;
343         if (tl && copy_to_user(A(n32.object_name), n.object_name, tl))
344                 goto out;
345
346         n32.auth_type = n.auth_type;
347         n32.object_name_len = n.object_name_len;
348         
349         if (copy_to_user((struct ncp_objectname_ioctl_32*)arg, &n32, sizeof(n32)))
350                 goto out;
351         
352         err = 0;
353  out:
354         if (n.object_name)
355                 kfree(n.object_name);
356
357         return err;
358 }
359
360 static int do_ncp_setobjectname(unsigned int fd, unsigned int cmd, unsigned long arg)
361 {
362         struct ncp_objectname_ioctl_32 n32;
363         struct ncp_objectname_ioctl n;
364         mm_segment_t old_fs;
365         int err;
366         size_t tl;
367
368         if (copy_from_user(&n32, (struct ncp_objectname_ioctl_32*)arg,
369             sizeof(n32)))
370                 return -EFAULT;
371
372         n.auth_type = n32.auth_type;
373         n.object_name_len = tl = n32.object_name_len;
374         if (tl) {
375                 n.object_name = kmalloc(tl, GFP_KERNEL);
376                 if (!n.object_name)
377                         return -ENOMEM;
378                 err = -EFAULT;
379                 if (copy_from_user(n.object_name, A(n32.object_name), tl))
380                         goto out;
381         } else {
382                 n.object_name = NULL;
383         }
384         
385         old_fs = get_fs(); set_fs (KERNEL_DS);
386         err = sys_ioctl (fd, NCP_IOC_SETOBJECTNAME, (unsigned long)&n);
387         set_fs (old_fs);
388                 
389  out:
390         if (n.object_name)
391                 kfree(n.object_name);
392
393         return err;
394 }
395
396 static int do_ncp_getprivatedata(unsigned int fd, unsigned int cmd, unsigned long arg)
397 {
398         struct ncp_privatedata_ioctl_32 n32;
399         struct ncp_privatedata_ioctl n;
400         mm_segment_t old_fs;
401         int err;
402         size_t tl;
403
404         if (copy_from_user(&n32, (struct ncp_privatedata_ioctl_32*)arg,
405             sizeof(n32)))
406                 return -EFAULT;
407
408         n.len = tl = n32.len;
409         if (tl) {
410                 n.data = kmalloc(tl, GFP_KERNEL);
411                 if (!n.data)
412                         return -ENOMEM;
413         } else {
414                 n.data = NULL;
415         }
416
417         old_fs = get_fs(); set_fs (KERNEL_DS);
418         err = sys_ioctl (fd, NCP_IOC_GETPRIVATEDATA, (unsigned long)&n);
419         set_fs (old_fs);
420         if(err)
421                 goto out;
422                 
423         if (tl > n.len)
424                 tl = n.len;
425
426         err = -EFAULT;
427         if (tl && copy_to_user(A(n32.data), n.data, tl))
428                 goto out;
429
430         n32.len = n.len;
431         
432         if (copy_to_user((struct ncp_privatedata_ioctl_32*)arg, &n32, sizeof(n32)))
433                 goto out;
434         
435         err = 0;
436  out:
437         if (n.data)
438                 kfree(n.data);
439
440         return err;
441 }
442
443 static int do_ncp_setprivatedata(unsigned int fd, unsigned int cmd, unsigned long arg)
444 {
445         struct ncp_privatedata_ioctl_32 n32;
446         struct ncp_privatedata_ioctl n;
447         mm_segment_t old_fs;
448         int err;
449         size_t tl;
450
451         if (copy_from_user(&n32, (struct ncp_privatedata_ioctl_32*)arg,
452             sizeof(n32)))
453                 return -EFAULT;
454
455         n.len = tl = n32.len;
456         if (tl) {
457                 n.data = kmalloc(tl, GFP_KERNEL);
458                 if (!n.data)
459                         return -ENOMEM;
460                 err = -EFAULT;
461                 if (copy_from_user(n.data, A(n32.data), tl))
462                         goto out;
463         } else {
464                 n.data = NULL;
465         }
466         
467         old_fs = get_fs(); set_fs (KERNEL_DS);
468         err = sys_ioctl (fd, NCP_IOC_SETPRIVATEDATA, (unsigned long)&n);
469         set_fs (old_fs);
470                 
471  out:
472         if (n.data)
473                 kfree(n.data);
474
475         return err;
476 }
477
478 #if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
479 /* This really belongs in include/linux/drm.h -DaveM */
480 #include "../../../drivers/char/drm/drm.h"
481
482 typedef struct drm32_version {
483         int    version_major;     /* Major version                          */
484         int    version_minor;     /* Minor version                          */
485         int    version_patchlevel;/* Patch level                            */
486         int    name_len;          /* Length of name buffer                  */
487         u32    name;              /* Name of driver                         */
488         int    date_len;          /* Length of date buffer                  */
489         u32    date;              /* User-space buffer to hold date         */
490         int    desc_len;          /* Length of desc buffer                  */
491         u32    desc;              /* User-space buffer to hold desc         */
492 } drm32_version_t;
493 #define DRM32_IOCTL_VERSION    DRM_IOWR(0x00, drm32_version_t)
494
495 static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg)
496 {
497         drm32_version_t *uversion = (drm32_version_t *)arg;
498         char __user *name_ptr, *date_ptr, *desc_ptr;
499         u32 tmp1, tmp2, tmp3;
500         drm_version_t kversion;
501         mm_segment_t old_fs;
502         int ret;
503
504         memset(&kversion, 0, sizeof(kversion));
505         if (get_user(kversion.name_len, &uversion->name_len) ||
506             get_user(kversion.date_len, &uversion->date_len) ||
507             get_user(kversion.desc_len, &uversion->desc_len) ||
508             get_user(tmp1, &uversion->name) ||
509             get_user(tmp2, &uversion->date) ||
510             get_user(tmp3, &uversion->desc))
511                 return -EFAULT;
512
513         name_ptr = A(tmp1);
514         date_ptr = A(tmp2);
515         desc_ptr = A(tmp3);
516
517         ret = -ENOMEM;
518         if (kversion.name_len && name_ptr) {
519                 kversion.name = kmalloc(kversion.name_len, GFP_KERNEL);
520                 if (!kversion.name)
521                         goto out;
522         }
523         if (kversion.date_len && date_ptr) {
524                 kversion.date = kmalloc(kversion.date_len, GFP_KERNEL);
525                 if (!kversion.date)
526                         goto out;
527         }
528         if (kversion.desc_len && desc_ptr) {
529                 kversion.desc = kmalloc(kversion.desc_len, GFP_KERNEL);
530                 if (!kversion.desc)
531                         goto out;
532         }
533
534         old_fs = get_fs();
535         set_fs(KERNEL_DS);
536         ret = sys_ioctl (fd, DRM_IOCTL_VERSION, (unsigned long)&kversion);
537         set_fs(old_fs);
538
539         if (!ret) {
540                 if ((kversion.name &&
541                      copy_to_user(name_ptr, kversion.name, kversion.name_len)) ||
542                     (kversion.date &&
543                      copy_to_user(date_ptr, kversion.date, kversion.date_len)) ||
544                     (kversion.desc &&
545                      copy_to_user(desc_ptr, kversion.desc, kversion.desc_len)))
546                         ret = -EFAULT;
547                 if (put_user(kversion.version_major, &uversion->version_major) ||
548                     put_user(kversion.version_minor, &uversion->version_minor) ||
549                     put_user(kversion.version_patchlevel, &uversion->version_patchlevel) ||
550                     put_user(kversion.name_len, &uversion->name_len) ||
551                     put_user(kversion.date_len, &uversion->date_len) ||
552                     put_user(kversion.desc_len, &uversion->desc_len))
553                         ret = -EFAULT;
554         }
555
556 out:
557         if (kversion.name)
558                 kfree(kversion.name);
559         if (kversion.date)
560                 kfree(kversion.date);
561         if (kversion.desc)
562                 kfree(kversion.desc);
563         return ret;
564 }
565
566 typedef struct drm32_unique {
567         int     unique_len;       /* Length of unique                       */
568         u32     unique;           /* Unique name for driver instantiation   */
569 } drm32_unique_t;
570 #define DRM32_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm32_unique_t)
571 #define DRM32_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm32_unique_t)
572
573 static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long arg)
574 {
575         drm32_unique_t *uarg = (drm32_unique_t *)arg;
576         drm_unique_t karg;
577         mm_segment_t old_fs;
578         char __user *uptr;
579         u32 tmp;
580         int ret;
581
582         if (get_user(karg.unique_len, &uarg->unique_len))
583                 return -EFAULT;
584         karg.unique = NULL;
585
586         if (get_user(tmp, &uarg->unique))
587                 return -EFAULT;
588
589         uptr = A(tmp);
590
591         if (uptr) {
592                 karg.unique = kmalloc(karg.unique_len, GFP_KERNEL);
593                 if (!karg.unique)
594                         return -ENOMEM;
595                 if (cmd == DRM32_IOCTL_SET_UNIQUE &&
596                     copy_from_user(karg.unique, uptr, karg.unique_len)) {
597                         kfree(karg.unique);
598                         return -EFAULT;
599                 }
600         }
601
602         old_fs = get_fs();
603         set_fs(KERNEL_DS);
604         if (cmd == DRM32_IOCTL_GET_UNIQUE)
605                 ret = sys_ioctl (fd, DRM_IOCTL_GET_UNIQUE, (unsigned long)&karg);
606         else
607                 ret = sys_ioctl (fd, DRM_IOCTL_SET_UNIQUE, (unsigned long)&karg);
608         set_fs(old_fs);
609
610         if (!ret) {
611                 if (cmd == DRM32_IOCTL_GET_UNIQUE &&
612                     uptr != NULL &&
613                     copy_to_user(uptr, karg.unique, karg.unique_len))
614                         ret = -EFAULT;
615                 if (put_user(karg.unique_len, &uarg->unique_len))
616                         ret = -EFAULT;
617         }
618
619         if (karg.unique != NULL)
620                 kfree(karg.unique);
621
622         return ret;
623 }
624
625 typedef struct drm32_map {
626         u32             offset;  /* Requested physical address (0 for SAREA)*/
627         u32             size;    /* Requested physical size (bytes)         */
628         drm_map_type_t  type;    /* Type of memory to map                   */
629         drm_map_flags_t flags;   /* Flags                                   */
630         u32             handle;  /* User-space: "Handle" to pass to mmap    */
631                                  /* Kernel-space: kernel-virtual address    */
632         int             mtrr;    /* MTRR slot used                          */
633                                  /* Private data                            */
634 } drm32_map_t;
635 #define DRM32_IOCTL_ADD_MAP    DRM_IOWR(0x15, drm32_map_t)
636
637 static int drm32_addmap(unsigned int fd, unsigned int cmd, unsigned long arg)
638 {
639         drm32_map_t *uarg = (drm32_map_t *) arg;
640         drm_map_t karg;
641         mm_segment_t old_fs;
642         u32 tmp;
643         int ret;
644
645         ret  = get_user(karg.offset, &uarg->offset);
646         ret |= get_user(karg.size, &uarg->size);
647         ret |= get_user(karg.type, &uarg->type);
648         ret |= get_user(karg.flags, &uarg->flags);
649         ret |= get_user(tmp, &uarg->handle);
650         ret |= get_user(karg.mtrr, &uarg->mtrr);
651         if (ret)
652                 return -EFAULT;
653
654         karg.handle = A(tmp);
655
656         old_fs = get_fs();
657         set_fs(KERNEL_DS);
658         ret = sys_ioctl(fd, DRM_IOCTL_ADD_MAP, (unsigned long) &karg);
659         set_fs(old_fs);
660
661         if (!ret) {
662                 ret  = put_user(karg.offset, &uarg->offset);
663                 ret |= put_user(karg.size, &uarg->size);
664                 ret |= put_user(karg.type, &uarg->type);
665                 ret |= put_user(karg.flags, &uarg->flags);
666                 tmp = (u32) (long)karg.handle;
667                 ret |= put_user(tmp, &uarg->handle);
668                 ret |= put_user(karg.mtrr, &uarg->mtrr);
669                 if (ret)
670                         ret = -EFAULT;
671         }
672
673         return ret;
674 }
675
676 typedef struct drm32_buf_info {
677         int            count;   /* Entries in list                           */
678         u32            list;    /* (drm_buf_desc_t *) */ 
679 } drm32_buf_info_t;
680 #define DRM32_IOCTL_INFO_BUFS  DRM_IOWR(0x18, drm32_buf_info_t)
681
682 static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
683 {
684         drm32_buf_info_t *uarg = (drm32_buf_info_t *)arg;
685         drm_buf_desc_t __user *ulist;
686         drm_buf_info_t karg;
687         mm_segment_t old_fs;
688         int orig_count, ret;
689         u32 tmp;
690
691         if (get_user(karg.count, &uarg->count) ||
692             get_user(tmp, &uarg->list))
693                 return -EFAULT;
694
695         ulist = A(tmp);
696
697         orig_count = karg.count;
698
699         karg.list = kmalloc(karg.count * sizeof(drm_buf_desc_t), GFP_KERNEL);
700         if (!karg.list)
701                 return -EFAULT;
702
703         old_fs = get_fs();
704         set_fs(KERNEL_DS);
705         ret = sys_ioctl(fd, DRM_IOCTL_INFO_BUFS, (unsigned long) &karg);
706         set_fs(old_fs);
707
708         if (!ret) {
709                 if (karg.count <= orig_count &&
710                     (copy_to_user(ulist, karg.list,
711                                   karg.count * sizeof(drm_buf_desc_t))))
712                         ret = -EFAULT;
713                 if (put_user(karg.count, &uarg->count))
714                         ret = -EFAULT;
715         }
716
717         kfree(karg.list);
718
719         return ret;
720 }
721
722 typedef struct drm32_buf_free {
723         int            count;
724         u32            list;    /* (int *) */
725 } drm32_buf_free_t;
726 #define DRM32_IOCTL_FREE_BUFS  DRM_IOW( 0x1a, drm32_buf_free_t)
727
728 static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
729 {
730         drm32_buf_free_t *uarg = (drm32_buf_free_t *)arg;
731         drm_buf_free_t karg;
732         mm_segment_t old_fs;
733         int __user *ulist;
734         int ret;
735         u32 tmp;
736
737         if (get_user(karg.count, &uarg->count) ||
738             get_user(tmp, &uarg->list))
739                 return -EFAULT;
740
741         ulist = A(tmp);
742
743         karg.list = kmalloc(karg.count * sizeof(int), GFP_KERNEL);
744         if (!karg.list)
745                 return -ENOMEM;
746
747         ret = -EFAULT;
748         if (copy_from_user(karg.list, ulist, (karg.count * sizeof(int))))
749                 goto out;
750
751         old_fs = get_fs();
752         set_fs(KERNEL_DS);
753         ret = sys_ioctl(fd, DRM_IOCTL_FREE_BUFS, (unsigned long) &karg);
754         set_fs(old_fs);
755
756 out:
757         kfree(karg.list);
758
759         return ret;
760 }
761
762 typedef struct drm32_buf_pub {
763         int               idx;         /* Index into master buflist          */
764         int               total;       /* Buffer size                        */
765         int               used;        /* Amount of buffer in use (for DMA)  */
766         u32               address;     /* Address of buffer (void *)         */
767 } drm32_buf_pub_t;
768
769 typedef struct drm32_buf_map {
770         int           count;    /* Length of buflist                        */
771         u32           virtual;  /* Mmaped area in user-virtual (void *)     */
772         u32           list;     /* Buffer information (drm_buf_pub_t *)     */
773 } drm32_buf_map_t;
774 #define DRM32_IOCTL_MAP_BUFS   DRM_IOWR(0x19, drm32_buf_map_t)
775
776 static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
777 {
778         drm32_buf_map_t *uarg = (drm32_buf_map_t *)arg;
779         drm32_buf_pub_t __user *ulist;
780         drm_buf_map_t karg;
781         mm_segment_t old_fs;
782         int orig_count, ret, i;
783         u32 tmp1, tmp2;
784
785         if (get_user(karg.count, &uarg->count) ||
786             get_user(tmp1, &uarg->virtual) ||
787             get_user(tmp2, &uarg->list))
788                 return -EFAULT;
789
790         karg.virtual = A(tmp1);
791         ulist = A(tmp2);
792
793         orig_count = karg.count;
794
795         karg.list = kmalloc(karg.count * sizeof(drm_buf_pub_t), GFP_KERNEL);
796         if (!karg.list)
797                 return -ENOMEM;
798
799         ret = -EFAULT;
800         for (i = 0; i < karg.count; i++) {
801                 if (get_user(karg.list[i].idx, &ulist[i].idx) ||
802                     get_user(karg.list[i].total, &ulist[i].total) ||
803                     get_user(karg.list[i].used, &ulist[i].used) ||
804                     get_user(tmp1, &ulist[i].address))
805                         goto out;
806
807                 karg.list[i].address = A(tmp1);
808         }
809
810         old_fs = get_fs();
811         set_fs(KERNEL_DS);
812         ret = sys_ioctl(fd, DRM_IOCTL_MAP_BUFS, (unsigned long) &karg);
813         set_fs(old_fs);
814
815         if (!ret) {
816                 for (i = 0; i < orig_count; i++) {
817                         tmp1 = (u32) (long) karg.list[i].address;
818                         if (put_user(karg.list[i].idx, &ulist[i].idx) ||
819                             put_user(karg.list[i].total, &ulist[i].total) ||
820                             put_user(karg.list[i].used, &ulist[i].used) ||
821                             put_user(tmp1, &ulist[i].address)) {
822                                 ret = -EFAULT;
823                                 goto out;
824                         }
825                 }
826                 if (put_user(karg.count, &uarg->count))
827                         ret = -EFAULT;
828         }
829
830 out:
831         kfree(karg.list);
832         return ret;
833 }
834
835 typedef struct drm32_dma {
836                                 /* Indices here refer to the offset into
837                                    buflist in drm_buf_get_t.  */
838         int             context;          /* Context handle                 */
839         int             send_count;       /* Number of buffers to send      */
840         u32             send_indices;     /* List of handles to buffers (int *) */
841         u32             send_sizes;       /* Lengths of data to send (int *) */
842         drm_dma_flags_t flags;            /* Flags                          */
843         int             request_count;    /* Number of buffers requested    */
844         int             request_size;     /* Desired size for buffers       */
845         u32             request_indices;  /* Buffer information (int *)     */
846         u32             request_sizes;    /* (int *) */
847         int             granted_count;    /* Number of buffers granted      */
848 } drm32_dma_t;
849 #define DRM32_IOCTL_DMA      DRM_IOWR(0x29, drm32_dma_t)
850
851 /* RED PEN      The DRM layer blindly dereferences the send/request
852  *              index/size arrays even though they are userland
853  *              pointers.  -DaveM
854  */
855 static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg)
856 {
857         drm32_dma_t *uarg = (drm32_dma_t *) arg;
858         int __user *u_si, *u_ss, *u_ri, *u_rs;
859         drm_dma_t karg;
860         mm_segment_t old_fs;
861         int ret;
862         u32 tmp1, tmp2, tmp3, tmp4;
863
864         karg.send_indices = karg.send_sizes = NULL;
865         karg.request_indices = karg.request_sizes = NULL;
866
867         if (get_user(karg.context, &uarg->context) ||
868             get_user(karg.send_count, &uarg->send_count) ||
869             get_user(tmp1, &uarg->send_indices) ||
870             get_user(tmp2, &uarg->send_sizes) ||
871             get_user(karg.flags, &uarg->flags) ||
872             get_user(karg.request_count, &uarg->request_count) ||
873             get_user(karg.request_size, &uarg->request_size) ||
874             get_user(tmp3, &uarg->request_indices) ||
875             get_user(tmp4, &uarg->request_sizes) ||
876             get_user(karg.granted_count, &uarg->granted_count))
877                 return -EFAULT;
878
879         u_si = A(tmp1);
880         u_ss = A(tmp2);
881         u_ri = A(tmp3);
882         u_rs = A(tmp4);
883
884         if (karg.send_count) {
885                 karg.send_indices = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
886                 karg.send_sizes = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
887
888                 ret = -ENOMEM;
889                 if (!karg.send_indices || !karg.send_sizes)
890                         goto out;
891
892                 ret = -EFAULT;
893                 if (copy_from_user(karg.send_indices, u_si,
894                                    (karg.send_count * sizeof(int))) ||
895                     copy_from_user(karg.send_sizes, u_ss,
896                                    (karg.send_count * sizeof(int))))
897                         goto out;
898         }
899
900         if (karg.request_count) {
901                 karg.request_indices = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
902                 karg.request_sizes = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
903
904                 ret = -ENOMEM;
905                 if (!karg.request_indices || !karg.request_sizes)
906                         goto out;
907
908                 ret = -EFAULT;
909                 if (copy_from_user(karg.request_indices, u_ri,
910                                    (karg.request_count * sizeof(int))) ||
911                     copy_from_user(karg.request_sizes, u_rs,
912                                    (karg.request_count * sizeof(int))))
913                         goto out;
914         }
915
916         old_fs = get_fs();
917         set_fs(KERNEL_DS);
918         ret = sys_ioctl(fd, DRM_IOCTL_DMA, (unsigned long) &karg);
919         set_fs(old_fs);
920
921         if (!ret) {
922                 if (put_user(karg.context, &uarg->context) ||
923                     put_user(karg.send_count, &uarg->send_count) ||
924                     put_user(karg.flags, &uarg->flags) ||
925                     put_user(karg.request_count, &uarg->request_count) ||
926                     put_user(karg.request_size, &uarg->request_size) ||
927                     put_user(karg.granted_count, &uarg->granted_count))
928                         ret = -EFAULT;
929
930                 if (karg.send_count) {
931                         if (copy_to_user(u_si, karg.send_indices,
932                                          (karg.send_count * sizeof(int))) ||
933                             copy_to_user(u_ss, karg.send_sizes,
934                                          (karg.send_count * sizeof(int))))
935                                 ret = -EFAULT;
936                 }
937                 if (karg.request_count) {
938                         if (copy_to_user(u_ri, karg.request_indices,
939                                          (karg.request_count * sizeof(int))) ||
940                             copy_to_user(u_rs, karg.request_sizes,
941                                          (karg.request_count * sizeof(int))))
942                                 ret = -EFAULT;
943                 }
944         }
945
946 out:
947         if (karg.send_indices)
948                 kfree(karg.send_indices);
949         if (karg.send_sizes)
950                 kfree(karg.send_sizes);
951         if (karg.request_indices)
952                 kfree(karg.request_indices);
953         if (karg.request_sizes)
954                 kfree(karg.request_sizes);
955
956         return ret;
957 }
958
959 typedef struct drm32_ctx_res {
960         int             count;
961         u32             contexts; /* (drm_ctx_t *) */
962 } drm32_ctx_res_t;
963 #define DRM32_IOCTL_RES_CTX    DRM_IOWR(0x26, drm32_ctx_res_t)
964
965 static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg)
966 {
967         drm32_ctx_res_t *uarg = (drm32_ctx_res_t *) arg;
968         drm_ctx_t __user *ulist;
969         drm_ctx_res_t karg;
970         mm_segment_t old_fs;
971         int orig_count, ret;
972         u32 tmp;
973
974         karg.contexts = NULL;
975         if (get_user(karg.count, &uarg->count) ||
976             get_user(tmp, &uarg->contexts))
977                 return -EFAULT;
978
979         ulist = A(tmp);
980
981         orig_count = karg.count;
982         if (karg.count && ulist) {
983                 karg.contexts = kmalloc((karg.count * sizeof(drm_ctx_t)), GFP_KERNEL);
984                 if (!karg.contexts)
985                         return -ENOMEM;
986                 if (copy_from_user(karg.contexts, ulist,
987                                    (karg.count * sizeof(drm_ctx_t)))) {
988                         kfree(karg.contexts);
989                         return -EFAULT;
990                 }
991         }
992
993         old_fs = get_fs();
994         set_fs(KERNEL_DS);
995         ret = sys_ioctl(fd, DRM_IOCTL_RES_CTX, (unsigned long) &karg);
996         set_fs(old_fs);
997
998         if (!ret) {
999                 if (orig_count) {
1000                         if (copy_to_user(ulist, karg.contexts,
1001                                          (orig_count * sizeof(drm_ctx_t))))
1002                                 ret = -EFAULT;
1003                 }
1004                 if (put_user(karg.count, &uarg->count))
1005                         ret = -EFAULT;
1006         }
1007
1008         if (karg.contexts)
1009                 kfree(karg.contexts);
1010
1011         return ret;
1012 }
1013
1014 #endif
1015
1016 /* HERE! */
1017
1018 struct usbdevfs_ctrltransfer32 {
1019         __u8 bRequestType;
1020         __u8 bRequest;
1021         __u16 wValue;
1022         __u16 wIndex;
1023         __u16 wLength;
1024         __u32 timeout;  /* in milliseconds */
1025         __u32 data;
1026 };
1027
1028 #define USBDEVFS_CONTROL32           _IOWR('U', 0, struct usbdevfs_ctrltransfer32)
1029
1030 static int do_usbdevfs_control(unsigned int fd, unsigned int cmd, unsigned long arg)
1031 {
1032         struct usbdevfs_ctrltransfer kctrl;
1033         struct usbdevfs_ctrltransfer32 *uctrl;
1034         mm_segment_t old_fs;
1035         __u32 udata;
1036         void __user *uptr;
1037         void *kptr;
1038         int err;
1039
1040         uctrl = (struct usbdevfs_ctrltransfer32 *) arg;
1041
1042         if (copy_from_user(&kctrl, uctrl,
1043                            (sizeof(struct usbdevfs_ctrltransfer) -
1044                             sizeof(void *))))
1045                 return -EFAULT;
1046
1047         if (get_user(udata, &uctrl->data))
1048                 return -EFAULT;
1049         uptr = A(udata);
1050
1051         /* In usbdevice_fs, it limits the control buffer to a page,
1052          * for simplicity so do we.
1053          */
1054         if (!uptr || kctrl.wLength > PAGE_SIZE)
1055                 return -EINVAL;
1056
1057         kptr = (void *)__get_free_page(GFP_KERNEL);
1058
1059         if ((kctrl.bRequestType & 0x80) == 0) {
1060                 err = -EFAULT;
1061                 if (copy_from_user(kptr, uptr, kctrl.wLength))
1062                         goto out;
1063         }
1064
1065         kctrl.data = kptr;
1066
1067         old_fs = get_fs();
1068         set_fs(KERNEL_DS);
1069         err = sys_ioctl(fd, USBDEVFS_CONTROL, (unsigned long)&kctrl);
1070         set_fs(old_fs);
1071
1072         if (err >= 0 &&
1073             ((kctrl.bRequestType & 0x80) != 0)) {
1074                 if (copy_to_user(uptr, kptr, kctrl.wLength))
1075                         err = -EFAULT;
1076         }
1077
1078 out:
1079         free_page((unsigned long) kptr);
1080         return err;
1081 }
1082
1083 struct usbdevfs_bulktransfer32 {
1084         unsigned int ep;
1085         unsigned int len;
1086         unsigned int timeout; /* in milliseconds */
1087         __u32 data;
1088 };
1089
1090 #define USBDEVFS_BULK32              _IOWR('U', 2, struct usbdevfs_bulktransfer32)
1091
1092 static int do_usbdevfs_bulk(unsigned int fd, unsigned int cmd, unsigned long arg)
1093 {
1094         struct usbdevfs_bulktransfer kbulk;
1095         struct usbdevfs_bulktransfer32 *ubulk;
1096         mm_segment_t old_fs;
1097         __u32 udata;
1098         void __user *uptr;
1099         void *kptr;
1100         int err;
1101
1102         ubulk = (struct usbdevfs_bulktransfer32 *) arg;
1103
1104         if (get_user(kbulk.ep, &ubulk->ep) ||
1105             get_user(kbulk.len, &ubulk->len) ||
1106             get_user(kbulk.timeout, &ubulk->timeout) ||
1107             get_user(udata, &ubulk->data))
1108                 return -EFAULT;
1109
1110         uptr = A(udata);
1111
1112         /* In usbdevice_fs, it limits the control buffer to a page,
1113          * for simplicity so do we.
1114          */
1115         if (!uptr || kbulk.len > PAGE_SIZE)
1116                 return -EINVAL;
1117
1118         kptr = (void *) __get_free_page(GFP_KERNEL);
1119
1120         if ((kbulk.ep & 0x80) == 0) {
1121                 err = -EFAULT;
1122                 if (copy_from_user(kptr, uptr, kbulk.len))
1123                         goto out;
1124         }
1125
1126         kbulk.data = kptr;
1127
1128         old_fs = get_fs();
1129         set_fs(KERNEL_DS);
1130         err = sys_ioctl(fd, USBDEVFS_BULK, (unsigned long) &kbulk);
1131         set_fs(old_fs);
1132
1133         if (err >= 0 &&
1134             ((kbulk.ep & 0x80) != 0)) {
1135                 if (copy_to_user(uptr, kptr, kbulk.len))
1136                         err = -EFAULT;
1137         }
1138
1139 out:
1140         free_page((unsigned long) kptr);
1141         return err;
1142 }
1143
1144 /* This needs more work before we can enable it.  Unfortunately
1145  * because of the fancy asynchronous way URB status/error is written
1146  * back to userspace, we'll need to fiddle with USB devio internals
1147  * and/or reimplement entirely the frontend of it ourselves. -DaveM
1148  *
1149  * The issue is:
1150  *
1151  *      When an URB is submitted via usbdevicefs it is put onto an
1152  *      asynchronous queue.  When the URB completes, it may be reaped
1153  *      via another ioctl.  During this reaping the status is written
1154  *      back to userspace along with the length of the transfer.
1155  *
1156  *      We must translate into 64-bit kernel types so we pass in a kernel
1157  *      space copy of the usbdevfs_urb structure.  This would mean that we
1158  *      must do something to deal with the async entry reaping.  First we
1159  *      have to deal somehow with this transitory memory we've allocated.
1160  *      This is problematic since there are many call sites from which the
1161  *      async entries can be destroyed (and thus when we'd need to free up
1162  *      this kernel memory).  One of which is the close() op of usbdevicefs.
1163  *      To handle that we'd need to make our own file_operations struct which
1164  *      overrides usbdevicefs's release op with our own which runs usbdevicefs's
1165  *      real release op then frees up the kernel memory.
1166  *
1167  *      But how to keep track of these kernel buffers?  We'd need to either
1168  *      keep track of them in some table _or_ know about usbdevicefs internals
1169  *      (ie. the exact layout of its file private, which is actually defined
1170  *      in linux/usbdevice_fs.h, the layout of the async queues are private to
1171  *      devio.c)
1172  *
1173  * There is one possible other solution I considered, also involving knowledge
1174  * of usbdevicefs internals:
1175  *
1176  *      After an URB is submitted, we "fix up" the address back to the user
1177  *      space one.  This would work if the status/length fields written back
1178  *      by the async URB completion lines up perfectly in the 32-bit type with
1179  *      the 64-bit kernel type.  Unfortunately, it does not because the iso
1180  *      frame descriptors, at the end of the struct, can be written back.
1181  *
1182  * I think we'll just need to simply duplicate the devio URB engine here.
1183  */
1184 #if 0
1185 struct usbdevfs_urb32 {
1186         __u8 type;
1187         __u8 endpoint;
1188         __s32 status;
1189         __u32 flags;
1190         __u32 buffer;
1191         __s32 buffer_length;
1192         __s32 actual_length;
1193         __s32 start_frame;
1194         __s32 number_of_packets;
1195         __s32 error_count;
1196         __u32 signr;
1197         __u32 usercontext; /* unused */
1198         struct usbdevfs_iso_packet_desc iso_frame_desc[0];
1199 };
1200
1201 #define USBDEVFS_SUBMITURB32       _IOR('U', 10, struct usbdevfs_urb32)
1202
1203 static int get_urb32(struct usbdevfs_urb *kurb,
1204                      struct usbdevfs_urb32 *uurb)
1205 {
1206         if (get_user(kurb->type, &uurb->type) ||
1207             __get_user(kurb->endpoint, &uurb->endpoint) ||
1208             __get_user(kurb->status, &uurb->status) ||
1209             __get_user(kurb->flags, &uurb->flags) ||
1210             __get_user(kurb->buffer_length, &uurb->buffer_length) ||
1211             __get_user(kurb->actual_length, &uurb->actual_length) ||
1212             __get_user(kurb->start_frame, &uurb->start_frame) ||
1213             __get_user(kurb->number_of_packets, &uurb->number_of_packets) ||
1214             __get_user(kurb->error_count, &uurb->error_count) ||
1215             __get_user(kurb->signr, &uurb->signr))
1216                 return -EFAULT;
1217
1218         kurb->usercontext = 0; /* unused currently */
1219
1220         return 0;
1221 }
1222
1223 /* Just put back the values which usbdevfs actually changes. */
1224 static int put_urb32(struct usbdevfs_urb *kurb,
1225                      struct usbdevfs_urb32 *uurb)
1226 {
1227         if (put_user(kurb->status, &uurb->status) ||
1228             __put_user(kurb->actual_length, &uurb->actual_length) ||
1229             __put_user(kurb->error_count, &uurb->error_count))
1230                 return -EFAULT;
1231
1232         if (kurb->number_of_packets != 0) {
1233                 int i;
1234
1235                 for (i = 0; i < kurb->number_of_packets; i++) {
1236                         if (__put_user(kurb->iso_frame_desc[i].actual_length,
1237                                        &uurb->iso_frame_desc[i].actual_length) ||
1238                             __put_user(kurb->iso_frame_desc[i].status,
1239                                        &uurb->iso_frame_desc[i].status))
1240                                 return -EFAULT;
1241                 }
1242         }
1243
1244         return 0;
1245 }
1246
1247 static int get_urb32_isoframes(struct usbdevfs_urb *kurb,
1248                                struct usbdevfs_urb32 *uurb)
1249 {
1250         unsigned int totlen;
1251         int i;
1252
1253         if (kurb->type != USBDEVFS_URB_TYPE_ISO) {
1254                 kurb->number_of_packets = 0;
1255                 return 0;
1256         }
1257
1258         if (kurb->number_of_packets < 1 ||
1259             kurb->number_of_packets > 128)
1260                 return -EINVAL;
1261
1262         if (copy_from_user(&kurb->iso_frame_desc[0],
1263                            &uurb->iso_frame_desc[0],
1264                            sizeof(struct usbdevfs_iso_packet_desc) *
1265                            kurb->number_of_packets))
1266                 return -EFAULT;
1267
1268         totlen = 0;
1269         for (i = 0; i < kurb->number_of_packets; i++) {
1270                 unsigned int this_len;
1271
1272                 this_len = kurb->iso_frame_desc[i].length;
1273                 if (this_len > 1023)
1274                         return -EINVAL;
1275
1276                 totlen += this_len;
1277         }
1278
1279         if (totlen > 32768)
1280                 return -EINVAL;
1281
1282         kurb->buffer_length = totlen;
1283
1284         return 0;
1285 }
1286
1287 static int do_usbdevfs_urb(unsigned int fd, unsigned int cmd, unsigned long arg)
1288 {
1289         struct usbdevfs_urb *kurb;
1290         struct usbdevfs_urb32 *uurb;
1291         mm_segment_t old_fs;
1292         __u32 udata;
1293         void __user *uptr;
1294         void *kptr;
1295         unsigned int buflen;
1296         int err;
1297
1298         uurb = (struct usbdevfs_urb32 *) arg;
1299
1300         err = -ENOMEM;
1301         kurb = kmalloc(sizeof(struct usbdevfs_urb) +
1302                        (sizeof(struct usbdevfs_iso_packet_desc) * 128),
1303                        GFP_KERNEL);
1304         if (!kurb)
1305                 goto out;
1306
1307         err = -EFAULT;
1308         if (get_urb32(kurb, uurb))
1309                 goto out;
1310
1311         err = get_urb32_isoframes(kurb, uurb);
1312         if (err)
1313                 goto out;
1314
1315         err = -EFAULT;
1316         if (__get_user(udata, &uurb->buffer))
1317                 goto out;
1318         uptr = A(udata);
1319
1320         err = -ENOMEM;
1321         buflen = kurb->buffer_length;
1322         kptr = kmalloc(buflen, GFP_KERNEL);
1323         if (!kptr)
1324                 goto out;
1325
1326         kurb->buffer = kptr;
1327
1328         err = -EFAULT;
1329         if (copy_from_user(kptr, uptr, buflen))
1330                 goto out_kptr;
1331
1332         old_fs = get_fs();
1333         set_fs(KERNEL_DS);
1334         err = sys_ioctl(fd, USBDEVFS_SUBMITURB, (unsigned long) kurb);
1335         set_fs(old_fs);
1336
1337         if (err >= 0) {
1338                 /* XXX Shit, this doesn't work for async URBs :-( XXX */
1339                 if (put_urb32(kurb, uurb)) {
1340                         err = -EFAULT;
1341                 } else if ((kurb->endpoint & USB_DIR_IN) != 0) {
1342                         if (copy_to_user(uptr, kptr, buflen))
1343                                 err = -EFAULT;
1344                 }
1345         }
1346
1347 out_kptr:
1348         kfree(kptr);
1349
1350 out:
1351         kfree(kurb);
1352         return err;
1353 }
1354 #endif
1355
1356 #define USBDEVFS_REAPURB32         _IOW('U', 12, u32)
1357 #define USBDEVFS_REAPURBNDELAY32   _IOW('U', 13, u32)
1358
1359 static int do_usbdevfs_reapurb(unsigned int fd, unsigned int cmd, unsigned long arg)
1360 {
1361         mm_segment_t old_fs;
1362         void *kptr;
1363         int err;
1364
1365         old_fs = get_fs();
1366         set_fs(KERNEL_DS);
1367         err = sys_ioctl(fd,
1368                         (cmd == USBDEVFS_REAPURB32 ?
1369                          USBDEVFS_REAPURB :
1370                          USBDEVFS_REAPURBNDELAY),
1371                         (unsigned long) &kptr);
1372         set_fs(old_fs);
1373
1374         if (err >= 0 &&
1375             put_user(((u32)(long)kptr), (u32 __user *) A(arg)))
1376                 err = -EFAULT;
1377
1378         return err;
1379 }
1380
1381 struct usbdevfs_disconnectsignal32 {
1382         unsigned int signr;
1383         u32 context;
1384 };
1385
1386 #define USBDEVFS_DISCSIGNAL32      _IOR('U', 14, struct usbdevfs_disconnectsignal32)
1387
1388 static int do_usbdevfs_discsignal(unsigned int fd, unsigned int cmd, unsigned long arg)
1389 {
1390         struct usbdevfs_disconnectsignal kdis;
1391         struct usbdevfs_disconnectsignal32 *udis;
1392         mm_segment_t old_fs;
1393         u32 uctx;
1394         int err;
1395
1396         udis = (struct usbdevfs_disconnectsignal32 *) arg;
1397
1398         if (get_user(kdis.signr, &udis->signr) ||
1399             __get_user(uctx, &udis->context))
1400                 return -EFAULT;
1401
1402         kdis.context = (void *) (long)uctx;
1403
1404         old_fs = get_fs();
1405         set_fs(KERNEL_DS);
1406         err = sys_ioctl(fd, USBDEVFS_DISCSIGNAL, (unsigned long) &kdis);
1407         set_fs(old_fs);
1408
1409         return err;
1410 }
1411
1412 typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *);
1413
1414 #define COMPATIBLE_IOCTL(cmd)           HANDLE_IOCTL((cmd),sys_ioctl)
1415 #define HANDLE_IOCTL(cmd,handler)       { (cmd), (ioctl32_handler_t)(handler), NULL },
1416 #define IOCTL_TABLE_START \
1417         struct ioctl_trans ioctl_start[] = {
1418 #define IOCTL_TABLE_END \
1419         }; struct ioctl_trans ioctl_end[0];
1420
1421 IOCTL_TABLE_START
1422 #include <linux/compat_ioctl.h>
1423 #define DECLARES
1424 #include "compat_ioctl.c"
1425 COMPATIBLE_IOCTL(TCSBRKP)
1426 COMPATIBLE_IOCTL(TIOCSTART)
1427 COMPATIBLE_IOCTL(TIOCSTOP)
1428 COMPATIBLE_IOCTL(TIOCGSERIAL)
1429 COMPATIBLE_IOCTL(TIOCSSERIAL)
1430 COMPATIBLE_IOCTL(TIOCSLTC)
1431 COMPATIBLE_IOCTL(FBIOGTYPE)
1432 COMPATIBLE_IOCTL(FBIOSATTR)
1433 COMPATIBLE_IOCTL(FBIOGATTR)
1434 COMPATIBLE_IOCTL(FBIOSVIDEO)
1435 COMPATIBLE_IOCTL(FBIOGVIDEO)
1436 COMPATIBLE_IOCTL(FBIOGCURSOR32)  /* This is not implemented yet. Later it should be converted... */
1437 COMPATIBLE_IOCTL(FBIOSCURPOS)
1438 COMPATIBLE_IOCTL(FBIOGCURPOS)
1439 COMPATIBLE_IOCTL(FBIOGCURMAX)
1440 /* Little k */
1441 COMPATIBLE_IOCTL(KIOCTYPE)
1442 COMPATIBLE_IOCTL(KIOCLAYOUT)
1443 COMPATIBLE_IOCTL(KIOCGTRANS)
1444 COMPATIBLE_IOCTL(KIOCTRANS)
1445 COMPATIBLE_IOCTL(KIOCCMD)
1446 COMPATIBLE_IOCTL(KIOCSDIRECT)
1447 COMPATIBLE_IOCTL(KIOCSLED)
1448 COMPATIBLE_IOCTL(KIOCGLED)
1449 COMPATIBLE_IOCTL(KIOCSRATE)
1450 COMPATIBLE_IOCTL(KIOCGRATE)
1451 COMPATIBLE_IOCTL(VUIDSFORMAT)
1452 COMPATIBLE_IOCTL(VUIDGFORMAT)
1453 /* Little v, the video4linux ioctls */
1454 COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
1455 COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
1456 COMPATIBLE_IOCTL(ENVCTRL_RD_WARNING_TEMPERATURE)
1457 COMPATIBLE_IOCTL(ENVCTRL_RD_SHUTDOWN_TEMPERATURE)
1458 COMPATIBLE_IOCTL(ENVCTRL_RD_CPU_TEMPERATURE)
1459 COMPATIBLE_IOCTL(ENVCTRL_RD_FAN_STATUS)
1460 COMPATIBLE_IOCTL(ENVCTRL_RD_VOLTAGE_STATUS)
1461 COMPATIBLE_IOCTL(ENVCTRL_RD_SCSI_TEMPERATURE)
1462 COMPATIBLE_IOCTL(ENVCTRL_RD_ETHERNET_TEMPERATURE)
1463 COMPATIBLE_IOCTL(ENVCTRL_RD_MTHRBD_TEMPERATURE)
1464 COMPATIBLE_IOCTL(ENVCTRL_RD_CPU_VOLTAGE)
1465 COMPATIBLE_IOCTL(ENVCTRL_RD_GLOBALADDRESS)
1466 /* COMPATIBLE_IOCTL(D7SIOCRD) same value as ENVCTRL_RD_VOLTAGE_STATUS */
1467 COMPATIBLE_IOCTL(D7SIOCWR)
1468 COMPATIBLE_IOCTL(D7SIOCTM)
1469 /* OPENPROMIO, SunOS/Solaris only, the NetBSD one's have
1470  * embedded pointers in the arg which we'd need to clean up...
1471  */
1472 COMPATIBLE_IOCTL(OPROMGETOPT)
1473 COMPATIBLE_IOCTL(OPROMSETOPT)
1474 COMPATIBLE_IOCTL(OPROMNXTOPT)
1475 COMPATIBLE_IOCTL(OPROMSETOPT2)
1476 COMPATIBLE_IOCTL(OPROMNEXT)
1477 COMPATIBLE_IOCTL(OPROMCHILD)
1478 COMPATIBLE_IOCTL(OPROMGETPROP)
1479 COMPATIBLE_IOCTL(OPROMNXTPROP)
1480 COMPATIBLE_IOCTL(OPROMU2P)
1481 COMPATIBLE_IOCTL(OPROMGETCONS)
1482 COMPATIBLE_IOCTL(OPROMGETFBNAME)
1483 COMPATIBLE_IOCTL(OPROMGETBOOTARGS)
1484 COMPATIBLE_IOCTL(OPROMSETCUR)
1485 COMPATIBLE_IOCTL(OPROMPCI2NODE)
1486 COMPATIBLE_IOCTL(OPROMPATH2NODE)
1487 /* Big L */
1488 COMPATIBLE_IOCTL(LOOP_SET_STATUS64)
1489 COMPATIBLE_IOCTL(LOOP_GET_STATUS64)
1490 /* Big A */
1491 COMPATIBLE_IOCTL(AUDIO_GETINFO)
1492 COMPATIBLE_IOCTL(AUDIO_SETINFO)
1493 COMPATIBLE_IOCTL(AUDIO_DRAIN)
1494 COMPATIBLE_IOCTL(AUDIO_GETDEV)
1495 COMPATIBLE_IOCTL(AUDIO_GETDEV_SUNOS)
1496 COMPATIBLE_IOCTL(AUDIO_FLUSH)
1497 COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI)
1498 /* Raw devices */
1499 COMPATIBLE_IOCTL(RAW_SETBIND)
1500 COMPATIBLE_IOCTL(RAW_GETBIND)
1501 /* NCP ioctls which do not need any translations */
1502 COMPATIBLE_IOCTL(NCP_IOC_CONN_LOGGED_IN)
1503 COMPATIBLE_IOCTL(NCP_IOC_SIGN_INIT)
1504 COMPATIBLE_IOCTL(NCP_IOC_SIGN_WANTED)
1505 COMPATIBLE_IOCTL(NCP_IOC_SET_SIGN_WANTED)
1506 COMPATIBLE_IOCTL(NCP_IOC_LOCKUNLOCK)
1507 COMPATIBLE_IOCTL(NCP_IOC_GETROOT)
1508 COMPATIBLE_IOCTL(NCP_IOC_SETROOT)
1509 COMPATIBLE_IOCTL(NCP_IOC_GETCHARSETS)
1510 COMPATIBLE_IOCTL(NCP_IOC_SETCHARSETS)
1511 COMPATIBLE_IOCTL(NCP_IOC_GETDENTRYTTL)
1512 COMPATIBLE_IOCTL(NCP_IOC_SETDENTRYTTL)
1513 #if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
1514 COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC)
1515 COMPATIBLE_IOCTL(DRM_IOCTL_IRQ_BUSID)
1516 COMPATIBLE_IOCTL(DRM_IOCTL_AUTH_MAGIC)
1517 COMPATIBLE_IOCTL(DRM_IOCTL_BLOCK)
1518 COMPATIBLE_IOCTL(DRM_IOCTL_UNBLOCK)
1519 COMPATIBLE_IOCTL(DRM_IOCTL_CONTROL)
1520 COMPATIBLE_IOCTL(DRM_IOCTL_ADD_BUFS)
1521 COMPATIBLE_IOCTL(DRM_IOCTL_MARK_BUFS)
1522 COMPATIBLE_IOCTL(DRM_IOCTL_ADD_CTX)
1523 COMPATIBLE_IOCTL(DRM_IOCTL_RM_CTX)
1524 COMPATIBLE_IOCTL(DRM_IOCTL_MOD_CTX)
1525 COMPATIBLE_IOCTL(DRM_IOCTL_GET_CTX)
1526 COMPATIBLE_IOCTL(DRM_IOCTL_SWITCH_CTX)
1527 COMPATIBLE_IOCTL(DRM_IOCTL_NEW_CTX)
1528 COMPATIBLE_IOCTL(DRM_IOCTL_ADD_DRAW)
1529 COMPATIBLE_IOCTL(DRM_IOCTL_RM_DRAW)
1530 COMPATIBLE_IOCTL(DRM_IOCTL_LOCK)
1531 COMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK)
1532 COMPATIBLE_IOCTL(DRM_IOCTL_FINISH)
1533 #endif /* DRM */
1534 COMPATIBLE_IOCTL(WIOCSTART)
1535 COMPATIBLE_IOCTL(WIOCSTOP)
1536 COMPATIBLE_IOCTL(WIOCGSTAT)
1537 COMPATIBLE_IOCTL(HCIUARTSETPROTO)
1538 COMPATIBLE_IOCTL(HCIUARTGETPROTO)
1539 COMPATIBLE_IOCTL(RFCOMMCREATEDEV)
1540 COMPATIBLE_IOCTL(RFCOMMRELEASEDEV)
1541 COMPATIBLE_IOCTL(RFCOMMGETDEVLIST)
1542 COMPATIBLE_IOCTL(RFCOMMGETDEVINFO)
1543 COMPATIBLE_IOCTL(RFCOMMSTEALDLC)
1544 COMPATIBLE_IOCTL(BNEPCONNADD)
1545 COMPATIBLE_IOCTL(BNEPCONNDEL)
1546 COMPATIBLE_IOCTL(BNEPGETCONNLIST)
1547 COMPATIBLE_IOCTL(BNEPGETCONNINFO)
1548 /* device-mapper */
1549 #if defined(CONFIG_DM_IOCTL_V4)
1550 COMPATIBLE_IOCTL(DM_VERSION)
1551 COMPATIBLE_IOCTL(DM_REMOVE_ALL)
1552 COMPATIBLE_IOCTL(DM_LIST_DEVICES)
1553 COMPATIBLE_IOCTL(DM_DEV_CREATE)
1554 COMPATIBLE_IOCTL(DM_DEV_REMOVE)
1555 COMPATIBLE_IOCTL(DM_DEV_RENAME)
1556 COMPATIBLE_IOCTL(DM_DEV_SUSPEND)
1557 COMPATIBLE_IOCTL(DM_DEV_STATUS)
1558 COMPATIBLE_IOCTL(DM_DEV_WAIT)
1559 COMPATIBLE_IOCTL(DM_TABLE_LOAD)
1560 COMPATIBLE_IOCTL(DM_TABLE_CLEAR)
1561 COMPATIBLE_IOCTL(DM_TABLE_DEPS)
1562 COMPATIBLE_IOCTL(DM_TABLE_STATUS)
1563 #else
1564 COMPATIBLE_IOCTL(DM_VERSION)
1565 COMPATIBLE_IOCTL(DM_REMOVE_ALL)
1566 COMPATIBLE_IOCTL(DM_DEV_CREATE)
1567 COMPATIBLE_IOCTL(DM_DEV_REMOVE)
1568 COMPATIBLE_IOCTL(DM_DEV_RELOAD)
1569 COMPATIBLE_IOCTL(DM_DEV_SUSPEND)
1570 COMPATIBLE_IOCTL(DM_DEV_RENAME)
1571 COMPATIBLE_IOCTL(DM_DEV_DEPS)
1572 COMPATIBLE_IOCTL(DM_DEV_STATUS)
1573 COMPATIBLE_IOCTL(DM_TARGET_STATUS)
1574 COMPATIBLE_IOCTL(DM_TARGET_WAIT)
1575 #endif
1576 /* And these ioctls need translation */
1577 HANDLE_IOCTL(HDIO_GETGEO_BIG_RAW, hdio_getgeo_big)
1578 /* NCPFS */
1579 HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest)
1580 HANDLE_IOCTL(NCP_IOC_GETMOUNTUID2_32, do_ncp_getmountuid2)
1581 HANDLE_IOCTL(NCP_IOC_GET_FS_INFO_V2_32, do_ncp_getfsinfo2)
1582 HANDLE_IOCTL(NCP_IOC_GETOBJECTNAME_32, do_ncp_getobjectname)
1583 HANDLE_IOCTL(NCP_IOC_SETOBJECTNAME_32, do_ncp_setobjectname)
1584 HANDLE_IOCTL(NCP_IOC_GETPRIVATEDATA_32, do_ncp_getprivatedata)
1585 HANDLE_IOCTL(NCP_IOC_SETPRIVATEDATA_32, do_ncp_setprivatedata)
1586 /* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */
1587 HANDLE_IOCTL(FBIOPUTCMAP32, fbiogetputcmap)
1588 HANDLE_IOCTL(FBIOGETCMAP32, fbiogetputcmap)
1589 HANDLE_IOCTL(FBIOSCURSOR32, fbiogscursor)
1590 #if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
1591 HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version)
1592 HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique)
1593 HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique)
1594 HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap)
1595 HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs)
1596 HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs)
1597 HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs)
1598 HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma)
1599 HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx)
1600 #endif /* DRM */
1601 #if 0
1602 HANDLE_IOCTL(RTC32_IRQP_READ, do_rtc_ioctl)
1603 HANDLE_IOCTL(RTC32_IRQP_SET, do_rtc_ioctl)
1604 HANDLE_IOCTL(RTC32_EPOCH_READ, do_rtc_ioctl)
1605 HANDLE_IOCTL(RTC32_EPOCH_SET, do_rtc_ioctl)
1606 #endif
1607 HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control)
1608 HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk)
1609 /*HANDLE_IOCTL(USBDEVFS_SUBMITURB32, do_usbdevfs_urb)*/
1610 HANDLE_IOCTL(USBDEVFS_REAPURB32, do_usbdevfs_reapurb)
1611 HANDLE_IOCTL(USBDEVFS_REAPURBNDELAY32, do_usbdevfs_reapurb)
1612 HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal)
1613 /* take care of sizeof(sizeof()) breakage */
1614 IOCTL_TABLE_END