1
2
3
4
5
6
7
8
9
10
11
12
13#ifdef INCLUDES
14#include <linux/config.h>
15#include <linux/types.h>
16#include <linux/compat.h>
17#include <linux/kernel.h>
18#include <linux/compiler.h>
19#include <linux/sched.h>
20#include <linux/smp.h>
21#include <linux/smp_lock.h>
22#include <linux/ioctl.h>
23#include <linux/if.h>
24#include <linux/if_bridge.h>
25#include <linux/slab.h>
26#include <linux/hdreg.h>
27#include <linux/raid/md.h>
28#include <linux/kd.h>
29#include <linux/dirent.h>
30#include <linux/route.h>
31#include <linux/in6.h>
32#include <linux/ipv6_route.h>
33#include <linux/skbuff.h>
34#include <linux/netlink.h>
35#include <linux/vt.h>
36#include <linux/fs.h>
37#include <linux/file.h>
38#include <linux/fd.h>
39#include <linux/ppp_defs.h>
40#include <linux/if_ppp.h>
41#include <linux/if_pppox.h>
42#include <linux/mtio.h>
43#include <linux/cdrom.h>
44#include <linux/loop.h>
45#include <linux/auto_fs.h>
46#include <linux/auto_fs4.h>
47#include <linux/devfs_fs.h>
48#include <linux/tty.h>
49#include <linux/vt_kern.h>
50#include <linux/fb.h>
51#include <linux/ext2_fs.h>
52#include <linux/ext3_jbd.h>
53#include <linux/ext3_fs.h>
54#include <linux/videodev.h>
55#include <linux/netdevice.h>
56#include <linux/raw.h>
57#include <linux/smb_fs.h>
58#include <linux/blkpg.h>
59#include <linux/blkdev.h>
60#include <linux/elevator.h>
61#include <linux/rtc.h>
62#include <linux/pci.h>
63#include <linux/module.h>
64#include <linux/serial.h>
65#include <linux/reiserfs_fs.h>
66#include <linux/if_tun.h>
67#include <linux/ctype.h>
68#include <linux/ioctl32.h>
69#include <linux/syscalls.h>
70#include <linux/ncp_fs.h>
71#include <linux/i2c.h>
72#include <linux/i2c-dev.h>
73#include <linux/wireless.h>
74
75#include <net/sock.h>
76#include <net/bluetooth/bluetooth.h>
77#include <net/bluetooth/hci.h>
78#include <net/bluetooth/rfcomm.h>
79
80#include <linux/capi.h>
81
82#include <scsi/scsi.h>
83
84#undef __KERNEL__
85#include <scsi/scsi_ioctl.h>
86#define __KERNEL__
87#include <scsi/sg.h>
88
89#include <asm/types.h>
90#include <asm/uaccess.h>
91#include <linux/ethtool.h>
92#include <linux/mii.h>
93#include <linux/if_bonding.h>
94#include <linux/watchdog.h>
95#include <linux/dm-ioctl.h>
96
97#include <asm/module.h>
98#include <linux/soundcard.h>
99#include <linux/lp.h>
100
101#include <linux/atm.h>
102#include <linux/atmarp.h>
103#include <linux/atmclip.h>
104#include <linux/atmdev.h>
105#include <linux/atmioc.h>
106#include <linux/atmlec.h>
107#include <linux/atmmpc.h>
108#include <linux/atmsvc.h>
109#include <linux/atm_tcp.h>
110#include <linux/sonet.h>
111#include <linux/atm_suni.h>
112#include <linux/mtd/mtd.h>
113
114#include <linux/usb.h>
115#include <linux/usbdevice_fs.h>
116#include <linux/nbd.h>
117#include <linux/random.h>
118#include <linux/filter.h>
119#include <linux/msdos_fs.h>
120
121#include <linux/hiddev.h>
122
123#undef INCLUDES
124#endif
125
126#ifdef CODE
127
128
129#define EXT2_IOC32_GETFLAGS _IOR('f', 1, int)
130#define EXT2_IOC32_SETFLAGS _IOW('f', 2, int)
131#define EXT2_IOC32_GETVERSION _IOR('v', 1, int)
132#define EXT2_IOC32_SETVERSION _IOW('v', 2, int)
133#define EXT3_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int)
134
135static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
136{
137 mm_segment_t old_fs = get_fs();
138 int err;
139 unsigned long val;
140
141 set_fs (KERNEL_DS);
142 err = sys_ioctl(fd, cmd, (unsigned long)&val);
143 set_fs (old_fs);
144 if (!err && put_user(val, (u32 __user *)compat_ptr(arg)))
145 return -EFAULT;
146 return err;
147}
148
149static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg)
150{
151 mm_segment_t old_fs = get_fs();
152 u32 __user *argptr = compat_ptr(arg);
153 int err;
154 unsigned long val;
155
156 if(get_user(val, argptr))
157 return -EFAULT;
158 set_fs (KERNEL_DS);
159 err = sys_ioctl(fd, cmd, (unsigned long)&val);
160 set_fs (old_fs);
161 if (!err && put_user(val, argptr))
162 return -EFAULT;
163 return err;
164}
165
166static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
167{
168
169 switch (cmd) {
170 case EXT2_IOC32_GETFLAGS: cmd = EXT2_IOC_GETFLAGS; break;
171 case EXT2_IOC32_SETFLAGS: cmd = EXT2_IOC_SETFLAGS; break;
172 case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break;
173 case EXT2_IOC32_SETVERSION: cmd = EXT2_IOC_SETVERSION; break;
174 }
175 return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg));
176}
177
178static int do_ext3_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
179{
180
181 switch (cmd) {
182 case EXT3_IOC32_GROUP_EXTEND: cmd = EXT3_IOC_GROUP_EXTEND; break;
183 }
184 return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg));
185}
186
187struct video_tuner32 {
188 compat_int_t tuner;
189 char name[32];
190 compat_ulong_t rangelow, rangehigh;
191 u32 flags;
192 u16 mode, signal;
193};
194
195static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up)
196{
197 int i;
198
199 if(get_user(kp->tuner, &up->tuner))
200 return -EFAULT;
201 for(i = 0; i < 32; i++)
202 __get_user(kp->name[i], &up->name[i]);
203 __get_user(kp->rangelow, &up->rangelow);
204 __get_user(kp->rangehigh, &up->rangehigh);
205 __get_user(kp->flags, &up->flags);
206 __get_user(kp->mode, &up->mode);
207 __get_user(kp->signal, &up->signal);
208 return 0;
209}
210
211static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up)
212{
213 int i;
214
215 if(put_user(kp->tuner, &up->tuner))
216 return -EFAULT;
217 for(i = 0; i < 32; i++)
218 __put_user(kp->name[i], &up->name[i]);
219 __put_user(kp->rangelow, &up->rangelow);
220 __put_user(kp->rangehigh, &up->rangehigh);
221 __put_user(kp->flags, &up->flags);
222 __put_user(kp->mode, &up->mode);
223 __put_user(kp->signal, &up->signal);
224 return 0;
225}
226
227struct video_buffer32 {
228 compat_caddr_t base;
229 compat_int_t height, width, depth, bytesperline;
230};
231
232static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up)
233{
234 u32 tmp;
235
236 if (get_user(tmp, &up->base))
237 return -EFAULT;
238
239
240
241
242 kp->base = (void *)(unsigned long) tmp;
243
244 __get_user(kp->height, &up->height);
245 __get_user(kp->width, &up->width);
246 __get_user(kp->depth, &up->depth);
247 __get_user(kp->bytesperline, &up->bytesperline);
248 return 0;
249}
250
251static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up)
252{
253 u32 tmp = (u32)((unsigned long)kp->base);
254
255 if(put_user(tmp, &up->base))
256 return -EFAULT;
257 __put_user(kp->height, &up->height);
258 __put_user(kp->width, &up->width);
259 __put_user(kp->depth, &up->depth);
260 __put_user(kp->bytesperline, &up->bytesperline);
261 return 0;
262}
263
264struct video_clip32 {
265 s32 x, y, width, height;
266 compat_caddr_t next;
267};
268
269struct video_window32 {
270 u32 x, y, width, height, chromakey, flags;
271 compat_caddr_t clips;
272 compat_int_t clipcount;
273};
274
275
276static int put_video_window32(struct video_window *kp, struct video_window32 __user *up)
277{
278 if(put_user(kp->x, &up->x))
279 return -EFAULT;
280 __put_user(kp->y, &up->y);
281 __put_user(kp->width, &up->width);
282 __put_user(kp->height, &up->height);
283 __put_user(kp->chromakey, &up->chromakey);
284 __put_user(kp->flags, &up->flags);
285 __put_user(kp->clipcount, &up->clipcount);
286 return 0;
287}
288
289#define VIDIOCGTUNER32 _IOWR('v',4, struct video_tuner32)
290#define VIDIOCSTUNER32 _IOW('v',5, struct video_tuner32)
291#define VIDIOCGWIN32 _IOR('v',9, struct video_window32)
292#define VIDIOCSWIN32 _IOW('v',10, struct video_window32)
293#define VIDIOCGFBUF32 _IOR('v',11, struct video_buffer32)
294#define VIDIOCSFBUF32 _IOW('v',12, struct video_buffer32)
295#define VIDIOCGFREQ32 _IOR('v',14, u32)
296#define VIDIOCSFREQ32 _IOW('v',15, u32)
297
298enum {
299 MaxClips = (~0U-sizeof(struct video_window))/sizeof(struct video_clip)
300};
301
302static int do_set_window(unsigned int fd, unsigned int cmd, unsigned long arg)
303{
304 struct video_window32 __user *up = compat_ptr(arg);
305 struct video_window __user *vw;
306 struct video_clip __user *p;
307 int nclips;
308 u32 n;
309
310 if (get_user(nclips, &up->clipcount))
311 return -EFAULT;
312
313
314 if (nclips < 0)
315 nclips = VIDEO_CLIPMAP_SIZE;
316
317 if (nclips > MaxClips)
318 return -ENOMEM;
319
320 vw = compat_alloc_user_space(sizeof(struct video_window) +
321 nclips * sizeof(struct video_clip));
322
323 p = nclips ? (struct video_clip __user *)(vw + 1) : NULL;
324
325 if (get_user(n, &up->x) || put_user(n, &vw->x) ||
326 get_user(n, &up->y) || put_user(n, &vw->y) ||
327 get_user(n, &up->width) || put_user(n, &vw->width) ||
328 get_user(n, &up->height) || put_user(n, &vw->height) ||
329 get_user(n, &up->chromakey) || put_user(n, &vw->chromakey) ||
330 get_user(n, &up->flags) || put_user(n, &vw->flags) ||
331 get_user(n, &up->clipcount) || put_user(n, &vw->clipcount) ||
332 get_user(n, &up->clips) || put_user(p, &vw->clips))
333 return -EFAULT;
334
335 if (nclips) {
336 struct video_clip32 __user *u = compat_ptr(n);
337 int i;
338 if (!u)
339 return -EINVAL;
340 for (i = 0; i < nclips; i++, u++, p++) {
341 s32 v;
342 if (get_user(v, &u->x) ||
343 put_user(v, &p->x) ||
344 get_user(v, &u->y) ||
345 put_user(v, &p->y) ||
346 get_user(v, &u->width) ||
347 put_user(v, &p->width) ||
348 get_user(v, &u->height) ||
349 put_user(v, &p->height) ||
350 put_user(NULL, &p->next))
351 return -EFAULT;
352 }
353 }
354
355 return sys_ioctl(fd, VIDIOCSWIN, (unsigned long)p);
356}
357
358static int do_video_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
359{
360 union {
361 struct video_tuner vt;
362 struct video_buffer vb;
363 struct video_window vw;
364 unsigned long vx;
365 } karg;
366 mm_segment_t old_fs = get_fs();
367 void __user *up = compat_ptr(arg);
368 int err = 0;
369
370
371 switch(cmd) {
372 case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break;
373 case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break;
374 case VIDIOCGWIN32: cmd = VIDIOCGWIN; break;
375 case VIDIOCGFBUF32: cmd = VIDIOCGFBUF; break;
376 case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break;
377 case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break;
378 case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break;
379 };
380
381 switch(cmd) {
382 case VIDIOCSTUNER:
383 case VIDIOCGTUNER:
384 err = get_video_tuner32(&karg.vt, up);
385 break;
386
387 case VIDIOCSFBUF:
388 err = get_video_buffer32(&karg.vb, up);
389 break;
390
391 case VIDIOCSFREQ:
392 err = get_user(karg.vx, (u32 __user *)up);
393 break;
394 };
395 if(err)
396 goto out;
397
398 set_fs(KERNEL_DS);
399 err = sys_ioctl(fd, cmd, (unsigned long)&karg);
400 set_fs(old_fs);
401
402 if(err == 0) {
403 switch(cmd) {
404 case VIDIOCGTUNER:
405 err = put_video_tuner32(&karg.vt, up);
406 break;
407
408 case VIDIOCGWIN:
409 err = put_video_window32(&karg.vw, up);
410 break;
411
412 case VIDIOCGFBUF:
413 err = put_video_buffer32(&karg.vb, up);
414 break;
415
416 case VIDIOCGFREQ:
417 err = put_user(((u32)karg.vx), (u32 __user *)up);
418 break;
419 };
420 }
421out:
422 return err;
423}
424
425#ifdef CONFIG_NET
426static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg)
427{
428 struct compat_timeval __user *up = compat_ptr(arg);
429 struct timeval ktv;
430 mm_segment_t old_fs = get_fs();
431 int err;
432
433 set_fs(KERNEL_DS);
434 err = sys_ioctl(fd, cmd, (unsigned long)&ktv);
435 set_fs(old_fs);
436 if(!err) {
437 err = put_user(ktv.tv_sec, &up->tv_sec);
438 err |= __put_user(ktv.tv_usec, &up->tv_usec);
439 }
440 return err;
441}
442
443struct ifmap32 {
444 compat_ulong_t mem_start;
445 compat_ulong_t mem_end;
446 unsigned short base_addr;
447 unsigned char irq;
448 unsigned char dma;
449 unsigned char port;
450};
451
452struct ifreq32 {
453#define IFHWADDRLEN 6
454#define IFNAMSIZ 16
455 union {
456 char ifrn_name[IFNAMSIZ];
457 } ifr_ifrn;
458 union {
459 struct sockaddr ifru_addr;
460 struct sockaddr ifru_dstaddr;
461 struct sockaddr ifru_broadaddr;
462 struct sockaddr ifru_netmask;
463 struct sockaddr ifru_hwaddr;
464 short ifru_flags;
465 compat_int_t ifru_ivalue;
466 compat_int_t ifru_mtu;
467 struct ifmap32 ifru_map;
468 char ifru_slave[IFNAMSIZ];
469 char ifru_newname[IFNAMSIZ];
470 compat_caddr_t ifru_data;
471
472 } ifr_ifru;
473};
474
475struct ifconf32 {
476 compat_int_t ifc_len;
477 compat_caddr_t ifcbuf;
478};
479
480static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg)
481{
482 struct net_device *dev;
483 struct ifreq32 ifr32;
484 int err;
485
486 if (copy_from_user(&ifr32, compat_ptr(arg), sizeof(ifr32)))
487 return -EFAULT;
488
489 dev = dev_get_by_index(ifr32.ifr_ifindex);
490 if (!dev)
491 return -ENODEV;
492
493 strlcpy(ifr32.ifr_name, dev->name, sizeof(ifr32.ifr_name));
494 dev_put(dev);
495
496 err = copy_to_user(compat_ptr(arg), &ifr32, sizeof(ifr32));
497 return (err ? -EFAULT : 0);
498}
499
500static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
501{
502 struct ifconf32 ifc32;
503 struct ifconf ifc;
504 struct ifconf __user *uifc;
505 struct ifreq32 __user *ifr32;
506 struct ifreq __user *ifr;
507 unsigned int i, j;
508 int err;
509
510 if (copy_from_user(&ifc32, compat_ptr(arg), sizeof(struct ifconf32)))
511 return -EFAULT;
512
513 if (ifc32.ifcbuf == 0) {
514 ifc32.ifc_len = 0;
515 ifc.ifc_len = 0;
516 ifc.ifc_req = NULL;
517 uifc = compat_alloc_user_space(sizeof(struct ifconf));
518 } else {
519 size_t len =((ifc32.ifc_len / sizeof (struct ifreq32)) + 1) *
520 sizeof (struct ifreq);
521 uifc = compat_alloc_user_space(sizeof(struct ifconf) + len);
522 ifc.ifc_len = len;
523 ifr = ifc.ifc_req = (void __user *)(uifc + 1);
524 ifr32 = compat_ptr(ifc32.ifcbuf);
525 for (i = 0; i < ifc32.ifc_len; i += sizeof (struct ifreq32)) {
526 if (copy_in_user(ifr, ifr32, sizeof(struct ifreq32)))
527 return -EFAULT;
528 ifr++;
529 ifr32++;
530 }
531 }
532 if (copy_to_user(uifc, &ifc, sizeof(struct ifconf)))
533 return -EFAULT;
534
535 err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)uifc);
536 if (err)
537 return err;
538
539 if (copy_from_user(&ifc, uifc, sizeof(struct ifconf)))
540 return -EFAULT;
541
542 ifr = ifc.ifc_req;
543 ifr32 = compat_ptr(ifc32.ifcbuf);
544 for (i = 0, j = 0; i < ifc32.ifc_len && j < ifc.ifc_len;
545 i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) {
546 if (copy_in_user(ifr32, ifr, sizeof (struct ifreq32)))
547 return -EFAULT;
548 ifr32++;
549 ifr++;
550 }
551
552 if (ifc32.ifcbuf == 0) {
553
554
555
556 i = ifc.ifc_len;
557 i = ((i / sizeof(struct ifreq)) * sizeof(struct ifreq32));
558 ifc32.ifc_len = i;
559 } else {
560 if (i <= ifc32.ifc_len)
561 ifc32.ifc_len = i;
562 else
563 ifc32.ifc_len = i - sizeof (struct ifreq32);
564 }
565 if (copy_to_user(compat_ptr(arg), &ifc32, sizeof(struct ifconf32)))
566 return -EFAULT;
567
568 return 0;
569}
570
571static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
572{
573 struct ifreq __user *ifr;
574 struct ifreq32 __user *ifr32;
575 u32 data;
576 void __user *datap;
577
578 ifr = compat_alloc_user_space(sizeof(*ifr));
579 ifr32 = compat_ptr(arg);
580
581 if (copy_in_user(&ifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ))
582 return -EFAULT;
583
584 if (get_user(data, &ifr32->ifr_ifru.ifru_data))
585 return -EFAULT;
586
587 datap = compat_ptr(data);
588 if (put_user(datap, &ifr->ifr_ifru.ifru_data))
589 return -EFAULT;
590
591 return sys_ioctl(fd, cmd, (unsigned long) ifr);
592}
593
594static int bond_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
595{
596 struct ifreq kifr;
597 struct ifreq __user *uifr;
598 struct ifreq32 __user *ifr32 = compat_ptr(arg);
599 mm_segment_t old_fs;
600 int err;
601 u32 data;
602 void __user *datap;
603
604 switch (cmd) {
605 case SIOCBONDENSLAVE:
606 case SIOCBONDRELEASE:
607 case SIOCBONDSETHWADDR:
608 case SIOCBONDCHANGEACTIVE:
609 if (copy_from_user(&kifr, ifr32, sizeof(struct ifreq32)))
610 return -EFAULT;
611
612 old_fs = get_fs();
613 set_fs (KERNEL_DS);
614 err = sys_ioctl (fd, cmd, (unsigned long)&kifr);
615 set_fs (old_fs);
616
617 return err;
618 case SIOCBONDSLAVEINFOQUERY:
619 case SIOCBONDINFOQUERY:
620 uifr = compat_alloc_user_space(sizeof(*uifr));
621 if (copy_in_user(&uifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ))
622 return -EFAULT;
623
624 if (get_user(data, &ifr32->ifr_ifru.ifru_data))
625 return -EFAULT;
626
627 datap = compat_ptr(data);
628 if (put_user(datap, &uifr->ifr_ifru.ifru_data))
629 return -EFAULT;
630
631 return sys_ioctl (fd, cmd, (unsigned long)uifr);
632 default:
633 return -EINVAL;
634 };
635}
636
637int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
638{
639 struct ifreq __user *u_ifreq64;
640 struct ifreq32 __user *u_ifreq32 = compat_ptr(arg);
641 char tmp_buf[IFNAMSIZ];
642 void __user *data64;
643 u32 data32;
644
645 if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]),
646 IFNAMSIZ))
647 return -EFAULT;
648 if (__get_user(data32, &u_ifreq32->ifr_ifru.ifru_data))
649 return -EFAULT;
650 data64 = compat_ptr(data32);
651
652 u_ifreq64 = compat_alloc_user_space(sizeof(*u_ifreq64));
653
654
655
656
657 copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0], IFNAMSIZ);
658 __put_user(data64, &u_ifreq64->ifr_ifru.ifru_data);
659
660 return sys_ioctl(fd, cmd, (unsigned long) u_ifreq64);
661}
662
663static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
664{
665 struct ifreq ifr;
666 struct ifreq32 __user *uifr32;
667 struct ifmap32 __user *uifmap32;
668 mm_segment_t old_fs;
669 int err;
670
671 uifr32 = compat_ptr(arg);
672 uifmap32 = &uifr32->ifr_ifru.ifru_map;
673 switch (cmd) {
674 case SIOCSIFMAP:
675 err = copy_from_user(&ifr, uifr32, sizeof(ifr.ifr_name));
676 err |= __get_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
677 err |= __get_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
678 err |= __get_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
679 err |= __get_user(ifr.ifr_map.irq, &uifmap32->irq);
680 err |= __get_user(ifr.ifr_map.dma, &uifmap32->dma);
681 err |= __get_user(ifr.ifr_map.port, &uifmap32->port);
682 if (err)
683 return -EFAULT;
684 break;
685 default:
686 if (copy_from_user(&ifr, uifr32, sizeof(*uifr32)))
687 return -EFAULT;
688 break;
689 }
690 old_fs = get_fs();
691 set_fs (KERNEL_DS);
692 err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
693 set_fs (old_fs);
694 if (!err) {
695 switch (cmd) {
696 case SIOCGIFFLAGS:
697 case SIOCGIFMETRIC:
698 case SIOCGIFMTU:
699 case SIOCGIFMEM:
700 case SIOCGIFHWADDR:
701 case SIOCGIFINDEX:
702 case SIOCGIFADDR:
703 case SIOCGIFBRDADDR:
704 case SIOCGIFDSTADDR:
705 case SIOCGIFNETMASK:
706 case SIOCGIFTXQLEN:
707 if (copy_to_user(uifr32, &ifr, sizeof(*uifr32)))
708 return -EFAULT;
709 break;
710 case SIOCGIFMAP:
711 err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name));
712 err |= __put_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
713 err |= __put_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
714 err |= __put_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
715 err |= __put_user(ifr.ifr_map.irq, &uifmap32->irq);
716 err |= __put_user(ifr.ifr_map.dma, &uifmap32->dma);
717 err |= __put_user(ifr.ifr_map.port, &uifmap32->port);
718 if (err)
719 err = -EFAULT;
720 break;
721 }
722 }
723 return err;
724}
725
726struct rtentry32 {
727 u32 rt_pad1;
728 struct sockaddr rt_dst;
729 struct sockaddr rt_gateway;
730 struct sockaddr rt_genmask;
731 unsigned short rt_flags;
732 short rt_pad2;
733 u32 rt_pad3;
734 unsigned char rt_tos;
735 unsigned char rt_class;
736 short rt_pad4;
737 short rt_metric;
738 u32 rt_dev;
739 u32 rt_mtu;
740 u32 rt_window;
741 unsigned short rt_irtt;
742
743};
744
745struct in6_rtmsg32 {
746 struct in6_addr rtmsg_dst;
747 struct in6_addr rtmsg_src;
748 struct in6_addr rtmsg_gateway;
749 u32 rtmsg_type;
750 u16 rtmsg_dst_len;
751 u16 rtmsg_src_len;
752 u32 rtmsg_metric;
753 u32 rtmsg_info;
754 u32 rtmsg_flags;
755 s32 rtmsg_ifindex;
756};
757
758static int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
759{
760 int ret;
761 void *r = NULL;
762 struct in6_rtmsg r6;
763 struct rtentry r4;
764 char devname[16];
765 u32 rtdev;
766 mm_segment_t old_fs = get_fs();
767
768 struct socket *mysock = sockfd_lookup(fd, &ret);
769
770 if (mysock && mysock->sk && mysock->sk->sk_family == AF_INET6) {
771 struct in6_rtmsg32 __user *ur6 = compat_ptr(arg);
772 ret = copy_from_user (&r6.rtmsg_dst, &(ur6->rtmsg_dst),
773 3 * sizeof(struct in6_addr));
774 ret |= __get_user (r6.rtmsg_type, &(ur6->rtmsg_type));
775 ret |= __get_user (r6.rtmsg_dst_len, &(ur6->rtmsg_dst_len));
776 ret |= __get_user (r6.rtmsg_src_len, &(ur6->rtmsg_src_len));
777 ret |= __get_user (r6.rtmsg_metric, &(ur6->rtmsg_metric));
778 ret |= __get_user (r6.rtmsg_info, &(ur6->rtmsg_info));
779 ret |= __get_user (r6.rtmsg_flags, &(ur6->rtmsg_flags));
780 ret |= __get_user (r6.rtmsg_ifindex, &(ur6->rtmsg_ifindex));
781
782 r = (void *) &r6;
783 } else {
784 struct rtentry32 __user *ur4 = compat_ptr(arg);
785 ret = copy_from_user (&r4.rt_dst, &(ur4->rt_dst),
786 3 * sizeof(struct sockaddr));
787 ret |= __get_user (r4.rt_flags, &(ur4->rt_flags));
788 ret |= __get_user (r4.rt_metric, &(ur4->rt_metric));
789 ret |= __get_user (r4.rt_mtu, &(ur4->rt_mtu));
790 ret |= __get_user (r4.rt_window, &(ur4->rt_window));
791 ret |= __get_user (r4.rt_irtt, &(ur4->rt_irtt));
792 ret |= __get_user (rtdev, &(ur4->rt_dev));
793 if (rtdev) {
794 ret |= copy_from_user (devname, compat_ptr(rtdev), 15);
795 r4.rt_dev = devname; devname[15] = 0;
796 } else
797 r4.rt_dev = NULL;
798
799 r = (void *) &r4;
800 }
801
802 if (ret) {
803 ret = -EFAULT;
804 goto out;
805 }
806
807 set_fs (KERNEL_DS);
808 ret = sys_ioctl (fd, cmd, (unsigned long) r);
809 set_fs (old_fs);
810
811out:
812 if (mysock)
813 sockfd_put(mysock);
814
815 return ret;
816}
817#endif
818
819struct hd_geometry32 {
820 unsigned char heads;
821 unsigned char sectors;
822 unsigned short cylinders;
823 u32 start;
824};
825
826static int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg)
827{
828 mm_segment_t old_fs = get_fs();
829 struct hd_geometry geo;
830 struct hd_geometry32 __user *ugeo;
831 int err;
832
833 set_fs (KERNEL_DS);
834 err = sys_ioctl(fd, HDIO_GETGEO, (unsigned long)&geo);
835 set_fs (old_fs);
836 ugeo = compat_ptr(arg);
837 if (!err) {
838 err = copy_to_user (ugeo, &geo, 4);
839 err |= __put_user (geo.start, &ugeo->start);
840 }
841 return err ? -EFAULT : 0;
842}
843
844struct fb_fix_screeninfo32 {
845 char id[16];
846 compat_caddr_t smem_start;
847 u32 smem_len;
848 u32 type;
849 u32 type_aux;
850 u32 visual;
851 u16 xpanstep;
852 u16 ypanstep;
853 u16 ywrapstep;
854 u32 line_length;
855 compat_caddr_t mmio_start;
856 u32 mmio_len;
857 u32 accel;
858 u16 reserved[3];
859};
860
861struct fb_cmap32 {
862 u32 start;
863 u32 len;
864 compat_caddr_t red;
865 compat_caddr_t green;
866 compat_caddr_t blue;
867 compat_caddr_t transp;
868};
869
870static int fb_getput_cmap(unsigned int fd, unsigned int cmd, unsigned long arg)
871{
872 struct fb_cmap_user __user *cmap;
873 struct fb_cmap32 __user *cmap32;
874 __u32 data;
875 int err;
876
877 cmap = compat_alloc_user_space(sizeof(*cmap));
878 cmap32 = compat_ptr(arg);
879
880 if (copy_in_user(&cmap->start, &cmap32->start, 2 * sizeof(__u32)))
881 return -EFAULT;
882
883 if (get_user(data, &cmap32->red) ||
884 put_user(compat_ptr(data), &cmap->red) ||
885 get_user(data, &cmap32->green) ||
886 put_user(compat_ptr(data), &cmap->green) ||
887 get_user(data, &cmap32->blue) ||
888 put_user(compat_ptr(data), &cmap->blue) ||
889 get_user(data, &cmap32->transp) ||
890 put_user(compat_ptr(data), &cmap->transp))
891 return -EFAULT;
892
893 err = sys_ioctl(fd, cmd, (unsigned long) cmap);
894
895 if (!err) {
896 if (copy_in_user(&cmap32->start,
897 &cmap->start,
898 2 * sizeof(__u32)))
899 err = -EFAULT;
900 }
901 return err;
902}
903
904static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix,
905 struct fb_fix_screeninfo32 __user *fix32)
906{
907 __u32 data;
908 int err;
909
910 err = copy_to_user(&fix32->id, &fix->id, sizeof(fix32->id));
911
912 data = (__u32) (unsigned long) fix->smem_start;
913 err |= put_user(data, &fix32->smem_start);
914
915 err |= put_user(fix->smem_len, &fix32->smem_len);
916 err |= put_user(fix->type, &fix32->type);
917 err |= put_user(fix->type_aux, &fix32->type_aux);
918 err |= put_user(fix->visual, &fix32->visual);
919 err |= put_user(fix->xpanstep, &fix32->xpanstep);
920 err |= put_user(fix->ypanstep, &fix32->ypanstep);
921 err |= put_user(fix->ywrapstep, &fix32->ywrapstep);
922 err |= put_user(fix->line_length, &fix32->line_length);
923
924 data = (__u32) (unsigned long) fix->mmio_start;
925 err |= put_user(data, &fix32->mmio_start);
926
927 err |= put_user(fix->mmio_len, &fix32->mmio_len);
928 err |= put_user(fix->accel, &fix32->accel);
929 err |= copy_to_user(fix32->reserved, fix->reserved,
930 sizeof(fix->reserved));
931
932 return err;
933}
934
935static int fb_get_fscreeninfo(unsigned int fd, unsigned int cmd, unsigned long arg)
936{
937 mm_segment_t old_fs;
938 struct fb_fix_screeninfo fix;
939 struct fb_fix_screeninfo32 __user *fix32;
940 int err;
941
942 fix32 = compat_ptr(arg);
943
944 old_fs = get_fs();
945 set_fs(KERNEL_DS);
946 err = sys_ioctl(fd, cmd, (unsigned long) &fix);
947 set_fs(old_fs);
948
949 if (!err)
950 err = do_fscreeninfo_to_user(&fix, fix32);
951
952 return err;
953}
954
955static int fb_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
956{
957 int err;
958
959 switch (cmd) {
960 case FBIOGET_FSCREENINFO:
961 err = fb_get_fscreeninfo(fd,cmd, arg);
962 break;
963
964 case FBIOGETCMAP:
965 case FBIOPUTCMAP:
966 err = fb_getput_cmap(fd, cmd, arg);
967 break;
968
969 default:
970 do {
971 static int count;
972 if (++count <= 20)
973 printk("%s: Unknown fb ioctl cmd fd(%d) "
974 "cmd(%08x) arg(%08lx)\n",
975 __FUNCTION__, fd, cmd, arg);
976 } while(0);
977 err = -ENOSYS;
978 break;
979 };
980
981 return err;
982}
983
984static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
985{
986 mm_segment_t old_fs = get_fs();
987 unsigned long kval;
988 unsigned int __user *uvp;
989 int error;
990
991 set_fs(KERNEL_DS);
992 error = sys_ioctl(fd, cmd, (long)&kval);
993 set_fs(old_fs);
994
995 if(error == 0) {
996 uvp = compat_ptr(arg);
997 if(put_user(kval, uvp))
998 error = -EFAULT;
999 }
1000 return error;
1001}
1002
1003
1004typedef struct sg_io_hdr32 {
1005 compat_int_t interface_id;
1006 compat_int_t dxfer_direction;
1007 unsigned char cmd_len;
1008 unsigned char mx_sb_len;
1009 unsigned short iovec_count;
1010 compat_uint_t dxfer_len;
1011 compat_uint_t dxferp;
1012
1013 compat_uptr_t cmdp;
1014 compat_uptr_t sbp;
1015 compat_uint_t timeout;
1016 compat_uint_t flags;
1017 compat_int_t pack_id;
1018 compat_uptr_t usr_ptr;
1019 unsigned char status;
1020 unsigned char masked_status;
1021 unsigned char msg_status;
1022 unsigned char sb_len_wr;
1023 unsigned short host_status;
1024 unsigned short driver_status;
1025 compat_int_t resid;
1026 compat_uint_t duration;
1027 compat_uint_t info;
1028} sg_io_hdr32_t;
1029
1030typedef struct sg_iovec32 {
1031 compat_uint_t iov_base;
1032 compat_uint_t iov_len;
1033} sg_iovec32_t;
1034
1035static int sg_build_iovec(sg_io_hdr_t __user *sgio, void __user *dxferp, u16 iovec_count)
1036{
1037 sg_iovec_t __user *iov = (sg_iovec_t __user *) (sgio + 1);
1038 sg_iovec32_t __user *iov32 = dxferp;
1039 int i;
1040
1041 for (i = 0; i < iovec_count; i++) {
1042 u32 base, len;
1043
1044 if (get_user(base, &iov32[i].iov_base) ||
1045 get_user(len, &iov32[i].iov_len) ||
1046 put_user(compat_ptr(base), &iov[i].iov_base) ||
1047 put_user(len, &iov[i].iov_len))
1048 return -EFAULT;
1049 }
1050
1051 if (put_user(iov, &sgio->dxferp))
1052 return -EFAULT;
1053 return 0;
1054}
1055
1056static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
1057{
1058 sg_io_hdr_t __user *sgio;
1059 sg_io_hdr32_t __user *sgio32;
1060 u16 iovec_count;
1061 u32 data;
1062 void __user *dxferp;
1063 int err;
1064
1065 sgio32 = compat_ptr(arg);
1066 if (get_user(iovec_count, &sgio32->iovec_count))
1067 return -EFAULT;
1068
1069 {
1070 void __user *top = compat_alloc_user_space(0);
1071 void __user *new = compat_alloc_user_space(sizeof(sg_io_hdr_t) +
1072 (iovec_count * sizeof(sg_iovec_t)));
1073 if (new > top)
1074 return -EINVAL;
1075
1076 sgio = new;
1077 }
1078
1079
1080 if (copy_in_user(&sgio->interface_id, &sgio32->interface_id,
1081 (2 * sizeof(int)) +
1082 (2 * sizeof(unsigned char)) +
1083 (1 * sizeof(unsigned short)) +
1084 (1 * sizeof(unsigned int))))
1085 return -EFAULT;
1086
1087 if (get_user(data, &sgio32->dxferp))
1088 return -EFAULT;
1089 dxferp = compat_ptr(data);
1090 if (iovec_count) {
1091 if (sg_build_iovec(sgio, dxferp, iovec_count))
1092 return -EFAULT;
1093 } else {
1094 if (put_user(dxferp, &sgio->dxferp))
1095 return -EFAULT;
1096 }
1097
1098 {
1099 unsigned char __user *cmdp;
1100 unsigned char __user *sbp;
1101
1102 if (get_user(data, &sgio32->cmdp))
1103 return -EFAULT;
1104 cmdp = compat_ptr(data);
1105
1106 if (get_user(data, &sgio32->sbp))
1107 return -EFAULT;
1108 sbp = compat_ptr(data);
1109
1110 if (put_user(cmdp, &sgio->cmdp) ||
1111 put_user(sbp, &sgio->sbp))
1112 return -EFAULT;
1113 }
1114
1115 if (copy_in_user(&sgio->timeout, &sgio32->timeout,
1116 3 * sizeof(int)))
1117 return -EFAULT;
1118
1119 if (get_user(data, &sgio32->usr_ptr))
1120 return -EFAULT;
1121 if (put_user(compat_ptr(data), &sgio->usr_ptr))
1122 return -EFAULT;
1123
1124 if (copy_in_user(&sgio->status, &sgio32->status,
1125 (4 * sizeof(unsigned char)) +
1126 (2 * sizeof(unsigned (short))) +
1127 (3 * sizeof(int))))
1128 return -EFAULT;
1129
1130 err = sys_ioctl(fd, cmd, (unsigned long) sgio);
1131
1132 if (err >= 0) {
1133 void __user *datap;
1134
1135 if (copy_in_user(&sgio32->pack_id, &sgio->pack_id,
1136 sizeof(int)) ||
1137 get_user(datap, &sgio->usr_ptr) ||
1138 put_user((u32)(unsigned long)datap,
1139 &sgio32->usr_ptr) ||
1140 copy_in_user(&sgio32->status, &sgio->status,
1141 (4 * sizeof(unsigned char)) +
1142 (2 * sizeof(unsigned short)) +
1143 (3 * sizeof(int))))
1144 err = -EFAULT;
1145 }
1146
1147 return err;
1148}
1149
1150struct sock_fprog32 {
1151 unsigned short len;
1152 compat_caddr_t filter;
1153};
1154
1155#define PPPIOCSPASS32 _IOW('t', 71, struct sock_fprog32)
1156#define PPPIOCSACTIVE32 _IOW('t', 70, struct sock_fprog32)
1157
1158static int ppp_sock_fprog_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
1159{
1160 struct sock_fprog32 __user *u_fprog32 = compat_ptr(arg);
1161 struct sock_fprog __user *u_fprog64 = compat_alloc_user_space(sizeof(struct sock_fprog));
1162 void __user *fptr64;
1163 u32 fptr32;
1164 u16 flen;
1165
1166 if (get_user(flen, &u_fprog32->len) ||
1167 get_user(fptr32, &u_fprog32->filter))
1168 return -EFAULT;
1169
1170 fptr64 = compat_ptr(fptr32);
1171
1172 if (put_user(flen, &u_fprog64->len) ||
1173 put_user(fptr64, &u_fprog64->filter))
1174 return -EFAULT;
1175
1176 if (cmd == PPPIOCSPASS32)
1177 cmd = PPPIOCSPASS;
1178 else
1179 cmd = PPPIOCSACTIVE;
1180
1181 return sys_ioctl(fd, cmd, (unsigned long) u_fprog64);
1182}
1183
1184struct ppp_option_data32 {
1185 compat_caddr_t ptr;
1186 u32 length;
1187 compat_int_t transmit;
1188};
1189#define PPPIOCSCOMPRESS32 _IOW('t', 77, struct ppp_option_data32)
1190
1191struct ppp_idle32 {
1192 compat_time_t xmit_idle;
1193 compat_time_t recv_idle;
1194};
1195#define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32)
1196
1197static int ppp_gidle(unsigned int fd, unsigned int cmd, unsigned long arg)
1198{
1199 struct ppp_idle __user *idle;
1200 struct ppp_idle32 __user *idle32;
1201 __kernel_time_t xmit, recv;
1202 int err;
1203
1204 idle = compat_alloc_user_space(sizeof(*idle));
1205 idle32 = compat_ptr(arg);
1206
1207 err = sys_ioctl(fd, PPPIOCGIDLE, (unsigned long) idle);
1208
1209 if (!err) {
1210 if (get_user(xmit, &idle->xmit_idle) ||
1211 get_user(recv, &idle->recv_idle) ||
1212 put_user(xmit, &idle32->xmit_idle) ||
1213 put_user(recv, &idle32->recv_idle))
1214 err = -EFAULT;
1215 }
1216 return err;
1217}
1218
1219static int ppp_scompress(unsigned int fd, unsigned int cmd, unsigned long arg)
1220{
1221 struct ppp_option_data __user *odata;
1222 struct ppp_option_data32 __user *odata32;
1223 __u32 data;
1224 void __user *datap;
1225
1226 odata = compat_alloc_user_space(sizeof(*odata));
1227 odata32 = compat_ptr(arg);
1228
1229 if (get_user(data, &odata32->ptr))
1230 return -EFAULT;
1231
1232 datap = compat_ptr(data);
1233 if (put_user(datap, &odata->ptr))
1234 return -EFAULT;
1235
1236 if (copy_in_user(&odata->length, &odata32->length,
1237 sizeof(__u32) + sizeof(int)))
1238 return -EFAULT;
1239
1240 return sys_ioctl(fd, PPPIOCSCOMPRESS, (unsigned long) odata);
1241}
1242
1243static int ppp_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
1244{
1245 int err;
1246
1247 switch (cmd) {
1248 case PPPIOCGIDLE32:
1249 err = ppp_gidle(fd, cmd, arg);
1250 break;
1251
1252 case PPPIOCSCOMPRESS32:
1253 err = ppp_scompress(fd, cmd, arg);
1254 break;
1255
1256 default:
1257 do {
1258 static int count;
1259 if (++count <= 20)
1260 printk("ppp_ioctl: Unknown cmd fd(%d) "
1261 "cmd(%08x) arg(%08x)\n",
1262 (int)fd, (unsigned int)cmd, (unsigned int)arg);
1263 } while(0);
1264 err = -EINVAL;
1265 break;
1266 };
1267
1268 return err;
1269}
1270
1271
1272struct mtget32 {
1273 compat_long_t mt_type;
1274 compat_long_t mt_resid;
1275 compat_long_t mt_dsreg;
1276 compat_long_t mt_gstat;
1277 compat_long_t mt_erreg;
1278 compat_daddr_t mt_fileno;
1279 compat_daddr_t mt_blkno;
1280};
1281#define MTIOCGET32 _IOR('m', 2, struct mtget32)
1282
1283struct mtpos32 {
1284 compat_long_t mt_blkno;
1285};
1286#define MTIOCPOS32 _IOR('m', 3, struct mtpos32)
1287
1288struct mtconfiginfo32 {
1289 compat_long_t mt_type;
1290 compat_long_t ifc_type;
1291 unsigned short irqnr;
1292 unsigned short dmanr;
1293 unsigned short port;
1294 compat_ulong_t debug;
1295 compat_uint_t have_dens:1;
1296 compat_uint_t have_bsf:1;
1297 compat_uint_t have_fsr:1;
1298 compat_uint_t have_bsr:1;
1299 compat_uint_t have_eod:1;
1300 compat_uint_t have_seek:1;
1301 compat_uint_t have_tell:1;
1302 compat_uint_t have_ras1:1;
1303 compat_uint_t have_ras2:1;
1304 compat_uint_t have_ras3:1;
1305 compat_uint_t have_qfa:1;
1306 compat_uint_t pad1:5;
1307 char reserved[10];
1308};
1309#define MTIOCGETCONFIG32 _IOR('m', 4, struct mtconfiginfo32)
1310#define MTIOCSETCONFIG32 _IOW('m', 5, struct mtconfiginfo32)
1311
1312static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
1313{
1314 mm_segment_t old_fs = get_fs();
1315 struct mtconfiginfo info;
1316 struct mtconfiginfo32 __user *uinfo32;
1317 struct mtget get;
1318 struct mtget32 __user *umget32;
1319 struct mtpos pos;
1320 struct mtpos32 __user *upos32;
1321 unsigned long kcmd;
1322 void *karg;
1323 int err = 0;
1324
1325 switch(cmd) {
1326 case MTIOCPOS32:
1327 kcmd = MTIOCPOS;
1328 karg = &pos;
1329 break;
1330 case MTIOCGET32:
1331 kcmd = MTIOCGET;
1332 karg = &get;
1333 break;
1334 case MTIOCGETCONFIG32:
1335 kcmd = MTIOCGETCONFIG;
1336 karg = &info;
1337 break;
1338 case MTIOCSETCONFIG32:
1339 kcmd = MTIOCSETCONFIG;
1340 karg = &info;
1341 uinfo32 = compat_ptr(arg);
1342 err = __get_user(info.mt_type, &uinfo32->mt_type);
1343 err |= __get_user(info.ifc_type, &uinfo32->ifc_type);
1344 err |= __get_user(info.irqnr, &uinfo32->irqnr);
1345 err |= __get_user(info.dmanr, &uinfo32->dmanr);
1346 err |= __get_user(info.port, &uinfo32->port);
1347 err |= __get_user(info.debug, &uinfo32->debug);
1348 err |= __copy_from_user((char *)&info.debug
1349 + sizeof(info.debug),
1350 (char __user *)&uinfo32->debug
1351 + sizeof(uinfo32->debug), sizeof(__u32));
1352 if (err)
1353 return -EFAULT;
1354 break;
1355 default:
1356 do {
1357 static int count;
1358 if (++count <= 20)
1359 printk("mt_ioctl: Unknown cmd fd(%d) "
1360 "cmd(%08x) arg(%08x)\n",
1361 (int)fd, (unsigned int)cmd, (unsigned int)arg);
1362 } while(0);
1363 return -EINVAL;
1364 }
1365 set_fs (KERNEL_DS);
1366 err = sys_ioctl (fd, kcmd, (unsigned long)karg);
1367 set_fs (old_fs);
1368 if (err)
1369 return err;
1370 switch (cmd) {
1371 case MTIOCPOS32:
1372 upos32 = compat_ptr(arg);
1373 err = __put_user(pos.mt_blkno, &upos32->mt_blkno);
1374 break;
1375 case MTIOCGET32:
1376 umget32 = compat_ptr(arg);
1377 err = __put_user(get.mt_type, &umget32->mt_type);
1378 err |= __put_user(get.mt_resid, &umget32->mt_resid);
1379 err |= __put_user(get.mt_dsreg, &umget32->mt_dsreg);
1380 err |= __put_user(get.mt_gstat, &umget32->mt_gstat);
1381 err |= __put_user(get.mt_erreg, &umget32->mt_erreg);
1382 err |= __put_user(get.mt_fileno, &umget32->mt_fileno);
1383 err |= __put_user(get.mt_blkno, &umget32->mt_blkno);
1384 break;
1385 case MTIOCGETCONFIG32:
1386 uinfo32 = compat_ptr(arg);
1387 err = __put_user(info.mt_type, &uinfo32->mt_type);
1388 err |= __put_user(info.ifc_type, &uinfo32->ifc_type);
1389 err |= __put_user(info.irqnr, &uinfo32->irqnr);
1390 err |= __put_user(info.dmanr, &uinfo32->dmanr);
1391 err |= __put_user(info.port, &uinfo32->port);
1392 err |= __put_user(info.debug, &uinfo32->debug);
1393 err |= __copy_to_user((char __user *)&uinfo32->debug
1394 + sizeof(uinfo32->debug),
1395 (char *)&info.debug + sizeof(info.debug), sizeof(__u32));
1396 break;
1397 case MTIOCSETCONFIG32:
1398 break;
1399 }
1400 return err ? -EFAULT: 0;
1401}
1402
1403struct cdrom_read_audio32 {
1404 union cdrom_addr addr;
1405 u8 addr_format;
1406 compat_int_t nframes;
1407 compat_caddr_t buf;
1408};
1409
1410struct cdrom_generic_command32 {
1411 unsigned char cmd[CDROM_PACKET_SIZE];
1412 compat_caddr_t buffer;
1413 compat_uint_t buflen;
1414 compat_int_t stat;
1415 compat_caddr_t sense;
1416 unsigned char data_direction;
1417 compat_int_t quiet;
1418 compat_int_t timeout;
1419 compat_caddr_t reserved[1];
1420};
1421
1422static int cdrom_do_read_audio(unsigned int fd, unsigned int cmd, unsigned long arg)
1423{
1424 struct cdrom_read_audio __user *cdread_audio;
1425 struct cdrom_read_audio32 __user *cdread_audio32;
1426 __u32 data;
1427 void __user *datap;
1428
1429 cdread_audio = compat_alloc_user_space(sizeof(*cdread_audio));
1430 cdread_audio32 = compat_ptr(arg);
1431
1432 if (copy_in_user(&cdread_audio->addr,
1433 &cdread_audio32->addr,
1434 (sizeof(*cdread_audio32) -
1435 sizeof(compat_caddr_t))))
1436 return -EFAULT;
1437
1438 if (get_user(data, &cdread_audio32->buf))
1439 return -EFAULT;
1440 datap = compat_ptr(data);
1441 if (put_user(datap, &cdread_audio->buf))
1442 return -EFAULT;
1443
1444 return sys_ioctl(fd, cmd, (unsigned long) cdread_audio);
1445}
1446
1447static int cdrom_do_generic_command(unsigned int fd, unsigned int cmd, unsigned long arg)
1448{
1449 struct cdrom_generic_command __user *cgc;
1450 struct cdrom_generic_command32 __user *cgc32;
1451 u32 data;
1452 unsigned char dir;
1453 int itmp;
1454
1455 cgc = compat_alloc_user_space(sizeof(*cgc));
1456 cgc32 = compat_ptr(arg);
1457
1458 if (copy_in_user(&cgc->cmd, &cgc32->cmd, sizeof(cgc->cmd)) ||
1459 get_user(data, &cgc32->buffer) ||
1460 put_user(compat_ptr(data), &cgc->buffer) ||
1461 copy_in_user(&cgc->buflen, &cgc32->buflen,
1462 (sizeof(unsigned int) + sizeof(int))) ||
1463 get_user(data, &cgc32->sense) ||
1464 put_user(compat_ptr(data), &cgc->sense) ||
1465 get_user(dir, &cgc32->data_direction) ||
1466 put_user(dir, &cgc->data_direction) ||
1467 get_user(itmp, &cgc32->quiet) ||
1468 put_user(itmp, &cgc->quiet) ||
1469 get_user(itmp, &cgc32->timeout) ||
1470 put_user(itmp, &cgc->timeout) ||
1471 get_user(data, &cgc32->reserved[0]) ||
1472 put_user(compat_ptr(data), &cgc->reserved[0]))
1473 return -EFAULT;
1474
1475 return sys_ioctl(fd, cmd, (unsigned long) cgc);
1476}
1477
1478static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
1479{
1480 int err;
1481
1482 switch(cmd) {
1483 case CDROMREADAUDIO:
1484 err = cdrom_do_read_audio(fd, cmd, arg);
1485 break;
1486
1487 case CDROM_SEND_PACKET:
1488 err = cdrom_do_generic_command(fd, cmd, arg);
1489 break;
1490
1491 default:
1492 do {
1493 static int count;
1494 if (++count <= 20)
1495 printk("cdrom_ioctl: Unknown cmd fd(%d) "
1496 "cmd(%08x) arg(%08x)\n",
1497 (int)fd, (unsigned int)cmd, (unsigned int)arg);
1498 } while(0);
1499 err = -EINVAL;
1500 break;
1501 };
1502
1503 return err;
1504}
1505
1506struct loop_info32 {
1507 compat_int_t lo_number;
1508 compat_dev_t lo_device;
1509 compat_ulong_t lo_inode;
1510 compat_dev_t lo_rdevice;
1511 compat_int_t lo_offset;
1512 compat_int_t lo_encrypt_type;
1513 compat_int_t lo_encrypt_key_size;
1514 compat_int_t lo_flags;
1515 char lo_name[LO_NAME_SIZE];
1516 unsigned char lo_encrypt_key[LO_KEY_SIZE];
1517 compat_ulong_t lo_init[2];
1518 char reserved[4];
1519};
1520
1521static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg)
1522{
1523 mm_segment_t old_fs = get_fs();
1524 struct loop_info l;
1525 struct loop_info32 __user *ul;
1526 int err = -EINVAL;
1527
1528 ul = compat_ptr(arg);
1529 switch(cmd) {
1530 case LOOP_SET_STATUS:
1531 err = get_user(l.lo_number, &ul->lo_number);
1532 err |= __get_user(l.lo_device, &ul->lo_device);
1533 err |= __get_user(l.lo_inode, &ul->lo_inode);
1534 err |= __get_user(l.lo_rdevice, &ul->lo_rdevice);
1535 err |= __copy_from_user(&l.lo_offset, &ul->lo_offset,
1536 8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
1537 if (err) {
1538 err = -EFAULT;
1539 } else {
1540 set_fs (KERNEL_DS);
1541 err = sys_ioctl (fd, cmd, (unsigned long)&l);
1542 set_fs (old_fs);
1543 }
1544 break;
1545 case LOOP_GET_STATUS:
1546 set_fs (KERNEL_DS);
1547 err = sys_ioctl (fd, cmd, (unsigned long)&l);
1548 set_fs (old_fs);
1549 if (!err) {
1550 err = put_user(l.lo_number, &ul->lo_number);
1551 err |= __put_user(l.lo_device, &ul->lo_device);
1552 err |= __put_user(l.lo_inode, &ul->lo_inode);
1553 err |= __put_user(l.lo_rdevice, &ul->lo_rdevice);
1554 err |= __copy_to_user(&ul->lo_offset, &l.lo_offset,
1555 (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
1556 if (err)
1557 err = -EFAULT;
1558 }
1559 break;
1560 default: {
1561 static int count;
1562 if (++count <= 20)
1563 printk("%s: Unknown loop ioctl cmd, fd(%d) "
1564 "cmd(%08x) arg(%08lx)\n",
1565 __FUNCTION__, fd, cmd, arg);
1566 }
1567 }
1568 return err;
1569}
1570
1571extern int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg);
1572
1573#ifdef CONFIG_VT
1574
1575static int vt_check(struct file *file)
1576{
1577 struct tty_struct *tty;
1578 struct inode *inode = file->f_dentry->d_inode;
1579
1580 if (file->f_op->ioctl != tty_ioctl)
1581 return -EINVAL;
1582
1583 tty = (struct tty_struct *)file->private_data;
1584 if (tty_paranoia_check(tty, inode, "tty_ioctl"))
1585 return -EINVAL;
1586
1587 if (tty->driver->ioctl != vt_ioctl)
1588 return -EINVAL;
1589
1590
1591
1592
1593
1594 if (current->signal->tty == tty || capable(CAP_SYS_ADMIN))
1595 return 1;
1596 return 0;
1597}
1598
1599struct consolefontdesc32 {
1600 unsigned short charcount;
1601 unsigned short charheight;
1602 compat_caddr_t chardata;
1603};
1604
1605static int do_fontx_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file)
1606{
1607 struct consolefontdesc32 __user *user_cfd = compat_ptr(arg);
1608 struct console_font_op op;
1609 compat_caddr_t data;
1610 int i, perm;
1611
1612 perm = vt_check(file);
1613 if (perm < 0) return perm;
1614
1615 switch (cmd) {
1616 case PIO_FONTX:
1617 if (!perm)
1618 return -EPERM;
1619 op.op = KD_FONT_OP_SET;
1620 op.flags = 0;
1621 op.width = 8;
1622 if (get_user(op.height, &user_cfd->charheight) ||
1623 get_user(op.charcount, &user_cfd->charcount) ||
1624 get_user(data, &user_cfd->chardata))
1625 return -EFAULT;
1626 op.data = compat_ptr(data);
1627 return con_font_op(fg_console, &op);
1628 case GIO_FONTX:
1629 op.op = KD_FONT_OP_GET;
1630 op.flags = 0;
1631 op.width = 8;
1632 if (get_user(op.height, &user_cfd->charheight) ||
1633 get_user(op.charcount, &user_cfd->charcount) ||
1634 get_user(data, &user_cfd->chardata))
1635 return -EFAULT;
1636 if (!data)
1637 return 0;
1638 op.data = compat_ptr(data);
1639 i = con_font_op(fg_console, &op);
1640 if (i)
1641 return i;
1642 if (put_user(op.height, &user_cfd->charheight) ||
1643 put_user(op.charcount, &user_cfd->charcount) ||
1644 put_user((compat_caddr_t)(unsigned long)op.data,
1645 &user_cfd->chardata))
1646 return -EFAULT;
1647 return 0;
1648 }
1649 return -EINVAL;
1650}
1651
1652struct console_font_op32 {
1653 compat_uint_t op;
1654 compat_uint_t flags;
1655 compat_uint_t width, height;
1656 compat_uint_t charcount;
1657 compat_caddr_t data;
1658};
1659
1660static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file)
1661{
1662 struct console_font_op op;
1663 struct console_font_op32 __user *fontop = compat_ptr(arg);
1664 int perm = vt_check(file), i;
1665 struct vt_struct *vt;
1666
1667 if (perm < 0) return perm;
1668
1669 if (copy_from_user(&op, fontop, sizeof(struct console_font_op32)))
1670 return -EFAULT;
1671 if (!perm && op.op != KD_FONT_OP_GET)
1672 return -EPERM;
1673 op.data = compat_ptr(((struct console_font_op32 *)&op)->data);
1674 op.flags |= KD_FONT_FLAG_OLD;
1675 vt = (struct vt_struct *)((struct tty_struct *)file->private_data)->driver_data;
1676 i = con_font_op(vt->vc_num, &op);
1677 if (i) return i;
1678 ((struct console_font_op32 *)&op)->data = (unsigned long)op.data;
1679 if (copy_to_user(fontop, &op, sizeof(struct console_font_op32)))
1680 return -EFAULT;
1681 return 0;
1682}
1683
1684struct unimapdesc32 {
1685 unsigned short entry_ct;
1686 compat_caddr_t entries;
1687};
1688
1689static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file)
1690{
1691 struct unimapdesc32 tmp;
1692 struct unimapdesc32 __user *user_ud = compat_ptr(arg);
1693 int perm = vt_check(file);
1694
1695 if (perm < 0) return perm;
1696 if (copy_from_user(&tmp, user_ud, sizeof tmp))
1697 return -EFAULT;
1698 switch (cmd) {
1699 case PIO_UNIMAP:
1700 if (!perm) return -EPERM;
1701 return con_set_unimap(fg_console, tmp.entry_ct, compat_ptr(tmp.entries));
1702 case GIO_UNIMAP:
1703 return con_get_unimap(fg_console, tmp.entry_ct, &(user_ud->entry_ct), compat_ptr(tmp.entries));
1704 }
1705 return 0;
1706}
1707
1708#endif
1709
1710static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long arg)
1711{
1712 mm_segment_t old_fs = get_fs();
1713 __kernel_uid_t kuid;
1714 int err;
1715
1716 cmd = SMB_IOC_GETMOUNTUID;
1717
1718 set_fs(KERNEL_DS);
1719 err = sys_ioctl(fd, cmd, (unsigned long)&kuid);
1720 set_fs(old_fs);
1721
1722 if (err >= 0)
1723 err = put_user(kuid, (compat_uid_t __user *)compat_ptr(arg));
1724
1725 return err;
1726}
1727
1728struct atmif_sioc32 {
1729 compat_int_t number;
1730 compat_int_t length;
1731 compat_caddr_t arg;
1732};
1733
1734struct atm_iobuf32 {
1735 compat_int_t length;
1736 compat_caddr_t buffer;
1737};
1738
1739#define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct atmif_sioc32)
1740#define ATM_GETNAMES32 _IOW('a', ATMIOC_ITF+3, struct atm_iobuf32)
1741#define ATM_GETTYPE32 _IOW('a', ATMIOC_ITF+4, struct atmif_sioc32)
1742#define ATM_GETESI32 _IOW('a', ATMIOC_ITF+5, struct atmif_sioc32)
1743#define ATM_GETADDR32 _IOW('a', ATMIOC_ITF+6, struct atmif_sioc32)
1744#define ATM_RSTADDR32 _IOW('a', ATMIOC_ITF+7, struct atmif_sioc32)
1745#define ATM_ADDADDR32 _IOW('a', ATMIOC_ITF+8, struct atmif_sioc32)
1746#define ATM_DELADDR32 _IOW('a', ATMIOC_ITF+9, struct atmif_sioc32)
1747#define ATM_GETCIRANGE32 _IOW('a', ATMIOC_ITF+10, struct atmif_sioc32)
1748#define ATM_SETCIRANGE32 _IOW('a', ATMIOC_ITF+11, struct atmif_sioc32)
1749#define ATM_SETESI32 _IOW('a', ATMIOC_ITF+12, struct atmif_sioc32)
1750#define ATM_SETESIF32 _IOW('a', ATMIOC_ITF+13, struct atmif_sioc32)
1751#define ATM_GETSTAT32 _IOW('a', ATMIOC_SARCOM+0, struct atmif_sioc32)
1752#define ATM_GETSTATZ32 _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32)
1753#define ATM_GETLOOP32 _IOW('a', ATMIOC_SARCOM+2, struct atmif_sioc32)
1754#define ATM_SETLOOP32 _IOW('a', ATMIOC_SARCOM+3, struct atmif_sioc32)
1755#define ATM_QUERYLOOP32 _IOW('a', ATMIOC_SARCOM+4, struct atmif_sioc32)
1756
1757static struct {
1758 unsigned int cmd32;
1759 unsigned int cmd;
1760} atm_ioctl_map[] = {
1761 { ATM_GETLINKRATE32, ATM_GETLINKRATE },
1762 { ATM_GETNAMES32, ATM_GETNAMES },
1763 { ATM_GETTYPE32, ATM_GETTYPE },
1764 { ATM_GETESI32, ATM_GETESI },
1765 { ATM_GETADDR32, ATM_GETADDR },
1766 { ATM_RSTADDR32, ATM_RSTADDR },
1767 { ATM_ADDADDR32, ATM_ADDADDR },
1768 { ATM_DELADDR32, ATM_DELADDR },
1769 { ATM_GETCIRANGE32, ATM_GETCIRANGE },
1770 { ATM_SETCIRANGE32, ATM_SETCIRANGE },
1771 { ATM_SETESI32, ATM_SETESI },
1772 { ATM_SETESIF32, ATM_SETESIF },
1773 { ATM_GETSTAT32, ATM_GETSTAT },
1774 { ATM_GETSTATZ32, ATM_GETSTATZ },
1775 { ATM_GETLOOP32, ATM_GETLOOP },
1776 { ATM_SETLOOP32, ATM_SETLOOP },
1777 { ATM_QUERYLOOP32, ATM_QUERYLOOP }
1778};
1779
1780#define NR_ATM_IOCTL (sizeof(atm_ioctl_map)/sizeof(atm_ioctl_map[0]))
1781
1782
1783static int do_atm_iobuf(unsigned int fd, unsigned int cmd, unsigned long arg)
1784{
1785 struct atm_iobuf __user *iobuf;
1786 struct atm_iobuf32 __user *iobuf32;
1787 u32 data;
1788 void __user *datap;
1789 int len, err;
1790
1791 iobuf = compat_alloc_user_space(sizeof(*iobuf));
1792 iobuf32 = compat_ptr(arg);
1793
1794 if (get_user(len, &iobuf32->length) ||
1795 get_user(data, &iobuf32->buffer))
1796 return -EFAULT;
1797 datap = compat_ptr(data);
1798 if (put_user(len, &iobuf->length) ||
1799 put_user(datap, &iobuf->buffer))
1800 return -EFAULT;
1801
1802 err = sys_ioctl(fd, cmd, (unsigned long)iobuf);
1803
1804 if (!err) {
1805 if (copy_in_user(&iobuf32->length, &iobuf->length,
1806 sizeof(int)))
1807 err = -EFAULT;
1808 }
1809
1810 return err;
1811}
1812
1813static int do_atmif_sioc(unsigned int fd, unsigned int cmd, unsigned long arg)
1814{
1815 struct atmif_sioc __user *sioc;
1816 struct atmif_sioc32 __user *sioc32;
1817 u32 data;
1818 void __user *datap;
1819 int err;
1820
1821 sioc = compat_alloc_user_space(sizeof(*sioc));
1822 sioc32 = compat_ptr(arg);
1823
1824 if (copy_in_user(&sioc->number, &sioc32->number, 2 * sizeof(int)) ||
1825 get_user(data, &sioc32->arg))
1826 return -EFAULT;
1827 datap = compat_ptr(data);
1828 if (put_user(datap, &sioc->arg))
1829 return -EFAULT;
1830
1831 err = sys_ioctl(fd, cmd, (unsigned long) sioc);
1832
1833 if (!err) {
1834 if (copy_in_user(&sioc32->length, &sioc->length,
1835 sizeof(int)))
1836 err = -EFAULT;
1837 }
1838 return err;
1839}
1840
1841static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg)
1842{
1843 int i;
1844 unsigned int cmd = 0;
1845
1846 switch (cmd32) {
1847 case SONET_GETSTAT:
1848 case SONET_GETSTATZ:
1849 case SONET_GETDIAG:
1850 case SONET_SETDIAG:
1851 case SONET_CLRDIAG:
1852 case SONET_SETFRAMING:
1853 case SONET_GETFRAMING:
1854 case SONET_GETFRSENSE:
1855 return do_atmif_sioc(fd, cmd32, arg);
1856 }
1857
1858 for (i = 0; i < NR_ATM_IOCTL; i++) {
1859 if (cmd32 == atm_ioctl_map[i].cmd32) {
1860 cmd = atm_ioctl_map[i].cmd;
1861 break;
1862 }
1863 }
1864 if (i == NR_ATM_IOCTL)
1865 return -EINVAL;
1866
1867 switch (cmd) {
1868 case ATM_GETNAMES:
1869 return do_atm_iobuf(fd, cmd, arg);
1870
1871 case ATM_GETLINKRATE:
1872 case ATM_GETTYPE:
1873 case ATM_GETESI:
1874 case ATM_GETADDR:
1875 case ATM_RSTADDR:
1876 case ATM_ADDADDR:
1877 case ATM_DELADDR:
1878 case ATM_GETCIRANGE:
1879 case ATM_SETCIRANGE:
1880 case ATM_SETESI:
1881 case ATM_SETESIF:
1882 case ATM_GETSTAT:
1883 case ATM_GETSTATZ:
1884 case ATM_GETLOOP:
1885 case ATM_SETLOOP:
1886 case ATM_QUERYLOOP:
1887 return do_atmif_sioc(fd, cmd, arg);
1888 }
1889
1890 return -EINVAL;
1891}
1892
1893static __attribute_used__ int
1894ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg)
1895{
1896 return -EINVAL;
1897}
1898
1899static int do_blkgetsize(unsigned int fd, unsigned int cmd, unsigned long arg)
1900{
1901
1902
1903 int err;
1904 unsigned long val = 0;
1905 unsigned long __user *arg64 = compat_alloc_user_space(sizeof(long));
1906
1907 err = sys_ioctl(fd, cmd, (unsigned long) arg64);
1908 if (!err)
1909 err = get_user(val, arg64);
1910 if (!err && val >= (1UL << 32))
1911 err = -EFBIG;
1912 if (!err && put_user(val, (u32 __user *)compat_ptr(arg)))
1913 err = -EFAULT;
1914 return err;
1915}
1916
1917static int broken_blkgetsize(unsigned int fd, unsigned int cmd, unsigned long arg)
1918{
1919
1920 return do_blkgetsize(fd, BLKGETSIZE, arg);
1921}
1922
1923struct blkpg_ioctl_arg32 {
1924 compat_int_t op;
1925 compat_int_t flags;
1926 compat_int_t datalen;
1927 compat_caddr_t data;
1928};
1929
1930static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
1931{
1932 struct blkpg_ioctl_arg32 __user *ua32 = compat_ptr(arg);
1933 struct blkpg_ioctl_arg __user *a = compat_alloc_user_space(sizeof(*a));
1934 compat_caddr_t udata;
1935 compat_int_t n;
1936 int err;
1937
1938 err = get_user(n, &ua32->op);
1939 err |= put_user(n, &a->op);
1940 err |= get_user(n, &ua32->flags);
1941 err |= put_user(n, &a->flags);
1942 err |= get_user(n, &ua32->datalen);
1943 err |= put_user(n, &a->datalen);
1944 err |= get_user(udata, &ua32->data);
1945 err |= put_user(compat_ptr(udata), &a->data);
1946 if (err)
1947 return err;
1948
1949 return sys_ioctl(fd, cmd, (unsigned long)a);
1950}
1951
1952static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg)
1953{
1954 return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg);
1955}
1956
1957
1958#define BLKBSZGET_32 _IOR(0x12,112,int)
1959#define BLKBSZSET_32 _IOW(0x12,113,int)
1960#define BLKGETSIZE64_32 _IOR(0x12,114,int)
1961
1962static int do_blkbszget(unsigned int fd, unsigned int cmd, unsigned long arg)
1963{
1964 return sys_ioctl(fd, BLKBSZGET, (unsigned long)compat_ptr(arg));
1965}
1966
1967static int do_blkbszset(unsigned int fd, unsigned int cmd, unsigned long arg)
1968{
1969 return sys_ioctl(fd, BLKBSZSET, (unsigned long)compat_ptr(arg));
1970}
1971
1972static int do_blkgetsize64(unsigned int fd, unsigned int cmd,
1973 unsigned long arg)
1974{
1975 return sys_ioctl(fd, BLKGETSIZE64, (unsigned long)compat_ptr(arg));
1976}
1977
1978
1979#define HCIUARTSETPROTO _IOW('U', 200, int)
1980#define HCIUARTGETPROTO _IOR('U', 201, int)
1981
1982#define BNEPCONNADD _IOW('B', 200, int)
1983#define BNEPCONNDEL _IOW('B', 201, int)
1984#define BNEPGETCONNLIST _IOR('B', 210, int)
1985#define BNEPGETCONNINFO _IOR('B', 211, int)
1986
1987#define CMTPCONNADD _IOW('C', 200, int)
1988#define CMTPCONNDEL _IOW('C', 201, int)
1989#define CMTPGETCONNLIST _IOR('C', 210, int)
1990#define CMTPGETCONNINFO _IOR('C', 211, int)
1991
1992#define HIDPCONNADD _IOW('H', 200, int)
1993#define HIDPCONNDEL _IOW('H', 201, int)
1994#define HIDPGETCONNLIST _IOR('H', 210, int)
1995#define HIDPGETCONNINFO _IOR('H', 211, int)
1996
1997struct floppy_struct32 {
1998 compat_uint_t size;
1999 compat_uint_t sect;
2000 compat_uint_t head;
2001 compat_uint_t track;
2002 compat_uint_t stretch;
2003 unsigned char gap;
2004 unsigned char rate;
2005 unsigned char spec1;
2006 unsigned char fmt_gap;
2007 const compat_caddr_t name;
2008};
2009
2010struct floppy_drive_params32 {
2011 char cmos;
2012 compat_ulong_t max_dtr;
2013 compat_ulong_t hlt;
2014 compat_ulong_t hut;
2015 compat_ulong_t srt;
2016 compat_ulong_t spinup;
2017 compat_ulong_t spindown;
2018 unsigned char spindown_offset;
2019 unsigned char select_delay;
2020 unsigned char rps;
2021 unsigned char tracks;
2022 compat_ulong_t timeout;
2023 unsigned char interleave_sect;
2024 struct floppy_max_errors max_errors;
2025 char flags;
2026 char read_track;
2027 short autodetect[8];
2028 compat_int_t checkfreq;
2029 compat_int_t native_format;
2030};
2031
2032struct floppy_drive_struct32 {
2033 signed char flags;
2034 compat_ulong_t spinup_date;
2035 compat_ulong_t select_date;
2036 compat_ulong_t first_read_date;
2037 short probed_format;
2038 short track;
2039 short maxblock;
2040 short maxtrack;
2041 compat_int_t generation;
2042 compat_int_t keep_data;
2043 compat_int_t fd_ref;
2044 compat_int_t fd_device;
2045 compat_int_t last_checked;
2046 compat_caddr_t dmabuf;
2047 compat_int_t bufblocks;
2048};
2049
2050struct floppy_fdc_state32 {
2051 compat_int_t spec1;
2052 compat_int_t spec2;
2053 compat_int_t dtr;
2054 unsigned char version;
2055 unsigned char dor;
2056 compat_ulong_t address;
2057 unsigned int rawcmd:2;
2058 unsigned int reset:1;
2059 unsigned int need_configure:1;
2060 unsigned int perp_mode:2;
2061 unsigned int has_fifo:1;
2062 unsigned int driver_version;
2063 unsigned char track[4];
2064};
2065
2066struct floppy_write_errors32 {
2067 unsigned int write_errors;
2068 compat_ulong_t first_error_sector;
2069 compat_int_t first_error_generation;
2070 compat_ulong_t last_error_sector;
2071 compat_int_t last_error_generation;
2072 compat_uint_t badness;
2073};
2074
2075#define FDSETPRM32 _IOW(2, 0x42, struct floppy_struct32)
2076#define FDDEFPRM32 _IOW(2, 0x43, struct floppy_struct32)
2077#define FDGETPRM32 _IOR(2, 0x04, struct floppy_struct32)
2078#define FDSETDRVPRM32 _IOW(2, 0x90, struct floppy_drive_params32)
2079#define FDGETDRVPRM32 _IOR(2, 0x11, struct floppy_drive_params32)
2080#define FDGETDRVSTAT32 _IOR(2, 0x12, struct floppy_drive_struct32)
2081#define FDPOLLDRVSTAT32 _IOR(2, 0x13, struct floppy_drive_struct32)
2082#define FDGETFDCSTAT32 _IOR(2, 0x15, struct floppy_fdc_state32)
2083#define FDWERRORGET32 _IOR(2, 0x17, struct floppy_write_errors32)
2084
2085static struct {
2086 unsigned int cmd32;
2087 unsigned int cmd;
2088} fd_ioctl_trans_table[] = {
2089 { FDSETPRM32, FDSETPRM },
2090 { FDDEFPRM32, FDDEFPRM },
2091 { FDGETPRM32, FDGETPRM },
2092 { FDSETDRVPRM32, FDSETDRVPRM },
2093 { FDGETDRVPRM32, FDGETDRVPRM },
2094 { FDGETDRVSTAT32, FDGETDRVSTAT },
2095 { FDPOLLDRVSTAT32, FDPOLLDRVSTAT },
2096 { FDGETFDCSTAT32, FDGETFDCSTAT },
2097 { FDWERRORGET32, FDWERRORGET }
2098};
2099
2100#define NR_FD_IOCTL_TRANS (sizeof(fd_ioctl_trans_table)/sizeof(fd_ioctl_trans_table[0]))
2101
2102static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
2103{
2104 mm_segment_t old_fs = get_fs();
2105 void *karg = NULL;
2106 unsigned int kcmd = 0;
2107 int i, err;
2108
2109 for (i = 0; i < NR_FD_IOCTL_TRANS; i++)
2110 if (cmd == fd_ioctl_trans_table[i].cmd32) {
2111 kcmd = fd_ioctl_trans_table[i].cmd;
2112 break;
2113 }
2114 if (!kcmd)
2115 return -EINVAL;
2116
2117 switch (cmd) {
2118 case FDSETPRM32:
2119 case FDDEFPRM32:
2120 case FDGETPRM32:
2121 {
2122 compat_uptr_t name;
2123 struct floppy_struct32 __user *uf;
2124 struct floppy_struct *f;
2125
2126 uf = compat_ptr(arg);
2127 f = karg = kmalloc(sizeof(struct floppy_struct), GFP_KERNEL);
2128 if (!karg)
2129 return -ENOMEM;
2130 if (cmd == FDGETPRM32)
2131 break;
2132 err = __get_user(f->size, &uf->size);
2133 err |= __get_user(f->sect, &uf->sect);
2134 err |= __get_user(f->head, &uf->head);
2135 err |= __get_user(f->track, &uf->track);
2136 err |= __get_user(f->stretch, &uf->stretch);
2137 err |= __get_user(f->gap, &uf->gap);
2138 err |= __get_user(f->rate, &uf->rate);
2139 err |= __get_user(f->spec1, &uf->spec1);
2140 err |= __get_user(f->fmt_gap, &uf->fmt_gap);
2141 err |= __get_user(name, &uf->name);
2142 f->name = compat_ptr(name);
2143 if (err) {
2144 err = -EFAULT;
2145 goto out;
2146 }
2147 break;
2148 }
2149 case FDSETDRVPRM32:
2150 case FDGETDRVPRM32:
2151 {
2152 struct floppy_drive_params32 __user *uf;
2153 struct floppy_drive_params *f;
2154
2155 uf = compat_ptr(arg);
2156 f = karg = kmalloc(sizeof(struct floppy_drive_params), GFP_KERNEL);
2157 if (!karg)
2158 return -ENOMEM;
2159 if (cmd == FDGETDRVPRM32)
2160 break;
2161 err = __get_user(f->cmos, &uf->cmos);
2162 err |= __get_user(f->max_dtr, &uf->max_dtr);
2163 err |= __get_user(f->hlt, &uf->hlt);
2164 err |= __get_user(f->hut, &uf->hut);
2165 err |= __get_user(f->srt, &uf->srt);
2166 err |= __get_user(f->spinup, &uf->spinup);
2167 err |= __get_user(f->spindown, &uf->spindown);
2168 err |= __get_user(f->spindown_offset, &uf->spindown_offset);
2169 err |= __get_user(f->select_delay, &uf->select_delay);
2170 err |= __get_user(f->rps, &uf->rps);
2171 err |= __get_user(f->tracks, &uf->tracks);
2172 err |= __get_user(f->timeout, &uf->timeout);
2173 err |= __get_user(f->interleave_sect, &uf->interleave_sect);
2174 err |= __copy_from_user(&f->max_errors, &uf->max_errors, sizeof(f->max_errors));
2175 err |= __get_user(f->flags, &uf->flags);
2176 err |= __get_user(f->read_track, &uf->read_track);
2177 err |= __copy_from_user(f->autodetect, uf->autodetect, sizeof(f->autodetect));
2178 err |= __get_user(f->checkfreq, &uf->checkfreq);
2179 err |= __get_user(f->native_format, &uf->native_format);
2180 if (err) {
2181 err = -EFAULT;
2182 goto out;
2183 }
2184 break;
2185 }
2186 case FDGETDRVSTAT32:
2187 case FDPOLLDRVSTAT32:
2188 karg = kmalloc(sizeof(struct floppy_drive_struct), GFP_KERNEL);
2189 if (!karg)
2190 return -ENOMEM;
2191 break;
2192 case FDGETFDCSTAT32:
2193 karg = kmalloc(sizeof(struct floppy_fdc_state), GFP_KERNEL);
2194 if (!karg)
2195 return -ENOMEM;
2196 break;
2197 case FDWERRORGET32:
2198 karg = kmalloc(sizeof(struct floppy_write_errors), GFP_KERNEL);
2199 if (!karg)
2200 return -ENOMEM;
2201 break;
2202 default:
2203 return -EINVAL;
2204 }
2205 set_fs (KERNEL_DS);
2206 err = sys_ioctl (fd, kcmd, (unsigned long)karg);
2207 set_fs (old_fs);
2208 if (err)
2209 goto out;
2210 switch (cmd) {
2211 case FDGETPRM32:
2212 {
2213 struct floppy_struct *f = karg;
2214 struct floppy_struct32 __user *uf = compat_ptr(arg);
2215
2216 err = __put_user(f->size, &uf->size);
2217 err |= __put_user(f->sect, &uf->sect);
2218 err |= __put_user(f->head, &uf->head);
2219 err |= __put_user(f->track, &uf->track);
2220 err |= __put_user(f->stretch, &uf->stretch);
2221 err |= __put_user(f->gap, &uf->gap);
2222 err |= __put_user(f->rate, &uf->rate);
2223 err |= __put_user(f->spec1, &uf->spec1);
2224 err |= __put_user(f->fmt_gap, &uf->fmt_gap);
2225 err |= __put_user((u64)f->name, (compat_caddr_t __user *)&uf->name);
2226 break;
2227 }
2228 case FDGETDRVPRM32:
2229 {
2230 struct floppy_drive_params32 __user *uf;
2231 struct floppy_drive_params *f = karg;
2232
2233 uf = compat_ptr(arg);
2234 err = __put_user(f->cmos, &uf->cmos);
2235 err |= __put_user(f->max_dtr, &uf->max_dtr);
2236 err |= __put_user(f->hlt, &uf->hlt);
2237 err |= __put_user(f->hut, &uf->hut);
2238 err |= __put_user(f->srt, &uf->srt);
2239 err |= __put_user(f->spinup, &uf->spinup);
2240 err |= __put_user(f->spindown, &uf->spindown);
2241 err |= __put_user(f->spindown_offset, &uf->spindown_offset);
2242 err |= __put_user(f->select_delay, &uf->select_delay);
2243 err |= __put_user(f->rps, &uf->rps);
2244 err |= __put_user(f->tracks, &uf->tracks);
2245 err |= __put_user(f->timeout, &uf->timeout);
2246 err |= __put_user(f->interleave_sect, &uf->interleave_sect);
2247 err |= __copy_to_user(&uf->max_errors, &f->max_errors, sizeof(f->max_errors));
2248 err |= __put_user(f->flags, &uf->flags);
2249 err |= __put_user(f->read_track, &uf->read_track);
2250 err |= __copy_to_user(uf->autodetect, f->autodetect, sizeof(f->autodetect));
2251 err |= __put_user(f->checkfreq, &uf->checkfreq);
2252 err |= __put_user(f->native_format, &uf->native_format);
2253 break;
2254 }
2255 case FDGETDRVSTAT32:
2256 case FDPOLLDRVSTAT32:
2257 {
2258 struct floppy_drive_struct32 __user *uf;
2259 struct floppy_drive_struct *f = karg;
2260
2261 uf = compat_ptr(arg);
2262 err = __put_user(f->flags, &uf->flags);
2263 err |= __put_user(f->spinup_date, &uf->spinup_date);
2264 err |= __put_user(f->select_date, &uf->select_date);
2265 err |= __put_user(f->first_read_date, &uf->first_read_date);
2266 err |= __put_user(f->probed_format, &uf->probed_format);
2267 err |= __put_user(f->track, &uf->track);
2268 err |= __put_user(f->maxblock, &uf->maxblock);
2269 err |= __put_user(f->maxtrack, &uf->maxtrack);
2270 err |= __put_user(f->generation, &uf->generation);
2271 err |= __put_user(f->keep_data, &uf->keep_data);
2272 err |= __put_user(f->fd_ref, &uf->fd_ref);
2273 err |= __put_user(f->fd_device, &uf->fd_device);
2274 err |= __put_user(f->last_checked, &uf->last_checked);
2275 err |= __put_user((u64)f->dmabuf, &uf->dmabuf);
2276 err |= __put_user((u64)f->bufblocks, &uf->bufblocks);
2277 break;
2278 }
2279 case FDGETFDCSTAT32:
2280 {
2281 struct floppy_fdc_state32 __user *uf;
2282 struct floppy_fdc_state *f = karg;
2283
2284 uf = compat_ptr(arg);
2285 err = __put_user(f->spec1, &uf->spec1);
2286 err |= __put_user(f->spec2, &uf->spec2);
2287 err |= __put_user(f->dtr, &uf->dtr);
2288 err |= __put_user(f->version, &uf->version);
2289 err |= __put_user(f->dor, &uf->dor);
2290 err |= __put_user(f->address, &uf->address);
2291 err |= __copy_to_user((char __user *)&uf->address + sizeof(uf->address),
2292 (char *)&f->address + sizeof(f->address), sizeof(int));
2293 err |= __put_user(f->driver_version, &uf->driver_version);
2294 err |= __copy_to_user(uf->track, f->track, sizeof(f->track));
2295 break;
2296 }
2297 case FDWERRORGET32:
2298 {
2299 struct floppy_write_errors32 __user *uf;
2300 struct floppy_write_errors *f = karg;
2301
2302 uf = compat_ptr(arg);
2303 err = __put_user(f->write_errors, &uf->write_errors);
2304 err |= __put_user(f->first_error_sector, &uf->first_error_sector);
2305 err |= __put_user(f->first_error_generation, &uf->first_error_generation);
2306 err |= __put_user(f->last_error_sector, &uf->last_error_sector);
2307 err |= __put_user(f->last_error_generation, &uf->last_error_generation);
2308 err |= __put_user(f->badness, &uf->badness);
2309 break;
2310 }
2311 default:
2312 break;
2313 }
2314 if (err)
2315 err = -EFAULT;
2316
2317out: if (karg) kfree(karg);
2318 return err;
2319}
2320
2321struct mtd_oob_buf32 {
2322 u_int32_t start;
2323 u_int32_t length;
2324 compat_caddr_t ptr;
2325};
2326
2327#define MEMWRITEOOB32 _IOWR('M',3,struct mtd_oob_buf32)
2328#define MEMREADOOB32 _IOWR('M',4,struct mtd_oob_buf32)
2329
2330static int mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg)
2331{
2332 struct mtd_oob_buf __user *buf = compat_alloc_user_space(sizeof(*buf));
2333 struct mtd_oob_buf32 __user *buf32 = compat_ptr(arg);
2334 u32 data;
2335 char __user *datap;
2336 unsigned int real_cmd;
2337 int err;
2338
2339 real_cmd = (cmd == MEMREADOOB32) ?
2340 MEMREADOOB : MEMWRITEOOB;
2341
2342 if (copy_in_user(&buf->start, &buf32->start,
2343 2 * sizeof(u32)) ||
2344 get_user(data, &buf32->ptr))
2345 return -EFAULT;
2346 datap = compat_ptr(data);
2347 if (put_user(datap, &buf->ptr))
2348 return -EFAULT;
2349
2350 err = sys_ioctl(fd, real_cmd, (unsigned long) buf);
2351
2352 if (!err) {
2353 if (copy_in_user(&buf32->start, &buf->start,
2354 2 * sizeof(u32)))
2355 err = -EFAULT;
2356 }
2357
2358 return err;
2359}
2360
2361#define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2])
2362#define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2])
2363
2364static long
2365put_dirent32 (struct dirent *d, struct compat_dirent __user *d32)
2366{
2367 if (!access_ok(VERIFY_WRITE, d32, sizeof(struct compat_dirent[2])))
2368 return -EFAULT;
2369
2370
2371 __put_user(d->d_reclen, &d32->d_reclen);
2372 __put_user(0, d32->d_name + d->d_reclen);
2373 if (__copy_to_user(d32->d_name, d->d_name, d->d_reclen))
2374 return -EFAULT;
2375<