1 /*
2 * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
3 *
4 * Based on sparc64 ioctl32.c by:
5 *
6 * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
7 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
8 *
9 * ppc64 changes:
10 *
11 * Copyright (C) 2000 Ken Aaker (kdaaker@rchland.vnet.ibm.com)
12 * Copyright (C) 2001 Anton Blanchard (antonb@au.ibm.com)
13 *
14 * These routines maintain argument size conversion between 32bit and 64bit
15 * ioctls.
16 *
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * as published by the Free Software Foundation; either version
20 * 2 of the License, or (at your option) any later version.
21 */
22
23 #include <linux/config.h>
24 #include <linux/types.h>
25 #include <linux/kernel.h>
26 #include <linux/sched.h>
27 #include <linux/smp.h>
28 #include <linux/smp_lock.h>
29 #include <linux/ioctl.h>
30 #include <linux/if.h>
31 #include <linux/slab.h>
32 #include <linux/hdreg.h>
33 #include <linux/raid/md.h>
34 #include <linux/kd.h>
35 #include <linux/route.h>
36 #include <linux/in6.h>
37 #include <linux/ipv6_route.h>
38 #include <linux/skbuff.h>
39 #include <linux/netlink.h>
40 #include <linux/vt.h>
41 #include <linux/fs.h>
42 #include <linux/file.h>
43 #include <linux/fd.h>
44 #include <linux/ppp_defs.h>
45 #include <linux/if_ppp.h>
46 #include <linux/if_pppox.h>
47 #include <linux/if_tun.h>
48 #include <linux/mtio.h>
49 #include <linux/cdrom.h>
50 #include <linux/loop.h>
51 #include <linux/auto_fs.h>
52 #include <linux/autofs_4.h>
53 #include <linux/devfs_fs.h>
54 #include <linux/tty.h>
55 #include <linux/vt_kern.h>
56 #include <linux/fb.h>
57 #include <linux/ext2_fs.h>
58 #include <linux/videodev.h>
59 #include <linux/netdevice.h>
60 #include <linux/raw.h>
61 #include <linux/smb_fs.h>
62 #include <linux/blkpg.h>
63 #include <linux/blk.h>
64 #include <linux/elevator.h>
65 #include <linux/rtc.h>
66 #include <linux/pci.h>
67 #if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
68 #include <linux/lvm.h>
69 #endif /* LVM */
70
71 #include <scsi/scsi.h>
72 /* Ugly hack. */
73 #undef __KERNEL__
74 #include <scsi/scsi_ioctl.h>
75 #define __KERNEL__
76 #include <scsi/sg.h>
77
78 #include <asm/types.h>
79 #include <asm/uaccess.h>
80 #include <linux/ethtool.h>
81 #include <linux/mii.h>
82 #include <linux/if_bonding.h>
83 #include <asm/module.h>
84 #include <linux/soundcard.h>
85 #include <linux/watchdog.h>
86 #include <linux/lp.h>
87
88 #include <linux/atm.h>
89 #include <linux/atmarp.h>
90 #include <linux/atmclip.h>
91 #include <linux/atmdev.h>
92 #include <linux/atmioc.h>
93 #include <linux/atmlec.h>
94 #include <linux/atmmpc.h>
95 #include <linux/atmsvc.h>
96 #include <linux/atm_tcp.h>
97 #include <linux/sonet.h>
98 #include <linux/atm_suni.h>
99 #include <linux/mtd/mtd.h>
100
101 #include <net/bluetooth/bluetooth.h>
102 #include <net/bluetooth/hci.h>
103
104 #include <linux/usb.h>
105 #include <linux/usbdevice_fs.h>
106 #include <linux/nbd.h>
107 #include <linux/random.h>
108 #include <asm/ppc32.h>
109 #include <asm/ppcdebug.h>
110
111 /* Aiee. Someone does not find a difference between int and long */
112 #define EXT2_IOC32_GETFLAGS _IOR('f', 1, int)
113 #define EXT2_IOC32_SETFLAGS _IOW('f', 2, int)
114 #define EXT2_IOC32_GETVERSION _IOR('v', 1, int)
115 #define EXT2_IOC32_SETVERSION _IOW('v', 2, int)
116
117 extern asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
118
w_long(unsigned int fd,unsigned int cmd,unsigned long arg)119 static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
120 {
121 mm_segment_t old_fs = get_fs();
122 int err;
123 unsigned long val;
124
125 set_fs (KERNEL_DS);
126 err = sys_ioctl(fd, cmd, (unsigned long)&val);
127 set_fs (old_fs);
128 if (!err && put_user(val, (u32 *)arg))
129 return -EFAULT;
130 return err;
131 }
132
rw_long(unsigned int fd,unsigned int cmd,unsigned long arg)133 static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg)
134 {
135 mm_segment_t old_fs = get_fs();
136 int err;
137 unsigned long val;
138
139 if (get_user(val, (u32 *)arg))
140 return -EFAULT;
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 *)arg))
145 return -EFAULT;
146 return err;
147 }
148
do_ext2_ioctl(unsigned int fd,unsigned int cmd,unsigned long arg)149 static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
150 {
151 /* These are just misnamed, they actually get/put from/to user an int */
152 switch (cmd) {
153 case EXT2_IOC32_GETFLAGS: cmd = EXT2_IOC_GETFLAGS; break;
154 case EXT2_IOC32_SETFLAGS: cmd = EXT2_IOC_SETFLAGS; break;
155 case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break;
156 case EXT2_IOC32_SETVERSION: cmd = EXT2_IOC_SETVERSION; break;
157 }
158 return sys_ioctl(fd, cmd, arg);
159 }
160
161 struct video_tuner32 {
162 s32 tuner;
163 u8 name[32];
164 u32 rangelow, rangehigh;
165 u32 flags;
166 u16 mode, signal;
167 };
168
get_video_tuner32(struct video_tuner * kp,struct video_tuner32 * up)169 static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 *up)
170 {
171 int i;
172
173 if (get_user(kp->tuner, &up->tuner))
174 return -EFAULT;
175 for(i = 0; i < 32; i++)
176 __get_user(kp->name[i], &up->name[i]);
177 __get_user(kp->rangelow, &up->rangelow);
178 __get_user(kp->rangehigh, &up->rangehigh);
179 __get_user(kp->flags, &up->flags);
180 __get_user(kp->mode, &up->mode);
181 __get_user(kp->signal, &up->signal);
182 return 0;
183 }
184
put_video_tuner32(struct video_tuner * kp,struct video_tuner32 * up)185 static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 *up)
186 {
187 int i;
188
189 if (put_user(kp->tuner, &up->tuner))
190 return -EFAULT;
191 for(i = 0; i < 32; i++)
192 __put_user(kp->name[i], &up->name[i]);
193 __put_user(kp->rangelow, &up->rangelow);
194 __put_user(kp->rangehigh, &up->rangehigh);
195 __put_user(kp->flags, &up->flags);
196 __put_user(kp->mode, &up->mode);
197 __put_user(kp->signal, &up->signal);
198 return 0;
199 }
200
201 struct video_buffer32 {
202 /* void * */ u32 base;
203 s32 height, width, depth, bytesperline;
204 };
205
get_video_buffer32(struct video_buffer * kp,struct video_buffer32 * up)206 static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 *up)
207 {
208 u32 tmp;
209
210 if (get_user(tmp, &up->base))
211 return -EFAULT;
212 kp->base = (void *) ((unsigned long)tmp);
213 __get_user(kp->height, &up->height);
214 __get_user(kp->width, &up->width);
215 __get_user(kp->depth, &up->depth);
216 __get_user(kp->bytesperline, &up->bytesperline);
217 return 0;
218 }
219
put_video_buffer32(struct video_buffer * kp,struct video_buffer32 * up)220 static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 *up)
221 {
222 u32 tmp = (u32)((unsigned long)kp->base);
223
224 if (put_user(tmp, &up->base))
225 return -EFAULT;
226 __put_user(kp->height, &up->height);
227 __put_user(kp->width, &up->width);
228 __put_user(kp->depth, &up->depth);
229 __put_user(kp->bytesperline, &up->bytesperline);
230 return 0;
231 }
232
233 struct video_clip32 {
234 s32 x, y, width, height;
235 /* struct video_clip32 * */ u32 next;
236 };
237
238 struct video_window32 {
239 u32 x, y, width, height, chromakey, flags;
240 /* struct video_clip32 * */ u32 clips;
241 s32 clipcount;
242 };
243
free_kvideo_clips(struct video_window * kp)244 static void free_kvideo_clips(struct video_window *kp)
245 {
246 struct video_clip *cp;
247
248 cp = kp->clips;
249 if (cp != NULL)
250 kfree(cp);
251 }
252
get_video_window32(struct video_window * kp,struct video_window32 * up)253 static int get_video_window32(struct video_window *kp, struct video_window32 *up)
254 {
255 struct video_clip32 *ucp;
256 struct video_clip *kcp;
257 int nclips, err, i;
258 u32 tmp;
259
260 if (get_user(kp->x, &up->x))
261 return -EFAULT;
262 __get_user(kp->y, &up->y);
263 __get_user(kp->width, &up->width);
264 __get_user(kp->height, &up->height);
265 __get_user(kp->chromakey, &up->chromakey);
266 __get_user(kp->flags, &up->flags);
267 __get_user(kp->clipcount, &up->clipcount);
268 __get_user(tmp, &up->clips);
269 ucp = (struct video_clip32 *)A(tmp);
270 kp->clips = NULL;
271
272 nclips = kp->clipcount;
273 if (nclips == 0)
274 return 0;
275
276 if (ucp == 0)
277 return -EINVAL;
278
279 /* Peculiar interface... */
280 if (nclips < 0)
281 nclips = VIDEO_CLIPMAP_SIZE;
282
283 kcp = kmalloc(nclips * sizeof(struct video_clip), GFP_KERNEL);
284 err = -ENOMEM;
285 if (kcp == NULL)
286 goto cleanup_and_err;
287
288 kp->clips = kcp;
289 for(i = 0; i < nclips; i++) {
290 __get_user(kcp[i].x, &ucp[i].x);
291 __get_user(kcp[i].y, &ucp[i].y);
292 __get_user(kcp[i].width, &ucp[i].width);
293 __get_user(kcp[i].height, &ucp[i].height);
294 kcp[nclips].next = NULL;
295 }
296
297 return 0;
298
299 cleanup_and_err:
300 free_kvideo_clips(kp);
301 return err;
302 }
303
304 /* You get back everything except the clips... */
put_video_window32(struct video_window * kp,struct video_window32 * up)305 static int put_video_window32(struct video_window *kp, struct video_window32 *up)
306 {
307 if (put_user(kp->x, &up->x))
308 return -EFAULT;
309 __put_user(kp->y, &up->y);
310 __put_user(kp->width, &up->width);
311 __put_user(kp->height, &up->height);
312 __put_user(kp->chromakey, &up->chromakey);
313 __put_user(kp->flags, &up->flags);
314 __put_user(kp->clipcount, &up->clipcount);
315 return 0;
316 }
317
318 #define VIDIOCGTUNER32 _IOWR('v',4, struct video_tuner32)
319 #define VIDIOCSTUNER32 _IOW('v',5, struct video_tuner32)
320 #define VIDIOCGWIN32 _IOR('v',9, struct video_window32)
321 #define VIDIOCSWIN32 _IOW('v',10, struct video_window32)
322 #define VIDIOCGFBUF32 _IOR('v',11, struct video_buffer32)
323 #define VIDIOCSFBUF32 _IOW('v',12, struct video_buffer32)
324 #define VIDIOCGFREQ32 _IOR('v',14, u32)
325 #define VIDIOCSFREQ32 _IOW('v',15, u32)
326
do_video_ioctl(unsigned int fd,unsigned int cmd,unsigned long arg)327 static int do_video_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
328 {
329 union {
330 struct video_tuner vt;
331 struct video_buffer vb;
332 struct video_window vw;
333 unsigned long vx;
334 } karg;
335 mm_segment_t old_fs = get_fs();
336 void *up = (void *)arg;
337 int err = 0;
338
339 /* First, convert the command. */
340 switch(cmd) {
341 case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break;
342 case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break;
343 case VIDIOCGWIN32: cmd = VIDIOCGWIN; break;
344 case VIDIOCSWIN32: cmd = VIDIOCSWIN; break;
345 case VIDIOCGFBUF32: cmd = VIDIOCGFBUF; break;
346 case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break;
347 case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break;
348 case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break;
349 };
350
351 switch(cmd) {
352 case VIDIOCSTUNER:
353 case VIDIOCGTUNER:
354 err = get_video_tuner32(&karg.vt, up);
355 break;
356
357 case VIDIOCSWIN:
358 err = get_video_window32(&karg.vw, up);
359 break;
360
361 case VIDIOCSFBUF:
362 err = get_video_buffer32(&karg.vb, up);
363 break;
364
365 case VIDIOCSFREQ:
366 err = get_user(karg.vx, (u32 *)up);
367 break;
368 };
369 if (err)
370 goto out;
371
372 set_fs(KERNEL_DS);
373 err = sys_ioctl(fd, cmd, (unsigned long)&karg);
374 set_fs(old_fs);
375
376 if (cmd == VIDIOCSWIN)
377 free_kvideo_clips(&karg.vw);
378
379 if (err == 0) {
380 switch(cmd) {
381 case VIDIOCGTUNER:
382 err = put_video_tuner32(&karg.vt, up);
383 break;
384
385 case VIDIOCGWIN:
386 err = put_video_window32(&karg.vw, up);
387 break;
388
389 case VIDIOCGFBUF:
390 err = put_video_buffer32(&karg.vb, up);
391 break;
392
393 case VIDIOCGFREQ:
394 err = put_user(((u32)karg.vx), (u32 *)up);
395 break;
396 };
397 }
398 out:
399 return err;
400 }
401
402 struct timeval32 {
403 int tv_sec;
404 int tv_usec;
405 };
406
do_siocgstamp(unsigned int fd,unsigned int cmd,unsigned long arg)407 static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg)
408 {
409 struct timeval32 *up = (struct timeval32 *)arg;
410 struct timeval ktv;
411 mm_segment_t old_fs = get_fs();
412 int err;
413
414 set_fs(KERNEL_DS);
415 err = sys_ioctl(fd, cmd, (unsigned long)&ktv);
416 set_fs(old_fs);
417 if (!err) {
418 err = put_user(ktv.tv_sec, &up->tv_sec);
419 err |= __put_user(ktv.tv_usec, &up->tv_usec);
420 }
421 return err;
422 }
423
424 struct ifmap32 {
425 u32 mem_start;
426 u32 mem_end;
427 unsigned short base_addr;
428 unsigned char irq;
429 unsigned char dma;
430 unsigned char port;
431 };
432
433 struct ifreq32 {
434 #define IFHWADDRLEN 6
435 #define IFNAMSIZ 16
436 union {
437 char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
438 } ifr_ifrn;
439 union {
440 struct sockaddr ifru_addr;
441 struct sockaddr ifru_dstaddr;
442 struct sockaddr ifru_broadaddr;
443 struct sockaddr ifru_netmask;
444 struct sockaddr ifru_hwaddr;
445 short ifru_flags;
446 int ifru_ivalue;
447 int ifru_mtu;
448 struct ifmap32 ifru_map;
449 char ifru_slave[IFNAMSIZ]; /* Just fits the size */
450 char ifru_newname[IFNAMSIZ];
451 __kernel_caddr_t32 ifru_data;
452 } ifr_ifru;
453 };
454
455 struct ifconf32 {
456 int ifc_len; /* size of buffer */
457 __kernel_caddr_t32 ifcbuf;
458 };
459
460 #ifdef CONFIG_NET
dev_ifname32(unsigned int fd,unsigned int cmd,unsigned long arg)461 static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg)
462 {
463 struct net_device *dev;
464 struct ifreq32 ifr32;
465 int err;
466
467 if (copy_from_user(&ifr32, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
468 return -EFAULT;
469
470 dev = dev_get_by_index(ifr32.ifr_ifindex);
471 if (!dev)
472 return -ENODEV;
473
474 strcpy(ifr32.ifr_name, dev->name);
475 dev_put(dev);
476
477 err = copy_to_user((struct ifreq32 *)arg, &ifr32, sizeof(struct ifreq32));
478 return (err ? -EFAULT : 0);
479 }
480 #endif
481
dev_ifconf(unsigned int fd,unsigned int cmd,unsigned long arg)482 static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
483 {
484 struct ifconf32 ifc32;
485 struct ifconf ifc;
486 struct ifreq32 *ifr32;
487 struct ifreq *ifr;
488 mm_segment_t old_fs;
489 unsigned int i, j;
490 int err;
491
492 if (copy_from_user(&ifc32, (struct ifconf32 *)arg, sizeof(struct ifconf32)))
493 return -EFAULT;
494
495 if (ifc32.ifcbuf == 0) {
496 ifc32.ifc_len = 0;
497 ifc.ifc_len = 0;
498 ifc.ifc_buf = NULL;
499 } else {
500 ifc.ifc_len = ((ifc32.ifc_len / sizeof (struct ifreq32)) + 1) *
501 sizeof (struct ifreq);
502 ifc.ifc_buf = kmalloc (ifc.ifc_len, GFP_KERNEL);
503 if (!ifc.ifc_buf)
504 return -ENOMEM;
505 }
506 ifr = ifc.ifc_req;
507 ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf);
508 for (i = 0; i < ifc32.ifc_len; i += sizeof (struct ifreq32)) {
509 if (copy_from_user(ifr++, ifr32++, sizeof (struct ifreq32))) {
510 kfree (ifc.ifc_buf);
511 return -EFAULT;
512 }
513 }
514 old_fs = get_fs(); set_fs (KERNEL_DS);
515 err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc);
516 set_fs (old_fs);
517 if (!err) {
518 ifr = ifc.ifc_req;
519 ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf);
520 for (i = 0, j = 0; i < ifc32.ifc_len && j < ifc.ifc_len;
521 i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) {
522 if (copy_to_user(ifr32++, ifr++, sizeof (struct ifreq32))) {
523 err = -EFAULT;
524 break;
525 }
526 }
527 if (!err) {
528 if (ifc32.ifcbuf == 0) {
529 /* Translate from 64-bit structure multiple to
530 * a 32-bit one.
531 */
532 i = ifc.ifc_len;
533 i = ((i / sizeof(struct ifreq)) * sizeof(struct ifreq32));
534 ifc32.ifc_len = i;
535 } else {
536 if (i <= ifc32.ifc_len)
537 ifc32.ifc_len = i;
538 else
539 ifc32.ifc_len = i - sizeof (struct ifreq32);
540 }
541 if (copy_to_user((struct ifconf32 *)arg, &ifc32, sizeof(struct ifconf32)))
542 err = -EFAULT;
543 }
544 }
545 if (ifc.ifc_buf != NULL)
546 kfree (ifc.ifc_buf);
547 return err;
548 }
549
ethtool_ioctl(unsigned int fd,unsigned int cmd,unsigned long arg)550 static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
551 {
552 struct ifreq ifr;
553 mm_segment_t old_fs;
554 int err, len;
555 u32 data, ethcmd;
556
557 if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
558 return -EFAULT;
559 ifr.ifr_data = (__kernel_caddr_t)get_free_page(GFP_KERNEL);
560 if (!ifr.ifr_data)
561 return -EAGAIN;
562
563 __get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
564
565 if (get_user(ethcmd, (u32 *)A(data))) {
566 err = -EFAULT;
567 goto out;
568 }
569 switch (ethcmd) {
570 case ETHTOOL_GSTRINGS: {
571 struct ethtool_gstrings *stringsaddr = (struct ethtool_gstrings *)A(data);
572 if (get_user(len, (u32 *)&stringsaddr->len)) {
573 err = -EFAULT;
574 goto out;
575 }
576 if (len > (PAGE_SIZE - sizeof(struct ethtool_gstrings))/ETH_GSTRING_LEN ) {
577 err = -EINVAL;
578 goto out;
579 }
580 len = (len*ETH_GSTRING_LEN) + sizeof(struct ethtool_gstrings);
581 break;
582 }
583 case ETHTOOL_GSTATS: {
584 struct ethtool_stats *statsaddr = (struct ethtool_stats *)A(data);
585 if (get_user(len, (u32 *)&statsaddr->n_stats)) {
586 err = -EFAULT;
587 goto out;
588 }
589 if (len > (PAGE_SIZE - sizeof(struct ethtool_stats))/sizeof(u64) ) {
590 err = -EINVAL;
591 goto out;
592 }
593 len = (len*sizeof(u64)) + sizeof(struct ethtool_stats);
594 break;
595 }
596 case ETHTOOL_SWOL:
597 case ETHTOOL_GWOL:
598 len = sizeof(struct ethtool_wolinfo);
599 break;
600 case ETHTOOL_GDRVINFO:
601 len = sizeof(struct ethtool_drvinfo);
602 break;
603 case ETHTOOL_GMSGLVL:
604 case ETHTOOL_SMSGLVL:
605 case ETHTOOL_GLINK:
606 case ETHTOOL_NWAY_RST:
607 case ETHTOOL_SSG:
608 case ETHTOOL_GSG:
609 case ETHTOOL_GTXCSUM:
610 case ETHTOOL_STXCSUM:
611 case ETHTOOL_GRXCSUM:
612 case ETHTOOL_SRXCSUM:
613 case ETHTOOL_PHYS_ID:
614 len = sizeof(struct ethtool_value);
615 break;
616 case ETHTOOL_GREGS: {
617 struct ethtool_regs *regaddr = (struct ethtool_regs *)A(data);
618 /* darned variable size arguments */
619 if (get_user(len, (u32 *)®addr->len)) {
620 err = -EFAULT;
621 goto out;
622 }
623 if (len > PAGE_SIZE - sizeof(struct ethtool_regs)) {
624 err = -EINVAL;
625 goto out;
626 }
627 len += sizeof(struct ethtool_regs);
628 break;
629 }
630 case ETHTOOL_GEEPROM:
631 case ETHTOOL_SEEPROM: {
632 struct ethtool_eeprom *promaddr = (struct ethtool_eeprom *)A(data);
633 /* darned variable size arguments */
634 if (get_user(len, (u32 *)&promaddr->len)) {
635 err = -EFAULT;
636 goto out;
637 }
638 if (len > PAGE_SIZE - sizeof(struct ethtool_eeprom)) {
639 err = -EINVAL;
640 goto out;
641 }
642 len += sizeof(struct ethtool_eeprom);
643 break;
644 }
645 case ETHTOOL_GRINGPARAM:
646 case ETHTOOL_SRINGPARAM:
647 len = sizeof(struct ethtool_ringparam);
648 break;
649 case ETHTOOL_GPAUSEPARAM:
650 case ETHTOOL_SPAUSEPARAM:
651 len = sizeof(struct ethtool_pauseparam);
652 break;
653 case ETHTOOL_GCOALESCE:
654 case ETHTOOL_SCOALESCE:
655 len = sizeof(struct ethtool_coalesce);
656 break;
657 case ETHTOOL_GSET:
658 case ETHTOOL_SSET:
659 len = sizeof(struct ethtool_cmd);
660 break;
661 default:
662 err = -EOPNOTSUPP;
663 goto out;
664 }
665
666 if (copy_from_user(ifr.ifr_data, (char *)A(data), len)) {
667 err = -EFAULT;
668 goto out;
669 }
670
671 old_fs = get_fs();
672 set_fs (KERNEL_DS);
673 err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
674 set_fs (old_fs);
675 if (!err) {
676 u32 data;
677
678 __get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
679 len = copy_to_user((char *)A(data), ifr.ifr_data, len);
680 if (len)
681 err = -EFAULT;
682 }
683
684 out:
685 free_page((unsigned long)ifr.ifr_data);
686 return err;
687 }
688
bond_ioctl(unsigned long fd,unsigned int cmd,unsigned long arg)689 static int bond_ioctl(unsigned long fd, unsigned int cmd, unsigned long arg)
690 {
691 struct ifreq ifr;
692 mm_segment_t old_fs;
693 int err, len;
694 u32 data;
695
696 if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
697 return -EFAULT;
698 ifr.ifr_data = (__kernel_caddr_t)get_free_page(GFP_KERNEL);
699 if (!ifr.ifr_data)
700 return -EAGAIN;
701
702 switch (cmd) {
703 case SIOCBONDENSLAVE:
704 case SIOCBONDRELEASE:
705 case SIOCBONDSETHWADDR:
706 case SIOCBONDCHANGEACTIVE:
707 len = IFNAMSIZ * sizeof(char);
708 break;
709 case SIOCBONDSLAVEINFOQUERY:
710 len = sizeof(struct ifslave);
711 break;
712 case SIOCBONDINFOQUERY:
713 len = sizeof(struct ifbond);
714 break;
715 default:
716 err = -EINVAL;
717 goto out;
718 };
719
720 __get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
721 if (copy_from_user(ifr.ifr_data, (char *)A(data), len)) {
722 err = -EFAULT;
723 goto out;
724 }
725
726 old_fs = get_fs();
727 set_fs (KERNEL_DS);
728 err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
729 set_fs (old_fs);
730 if (!err) {
731 len = copy_to_user((char *)A(data), ifr.ifr_data, len);
732 if (len)
733 err = -EFAULT;
734 }
735
736 out:
737 free_page((unsigned long)ifr.ifr_data);
738 return err;
739 }
740
dev_ifsioc(unsigned int fd,unsigned int cmd,unsigned long arg)741 static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
742 {
743 struct ifreq ifr;
744 mm_segment_t old_fs;
745 int err;
746
747 switch (cmd) {
748 case SIOCSIFMAP:
749 err = copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(ifr.ifr_name));
750 err |= __get_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));
751 err |= __get_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));
752 err |= __get_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));
753 err |= __get_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));
754 err |= __get_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));
755 err |= __get_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));
756 if (err)
757 return -EFAULT;
758 break;
759 default:
760 if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
761 return -EFAULT;
762 break;
763 }
764 old_fs = get_fs();
765 set_fs (KERNEL_DS);
766 err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
767 set_fs (old_fs);
768 if (!err) {
769 switch (cmd) {
770 case SIOCGIFFLAGS:
771 case SIOCGIFMETRIC:
772 case SIOCGIFMTU:
773 case SIOCGIFMEM:
774 case SIOCGIFHWADDR:
775 case SIOCGIFINDEX:
776 case SIOCGIFADDR:
777 case SIOCGIFBRDADDR:
778 case SIOCGIFDSTADDR:
779 case SIOCGIFNETMASK:
780 case SIOCGIFTXQLEN:
781 if (copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(struct ifreq32)))
782 return -EFAULT;
783 break;
784 case SIOCGIFMAP:
785 err = copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(ifr.ifr_name));
786 err |= __put_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));
787 err |= __put_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));
788 err |= __put_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));
789 err |= __put_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));
790 err |= __put_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));
791 err |= __put_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));
792 if (err)
793 err = -EFAULT;
794 break;
795 }
796 }
797 return err;
798 }
799
800 struct rtentry32 {
801 u32 rt_pad1;
802 struct sockaddr rt_dst; /* target address */
803 struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */
804 struct sockaddr rt_genmask; /* target network mask (IP) */
805 unsigned short rt_flags;
806 short rt_pad2;
807 u32 rt_pad3;
808 unsigned char rt_tos;
809 unsigned char rt_class;
810 short rt_pad4;
811 short rt_metric; /* +1 for binary compatibility! */
812 /* char * */ u32 rt_dev; /* forcing the device at add */
813 u32 rt_mtu; /* per route MTU/Window */
814 u32 rt_window; /* Window clamping */
815 unsigned short rt_irtt; /* Initial RTT */
816
817 };
818
819 struct in6_rtmsg32 {
820 struct in6_addr rtmsg_dst;
821 struct in6_addr rtmsg_src;
822 struct in6_addr rtmsg_gateway;
823 u32 rtmsg_type;
824 u16 rtmsg_dst_len;
825 u16 rtmsg_src_len;
826 u32 rtmsg_metric;
827 u32 rtmsg_info;
828 u32 rtmsg_flags;
829 s32 rtmsg_ifindex;
830 };
831
832 extern struct socket *sockfd_lookup(int fd, int *err);
833
sockfd_put(struct socket * sock)834 extern __inline__ void sockfd_put(struct socket *sock)
835 {
836 fput(sock->file);
837 }
838
routing_ioctl(unsigned int fd,unsigned int cmd,unsigned long arg)839 static int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
840 {
841 int ret;
842 void *r = NULL;
843 struct in6_rtmsg r6;
844 struct rtentry r4;
845 char devname[16];
846 u32 rtdev;
847 mm_segment_t old_fs = get_fs();
848
849 struct socket *mysock = sockfd_lookup(fd, &ret);
850
851 if (mysock && mysock->sk && mysock->sk->family == AF_INET6) { /* ipv6 */
852 ret = copy_from_user (&r6.rtmsg_dst, &(((struct in6_rtmsg32 *)arg)->rtmsg_dst),
853 3 * sizeof(struct in6_addr));
854 ret |= __get_user (r6.rtmsg_type, &(((struct in6_rtmsg32 *)arg)->rtmsg_type));
855 ret |= __get_user (r6.rtmsg_dst_len, &(((struct in6_rtmsg32 *)arg)->rtmsg_dst_len));
856 ret |= __get_user (r6.rtmsg_src_len, &(((struct in6_rtmsg32 *)arg)->rtmsg_src_len));
857 ret |= __get_user (r6.rtmsg_metric, &(((struct in6_rtmsg32 *)arg)->rtmsg_metric));
858 ret |= __get_user (r6.rtmsg_info, &(((struct in6_rtmsg32 *)arg)->rtmsg_info));
859 ret |= __get_user (r6.rtmsg_flags, &(((struct in6_rtmsg32 *)arg)->rtmsg_flags));
860 ret |= __get_user (r6.rtmsg_ifindex, &(((struct in6_rtmsg32 *)arg)->rtmsg_ifindex));
861
862 r = (void *) &r6;
863 } else { /* ipv4 */
864 ret = copy_from_user (&r4.rt_dst, &(((struct rtentry32 *)arg)->rt_dst), 3 * sizeof(struct sockaddr));
865 ret |= __get_user (r4.rt_flags, &(((struct rtentry32 *)arg)->rt_flags));
866 ret |= __get_user (r4.rt_metric, &(((struct rtentry32 *)arg)->rt_metric));
867 ret |= __get_user (r4.rt_mtu, &(((struct rtentry32 *)arg)->rt_mtu));
868 ret |= __get_user (r4.rt_window, &(((struct rtentry32 *)arg)->rt_window));
869 ret |= __get_user (r4.rt_irtt, &(((struct rtentry32 *)arg)->rt_irtt));
870 ret |= __get_user (rtdev, &(((struct rtentry32 *)arg)->rt_dev));
871 if (rtdev) {
872 ret |= copy_from_user (devname, (char *)A(rtdev), 15);
873 r4.rt_dev = devname; devname[15] = 0;
874 } else
875 r4.rt_dev = 0;
876
877 r = (void *) &r4;
878 }
879
880 if (ret) {
881 ret = -EFAULT;
882 goto out;
883 }
884
885 set_fs (KERNEL_DS);
886 ret = sys_ioctl (fd, cmd, (long) r);
887 set_fs (old_fs);
888 out:
889 if (mysock)
890 sockfd_put(mysock);
891
892 return ret;
893 }
894
895 struct hd_geometry32 {
896 unsigned char heads;
897 unsigned char sectors;
898 unsigned short cylinders;
899 u32 start;
900 };
901
hdio_getgeo(unsigned int fd,unsigned int cmd,unsigned long arg)902 static int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg)
903 {
904 mm_segment_t old_fs = get_fs();
905 struct hd_geometry geo;
906 int err;
907
908 set_fs (KERNEL_DS);
909 err = sys_ioctl(fd, HDIO_GETGEO, (unsigned long)&geo);
910 set_fs (old_fs);
911 if (!err) {
912 err = copy_to_user ((struct hd_geometry32 *)arg, &geo, 4);
913 err |= __put_user (geo.start, &(((struct hd_geometry32 *)arg)->start));
914 }
915 return err ? -EFAULT : 0;
916 }
917
918 struct hd_big_geometry32 {
919 u8 heads;
920 u8 sectors;
921 u32 cylinders;
922 u32 start;
923 };
924
hdio_getgeo_big(unsigned int fd,unsigned int cmd,unsigned long arg)925 static int hdio_getgeo_big(unsigned int fd, unsigned int cmd, unsigned long arg)
926 {
927 mm_segment_t old_fs = get_fs();
928 struct hd_big_geometry geo;
929 int err;
930
931 set_fs (KERNEL_DS);
932 err = sys_ioctl(fd, HDIO_GETGEO_BIG, (unsigned long)&geo);
933 set_fs (old_fs);
934 if (err)
935 return err;
936 else {
937 struct hd_big_geometry32 *user_geo = (struct hd_big_geometry32 *)arg;
938 err = __put_user (geo.heads, &(user_geo->heads));
939 err |= __put_user (geo.sectors, &(user_geo->sectors));
940 err |= __put_user (geo.cylinders, &(user_geo->cylinders));
941 err |= __put_user (geo.start, &(user_geo->start));
942 }
943 return err ? -EFAULT : 0;
944 }
945
946
hdio_ioctl_trans(unsigned int fd,unsigned int cmd,unsigned long arg)947 static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
948 {
949 mm_segment_t old_fs = get_fs();
950 unsigned long kval;
951 unsigned int *uvp;
952 int error;
953
954 set_fs(KERNEL_DS);
955 error = sys_ioctl(fd, cmd, (long)&kval);
956 set_fs(old_fs);
957
958 if (error == 0) {
959 uvp = (unsigned int *)arg;
960 if (put_user(kval, uvp))
961 error = -EFAULT;
962 }
963 return error;
964 }
965
966 struct floppy_struct32 {
967 unsigned int size;
968 unsigned int sect;
969 unsigned int head;
970 unsigned int track;
971 unsigned int stretch;
972 unsigned char gap;
973 unsigned char rate;
974 unsigned char spec1;
975 unsigned char fmt_gap;
976 const __kernel_caddr_t32 name;
977 };
978
979 struct floppy_drive_params32 {
980 char cmos;
981 u32 max_dtr;
982 u32 hlt;
983 u32 hut;
984 u32 srt;
985 u32 spinup;
986 u32 spindown;
987 unsigned char spindown_offset;
988 unsigned char select_delay;
989 unsigned char rps;
990 unsigned char tracks;
991 u32 timeout;
992 unsigned char interleave_sect;
993 struct floppy_max_errors max_errors;
994 char flags;
995 char read_track;
996 short autodetect[8];
997 int checkfreq;
998 int native_format;
999 };
1000
1001 struct floppy_drive_struct32 {
1002 signed char flags;
1003 u32 spinup_date;
1004 u32 select_date;
1005 u32 first_read_date;
1006 short probed_format;
1007 short track;
1008 short maxblock;
1009 short maxtrack;
1010 int generation;
1011 int keep_data;
1012 int fd_ref;
1013 int fd_device;
1014 int last_checked;
1015 __kernel_caddr_t32 dmabuf;
1016 int bufblocks;
1017 };
1018
1019 struct floppy_fdc_state32 {
1020 int spec1;
1021 int spec2;
1022 int dtr;
1023 unsigned char version;
1024 unsigned char dor;
1025 u32 address;
1026 unsigned int rawcmd:2;
1027 unsigned int reset:1;
1028 unsigned int need_configure:1;
1029 unsigned int perp_mode:2;
1030 unsigned int has_fifo:1;
1031 unsigned int driver_version;
1032 unsigned char track[4];
1033 };
1034
1035 struct floppy_write_errors32 {
1036 unsigned int write_errors;
1037 u32 first_error_sector;
1038 int first_error_generation;
1039 u32 last_error_sector;
1040 int last_error_generation;
1041 unsigned int badness;
1042 };
1043
1044 #define FDSETPRM32 _IOW(2, 0x42, struct floppy_struct32)
1045 #define FDDEFPRM32 _IOW(2, 0x43, struct floppy_struct32)
1046 #define FDGETPRM32 _IOR(2, 0x04, struct floppy_struct32)
1047 #define FDSETDRVPRM32 _IOW(2, 0x90, struct floppy_drive_params32)
1048 #define FDGETDRVPRM32 _IOR(2, 0x11, struct floppy_drive_params32)
1049 #define FDGETDRVSTAT32 _IOR(2, 0x12, struct floppy_drive_struct32)
1050 #define FDPOLLDRVSTAT32 _IOR(2, 0x13, struct floppy_drive_struct32)
1051 #define FDGETFDCSTAT32 _IOR(2, 0x15, struct floppy_fdc_state32)
1052 #define FDWERRORGET32 _IOR(2, 0x17, struct floppy_write_errors32)
1053
1054 static struct {
1055 unsigned int cmd32;
1056 unsigned int cmd;
1057 } fd_ioctl_trans_table[] = {
1058 { FDSETPRM32, FDSETPRM },
1059 { FDDEFPRM32, FDDEFPRM },
1060 { FDGETPRM32, FDGETPRM },
1061 { FDSETDRVPRM32, FDSETDRVPRM },
1062 { FDGETDRVPRM32, FDGETDRVPRM },
1063 { FDGETDRVSTAT32, FDGETDRVSTAT },
1064 { FDPOLLDRVSTAT32, FDPOLLDRVSTAT },
1065 { FDGETFDCSTAT32, FDGETFDCSTAT },
1066 { FDWERRORGET32, FDWERRORGET }
1067 };
1068
1069 #define NR_FD_IOCTL_TRANS (sizeof(fd_ioctl_trans_table)/sizeof(fd_ioctl_trans_table[0]))
1070
fd_ioctl_trans(unsigned int fd,unsigned int cmd,unsigned long arg)1071 static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
1072 {
1073 mm_segment_t old_fs = get_fs();
1074 void *karg = NULL;
1075 unsigned int kcmd = 0;
1076 int i, err;
1077
1078 for (i = 0; i < NR_FD_IOCTL_TRANS; i++)
1079 if (cmd == fd_ioctl_trans_table[i].cmd32) {
1080 kcmd = fd_ioctl_trans_table[i].cmd;
1081 break;
1082 }
1083 if (!kcmd)
1084 return -EINVAL;
1085
1086 switch (cmd) {
1087 case FDSETPRM32:
1088 case FDDEFPRM32:
1089 case FDGETPRM32:
1090 {
1091 struct floppy_struct *f;
1092
1093 f = karg = kmalloc(sizeof(struct floppy_struct), GFP_KERNEL);
1094 if (!karg)
1095 return -ENOMEM;
1096 if (cmd == FDGETPRM32)
1097 break;
1098 err = __get_user(f->size, &((struct floppy_struct32 *)arg)->size);
1099 err |= __get_user(f->sect, &((struct floppy_struct32 *)arg)->sect);
1100 err |= __get_user(f->head, &((struct floppy_struct32 *)arg)->head);
1101 err |= __get_user(f->track, &((struct floppy_struct32 *)arg)->track);
1102 err |= __get_user(f->stretch, &((struct floppy_struct32 *)arg)->stretch);
1103 err |= __get_user(f->gap, &((struct floppy_struct32 *)arg)->gap);
1104 err |= __get_user(f->rate, &((struct floppy_struct32 *)arg)->rate);
1105 err |= __get_user(f->spec1, &((struct floppy_struct32 *)arg)->spec1);
1106 err |= __get_user(f->fmt_gap, &((struct floppy_struct32 *)arg)->fmt_gap);
1107 err |= __get_user((u64)f->name, &((struct floppy_struct32 *)arg)->name);
1108 if (err) {
1109 err = -EFAULT;
1110 goto out;
1111 }
1112 break;
1113 }
1114 case FDSETDRVPRM32:
1115 case FDGETDRVPRM32:
1116 {
1117 struct floppy_drive_params *f;
1118
1119 f = karg = kmalloc(sizeof(struct floppy_drive_params), GFP_KERNEL);
1120 if (!karg)
1121 return -ENOMEM;
1122 if (cmd == FDGETDRVPRM32)
1123 break;
1124 err = __get_user(f->cmos, &((struct floppy_drive_params32 *)arg)->cmos);
1125 err |= __get_user(f->max_dtr, &((struct floppy_drive_params32 *)arg)->max_dtr);
1126 err |= __get_user(f->hlt, &((struct floppy_drive_params32 *)arg)->hlt);
1127 err |= __get_user(f->hut, &((struct floppy_drive_params32 *)arg)->hut);
1128 err |= __get_user(f->srt, &((struct floppy_drive_params32 *)arg)->srt);
1129 err |= __get_user(f->spinup, &((struct floppy_drive_params32 *)arg)->spinup);
1130 err |= __get_user(f->spindown, &((struct floppy_drive_params32 *)arg)->spindown);
1131 err |= __get_user(f->spindown_offset, &((struct floppy_drive_params32 *)arg)->spindown_offset);
1132 err |= __get_user(f->select_delay, &((struct floppy_drive_params32 *)arg)->select_delay);
1133 err |= __get_user(f->rps, &((struct floppy_drive_params32 *)arg)->rps);
1134 err |= __get_user(f->tracks, &((struct floppy_drive_params32 *)arg)->tracks);
1135 err |= __get_user(f->timeout, &((struct floppy_drive_params32 *)arg)->timeout);
1136 err |= __get_user(f->interleave_sect, &((struct floppy_drive_params32 *)arg)->interleave_sect);
1137 err |= __copy_from_user(&f->max_errors, &((struct floppy_drive_params32 *)arg)->max_errors, sizeof(f->max_errors));
1138 err |= __get_user(f->flags, &((struct floppy_drive_params32 *)arg)->flags);
1139 err |= __get_user(f->read_track, &((struct floppy_drive_params32 *)arg)->read_track);
1140 err |= __copy_from_user(f->autodetect, ((struct floppy_drive_params32 *)arg)->autodetect, sizeof(f->autodetect));
1141 err |= __get_user(f->checkfreq, &((struct floppy_drive_params32 *)arg)->checkfreq);
1142 err |= __get_user(f->native_format, &((struct floppy_drive_params32 *)arg)->native_format);
1143 if (err) {
1144 err = -EFAULT;
1145 goto out;
1146 }
1147 break;
1148 }
1149 case FDGETDRVSTAT32:
1150 case FDPOLLDRVSTAT32:
1151 karg = kmalloc(sizeof(struct floppy_drive_struct), GFP_KERNEL);
1152 if (!karg)
1153 return -ENOMEM;
1154 break;
1155 case FDGETFDCSTAT32:
1156 karg = kmalloc(sizeof(struct floppy_fdc_state), GFP_KERNEL);
1157 if (!karg)
1158 return -ENOMEM;
1159 break;
1160 case FDWERRORGET32:
1161 karg = kmalloc(sizeof(struct floppy_write_errors), GFP_KERNEL);
1162 if (!karg)
1163 return -ENOMEM;
1164 break;
1165 default:
1166 return -EINVAL;
1167 }
1168 set_fs (KERNEL_DS);
1169 err = sys_ioctl (fd, kcmd, (unsigned long)karg);
1170 set_fs (old_fs);
1171 if (err)
1172 goto out;
1173 switch (cmd) {
1174 case FDGETPRM32:
1175 {
1176 struct floppy_struct *f = karg;
1177
1178 err = __put_user(f->size, &((struct floppy_struct32 *)arg)->size);
1179 err |= __put_user(f->sect, &((struct floppy_struct32 *)arg)->sect);
1180 err |= __put_user(f->head, &((struct floppy_struct32 *)arg)->head);
1181 err |= __put_user(f->track, &((struct floppy_struct32 *)arg)->track);
1182 err |= __put_user(f->stretch, &((struct floppy_struct32 *)arg)->stretch);
1183 err |= __put_user(f->gap, &((struct floppy_struct32 *)arg)->gap);
1184 err |= __put_user(f->rate, &((struct floppy_struct32 *)arg)->rate);
1185 err |= __put_user(f->spec1, &((struct floppy_struct32 *)arg)->spec1);
1186 err |= __put_user(f->fmt_gap, &((struct floppy_struct32 *)arg)->fmt_gap);
1187 err |= __put_user((u64)f->name, &((struct floppy_struct32 *)arg)->name);
1188 break;
1189 }
1190 case FDGETDRVPRM32:
1191 {
1192 struct floppy_drive_params *f = karg;
1193
1194 err = __put_user(f->cmos, &((struct floppy_drive_params32 *)arg)->cmos);
1195 err |= __put_user(f->max_dtr, &((struct floppy_drive_params32 *)arg)->max_dtr);
1196 err |= __put_user(f->hlt, &((struct floppy_drive_params32 *)arg)->hlt);
1197 err |= __put_user(f->hut, &((struct floppy_drive_params32 *)arg)->hut);
1198 err |= __put_user(f->srt, &((struct floppy_drive_params32 *)arg)->srt);
1199 err |= __put_user(f->spinup, &((struct floppy_drive_params32 *)arg)->spinup);
1200 err |= __put_user(f->spindown, &((struct floppy_drive_params32 *)arg)->spindown);
1201 err |= __put_user(f->spindown_offset, &((struct floppy_drive_params32 *)arg)->spindown_offset);
1202 err |= __put_user(f->select_delay, &((struct floppy_drive_params32 *)arg)->select_delay);
1203 err |= __put_user(f->rps, &((struct floppy_drive_params32 *)arg)->rps);
1204 err |= __put_user(f->tracks, &((struct floppy_drive_params32 *)arg)->tracks);
1205 err |= __put_user(f->timeout, &((struct floppy_drive_params32 *)arg)->timeout);
1206 err |= __put_user(f->interleave_sect, &((struct floppy_drive_params32 *)arg)->interleave_sect);
1207 err |= __copy_to_user(&((struct floppy_drive_params32 *)arg)->max_errors, &f->max_errors, sizeof(f->max_errors));
1208 err |= __put_user(f->flags, &((struct floppy_drive_params32 *)arg)->flags);
1209 err |= __put_user(f->read_track, &((struct floppy_drive_params32 *)arg)->read_track);
1210 err |= __copy_to_user(((struct floppy_drive_params32 *)arg)->autodetect, f->autodetect, sizeof(f->autodetect));
1211 err |= __put_user(f->checkfreq, &((struct floppy_drive_params32 *)arg)->checkfreq);
1212 err |= __put_user(f->native_format, &((struct floppy_drive_params32 *)arg)->native_format);
1213 break;
1214 }
1215 case FDGETDRVSTAT32:
1216 case FDPOLLDRVSTAT32:
1217 {
1218 struct floppy_drive_struct *f = karg;
1219
1220 err = __put_user(f->flags, &((struct floppy_drive_struct32 *)arg)->flags);
1221 err |= __put_user(f->spinup_date, &((struct floppy_drive_struct32 *)arg)->spinup_date);
1222 err |= __put_user(f->select_date, &((struct floppy_drive_struct32 *)arg)->select_date);
1223 err |= __put_user(f->first_read_date, &((struct floppy_drive_struct32 *)arg)->first_read_date);
1224 err |= __put_user(f->probed_format, &((struct floppy_drive_struct32 *)arg)->probed_format);
1225 err |= __put_user(f->track, &((struct floppy_drive_struct32 *)arg)->track);
1226 err |= __put_user(f->maxblock, &((struct floppy_drive_struct32 *)arg)->maxblock);
1227 err |= __put_user(f->maxtrack, &((struct floppy_drive_struct32 *)arg)->maxtrack);
1228 err |= __put_user(f->generation, &((struct floppy_drive_struct32 *)arg)->generation);
1229 err |= __put_user(f->keep_data, &((struct floppy_drive_struct32 *)arg)->keep_data);
1230 err |= __put_user(f->fd_ref, &((struct floppy_drive_struct32 *)arg)->fd_ref);
1231 err |= __put_user(f->fd_device, &((struct floppy_drive_struct32 *)arg)->fd_device);
1232 err |= __put_user(f->last_checked, &((struct floppy_drive_struct32 *)arg)->last_checked);
1233 err |= __put_user((u64)f->dmabuf, &((struct floppy_drive_struct32 *)arg)->dmabuf);
1234 err |= __put_user((u64)f->bufblocks, &((struct floppy_drive_struct32 *)arg)->bufblocks);
1235 break;
1236 }
1237 case FDGETFDCSTAT32:
1238 {
1239 struct floppy_fdc_state *f = karg;
1240
1241 err = __put_user(f->spec1, &((struct floppy_fdc_state32 *)arg)->spec1);
1242 err |= __put_user(f->spec2, &((struct floppy_fdc_state32 *)arg)->spec2);
1243 err |= __put_user(f->dtr, &((struct floppy_fdc_state32 *)arg)->dtr);
1244 err |= __put_user(f->version, &((struct floppy_fdc_state32 *)arg)->version);
1245 err |= __put_user(f->dor, &((struct floppy_fdc_state32 *)arg)->dor);
1246 err |= __put_user(f->address, &((struct floppy_fdc_state32 *)arg)->address);
1247 err |= __copy_to_user((char *)&((struct floppy_fdc_state32 *)arg)->address
1248 + sizeof(((struct floppy_fdc_state32 *)arg)->address),
1249 (char *)&f->address + sizeof(f->address), sizeof(int));
1250 err |= __put_user(f->driver_version, &((struct floppy_fdc_state32 *)arg)->driver_version);
1251 err |= __copy_to_user(((struct floppy_fdc_state32 *)arg)->track, f->track, sizeof(f->track));
1252 break;
1253 }
1254 case FDWERRORGET32:
1255 {
1256 struct floppy_write_errors *f = karg;
1257
1258 err = __put_user(f->write_errors, &((struct floppy_write_errors32 *)arg)->write_errors);
1259 err |= __put_user(f->first_error_sector, &((struct floppy_write_errors32 *)arg)->first_error_sector);
1260 err |= __put_user(f->first_error_generation, &((struct floppy_write_errors32 *)arg)->first_error_generation);
1261 err |= __put_user(f->last_error_sector, &((struct floppy_write_errors32 *)arg)->last_error_sector);
1262 err |= __put_user(f->last_error_generation, &((struct floppy_write_errors32 *)arg)->last_error_generation);
1263 err |= __put_user(f->badness, &((struct floppy_write_errors32 *)arg)->badness);
1264 break;
1265 }
1266 default:
1267 break;
1268 }
1269 if (err)
1270 err = -EFAULT;
1271
1272 out: if (karg) kfree(karg);
1273 return err;
1274 }
1275
1276 typedef struct sg_io_hdr32 {
1277 s32 interface_id; /* [i] 'S' for SCSI generic (required) */
1278 s32 dxfer_direction; /* [i] data transfer direction */
1279 u8 cmd_len; /* [i] SCSI command length ( <= 16 bytes) */
1280 u8 mx_sb_len; /* [i] max length to write to sbp */
1281 u16 iovec_count; /* [i] 0 implies no scatter gather */
1282 u32 dxfer_len; /* [i] byte count of data transfer */
1283 u32 dxferp; /* [i], [*io] points to data transfer memory
1284 or scatter gather list */
1285 u32 cmdp; /* [i], [*i] points to command to perform */
1286 u32 sbp; /* [i], [*o] points to sense_buffer memory */
1287 u32 timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */
1288 u32 flags; /* [i] 0 -> default, see SG_FLAG... */
1289 s32 pack_id; /* [i->o] unused internally (normally) */
1290 u32 usr_ptr; /* [i->o] unused internally */
1291 u8 status; /* [o] scsi status */
1292 u8 masked_status; /* [o] shifted, masked scsi status */
1293 u8 msg_status; /* [o] messaging level data (optional) */
1294 u8 sb_len_wr; /* [o] byte count actually written to sbp */
1295 u16 host_status; /* [o] errors from host adapter */
1296 u16 driver_status; /* [o] errors from software driver */
1297 s32 resid; /* [o] dxfer_len - actual_transferred */
1298 u32 duration; /* [o] time taken by cmd (unit: millisec) */
1299 u32 info; /* [o] auxiliary information */
1300 } sg_io_hdr32_t; /* 64 bytes long (on sparc32) */
1301
1302 typedef struct sg_iovec32 {
1303 u32 iov_base;
1304 u32 iov_len;
1305 } sg_iovec32_t;
1306
1307 #define EMU_SG_MAX 128
1308
alloc_sg_iovec(sg_io_hdr_t * sgp,u32 uptr32)1309 static int alloc_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32)
1310 {
1311 sg_iovec32_t *uiov = (sg_iovec32_t *) A(uptr32);
1312 sg_iovec_t *kiov;
1313 int i;
1314
1315 if (sgp->iovec_count > EMU_SG_MAX)
1316 return -EINVAL;
1317 sgp->dxferp = kmalloc(sgp->iovec_count *
1318 sizeof(sg_iovec_t), GFP_KERNEL);
1319 if (!sgp->dxferp)
1320 return -ENOMEM;
1321 memset(sgp->dxferp, 0,
1322 sgp->iovec_count * sizeof(sg_iovec_t));
1323
1324 kiov = (sg_iovec_t *) sgp->dxferp;
1325 for (i = 0; i < sgp->iovec_count; i++) {
1326 u32 iov_base32;
1327 if (__get_user(iov_base32, &uiov->iov_base) ||
1328 __get_user(kiov->iov_len, &uiov->iov_len))
1329 return -EFAULT;
1330 if (verify_area(VERIFY_WRITE, (void *)A(iov_base32), kiov->iov_len))
1331 return -EFAULT;
1332 kiov->iov_base = (void *)A(iov_base32);
1333 uiov++;
1334 kiov++;
1335 }
1336
1337 return 0;
1338 }
1339
free_sg_iovec(sg_io_hdr_t * sgp)1340 static void free_sg_iovec(sg_io_hdr_t *sgp)
1341 {
1342 kfree(sgp->dxferp);
1343 sgp->dxferp = NULL;
1344 }
1345
sg_ioctl_trans(unsigned int fd,unsigned int cmd,unsigned long arg)1346 static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
1347 {
1348 sg_io_hdr32_t *sg_io32;
1349 sg_io_hdr_t sg_io64;
1350 u32 dxferp32, cmdp32, sbp32;
1351 mm_segment_t old_fs;
1352 int err = 0;
1353
1354 sg_io32 = (sg_io_hdr32_t *)arg;
1355 err = __get_user(sg_io64.interface_id, &sg_io32->interface_id);
1356 err |= __get_user(sg_io64.dxfer_direction, &sg_io32->dxfer_direction);
1357 err |= __get_user(sg_io64.cmd_len, &sg_io32->cmd_len);
1358 err |= __get_user(sg_io64.mx_sb_len, &sg_io32->mx_sb_len);
1359 err |= __get_user(sg_io64.iovec_count, &sg_io32->iovec_count);
1360 err |= __get_user(sg_io64.dxfer_len, &sg_io32->dxfer_len);
1361 err |= __get_user(sg_io64.timeout, &sg_io32->timeout);
1362 err |= __get_user(sg_io64.flags, &sg_io32->flags);
1363 err |= __get_user(sg_io64.pack_id, &sg_io32->pack_id);
1364
1365 sg_io64.dxferp = NULL;
1366 sg_io64.cmdp = NULL;
1367 sg_io64.sbp = NULL;
1368
1369 err |= __get_user(cmdp32, &sg_io32->cmdp);
1370 if (sg_io64.cmd_len > 4*PAGE_SIZE || sg_io64.mx_sb_len > 4*PAGE_SIZE) {
1371 err = -EINVAL;
1372 goto out;
1373 }
1374 sg_io64.cmdp = kmalloc(sg_io64.cmd_len, GFP_KERNEL);
1375 if (!sg_io64.cmdp) {
1376 err = -ENOMEM;
1377 goto out;
1378 }
1379 if (copy_from_user(sg_io64.cmdp,
1380 (void *) A(cmdp32),
1381 sg_io64.cmd_len)) {
1382 err = -EFAULT;
1383 goto out;
1384 }
1385
1386 err |= __get_user(sbp32, &sg_io32->sbp);
1387 sg_io64.sbp = kmalloc(sg_io64.mx_sb_len, GFP_KERNEL);
1388 if (!sg_io64.sbp) {
1389 err = -ENOMEM;
1390 goto out;
1391 }
1392 if (copy_from_user(sg_io64.sbp,
1393 (void *) A(sbp32),
1394 sg_io64.mx_sb_len)) {
1395 err = -EFAULT;
1396 goto out;
1397 }
1398
1399 err |= __get_user(dxferp32, &sg_io32->dxferp);
1400 if (sg_io64.iovec_count) {
1401 int ret;
1402
1403 if ((ret = alloc_sg_iovec(&sg_io64, dxferp32))) {
1404 err = ret;
1405 goto out;
1406 }
1407 } else {
1408 if (sg_io64.dxfer_len > 4*PAGE_SIZE) {
1409 err = -EINVAL;
1410 goto out;
1411 }
1412 sg_io64.dxferp = kmalloc(sg_io64.dxfer_len, GFP_KERNEL);
1413 if (!sg_io64.dxferp) {
1414 err = -ENOMEM;
1415 goto out;
1416 }
1417 if (copy_from_user(sg_io64.dxferp,
1418 (void *) A(dxferp32),
1419 sg_io64.dxfer_len)) {
1420 err = -EFAULT;
1421 goto out;
1422 }
1423 }
1424
1425 /* Unused internally, do not even bother to copy it over. */
1426 sg_io64.usr_ptr = NULL;
1427
1428 if (err)
1429 return -EFAULT;
1430
1431 old_fs = get_fs();
1432 set_fs (KERNEL_DS);
1433 err = sys_ioctl (fd, cmd, (unsigned long) &sg_io64);
1434 set_fs (old_fs);
1435
1436 if (err < 0)
1437 goto out;
1438
1439 err = __put_user(sg_io64.pack_id, &sg_io32->pack_id);
1440 err |= __put_user(sg_io64.status, &sg_io32->status);
1441 err |= __put_user(sg_io64.masked_status, &sg_io32->masked_status);
1442 err |= __put_user(sg_io64.msg_status, &sg_io32->msg_status);
1443 err |= __put_user(sg_io64.sb_len_wr, &sg_io32->sb_len_wr);
1444 err |= __put_user(sg_io64.host_status, &sg_io32->host_status);
1445 err |= __put_user(sg_io64.driver_status, &sg_io32->driver_status);
1446 err |= __put_user(sg_io64.resid, &sg_io32->resid);
1447 err |= __put_user(sg_io64.duration, &sg_io32->duration);
1448 err |= __put_user(sg_io64.info, &sg_io32->info);
1449 err |= copy_to_user((void *)A(sbp32), sg_io64.sbp, sg_io64.mx_sb_len);
1450 if (sg_io64.dxferp) {
1451 if (sg_io64.iovec_count)
1452 ;
1453 else
1454 err |= copy_to_user((void *)A(dxferp32),
1455 sg_io64.dxferp,
1456 sg_io64.dxfer_len);
1457 }
1458 if (err)
1459 err = -EFAULT;
1460
1461 out:
1462 if (sg_io64.cmdp)
1463 kfree(sg_io64.cmdp);
1464 if (sg_io64.sbp)
1465 kfree(sg_io64.sbp);
1466 if (sg_io64.dxferp) {
1467 if (sg_io64.iovec_count) {
1468 free_sg_iovec(&sg_io64);
1469 } else {
1470 kfree(sg_io64.dxferp);
1471 }
1472 }
1473 return err;
1474 }
1475
1476 struct ppp_option_data32 {
1477 __kernel_caddr_t32 ptr;
1478 __u32 length;
1479 int transmit;
1480 };
1481 #define PPPIOCSCOMPRESS32 _IOW('t', 77, struct ppp_option_data32)
1482
1483 struct ppp_idle32 {
1484 __kernel_time_t32 xmit_idle;
1485 __kernel_time_t32 recv_idle;
1486 };
1487 #define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32)
1488
ppp_ioctl_trans(unsigned int fd,unsigned int cmd,unsigned long arg)1489 static int ppp_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
1490 {
1491 mm_segment_t old_fs = get_fs();
1492 struct ppp_option_data32 data32;
1493 struct ppp_option_data data;
1494 struct ppp_idle32 idle32;
1495 struct ppp_idle idle;
1496 unsigned int kcmd;
1497 void *karg;
1498 int err = 0;
1499
1500 switch (cmd) {
1501 case PPPIOCGIDLE32:
1502 kcmd = PPPIOCGIDLE;
1503 karg = &idle;
1504 break;
1505 case PPPIOCSCOMPRESS32:
1506 if (copy_from_user(&data32, (struct ppp_option_data32 *)arg, sizeof(struct ppp_option_data32)))
1507 return -EFAULT;
1508 if (data32.length > PAGE_SIZE)
1509 return -EINVAL;
1510 data.ptr = kmalloc (data32.length, GFP_KERNEL);
1511 if (!data.ptr)
1512 return -ENOMEM;
1513 if (copy_from_user(data.ptr, (__u8 *)A(data32.ptr), data32.length)) {
1514 kfree(data.ptr);
1515 return -EFAULT;
1516 }
1517 data.length = data32.length;
1518 data.transmit = data32.transmit;
1519 kcmd = PPPIOCSCOMPRESS;
1520 karg = &data;
1521 break;
1522 default:
1523 do {
1524 static int count = 0;
1525 if (++count <= 20)
1526 printk("ppp_ioctl: Unknown cmd fd(%d) "
1527 "cmd(%08x) arg(%08x)\n",
1528 (int)fd, (unsigned int)cmd, (unsigned int)arg);
1529 } while (0);
1530 return -EINVAL;
1531 }
1532 set_fs (KERNEL_DS);
1533 err = sys_ioctl (fd, kcmd, (unsigned long)karg);
1534 set_fs (old_fs);
1535 switch (cmd) {
1536 case PPPIOCGIDLE32:
1537 if (err)
1538 return err;
1539 idle32.xmit_idle = idle.xmit_idle;
1540 idle32.recv_idle = idle.recv_idle;
1541 if (copy_to_user((struct ppp_idle32 *)arg, &idle32, sizeof(struct ppp_idle32)))
1542 return -EFAULT;
1543 break;
1544 case PPPIOCSCOMPRESS32:
1545 kfree(data.ptr);
1546 break;
1547 default:
1548 break;
1549 }
1550 return err;
1551 }
1552
1553
1554 struct mtget32 {
1555 __u32 mt_type;
1556 __u32 mt_resid;
1557 __u32 mt_dsreg;
1558 __u32 mt_gstat;
1559 __u32 mt_erreg;
1560 __kernel_daddr_t32 mt_fileno;
1561 __kernel_daddr_t32 mt_blkno;
1562 };
1563 #define MTIOCGET32 _IOR('m', 2, struct mtget32)
1564
1565 struct mtpos32 {
1566 __u32 mt_blkno;
1567 };
1568 #define MTIOCPOS32 _IOR('m', 3, struct mtpos32)
1569
1570 struct mtconfiginfo32 {
1571 __u32 mt_type;
1572 __u32 ifc_type;
1573 __u16 irqnr;
1574 __u16 dmanr;
1575 __u16 port;
1576 __u32 debug;
1577 __u32 have_dens:1;
1578 __u32 have_bsf:1;
1579 __u32 have_fsr:1;
1580 __u32 have_bsr:1;
1581 __u32 have_eod:1;
1582 __u32 have_seek:1;
1583 __u32 have_tell:1;
1584 __u32 have_ras1:1;
1585 __u32 have_ras2:1;
1586 __u32 have_ras3:1;
1587 __u32 have_qfa:1;
1588 __u32 pad1:5;
1589 char reserved[10];
1590 };
1591 #define MTIOCGETCONFIG32 _IOR('m', 4, struct mtconfiginfo32)
1592 #define MTIOCSETCONFIG32 _IOW('m', 5, struct mtconfiginfo32)
1593
mt_ioctl_trans(unsigned int fd,unsigned int cmd,unsigned long arg)1594 static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
1595 {
1596 mm_segment_t old_fs = get_fs();
1597 struct mtconfiginfo info;
1598 struct mtget get;
1599 struct mtpos pos;
1600 unsigned long kcmd;
1601 void *karg;
1602 int err = 0;
1603
1604 switch(cmd) {
1605 case MTIOCPOS32:
1606 kcmd = MTIOCPOS;
1607 karg = &pos;
1608 break;
1609 case MTIOCGET32:
1610 kcmd = MTIOCGET;
1611 karg = &get;
1612 break;
1613 case MTIOCGETCONFIG32:
1614 kcmd = MTIOCGETCONFIG;
1615 karg = &info;
1616 break;
1617 case MTIOCSETCONFIG32:
1618 kcmd = MTIOCSETCONFIG;
1619 karg = &info;
1620 err = __get_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type);
1621 err |= __get_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type);
1622 err |= __get_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr);
1623 err |= __get_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr);
1624 err |= __get_user(info.port, &((struct mtconfiginfo32 *)arg)->port);
1625 err |= __get_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug);
1626 err |= __copy_from_user((char *)&info.debug + sizeof(info.debug),
1627 (char *)&((struct mtconfiginfo32 *)arg)->debug
1628 + sizeof(((struct mtconfiginfo32 *)arg)->debug), sizeof(__u32));
1629 if (err)
1630 return -EFAULT;
1631 break;
1632 default:
1633 do {
1634 static int count = 0;
1635 if (++count <= 20)
1636 printk("mt_ioctl: Unknown cmd fd(%d) "
1637 "cmd(%08x) arg(%08x)\n",
1638 (int)fd, (unsigned int)cmd, (unsigned int)arg);
1639 } while (0);
1640 return -EINVAL;
1641 }
1642 set_fs (KERNEL_DS);
1643 err = sys_ioctl (fd, kcmd, (unsigned long)karg);
1644 set_fs (old_fs);
1645 if (err)
1646 return err;
1647 switch (cmd) {
1648 case MTIOCPOS32:
1649 err = __put_user(pos.mt_blkno, &((struct mtpos32 *)arg)->mt_blkno);
1650 break;
1651 case MTIOCGET32:
1652 err = __put_user(get.mt_type, &((struct mtget32 *)arg)->mt_type);
1653 err |= __put_user(get.mt_resid, &((struct mtget32 *)arg)->mt_resid);
1654 err |= __put_user(get.mt_dsreg, &((struct mtget32 *)arg)->mt_dsreg);
1655 err |= __put_user(get.mt_gstat, &((struct mtget32 *)arg)->mt_gstat);
1656 err |= __put_user(get.mt_erreg, &((struct mtget32 *)arg)->mt_erreg);
1657 err |= __put_user(get.mt_fileno, &((struct mtget32 *)arg)->mt_fileno);
1658 err |= __put_user(get.mt_blkno, &((struct mtget32 *)arg)->mt_blkno);
1659 break;
1660 case MTIOCGETCONFIG32:
1661 err = __put_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type);
1662 err |= __put_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type);
1663 err |= __put_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr);
1664 err |= __put_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr);
1665 err |= __put_user(info.port, &((struct mtconfiginfo32 *)arg)->port);
1666 err |= __put_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug);
1667 err |= __copy_to_user((char *)&((struct mtconfiginfo32 *)arg)->debug
1668 + sizeof(((struct mtconfiginfo32 *)arg)->debug),
1669 (char *)&info.debug + sizeof(info.debug), sizeof(__u32));
1670 break;
1671 case MTIOCSETCONFIG32:
1672 break;
1673 }
1674 return err ? -EFAULT: 0;
1675 }
1676
1677 struct cdrom_read_audio32 {
1678 union cdrom_addr addr;
1679 u_char addr_format;
1680 int nframes;
1681 __kernel_caddr_t32 buf;
1682 };
1683
1684 struct cdrom_generic_command32 {
1685 unsigned char cmd[CDROM_PACKET_SIZE];
1686 __kernel_caddr_t32 buffer;
1687 unsigned int buflen;
1688 int stat;
1689 __kernel_caddr_t32 sense;
1690 __kernel_caddr_t32 reserved[3];
1691 };
1692
cdrom_ioctl_trans(unsigned int fd,unsigned int cmd,unsigned long arg)1693 static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
1694 {
1695 mm_segment_t old_fs = get_fs();
1696 struct cdrom_read_audio cdreadaudio;
1697 struct cdrom_generic_command cgc;
1698 __kernel_caddr_t32 addr;
1699 char *data = 0;
1700 void *karg;
1701 int err = 0;
1702
1703 switch(cmd) {
1704 case CDROMREADAUDIO:
1705 karg = &cdreadaudio;
1706 err = copy_from_user(&cdreadaudio.addr, &((struct cdrom_read_audio32 *)arg)->addr, sizeof(cdreadaudio.addr));
1707 err |= __get_user(cdreadaudio.addr_format, &((struct cdrom_read_audio32 *)arg)->addr_format);
1708 err |= __get_user(cdreadaudio.nframes, &((struct cdrom_read_audio32 *)arg)->nframes);
1709 err |= __get_user(addr, &((struct cdrom_read_audio32 *)arg)->buf);
1710 if (err)
1711 return -EFAULT;
1712 if (verify_area(VERIFY_WRITE, (void *)A(addr), cdreadaudio.nframes*2352))
1713 return -EFAULT;
1714 cdreadaudio.buf = (void *)A(addr);
1715 break;
1716 case CDROM_SEND_PACKET:
1717 karg = &cgc;
1718 err = copy_from_user(cgc.cmd, &((struct cdrom_generic_command32 *)arg)->cmd, sizeof(cgc.cmd));
1719 err |= __get_user(addr, &((struct cdrom_generic_command32 *)arg)->buffer);
1720 err |= __get_user(cgc.buflen, &((struct cdrom_generic_command32 *)arg)->buflen);
1721 if (err)
1722 return -EFAULT;
1723 if (verify_area(VERIFY_WRITE, (void *)A(addr), cgc.buflen))
1724 return -EFAULT;
1725 cgc.buffer = (void *)A(addr);
1726 break;
1727 default:
1728 do {
1729 static int count = 0;
1730 if (++count <= 20)
1731 printk("cdrom_ioctl: Unknown cmd fd(%d) "
1732 "cmd(%08x) arg(%08x)\n",
1733 (int)fd, (unsigned int)cmd, (unsigned int)arg);
1734 } while (0);
1735 return -EINVAL;
1736 }
1737 set_fs (KERNEL_DS);
1738 err = sys_ioctl (fd, cmd, (unsigned long)karg);
1739 set_fs (old_fs);
1740 out: if (data)
1741 kfree(data);
1742 return err ? -EFAULT : 0;
1743 }
1744
1745 struct loop_info32 {
1746 int lo_number; /* ioctl r/o */
1747 __kernel_dev_t32 lo_device; /* ioctl r/o */
1748 unsigned int lo_inode; /* ioctl r/o */
1749 __kernel_dev_t32 lo_rdevice; /* ioctl r/o */
1750 int lo_offset;
1751 int lo_encrypt_type;
1752 int lo_encrypt_key_size; /* ioctl w/o */
1753 int lo_flags; /* ioctl r/o */
1754 char lo_name[LO_NAME_SIZE];
1755 unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
1756 unsigned int lo_init[2];
1757 char reserved[4];
1758 };
1759
loop_status(unsigned int fd,unsigned int cmd,unsigned long arg)1760 static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg)
1761 {
1762 mm_segment_t old_fs = get_fs();
1763 struct loop_info l;
1764 int err = -EINVAL;
1765
1766 switch(cmd) {
1767 case LOOP_SET_STATUS:
1768 err = get_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number);
1769 err |= __get_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);
1770 err |= __get_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode);
1771 err |= __get_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice);
1772 err |= __copy_from_user((char *)&l.lo_offset, (char *)&((struct loop_info32 *)arg)->lo_offset,
1773 8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
1774 if (err) {
1775 err = -EFAULT;
1776 } else {
1777 set_fs (KERNEL_DS);
1778 err = sys_ioctl (fd, cmd, (unsigned long)&l);
1779 set_fs (old_fs);
1780 }
1781 break;
1782 case LOOP_GET_STATUS:
1783 set_fs (KERNEL_DS);
1784 err = sys_ioctl (fd, cmd, (unsigned long)&l);
1785 set_fs (old_fs);
1786 if (!err) {
1787 err = put_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number);
1788 err |= __put_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);
1789 err |= __put_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode);
1790 err |= __put_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice);
1791 err |= __copy_to_user((char *)&((struct loop_info32 *)arg)->lo_offset,
1792 (char *)&l.lo_offset, (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
1793 if (err)
1794 err = -EFAULT;
1795 }
1796 break;
1797 default: {
1798 static int count = 0;
1799 if (++count <= 20)
1800 printk("%s: Unknown loop ioctl cmd, fd(%d) "
1801 "cmd(%08x) arg(%08lx)\n",
1802 __FUNCTION__, fd, cmd, arg);
1803 }
1804 }
1805 return err;
1806 }
1807
1808 extern int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg);
1809
1810 #ifdef CONFIG_VT
vt_check(struct file * file)1811 static int vt_check(struct file *file)
1812 {
1813 struct tty_struct *tty;
1814 struct inode *inode = file->f_dentry->d_inode;
1815
1816 if (file->f_op->ioctl != tty_ioctl)
1817 return -EINVAL;
1818
1819 tty = (struct tty_struct *)file->private_data;
1820 if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl"))
1821 return -EINVAL;
1822
1823 if (tty->driver.ioctl != vt_ioctl)
1824 return -EINVAL;
1825
1826 /*
1827 * To have permissions to do most of the vt ioctls, we either have
1828 * to be the owner of the tty, or super-user.
1829 */
1830 if (current->tty == tty || suser())
1831 return 1;
1832 return 0;
1833 }
1834
1835 struct consolefontdesc32 {
1836 unsigned short charcount; /* characters in font (256 or 512) */
1837 unsigned short charheight; /* scan lines per character (1-32) */
1838 u32 chardata; /* font data in expanded form */
1839 };
1840
do_fontx_ioctl(unsigned int fd,int cmd,struct consolefontdesc32 * user_cfd,struct file * file)1841 static int do_fontx_ioctl(unsigned int fd, int cmd, struct consolefontdesc32 *user_cfd, struct file *file)
1842 {
1843 struct consolefontdesc cfdarg;
1844 struct console_font_op op;
1845 int i, perm;
1846
1847 perm = vt_check(file);
1848 if (perm < 0) return perm;
1849
1850 if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc32)))
1851 return -EFAULT;
1852
1853 cfdarg.chardata = (unsigned char *)A(((struct consolefontdesc32 *)&cfdarg)->chardata);
1854
1855 switch (cmd) {
1856 case PIO_FONTX:
1857 if (!perm)
1858 return -EPERM;
1859 op.op = KD_FONT_OP_SET;
1860 op.flags = 0;
1861 op.width = 8;
1862 op.height = cfdarg.charheight;
1863 op.charcount = cfdarg.charcount;
1864 op.data = cfdarg.chardata;
1865 return con_font_op(fg_console, &op);
1866 case GIO_FONTX:
1867 if (!cfdarg.chardata)
1868 return 0;
1869 op.op = KD_FONT_OP_GET;
1870 op.flags = 0;
1871 op.width = 8;
1872 op.height = cfdarg.charheight;
1873 op.charcount = cfdarg.charcount;
1874 op.data = cfdarg.chardata;
1875 i = con_font_op(fg_console, &op);
1876 if (i)
1877 return i;
1878 cfdarg.charheight = op.height;
1879 cfdarg.charcount = op.charcount;
1880 ((struct consolefontdesc32 *)&cfdarg)->chardata = (unsigned long)cfdarg.chardata;
1881 if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc32)))
1882 return -EFAULT;
1883 return 0;
1884 }
1885 return -EINVAL;
1886 }
1887
1888 struct console_font_op32 {
1889 unsigned int op; /* operation code KD_FONT_OP_* */
1890 unsigned int flags; /* KD_FONT_FLAG_* */
1891 unsigned int width, height; /* font size */
1892 unsigned int charcount;
1893 u32 data; /* font data with height fixed to 32 */
1894 };
1895
do_kdfontop_ioctl(unsigned int fd,unsigned int cmd,struct console_font_op32 * fontop,struct file * file)1896 static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, struct console_font_op32 *fontop, struct file *file)
1897 {
1898 struct console_font_op op;
1899 int perm = vt_check(file), i;
1900 struct vt_struct *vt;
1901
1902 if (perm < 0) return perm;
1903
1904 if (copy_from_user(&op, (void *) fontop, sizeof(struct console_font_op32)))
1905 return -EFAULT;
1906 if (!perm && op.op != KD_FONT_OP_GET)
1907 return -EPERM;
1908 op.data = (unsigned char *)A(((struct console_font_op32 *)&op)->data);
1909 op.flags |= KD_FONT_FLAG_OLD;
1910 vt = (struct vt_struct *)((struct tty_struct *)file->private_data)->driver_data;
1911 i = con_font_op(vt->vc_num, &op);
1912 if (i) return i;
1913 ((struct console_font_op32 *)&op)->data = (unsigned long)op.data;
1914 if (copy_to_user((void *) fontop, &op, sizeof(struct console_font_op32)))
1915 return -EFAULT;
1916 return 0;
1917 }
1918
1919 struct fb_fix_screeninfo32 {
1920 char id[16]; /* identification string eg "TT Builtin" */
1921 unsigned int smem_start; /* Start of frame buffer mem */
1922 /* (physical address) */
1923 __u32 smem_len; /* Length of frame buffer mem */
1924 __u32 type; /* see FB_TYPE_* */
1925 __u32 type_aux; /* Interleave for interleaved Planes */
1926 __u32 visual; /* see FB_VISUAL_* */
1927 __u16 xpanstep; /* zero if no hardware panning */
1928 __u16 ypanstep; /* zero if no hardware panning */
1929 __u16 ywrapstep; /* zero if no hardware ywrap */
1930 __u32 line_length; /* length of a line in bytes */
1931 unsigned int mmio_start; /* Start of Memory Mapped I/O */
1932 /* (physical address) */
1933 __u32 mmio_len; /* Length of Memory Mapped I/O */
1934 __u32 accel; /* Type of acceleration available */
1935 __u16 reserved[3]; /* Reserved for future compatibility */
1936 };
1937
do_fbioget_fscreeninfo_ioctl(unsigned int fd,unsigned int cmd,unsigned long arg)1938 static int do_fbioget_fscreeninfo_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
1939 {
1940 mm_segment_t old_fs = get_fs();
1941 struct fb_fix_screeninfo fix;
1942 int err;
1943
1944 set_fs(KERNEL_DS);
1945 err = sys_ioctl(fd, cmd, (long)&fix);
1946 set_fs(old_fs);
1947
1948 if (err == 0) {
1949 unsigned int smem_start = fix.smem_start; /* lose top 32 bits */
1950 unsigned int mmio_start = fix.mmio_start; /* lose top 32 bits */
1951 int i;
1952
1953 err = put_user(fix.id[0], &((struct fb_fix_screeninfo32 *)arg)->id[0]);
1954 for (i=1; i<16; i++) {
1955 err |= __put_user(fix.id[i], &((struct fb_fix_screeninfo32 *)arg)->id[i]);
1956 }
1957 err |= __put_user(smem_start, &((struct fb_fix_screeninfo32 *)arg)->smem_start);
1958 err |= __put_user(fix.smem_len, &((struct fb_fix_screeninfo32 *)arg)->smem_len);
1959 err |= __put_user(fix.type, &((struct fb_fix_screeninfo32 *)arg)->type);
1960 err |= __put_user(fix.type_aux, &((struct fb_fix_screeninfo32 *)arg)->type_aux);
1961 err |= __put_user(fix.visual, &((struct fb_fix_screeninfo32 *)arg)->visual);
1962 err |= __put_user(fix.xpanstep, &((struct fb_fix_screeninfo32 *)arg)->xpanstep);
1963 err |= __put_user(fix.ypanstep, &((struct fb_fix_screeninfo32 *)arg)->ypanstep);
1964 err |= __put_user(fix.ywrapstep, &((struct fb_fix_screeninfo32 *)arg)->ywrapstep);
1965 err |= __put_user(fix.line_length, &((struct fb_fix_screeninfo32 *)arg)->line_length);
1966 err |= __put_user(mmio_start, &((struct fb_fix_screeninfo32 *)arg)->mmio_start);
1967 err |= __put_user(fix.mmio_len, &((struct fb_fix_screeninfo32 *)arg)->mmio_len);
1968 err |= __put_user(fix.accel, &((struct fb_fix_screeninfo32 *)arg)->accel);
1969 err |= __put_user(fix.reserved[0], &((struct fb_fix_screeninfo32 *)arg)->reserved[0]);
1970 err |= __put_user(fix.reserved[1], &((struct fb_fix_screeninfo32 *)arg)->reserved[1]);
1971 err |= __put_user(fix.reserved[2], &((struct fb_fix_screeninfo32 *)arg)->reserved[2]);
1972 if (err)
1973 err = -EFAULT;
1974 }
1975 return err;
1976 }
1977
1978 struct fb_cmap32 {
1979 __u32 start; /* First entry */
1980 __u32 len; /* Number of entries */
1981 __u32 redptr; /* Red values */
1982 __u32 greenptr;
1983 __u32 blueptr;
1984 __u32 transpptr; /* transparency, can be NULL */
1985 };
1986
do_fbiogetcmap_ioctl(unsigned int fd,unsigned int cmd,unsigned long arg)1987 static int do_fbiogetcmap_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
1988 {
1989 mm_segment_t old_fs = get_fs();
1990 struct fb_cmap cmap;
1991 int err;
1992
1993 set_fs(KERNEL_DS);
1994 err = sys_ioctl(fd, cmd, (long)&cmap);
1995 set_fs(old_fs);
1996
1997 if (err == 0) {
1998 __u32 redptr = (__u32)(__u64)cmap.red;
1999 __u32 greenptr = (__u32)(__u64)cmap.green;
2000 __u32 blueptr = (__u32)(__u64)cmap.blue;
2001 __u32 transpptr = (__u32)(__u64)cmap.transp;
2002
2003 err = put_user(cmap.start, &((struct fb_cmap32 *)arg)->start);
2004 err |= __put_user(cmap.len, &((struct fb_cmap32 *)arg)->len);
2005 err |= __put_user(redptr, &((struct fb_cmap32 *)arg)->redptr);
2006 err |= __put_user(greenptr, &((struct fb_cmap32 *)arg)->greenptr);
2007 err |= __put_user(blueptr, &((struct fb_cmap32 *)arg)->blueptr);
2008 err |= __put_user(transpptr, &((struct fb_cmap32 *)arg)->transpptr);
2009 if (err)
2010 err = -EFAULT;
2011 }
2012 return err;
2013 }
2014
do_fbioputcmap_ioctl(unsigned int fd,unsigned int cmd,unsigned long arg)2015 static int do_fbioputcmap_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
2016 {
2017 mm_segment_t old_fs = get_fs();
2018 struct fb_cmap cmap;
2019 __u32 redptr, greenptr, blueptr, transpptr;
2020 int err;
2021
2022 err = get_user(cmap.start, &((struct fb_cmap32 *)arg)->start);
2023 err |= __get_user(cmap.len, &((struct fb_cmap32 *)arg)->len);
2024 err |= __get_user(redptr, &((struct fb_cmap32 *)arg)->redptr);
2025 err |= __get_user(greenptr, &((struct fb_cmap32 *)arg)->greenptr);
2026 err |= __get_user(blueptr, &((struct fb_cmap32 *)arg)->blueptr);
2027 err |= __get_user(transpptr, &((struct fb_cmap32 *)arg)->transpptr);
2028
2029 if (err) {
2030 err = -EFAULT;
2031 } else {
2032 cmap.red = (__u16 *)(__u64)redptr;
2033 cmap.green = (__u16 *)(__u64)greenptr;
2034 cmap.blue = (__u16 *)(__u64)blueptr;
2035 cmap.transp = (__u16 *)(__u64)transpptr;
2036 set_fs (KERNEL_DS);
2037 err = sys_ioctl (fd, cmd, (unsigned long)&cmap);
2038 set_fs (old_fs);
2039 }
2040 return err;
2041 }
2042
2043 struct unimapdesc32 {
2044 unsigned short entry_ct;
2045 u32 entries;
2046 };
2047
do_unimap_ioctl(unsigned int fd,unsigned int cmd,struct unimapdesc32 * user_ud,struct file * file)2048 static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, struct unimapdesc32 *user_ud, struct file *file)
2049 {
2050 struct unimapdesc32 tmp;
2051 int perm = vt_check(file);
2052
2053 if (perm < 0) return perm;
2054 if (copy_from_user(&tmp, user_ud, sizeof tmp))
2055 return -EFAULT;
2056 switch (cmd) {
2057 case PIO_UNIMAP:
2058 if (!perm) return -EPERM;
2059 return con_set_unimap(fg_console, tmp.entry_ct, (struct unipair *)A(tmp.entries));
2060 case GIO_UNIMAP:
2061 return con_get_unimap(fg_console, tmp.entry_ct, &(user_ud->entry_ct), (struct unipair *)A(tmp.entries));
2062 }
2063 return 0;
2064 }
2065 #endif /* CONFIG_VT */
do_smb_getmountuid(unsigned int fd,unsigned int cmd,unsigned long arg)2066 static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long arg)
2067 {
2068 mm_segment_t old_fs = get_fs();
2069 __kernel_uid_t kuid;
2070 int err;
2071
2072 cmd = SMB_IOC_GETMOUNTUID;
2073
2074 set_fs(KERNEL_DS);
2075 err = sys_ioctl(fd, cmd, (unsigned long)&kuid);
2076 set_fs(old_fs);
2077
2078 if (err >= 0)
2079 err = put_user(kuid, (__kernel_uid_t32 *)arg);
2080
2081 return err;
2082 }
2083
2084 struct atmif_sioc32 {
2085 int number;
2086 int length;
2087 __kernel_caddr_t32 arg;
2088 };
2089
2090 struct atm_iobuf32 {
2091 int length;
2092 __kernel_caddr_t32 buffer;
2093 };
2094
2095 #define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct atmif_sioc32)
2096 #define ATM_GETNAMES32 _IOW('a', ATMIOC_ITF+3, struct atm_iobuf32)
2097 #define ATM_GETTYPE32 _IOW('a', ATMIOC_ITF+4, struct atmif_sioc32)
2098 #define ATM_GETESI32 _IOW('a', ATMIOC_ITF+5, struct atmif_sioc32)
2099 #define ATM_GETADDR32 _IOW('a', ATMIOC_ITF+6, struct atmif_sioc32)
2100 #define ATM_RSTADDR32 _IOW('a', ATMIOC_ITF+7, struct atmif_sioc32)
2101 #define ATM_ADDADDR32 _IOW('a', ATMIOC_ITF+8, struct atmif_sioc32)
2102 #define ATM_DELADDR32 _IOW('a', ATMIOC_ITF+9, struct atmif_sioc32)
2103 #define ATM_GETCIRANGE32 _IOW('a', ATMIOC_ITF+10, struct atmif_sioc32)
2104 #define ATM_SETCIRANGE32 _IOW('a', ATMIOC_ITF+11, struct atmif_sioc32)
2105 #define ATM_SETESI32 _IOW('a', ATMIOC_ITF+12, struct atmif_sioc32)
2106 #define ATM_SETESIF32 _IOW('a', ATMIOC_ITF+13, struct atmif_sioc32)
2107 #define ATM_GETSTAT32 _IOW('a', ATMIOC_SARCOM+0, struct atmif_sioc32)
2108 #define ATM_GETSTATZ32 _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32)
2109 #define ATM_GETLOOP32 _IOW('a', ATMIOC_SARCOM+2, struct atmif_sioc32)
2110 #define ATM_SETLOOP32 _IOW('a', ATMIOC_SARCOM+3, struct atmif_sioc32)
2111 #define ATM_QUERYLOOP32 _IOW('a', ATMIOC_SARCOM+4, struct atmif_sioc32)
2112
2113 static struct {
2114 unsigned int cmd32;
2115 unsigned int cmd;
2116 } atm_ioctl_map[] = {
2117 { ATM_GETLINKRATE32, ATM_GETLINKRATE },
2118 { ATM_GETNAMES32, ATM_GETNAMES },
2119 { ATM_GETTYPE32, ATM_GETTYPE },
2120 { ATM_GETESI32, ATM_GETESI },
2121 { ATM_GETADDR32, ATM_GETADDR },
2122 { ATM_RSTADDR32, ATM_RSTADDR },
2123 { ATM_ADDADDR32, ATM_ADDADDR },
2124 { ATM_DELADDR32, ATM_DELADDR },
2125 { ATM_GETCIRANGE32, ATM_GETCIRANGE },
2126 { ATM_SETCIRANGE32, ATM_SETCIRANGE },
2127 { ATM_SETESI32, ATM_SETESI },
2128 { ATM_SETESIF32, ATM_SETESIF },
2129 { ATM_GETSTAT32, ATM_GETSTAT },
2130 { ATM_GETSTATZ32, ATM_GETSTATZ },
2131 { ATM_GETLOOP32, ATM_GETLOOP },
2132 { ATM_SETLOOP32, ATM_SETLOOP },
2133 { ATM_QUERYLOOP32, ATM_QUERYLOOP }
2134 };
2135
2136 #define NR_ATM_IOCTL (sizeof(atm_ioctl_map)/sizeof(atm_ioctl_map[0]))
2137
2138
do_atm_iobuf(unsigned int fd,unsigned int cmd,unsigned long arg)2139 static int do_atm_iobuf(unsigned int fd, unsigned int cmd, unsigned long arg)
2140 {
2141 struct atm_iobuf32 iobuf32;
2142 struct atm_iobuf iobuf = { 0, NULL };
2143 mm_segment_t old_fs;
2144 int err;
2145
2146 err = copy_from_user(&iobuf32, (struct atm_iobuf32*)arg,
2147 sizeof(struct atm_iobuf32));
2148 if (err)
2149 return -EFAULT;
2150
2151 iobuf.length = iobuf32.length;
2152
2153 if (iobuf32.buffer == (__kernel_caddr_t32) NULL || iobuf32.length == 0) {
2154 iobuf.buffer = (void*)(unsigned long)iobuf32.buffer;
2155 } else {
2156 iobuf.buffer = A(iobuf32.buffer);
2157 if (verify_area(VERIFY_WRITE, iobuf.buffer, iobuf.length))
2158 return -EINVAL;
2159 }
2160
2161 old_fs = get_fs(); set_fs (KERNEL_DS);
2162 err = sys_ioctl (fd, cmd, (unsigned long)&iobuf);
2163 set_fs (old_fs);
2164 if (!err)
2165 err = __put_user(iobuf.length, &(((struct atm_iobuf32*)arg)->length));
2166
2167 return err;
2168 }
2169
2170
do_atmif_sioc(unsigned int fd,unsigned int cmd,unsigned long arg)2171 static int do_atmif_sioc(unsigned int fd, unsigned int cmd, unsigned long arg)
2172 {
2173 struct atmif_sioc32 sioc32;
2174 struct atmif_sioc sioc = { 0, 0, NULL };
2175 mm_segment_t old_fs;
2176 int err;
2177
2178 err = copy_from_user(&sioc32, (struct atmif_sioc32*)arg,
2179 sizeof(struct atmif_sioc32));
2180 if (err)
2181 return -EFAULT;
2182
2183 sioc.number = sioc32.number;
2184 sioc.length = sioc32.length;
2185
2186 if (sioc32.arg == (__kernel_caddr_t32) NULL || sioc32.length == 0) {
2187 sioc.arg = (void*)(unsigned long)sioc32.arg;
2188 } else {
2189 sioc.arg = A(sioc32.arg);
2190 if (verify_area(VERIFY_WRITE, sioc.arg, sioc32.length))
2191 return -EFAULT;
2192 }
2193
2194 old_fs = get_fs(); set_fs (KERNEL_DS);
2195 err = sys_ioctl (fd, cmd, (unsigned long)&sioc);
2196 set_fs (old_fs);
2197
2198 if (!err)
2199 err = __put_user(sioc.length, &(((struct atmif_sioc32*)arg)->length));
2200
2201 return err;
2202 }
2203
2204
do_atm_ioctl(unsigned int fd,unsigned int cmd32,unsigned long arg)2205 static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg)
2206 {
2207 int i;
2208 unsigned int cmd = 0;
2209
2210 switch (cmd32) {
2211 case SONET_GETSTAT:
2212 case SONET_GETSTATZ:
2213 case SONET_GETDIAG:
2214 case SONET_SETDIAG:
2215 case SONET_CLRDIAG:
2216 case SONET_SETFRAMING:
2217 case SONET_GETFRAMING:
2218 case SONET_GETFRSENSE:
2219 return do_atmif_sioc(fd, cmd32, arg);
2220 }
2221
2222 for (i = 0; i < NR_ATM_IOCTL; i++) {
2223 if (cmd32 == atm_ioctl_map[i].cmd32) {
2224 cmd = atm_ioctl_map[i].cmd;
2225 break;
2226 }
2227 }
2228 if (i == NR_ATM_IOCTL) {
2229 return -EINVAL;
2230 }
2231
2232 switch (cmd) {
2233 case ATM_GETNAMES:
2234 return do_atm_iobuf(fd, cmd, arg);
2235
2236 case ATM_GETLINKRATE:
2237 case ATM_GETTYPE:
2238 case ATM_GETESI:
2239 case ATM_GETADDR:
2240 case ATM_RSTADDR:
2241 case ATM_ADDADDR:
2242 case ATM_DELADDR:
2243 case ATM_GETCIRANGE:
2244 case ATM_SETCIRANGE:
2245 case ATM_SETESI:
2246 case ATM_SETESIF:
2247 case ATM_GETSTAT:
2248 case ATM_GETSTATZ:
2249 case ATM_GETLOOP:
2250 case ATM_SETLOOP:
2251 case ATM_QUERYLOOP:
2252 return do_atmif_sioc(fd, cmd, arg);
2253 }
2254
2255 return -EINVAL;
2256 }
2257
2258 #if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
2259 /* Ugh, LVM. Pitty it was not cleaned up before accepted :((. */
2260 typedef struct {
2261 uint8_t vg_name[NAME_LEN];
2262 uint32_t vg_number;
2263 uint32_t vg_access;
2264 uint32_t vg_status;
2265 uint32_t lv_max;
2266 uint32_t lv_cur;
2267 uint32_t lv_open;
2268 uint32_t pv_max;
2269 uint32_t pv_cur;
2270 uint32_t pv_act;
2271 uint32_t dummy;
2272 uint32_t vgda;
2273 uint32_t pe_size;
2274 uint32_t pe_total;
2275 uint32_t pe_allocated;
2276 uint32_t pvg_total;
2277 u32 proc;
2278 u32 pv[ABS_MAX_PV + 1];
2279 u32 lv[ABS_MAX_LV + 1];
2280 uint8_t vg_uuid[UUID_LEN+1]; /* volume group UUID */
2281 uint8_t dummy1[200];
2282 } vg32_t;
2283
2284 typedef struct {
2285 uint8_t id[2];
2286 uint16_t version;
2287 lvm_disk_data_t pv_on_disk;
2288 lvm_disk_data_t vg_on_disk;
2289 lvm_disk_data_t pv_namelist_on_disk;
2290 lvm_disk_data_t lv_on_disk;
2291 lvm_disk_data_t pe_on_disk;
2292 uint8_t pv_name[NAME_LEN];
2293 uint8_t vg_name[NAME_LEN];
2294 uint8_t system_id[NAME_LEN];
2295 kdev_t pv_dev;
2296 uint32_t pv_number;
2297 uint32_t pv_status;
2298 uint32_t pv_allocatable;
2299 uint32_t pv_size;
2300 uint32_t lv_cur;
2301 uint32_t pe_size;
2302 uint32_t pe_total;
2303 uint32_t pe_allocated;
2304 uint32_t pe_stale;
2305 u32 pe;
2306 u32 inode;
2307 uint8_t pv_uuid[UUID_LEN+1];
2308 } pv32_t;
2309
2310 typedef struct {
2311 char lv_name[NAME_LEN];
2312 u32 lv;
2313 } lv_req32_t;
2314
2315 typedef struct {
2316 u32 lv_index;
2317 u32 lv;
2318 /* Transfer size because user space and kernel space differ */
2319 uint16_t size;
2320 } lv_status_byindex_req32_t;
2321
2322 typedef struct {
2323 __kernel_dev_t32 dev;
2324 u32 lv;
2325 } lv_status_bydev_req32_t;
2326
2327 typedef struct {
2328 uint8_t lv_name[NAME_LEN];
2329 kdev_t old_dev;
2330 kdev_t new_dev;
2331 u32 old_pe;
2332 u32 new_pe;
2333 } le_remap_req32_t;
2334
2335 typedef struct {
2336 char pv_name[NAME_LEN];
2337 u32 pv;
2338 } pv_status_req32_t;
2339
2340 typedef struct {
2341 uint8_t lv_name[NAME_LEN];
2342 uint8_t vg_name[NAME_LEN];
2343 uint32_t lv_access;
2344 uint32_t lv_status;
2345 uint32_t lv_open;
2346 kdev_t lv_dev;
2347 uint32_t lv_number;
2348 uint32_t lv_mirror_copies;
2349 uint32_t lv_recovery;
2350 uint32_t lv_schedule;
2351 uint32_t lv_size;
2352 u32 lv_current_pe;
2353 uint32_t lv_current_le;
2354 uint32_t lv_allocated_le;
2355 uint32_t lv_stripes;
2356 uint32_t lv_stripesize;
2357 uint32_t lv_badblock;
2358 uint32_t lv_allocation;
2359 uint32_t lv_io_timeout;
2360 uint32_t lv_read_ahead;
2361 /* delta to version 1 starts here */
2362 u32 lv_snapshot_org;
2363 u32 lv_snapshot_prev;
2364 u32 lv_snapshot_next;
2365 u32 lv_block_exception;
2366 uint32_t lv_remap_ptr;
2367 uint32_t lv_remap_end;
2368 uint32_t lv_chunk_size;
2369 uint32_t lv_snapshot_minor;
2370 char dummy[200];
2371 } lv32_t;
2372
2373 typedef struct {
2374 u32 hash[2];
2375 u32 rsector_org;
2376 kdev_t rdev_org;
2377 u32 rsector_new;
2378 kdev_t rdev_new;
2379 } lv_block_exception32_t;
2380
put_lv_t(lv_t * l)2381 static void put_lv_t(lv_t *l)
2382 {
2383 if (l->lv_current_pe) vfree(l->lv_current_pe);
2384 if (l->lv_block_exception) vfree(l->lv_block_exception);
2385 kfree(l);
2386 }
2387
get_lv_t(u32 p,int * errp)2388 static lv_t *get_lv_t(u32 p, int *errp)
2389 {
2390 int err, i;
2391 u32 ptr1, ptr2;
2392 size_t size;
2393 lv_block_exception32_t *lbe32;
2394 lv_block_exception_t *lbe;
2395 lv32_t *ul = (lv32_t *)A(p);
2396 lv_t *l = (lv_t *) kmalloc(sizeof(lv_t), GFP_KERNEL);
2397
2398 if (!l) {
2399 *errp = -ENOMEM;
2400 return NULL;
2401 }
2402 memset(l, 0, sizeof(lv_t));
2403 err = copy_from_user(l, ul, (long)&((lv32_t *)0)->lv_current_pe);
2404 err |= __copy_from_user(&l->lv_current_le, &ul->lv_current_le,
2405 ((long)&ul->lv_snapshot_org) - ((long)&ul->lv_current_le));
2406 err |= __copy_from_user(&l->lv_remap_ptr, &ul->lv_remap_ptr,
2407 ((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr));
2408 err |= __get_user(ptr1, &ul->lv_current_pe);
2409 err |= __get_user(ptr2, &ul->lv_block_exception);
2410 if (err) {
2411 kfree(l);
2412 *errp = -EFAULT;
2413 return NULL;
2414 }
2415 if (ptr1) {
2416 if (l->lv_allocated_le > 2*PAGE_SIZE/sizeof(pe_t)) {
2417 kfree(l);
2418 *errp = -EINVAL;
2419 return NULL;
2420 }
2421 size = l->lv_allocated_le * sizeof(pe_t);
2422 l->lv_current_pe = vmalloc(size);
2423 if (l->lv_current_pe)
2424 err = copy_from_user(l->lv_current_pe, (void *)A(ptr1), size);
2425 }
2426 if (!err && ptr2) {
2427 /* small limit */
2428 /* just verify area it? */
2429 if (l->lv_remap_end > 256*PAGE_SIZE/sizeof(lv_block_exception_t)) {
2430 put_lv_t(l);
2431 *errp = -EINVAL;
2432 return NULL;
2433 }
2434 size = l->lv_remap_end * sizeof(lv_block_exception_t);
2435 l->lv_block_exception = lbe = vmalloc(size);
2436 if (l->lv_block_exception) {
2437 lbe32 = (lv_block_exception32_t *)A(ptr2);
2438 memset(lbe, 0, size);
2439 for (i = 0; i < l->lv_remap_end; i++, lbe++, lbe32++) {
2440 err |= get_user(lbe->rsector_org, &lbe32->rsector_org);
2441 err |= __get_user(lbe->rdev_org, &lbe32->rdev_org);
2442 err |= __get_user(lbe->rsector_new, &lbe32->rsector_new);
2443 err |= __get_user(lbe->rdev_new, &lbe32->rdev_new);
2444 }
2445 }
2446 }
2447 if (err || (ptr1 && !l->lv_current_pe) || (ptr2 && !l->lv_block_exception)) {
2448 if (!err)
2449 *errp = -ENOMEM;
2450 else
2451 *errp = -EFAULT;
2452 put_lv_t(l);
2453 return NULL;
2454 }
2455 return l;
2456 }
2457
copy_lv_t(u32 ptr,lv_t * l)2458 static int copy_lv_t(u32 ptr, lv_t *l)
2459 {
2460 int err;
2461 lv32_t *ul = (lv32_t *)A(ptr);
2462 u32 ptr1;
2463 size_t size;
2464
2465 err = get_user(ptr1, &ul->lv_current_pe);
2466 if (err)
2467 return -EFAULT;
2468 err = copy_to_user(ul, l, (long)&((lv32_t *)0)->lv_current_pe);
2469 err |= __copy_to_user(&ul->lv_current_le, &l->lv_current_le,
2470 ((long)&ul->lv_snapshot_org) - ((long)&ul->lv_current_le));
2471 err |= __copy_to_user(&ul->lv_remap_ptr, &l->lv_remap_ptr,
2472 ((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr));
2473 size = l->lv_allocated_le * sizeof(pe_t);
2474 if (ptr1)
2475 err |= __copy_to_user((void *)A(ptr1), l->lv_current_pe, size);
2476 return err ? -EFAULT : 0;
2477 }
2478
do_lvm_ioctl(unsigned int fd,unsigned int cmd,unsigned long arg)2479 static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
2480 {
2481 vg_t *v = NULL;
2482 union {
2483 lv_req_t lv_req;
2484 le_remap_req_t le_remap;
2485 lv_status_byindex_req_t lv_byindex;
2486 lv_status_bydev_req_t lv_bydev;
2487 pv_status_req_t pv_status;
2488 } u;
2489 pv_t p;
2490 int err;
2491 u32 ptr = 0;
2492 int i;
2493 mm_segment_t old_fs;
2494 void *karg = &u;
2495
2496 switch (cmd) {
2497 case VG_STATUS:
2498 v = kmalloc(sizeof(vg_t), GFP_KERNEL);
2499 if (!v)
2500 return -ENOMEM;
2501 karg = v;
2502 break;
2503
2504 case VG_CREATE_OLD:
2505 case VG_CREATE:
2506 v = kmalloc(sizeof(vg_t), GFP_KERNEL);
2507 if (!v)
2508 return -ENOMEM;
2509 if (copy_from_user(v, (void *)arg, (long)&((vg32_t *)0)->proc)) {
2510 kfree(v);
2511 return -EFAULT;
2512 }
2513 /* 'proc' field is unused, just NULL it out. */
2514 v->proc = NULL;
2515 if (copy_from_user(v->vg_uuid, ((vg32_t *)arg)->vg_uuid, UUID_LEN+1)) {
2516 kfree(v);
2517 return -EFAULT;
2518 }
2519
2520 karg = v;
2521 memset(v->pv, 0, sizeof(v->pv) + sizeof(v->lv));
2522 if (v->pv_max > ABS_MAX_PV || v->lv_max > ABS_MAX_LV)
2523 return -EPERM;
2524 for (i = 0; i < v->pv_max; i++) {
2525 err = __get_user(ptr, &((vg32_t *)arg)->pv[i]);
2526 if (err)
2527 break;
2528 if (ptr) {
2529 v->pv[i] = kmalloc(sizeof(pv_t), GFP_KERNEL);
2530 if (!v->pv[i]) {
2531 err = -ENOMEM;
2532 break;
2533 }
2534 err = copy_from_user(v->pv[i], (void *)A(ptr),
2535 sizeof(pv32_t) - 8 - UUID_LEN+1);
2536 if (err) {
2537 err = -EFAULT;
2538 break;
2539 }
2540 err = copy_from_user(v->pv[i]->pv_uuid,
2541 ((pv32_t *)A(ptr))->pv_uuid,
2542 UUID_LEN+1);
2543 if (err) {
2544 err = -EFAULT;
2545 break;
2546 }
2547
2548 v->pv[i]->pe = NULL;
2549 v->pv[i]->bd = NULL;
2550 }
2551 }
2552 if (!err) {
2553 for (i = 0; i < v->lv_max; i++) {
2554 err = __get_user(ptr, &((vg32_t *)arg)->lv[i]);
2555 if (err)
2556 break;
2557 if (ptr) {
2558 v->lv[i] = get_lv_t(ptr, &err);
2559 if (err)
2560 break;
2561 }
2562 }
2563 }
2564 break;
2565
2566 case LV_CREATE:
2567 case LV_EXTEND:
2568 case LV_REDUCE:
2569 case LV_REMOVE:
2570 case LV_RENAME:
2571 case LV_STATUS_BYNAME:
2572 err = copy_from_user(&u.pv_status, arg, sizeof(u.pv_status.pv_name));
2573 if (err)
2574 return -EFAULT;
2575 if (cmd != LV_REMOVE) {
2576 err = __get_user(ptr, &((lv_req32_t *)arg)->lv);
2577 if (err)
2578 return err;
2579 u.lv_req.lv = get_lv_t(ptr, &err);
2580 } else
2581 u.lv_req.lv = NULL;
2582 break;
2583
2584 case LV_STATUS_BYINDEX:
2585 err = get_user(u.lv_byindex.lv_index,
2586 &((lv_status_byindex_req32_t *)arg)->lv_index);
2587 err |= __get_user(ptr, &((lv_status_byindex_req32_t *)arg)->lv);
2588 if (err)
2589 return err;
2590 u.lv_byindex.lv = get_lv_t(ptr, &err);
2591 break;
2592
2593 case LV_STATUS_BYDEV:
2594 err = get_user(u.lv_bydev.dev, &((lv_status_bydev_req32_t *)arg)->dev);
2595 err |= __get_user(ptr, &((lv_status_bydev_req32_t *)arg)->lv);
2596 if (err)
2597 return err;
2598 u.lv_bydev.lv = get_lv_t(ptr, &err);
2599 break;
2600
2601 case VG_EXTEND:
2602 err = copy_from_user(&p, (void *)arg, sizeof(pv32_t) - 8 - UUID_LEN+1);
2603 if (err)
2604 return -EFAULT;
2605 err = copy_from_user(p.pv_uuid, ((pv32_t *)arg)->pv_uuid, UUID_LEN+1);
2606 if (err)
2607 return -EFAULT;
2608 p.pe = NULL;
2609 p.bd = NULL;
2610 karg = &p;
2611 break;
2612
2613 case PV_CHANGE:
2614 case PV_STATUS:
2615 err = copy_from_user(&u.pv_status, arg, sizeof(u.lv_req.lv_name));
2616 if (err)
2617 return -EFAULT;
2618 err = __get_user(ptr, &((pv_status_req32_t *)arg)->pv);
2619 if (err)
2620 return err;
2621 u.pv_status.pv = &p;
2622 if (cmd == PV_CHANGE) {
2623 err = copy_from_user(&p, (void *)A(ptr),
2624 sizeof(pv32_t) - 8 - UUID_LEN+1);
2625 if (err)
2626 return -EFAULT;
2627 p.pe = NULL;
2628 p.bd = NULL;
2629 }
2630 break;
2631 };
2632
2633 old_fs = get_fs(); set_fs (KERNEL_DS);
2634 err = sys_ioctl (fd, cmd, (unsigned long)karg);
2635 set_fs (old_fs);
2636
2637 switch (cmd) {
2638 case VG_STATUS:
2639 if (!err) {
2640 if (copy_to_user((void *)arg, v, (long)&((vg32_t *)0)->proc) ||
2641 clear_user(&((vg32_t *)arg)->proc, sizeof(vg32_t) - (long)&((vg32_t *)0)->proc))
2642 err = -EFAULT;
2643 }
2644 if (copy_to_user(((vg32_t *)arg)->vg_uuid, v->vg_uuid, UUID_LEN+1)) {
2645 err = -EFAULT;
2646 }
2647 kfree(v);
2648 break;
2649
2650 case VG_CREATE_OLD:
2651 case VG_CREATE:
2652 for (i = 0; i < v->pv_max; i++) {
2653 if (v->pv[i])
2654 kfree(v->pv[i]);
2655 }
2656 for (i = 0; i < v->lv_max; i++) {
2657 if (v->lv[i])
2658 put_lv_t(v->lv[i]);
2659 }
2660 kfree(v);
2661 break;
2662
2663 case LV_STATUS_BYNAME:
2664 if (!err && u.lv_req.lv)
2665 err = copy_lv_t(ptr, u.lv_req.lv);
2666 /* Fall through */
2667
2668 case LV_CREATE:
2669 case LV_EXTEND:
2670 case LV_REDUCE:
2671 if (u.lv_req.lv)
2672 put_lv_t(u.lv_req.lv);
2673 break;
2674
2675 case LV_STATUS_BYINDEX:
2676 if (u.lv_byindex.lv) {
2677 if (!err)
2678 err = copy_lv_t(ptr, u.lv_byindex.lv);
2679 put_lv_t(u.lv_byindex.lv);
2680 }
2681 break;
2682
2683 case LV_STATUS_BYDEV:
2684 if (u.lv_bydev.lv) {
2685 if (!err)
2686 err = copy_lv_t(ptr, u.lv_bydev.lv);
2687 put_lv_t(u.lv_byindex.lv);
2688 }
2689 break;
2690
2691 case PV_STATUS:
2692 if (!err) {
2693 err = copy_to_user((void *)A(ptr), &p, sizeof(pv32_t) - 8 - UUID_LEN+1);
2694 if (err)
2695 return -EFAULT;
2696 err = copy_to_user(((pv_t *)A(ptr))->pv_uuid, p.pv_uuid, UUID_LEN + 1);
2697 if (err)
2698 return -EFAULT;
2699 }
2700 break;
2701 };
2702
2703 return err;
2704 }
2705 #endif
2706
2707 #if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
2708 /* This really belongs in include/linux/drm.h -DaveM */
2709 #include "../../../drivers/char/drm/drm.h"
2710
2711 typedef struct drm32_version {
2712 int version_major; /* Major version */
2713 int version_minor; /* Minor version */
2714 int version_patchlevel;/* Patch level */
2715 int name_len; /* Length of name buffer */
2716 u32 name; /* Name of driver */
2717 int date_len; /* Length of date buffer */
2718 u32 date; /* User-space buffer to hold date */
2719 int desc_len; /* Length of desc buffer */
2720 u32 desc; /* User-space buffer to hold desc */
2721 } drm32_version_t;
2722 #define DRM32_IOCTL_VERSION DRM_IOWR(0x00, drm32_version_t)
2723
drm32_version(unsigned int fd,unsigned int cmd,unsigned long arg)2724 static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg)
2725 {
2726 drm32_version_t *uversion = (drm32_version_t *)arg;
2727 char *name_ptr, *date_ptr, *desc_ptr;
2728 u32 tmp1, tmp2, tmp3;
2729 drm_version_t kversion;
2730 mm_segment_t old_fs;
2731 int ret;
2732
2733 memset(&kversion, 0, sizeof(kversion));
2734 if (get_user(kversion.name_len, &uversion->name_len) ||
2735 get_user(kversion.date_len, &uversion->date_len) ||
2736 get_user(kversion.desc_len, &uversion->desc_len) ||
2737 get_user(tmp1, &uversion->name) ||
2738 get_user(tmp2, &uversion->date) ||
2739 get_user(tmp3, &uversion->desc))
2740 return -EFAULT;
2741
2742 name_ptr = (char *) A(tmp1);
2743 date_ptr = (char *) A(tmp2);
2744 desc_ptr = (char *) A(tmp3);
2745
2746 ret = -ENOMEM;
2747 if (kversion.name_len && name_ptr) {
2748 kversion.name = kmalloc(kversion.name_len, GFP_KERNEL);
2749 if (!kversion.name)
2750 goto out;
2751 }
2752 if (kversion.date_len && date_ptr) {
2753 kversion.date = kmalloc(kversion.date_len, GFP_KERNEL);
2754 if (!kversion.date)
2755 goto out;
2756 }
2757 if (kversion.desc_len && desc_ptr) {
2758 kversion.desc = kmalloc(kversion.desc_len, GFP_KERNEL);
2759 if (!kversion.desc)
2760 goto out;
2761 }
2762
2763 old_fs = get_fs();
2764 set_fs(KERNEL_DS);
2765 ret = sys_ioctl (fd, DRM_IOCTL_VERSION, (unsigned long)&kversion);
2766 set_fs(old_fs);
2767
2768 if (!ret) {
2769 if ((kversion.name &&
2770 copy_to_user(name_ptr, kversion.name, kversion.name_len)) ||
2771 (kversion.date &&
2772 copy_to_user(date_ptr, kversion.date, kversion.date_len)) ||
2773 (kversion.desc &&
2774 copy_to_user(desc_ptr, kversion.desc, kversion.desc_len)))
2775 ret = -EFAULT;
2776 if (put_user(kversion.version_major, &uversion->version_major) ||
2777 put_user(kversion.version_minor, &uversion->version_minor) ||
2778 put_user(kversion.version_patchlevel, &uversion->version_patchlevel) ||
2779 put_user(kversion.name_len, &uversion->name_len) ||
2780 put_user(kversion.date_len, &uversion->date_len) ||
2781 put_user(kversion.desc_len, &uversion->desc_len))
2782 ret = -EFAULT;
2783 }
2784
2785 out:
2786 if (kversion.name)
2787 kfree(kversion.name);
2788 if (kversion.date)
2789 kfree(kversion.date);
2790 if (kversion.desc)
2791 kfree(kversion.desc);
2792 return ret;
2793 }
2794
2795 typedef struct drm32_unique {
2796 int unique_len; /* Length of unique */
2797 u32 unique; /* Unique name for driver instantiation */
2798 } drm32_unique_t;
2799 #define DRM32_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm32_unique_t)
2800 #define DRM32_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm32_unique_t)
2801
drm32_getsetunique(unsigned int fd,unsigned int cmd,unsigned long arg)2802 static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long arg)
2803 {
2804 drm32_unique_t *uarg = (drm32_unique_t *)arg;
2805 drm_unique_t karg;
2806 mm_segment_t old_fs;
2807 char *uptr;
2808 u32 tmp;
2809 int ret;
2810
2811 if (get_user(karg.unique_len, &uarg->unique_len))
2812 return -EFAULT;
2813 karg.unique = NULL;
2814
2815 if (get_user(tmp, &uarg->unique))
2816 return -EFAULT;
2817
2818 uptr = (char *) A(tmp);
2819
2820 if (uptr) {
2821 karg.unique = kmalloc(karg.unique_len, GFP_KERNEL);
2822 if (!karg.unique)
2823 return -ENOMEM;
2824 if (cmd == DRM32_IOCTL_SET_UNIQUE &&
2825 copy_from_user(karg.unique, uptr, karg.unique_len)) {
2826 kfree(karg.unique);
2827 return -EFAULT;
2828 }
2829 }
2830
2831 old_fs = get_fs();
2832 set_fs(KERNEL_DS);
2833 if (cmd == DRM32_IOCTL_GET_UNIQUE)
2834 ret = sys_ioctl (fd, DRM_IOCTL_GET_UNIQUE, (unsigned long)&karg);
2835 else
2836 ret = sys_ioctl (fd, DRM_IOCTL_SET_UNIQUE, (unsigned long)&karg);
2837 set_fs(old_fs);
2838
2839 if (!ret) {
2840 if (cmd == DRM32_IOCTL_GET_UNIQUE &&
2841 uptr != NULL &&
2842 copy_to_user(uptr, karg.unique, karg.unique_len))
2843 ret = -EFAULT;
2844 if (put_user(karg.unique_len, &uarg->unique_len))
2845 ret = -EFAULT;
2846 }
2847
2848 if (karg.unique != NULL)
2849 kfree(karg.unique);
2850
2851 return ret;
2852 }
2853
2854 typedef struct drm32_map {
2855 u32 offset; /* Requested physical address (0 for SAREA)*/
2856 u32 size; /* Requested physical size (bytes) */
2857 drm_map_type_t type; /* Type of memory to map */
2858 drm_map_flags_t flags; /* Flags */
2859 u32 handle; /* User-space: "Handle" to pass to mmap */
2860 /* Kernel-space: kernel-virtual address */
2861 int mtrr; /* MTRR slot used */
2862 /* Private data */
2863 } drm32_map_t;
2864 #define DRM32_IOCTL_ADD_MAP DRM_IOWR(0x15, drm32_map_t)
2865
drm32_addmap(unsigned int fd,unsigned int cmd,unsigned long arg)2866 static int drm32_addmap(unsigned int fd, unsigned int cmd, unsigned long arg)
2867 {
2868 drm32_map_t *uarg = (drm32_map_t *) arg;
2869 drm_map_t karg;
2870 mm_segment_t old_fs;
2871 u32 tmp;
2872 int ret;
2873
2874 ret = get_user(karg.offset, &uarg->offset);
2875 ret |= get_user(karg.size, &uarg->size);
2876 ret |= get_user(karg.type, &uarg->type);
2877 ret |= get_user(karg.flags, &uarg->flags);
2878 ret |= get_user(tmp, &uarg->handle);
2879 ret |= get_user(karg.mtrr, &uarg->mtrr);
2880 if (ret)
2881 return -EFAULT;
2882
2883 karg.handle = (void *) A(tmp);
2884
2885 old_fs = get_fs();
2886 set_fs(KERNEL_DS);
2887 ret = sys_ioctl(fd, DRM_IOCTL_ADD_MAP, (unsigned long) &karg);
2888 set_fs(old_fs);
2889
2890 if (!ret) {
2891 ret = put_user(karg.offset, &uarg->offset);
2892 ret |= put_user(karg.size, &uarg->size);
2893 ret |= put_user(karg.type, &uarg->type);
2894 ret |= put_user(karg.flags, &uarg->flags);
2895 tmp = (u32) (long)karg.handle;
2896 ret |= put_user(tmp, &uarg->handle);
2897 ret |= put_user(karg.mtrr, &uarg->mtrr);
2898 if (ret)
2899 ret = -EFAULT;
2900 }
2901
2902 return ret;
2903 }
2904
2905 typedef struct drm32_buf_info {
2906 int count; /* Entries in list */
2907 u32 list; /* (drm_buf_desc_t *) */
2908 } drm32_buf_info_t;
2909 #define DRM32_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm32_buf_info_t)
2910
drm32_info_bufs(unsigned int fd,unsigned int cmd,unsigned long arg)2911 static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
2912 {
2913 drm32_buf_info_t *uarg = (drm32_buf_info_t *)arg;
2914 drm_buf_desc_t *ulist;
2915 drm_buf_info_t karg;
2916 mm_segment_t old_fs;
2917 int orig_count, ret;
2918 u32 tmp;
2919
2920 if (get_user(karg.count, &uarg->count) ||
2921 get_user(tmp, &uarg->list))
2922 return -EFAULT;
2923
2924 ulist = (drm_buf_desc_t *) A(tmp);
2925
2926 orig_count = karg.count;
2927
2928 karg.list = kmalloc(karg.count * sizeof(drm_buf_desc_t), GFP_KERNEL);
2929 if (!karg.list)
2930 return -EFAULT;
2931
2932 old_fs = get_fs();
2933 set_fs(KERNEL_DS);
2934 ret = sys_ioctl(fd, DRM_IOCTL_INFO_BUFS, (unsigned long) &karg);
2935 set_fs(old_fs);
2936
2937 if (!ret) {
2938 if (karg.count <= orig_count &&
2939 (copy_to_user(ulist, karg.list,
2940 karg.count * sizeof(drm_buf_desc_t))))
2941 ret = -EFAULT;
2942 if (put_user(karg.count, &uarg->count))
2943 ret = -EFAULT;
2944 }
2945
2946 kfree(karg.list);
2947
2948 return ret;
2949 }
2950
2951 typedef struct drm32_buf_free {
2952 int count;
2953 u32 list; /* (int *) */
2954 } drm32_buf_free_t;
2955 #define DRM32_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm32_buf_free_t)
2956
drm32_free_bufs(unsigned int fd,unsigned int cmd,unsigned long arg)2957 static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
2958 {
2959 drm32_buf_free_t *uarg = (drm32_buf_free_t *)arg;
2960 drm_buf_free_t karg;
2961 mm_segment_t old_fs;
2962 int *ulist;
2963 int ret;
2964 u32 tmp;
2965
2966 if (get_user(karg.count, &uarg->count) ||
2967 get_user(tmp, &uarg->list))
2968 return -EFAULT;
2969
2970 ulist = (int *) A(tmp);
2971
2972 karg.list = kmalloc(karg.count * sizeof(int), GFP_KERNEL);
2973 if (!karg.list)
2974 return -ENOMEM;
2975
2976 ret = -EFAULT;
2977 if (copy_from_user(karg.list, ulist, (karg.count * sizeof(int))))
2978 goto out;
2979
2980 old_fs = get_fs();
2981 set_fs(KERNEL_DS);
2982 ret = sys_ioctl(fd, DRM_IOCTL_FREE_BUFS, (unsigned long) &karg);
2983 set_fs(old_fs);
2984
2985 out:
2986 kfree(karg.list);
2987
2988 return ret;
2989 }
2990
2991 typedef struct drm32_buf_pub {
2992 int idx; /* Index into master buflist */
2993 int total; /* Buffer size */
2994 int used; /* Amount of buffer in use (for DMA) */
2995 u32 address; /* Address of buffer (void *) */
2996 } drm32_buf_pub_t;
2997
2998 typedef struct drm32_buf_map {
2999 int count; /* Length of buflist */
3000 u32 virtual; /* Mmaped area in user-virtual (void *) */
3001 u32 list; /* Buffer information (drm_buf_pub_t *) */
3002 } drm32_buf_map_t;
3003 #define DRM32_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm32_buf_map_t)
3004
drm32_map_bufs(unsigned int fd,unsigned int cmd,unsigned long arg)3005 static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
3006 {
3007 drm32_buf_map_t *uarg = (drm32_buf_map_t *)arg;
3008 drm32_buf_pub_t *ulist;
3009 drm_buf_map_t karg;
3010 mm_segment_t old_fs;
3011 int orig_count, ret, i;
3012 u32 tmp1, tmp2;
3013
3014 if (get_user(karg.count, &uarg->count) ||
3015 get_user(tmp1, &uarg->virtual) ||
3016 get_user(tmp2, &uarg->list))
3017 return -EFAULT;
3018
3019 karg.virtual = (void *) A(tmp1);
3020 ulist = (drm32_buf_pub_t *) A(tmp2);
3021
3022 orig_count = karg.count;
3023
3024 karg.list = kmalloc(karg.count * sizeof(drm_buf_pub_t), GFP_KERNEL);
3025 if (!karg.list)
3026 return -ENOMEM;
3027
3028 ret = -EFAULT;
3029 for (i = 0; i < karg.count; i++) {
3030 if (get_user(karg.list[i].idx, &ulist[i].idx) ||
3031 get_user(karg.list[i].total, &ulist[i].total) ||
3032 get_user(karg.list[i].used, &ulist[i].used) ||
3033 get_user(tmp1, &ulist[i].address))
3034 goto out;
3035
3036 karg.list[i].address = (void *) A(tmp1);
3037 }
3038
3039 old_fs = get_fs();
3040 set_fs(KERNEL_DS);
3041 ret = sys_ioctl(fd, DRM_IOCTL_MAP_BUFS, (unsigned long) &karg);
3042 set_fs(old_fs);
3043
3044 if (!ret) {
3045 for (i = 0; i < orig_count; i++) {
3046 tmp1 = (u32) (long) karg.list[i].address;
3047 if (put_user(karg.list[i].idx, &ulist[i].idx) ||
3048 put_user(karg.list[i].total, &ulist[i].total) ||
3049 put_user(karg.list[i].used, &ulist[i].used) ||
3050 put_user(tmp1, &ulist[i].address)) {
3051 ret = -EFAULT;
3052 goto out;
3053 }
3054 }
3055 if (put_user(karg.count, &uarg->count))
3056 ret = -EFAULT;
3057 }
3058
3059 out:
3060 kfree(karg.list);
3061 return ret;
3062 }
3063
3064 typedef struct drm32_dma {
3065 /* Indices here refer to the offset into
3066 buflist in drm_buf_get_t. */
3067 int context; /* Context handle */
3068 int send_count; /* Number of buffers to send */
3069 u32 send_indices; /* List of handles to buffers (int *) */
3070 u32 send_sizes; /* Lengths of data to send (int *) */
3071 drm_dma_flags_t flags; /* Flags */
3072 int request_count; /* Number of buffers requested */
3073 int request_size; /* Desired size for buffers */
3074 u32 request_indices; /* Buffer information (int *) */
3075 u32 request_sizes; /* (int *) */
3076 int granted_count; /* Number of buffers granted */
3077 } drm32_dma_t;
3078 #define DRM32_IOCTL_DMA DRM_IOWR(0x29, drm32_dma_t)
3079
3080 /* RED PEN The DRM layer blindly dereferences the send/request
3081 * index/size arrays even though they are userland
3082 * pointers. -DaveM
3083 */
drm32_dma(unsigned int fd,unsigned int cmd,unsigned long arg)3084 static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg)
3085 {
3086 drm32_dma_t *uarg = (drm32_dma_t *) arg;
3087 int *u_si, *u_ss, *u_ri, *u_rs;
3088 drm_dma_t karg;
3089 mm_segment_t old_fs;
3090 int ret;
3091 u32 tmp1, tmp2, tmp3, tmp4;
3092
3093 karg.send_indices = karg.send_sizes = NULL;
3094 karg.request_indices = karg.request_sizes = NULL;
3095
3096 if (get_user(karg.context, &uarg->context) ||
3097 get_user(karg.send_count, &uarg->send_count) ||
3098 get_user(tmp1, &uarg->send_indices) ||
3099 get_user(tmp2, &uarg->send_sizes) ||
3100 get_user(karg.flags, &uarg->flags) ||
3101 get_user(karg.request_count, &uarg->request_count) ||
3102 get_user(karg.request_size, &uarg->request_size) ||
3103 get_user(tmp3, &uarg->request_indices) ||
3104 get_user(tmp4, &uarg->request_sizes) ||
3105 get_user(karg.granted_count, &uarg->granted_count))
3106 return -EFAULT;
3107
3108 u_si = (int *) A(tmp1);
3109 u_ss = (int *) A(tmp2);
3110 u_ri = (int *) A(tmp3);
3111 u_rs = (int *) A(tmp4);
3112
3113 if (karg.send_count) {
3114 karg.send_indices = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
3115 karg.send_sizes = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
3116
3117 ret = -ENOMEM;
3118 if (!karg.send_indices || !karg.send_sizes)
3119 goto out;
3120
3121 ret = -EFAULT;
3122 if (copy_from_user(karg.send_indices, u_si,
3123 (karg.send_count * sizeof(int))) ||
3124 copy_from_user(karg.send_sizes, u_ss,
3125 (karg.send_count * sizeof(int))))
3126 goto out;
3127 }
3128
3129 if (karg.request_count) {
3130 karg.request_indices = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
3131 karg.request_sizes = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
3132
3133 ret = -ENOMEM;
3134 if (!karg.request_indices || !karg.request_sizes)
3135 goto out;
3136
3137 ret = -EFAULT;
3138 if (copy_from_user(karg.request_indices, u_ri,
3139 (karg.request_count * sizeof(int))) ||
3140 copy_from_user(karg.request_sizes, u_rs,
3141 (karg.request_count * sizeof(int))))
3142 goto out;
3143 }
3144
3145 old_fs = get_fs();
3146 set_fs(KERNEL_DS);
3147 ret = sys_ioctl(fd, DRM_IOCTL_DMA, (unsigned long) &karg);
3148 set_fs(old_fs);
3149
3150 if (!ret) {
3151 if (put_user(karg.context, &uarg->context) ||
3152 put_user(karg.send_count, &uarg->send_count) ||
3153 put_user(karg.flags, &uarg->flags) ||
3154 put_user(karg.request_count, &uarg->request_count) ||
3155 put_user(karg.request_size, &uarg->request_size) ||
3156 put_user(karg.granted_count, &uarg->granted_count))
3157 ret = -EFAULT;
3158
3159 if (karg.send_count) {
3160 if (copy_to_user(u_si, karg.send_indices,
3161 (karg.send_count * sizeof(int))) ||
3162 copy_to_user(u_ss, karg.send_sizes,
3163 (karg.send_count * sizeof(int))))
3164 ret = -EFAULT;
3165 }
3166 if (karg.request_count) {
3167 if (copy_to_user(u_ri, karg.request_indices,
3168 (karg.request_count * sizeof(int))) ||
3169 copy_to_user(u_rs, karg.request_sizes,
3170 (karg.request_count * sizeof(int))))
3171 ret = -EFAULT;
3172 }
3173 }
3174
3175 out:
3176 if (karg.send_indices)
3177 kfree(karg.send_indices);
3178 if (karg.send_sizes)
3179 kfree(karg.send_sizes);
3180 if (karg.request_indices)
3181 kfree(karg.request_indices);
3182 if (karg.request_sizes)
3183 kfree(karg.request_sizes);
3184
3185 return ret;
3186 }
3187
3188 typedef struct drm32_ctx_res {
3189 int count;
3190 u32 contexts; /* (drm_ctx_t *) */
3191 } drm32_ctx_res_t;
3192 #define DRM32_IOCTL_RES_CTX DRM_IOWR(0x26, drm32_ctx_res_t)
3193
drm32_res_ctx(unsigned int fd,unsigned int cmd,unsigned long arg)3194 static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg)
3195 {
3196 drm32_ctx_res_t *uarg = (drm32_ctx_res_t *) arg;
3197 drm_ctx_t *ulist;
3198 drm_ctx_res_t karg;
3199 mm_segment_t old_fs;
3200 int orig_count, ret;
3201 u32 tmp;
3202
3203 karg.contexts = NULL;
3204 if (get_user(karg.count, &uarg->count) ||
3205 get_user(tmp, &uarg->contexts))
3206 return -EFAULT;
3207
3208 ulist = (drm_ctx_t *) A(tmp);
3209
3210 orig_count = karg.count;
3211 if (karg.count && ulist) {
3212 karg.contexts = kmalloc((karg.count * sizeof(drm_ctx_t)), GFP_KERNEL);
3213 if (!karg.contexts)
3214 return -ENOMEM;
3215 if (copy_from_user(karg.contexts, ulist,
3216 (karg.count * sizeof(drm_ctx_t)))) {
3217 kfree(karg.contexts);
3218 return -EFAULT;
3219 }
3220 }
3221
3222 old_fs = get_fs();
3223 set_fs(KERNEL_DS);
3224 ret = sys_ioctl(fd, DRM_IOCTL_RES_CTX, (unsigned long) &karg);
3225 set_fs(old_fs);
3226
3227 if (!ret) {
3228 if (orig_count) {
3229 if (copy_to_user(ulist, karg.contexts,
3230 (orig_count * sizeof(drm_ctx_t))))
3231 ret = -EFAULT;
3232 }
3233 if (put_user(karg.count, &uarg->count))
3234 ret = -EFAULT;
3235 }
3236
3237 if (karg.contexts)
3238 kfree(karg.contexts);
3239
3240 return ret;
3241 }
3242
3243 #endif
3244
ret_einval(unsigned int fd,unsigned int cmd,unsigned long arg)3245 static int ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg)
3246 {
3247 return -EINVAL;
3248 }
3249
broken_blkgetsize(unsigned int fd,unsigned int cmd,unsigned long arg)3250 static int broken_blkgetsize(unsigned int fd, unsigned int cmd, unsigned long arg)
3251 {
3252 /* The mkswap binary hard codes it to Intel value :-((( */
3253 return w_long(fd, BLKGETSIZE, arg);
3254 }
3255
3256 struct blkpg_ioctl_arg32 {
3257 int op;
3258 int flags;
3259 int datalen;
3260 u32 data;
3261 };
3262
blkpg_ioctl_trans(unsigned int fd,unsigned int cmd,struct blkpg_ioctl_arg32 * arg)3263 static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, struct blkpg_ioctl_arg32 *arg)
3264 {
3265 struct blkpg_ioctl_arg a;
3266 struct blkpg_partition p;
3267 int err;
3268 mm_segment_t old_fs = get_fs();
3269
3270 err = get_user(a.op, &arg->op);
3271 err |= __get_user(a.flags, &arg->flags);
3272 err |= __get_user(a.datalen, &arg->datalen);
3273 err |= __get_user((long)a.data, &arg->data);
3274 if (err) return err;
3275 switch (a.op) {
3276 case BLKPG_ADD_PARTITION:
3277 case BLKPG_DEL_PARTITION:
3278 if (a.datalen < sizeof(struct blkpg_partition))
3279 return -EINVAL;
3280 if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition)))
3281 return -EFAULT;
3282 a.data = &p;
3283 set_fs (KERNEL_DS);
3284 err = sys_ioctl(fd, cmd, (unsigned long)&a);
3285 set_fs (old_fs);
3286 break;
3287 default:
3288 return -EINVAL;
3289 }
3290 return err;
3291 }
3292
ioc_settimeout(unsigned int fd,unsigned int cmd,unsigned long arg)3293 static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg)
3294 {
3295 return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg);
3296 }
3297
3298 struct usbdevfs_ctrltransfer32 {
3299 __u8 requesttype;
3300 __u8 request;
3301 __u16 value;
3302 __u16 index;
3303 __u16 length;
3304 __u32 timeout; /* in milliseconds */
3305 __u32 data;
3306 };
3307
3308 #define USBDEVFS_CONTROL32 _IOWR('U', 0, struct usbdevfs_ctrltransfer32)
3309
do_usbdevfs_control(unsigned int fd,unsigned int cmd,unsigned long arg)3310 static int do_usbdevfs_control(unsigned int fd, unsigned int cmd, unsigned long arg)
3311 {
3312 struct usbdevfs_ctrltransfer kctrl;
3313 struct usbdevfs_ctrltransfer32 *uctrl;
3314 mm_segment_t old_fs;
3315 __u32 udata;
3316 void *uptr, *kptr;
3317 int err;
3318
3319 uctrl = (struct usbdevfs_ctrltransfer32 *) arg;
3320
3321 if (copy_from_user(&kctrl, uctrl,
3322 (sizeof(struct usbdevfs_ctrltransfer) -
3323 sizeof(void *))))
3324 return -EFAULT;
3325
3326 if (get_user(udata, &uctrl->data))
3327 return -EFAULT;
3328 uptr = (void *) A(udata);
3329
3330 /* In usbdevice_fs, it limits the control buffer to a page,
3331 * for simplicity so do we.
3332 */
3333 if (!uptr || kctrl.length > PAGE_SIZE)
3334 return -EINVAL;
3335
3336 kptr = (void *)__get_free_page(GFP_KERNEL);
3337
3338 if ((kctrl.requesttype & 0x80) == 0) {
3339 err = -EFAULT;
3340 if (copy_from_user(kptr, uptr, kctrl.length))
3341 goto out;
3342 }
3343
3344 kctrl.data = kptr;
3345
3346 old_fs = get_fs();
3347 set_fs(KERNEL_DS);
3348 err = sys_ioctl(fd, USBDEVFS_CONTROL, (unsigned long)&kctrl);
3349 set_fs(old_fs);
3350
3351 if (err >= 0 &&
3352 ((kctrl.requesttype & 0x80) != 0)) {
3353 if (copy_to_user(uptr, kptr, kctrl.length))
3354 err = -EFAULT;
3355 }
3356
3357 out:
3358 free_page((unsigned long) kptr);
3359 return err;
3360 }
3361
3362 struct usbdevfs_bulktransfer32 {
3363 unsigned int ep;
3364 unsigned int len;
3365 unsigned int timeout; /* in milliseconds */
3366 __u32 data;
3367 };
3368
3369 #define USBDEVFS_BULK32 _IOWR('U', 2, struct usbdevfs_bulktransfer32)
3370
do_usbdevfs_bulk(unsigned int fd,unsigned int cmd,unsigned long arg)3371 static int do_usbdevfs_bulk(unsigned int fd, unsigned int cmd, unsigned long arg)
3372 {
3373 struct usbdevfs_bulktransfer kbulk;
3374 struct usbdevfs_bulktransfer32 *ubulk;
3375 mm_segment_t old_fs;
3376 __u32 udata;
3377 void *uptr, *kptr;
3378 int err;
3379
3380 ubulk = (struct usbdevfs_bulktransfer32 *) arg;
3381
3382 if (get_user(kbulk.ep, &ubulk->ep) ||
3383 get_user(kbulk.len, &ubulk->len) ||
3384 get_user(kbulk.timeout, &ubulk->timeout) ||
3385 get_user(udata, &ubulk->data))
3386 return -EFAULT;
3387
3388 uptr = (void *) A(udata);
3389
3390 /* In usbdevice_fs, it limits the control buffer to a page,
3391 * for simplicity so do we.
3392 */
3393 if (!uptr || kbulk.len > PAGE_SIZE)
3394 return -EINVAL;
3395
3396 kptr = (void *) __get_free_page(GFP_KERNEL);
3397
3398 if ((kbulk.ep & 0x80) == 0) {
3399 err = -EFAULT;
3400 if (copy_from_user(kptr, uptr, kbulk.len))
3401 goto out;
3402 }
3403
3404 kbulk.data = kptr;
3405
3406 old_fs = get_fs();
3407 set_fs(KERNEL_DS);
3408 err = sys_ioctl(fd, USBDEVFS_BULK, (unsigned long) &kbulk);
3409 set_fs(old_fs);
3410
3411 if (err >= 0 &&
3412 ((kbulk.ep & 0x80) != 0)) {
3413 if (copy_to_user(uptr, kptr, kbulk.len))
3414 err = -EFAULT;
3415 }
3416
3417 out:
3418 free_page((unsigned long) kptr);
3419 return err;
3420 }
3421
3422 /* This needs more work before we can enable it. Unfortunately
3423 * because of the fancy asynchronous way URB status/error is written
3424 * back to userspace, we'll need to fiddle with USB devio internals
3425 * and/or reimplement entirely the frontend of it ourselves. -DaveM
3426 *
3427 * The issue is:
3428 *
3429 * When an URB is submitted via usbdevicefs it is put onto an
3430 * asynchronous queue. When the URB completes, it may be reaped
3431 * via another ioctl. During this reaping the status is written
3432 * back to userspace along with the length of the transfer.
3433 *
3434 * We must translate into 64-bit kernel types so we pass in a kernel
3435 * space copy of the usbdevfs_urb structure. This would mean that we
3436 * must do something to deal with the async entry reaping. First we
3437 * have to deal somehow with this transitory memory we've allocated.
3438 * This is problematic since there are many call sites from which the
3439 * async entries can be destroyed (and thus when we'd need to free up
3440 * this kernel memory). One of which is the close() op of usbdevicefs.
3441 * To handle that we'd need to make our own file_operations struct which
3442 * overrides usbdevicefs's release op with our own which runs usbdevicefs's
3443 * real release op then frees up the kernel memory.
3444 *
3445 * But how to keep track of these kernel buffers? We'd need to either
3446 * keep track of them in some table _or_ know about usbdevicefs internals
3447 * (ie. the exact layout of it's file private, which is actually defined
3448 * in linux/usbdevice_fs.h, the layout of the async queues are private to
3449 * devio.c)
3450 *
3451 * There is one possible other solution I considered, also involving knowledge
3452 * of usbdevicefs internals:
3453 *
3454 * After an URB is submitted, we "fix up" the address back to the user
3455 * space one. This would work if the status/length fields written back
3456 * by the async URB completion lines up perfectly in the 32-bit type with
3457 * the 64-bit kernel type. Unfortunately, it does not because the iso
3458 * frame descriptors, at the end of the struct, can be written back.
3459 *
3460 * I think we'll just need to simply duplicate the devio URB engine here.
3461 */
3462 #if 0
3463 struct usbdevfs_urb32 {
3464 __u8 type;
3465 __u8 endpoint;
3466 __s32 status;
3467 __u32 flags;
3468 __u32 buffer;
3469 __s32 buffer_length;
3470 __s32 actual_length;
3471 __s32 start_frame;
3472 __s32 number_of_packets;
3473 __s32 error_count;
3474 __u32 signr;
3475 __u32 usercontext; /* unused */
3476 struct usbdevfs_iso_packet_desc iso_frame_desc[0];
3477 };
3478
3479 #define USBDEVFS_SUBMITURB32 _IOR('U', 10, struct usbdevfs_urb32)
3480
3481 static int get_urb32(struct usbdevfs_urb *kurb,
3482 struct usbdevfs_urb32 *uurb)
3483 {
3484 if (get_user(kurb->type, &uurb->type) ||
3485 __get_user(kurb->endpoint, &uurb->endpoint) ||
3486 __get_user(kurb->status, &uurb->status) ||
3487 __get_user(kurb->flags, &uurb->flags) ||
3488 __get_user(kurb->buffer_length, &uurb->buffer_length) ||
3489 __get_user(kurb->actual_length, &uurb->actual_length) ||
3490 __get_user(kurb->start_frame, &uurb->start_frame) ||
3491 __get_user(kurb->number_of_packets, &uurb->number_of_packets) ||
3492 __get_user(kurb->error_count, &uurb->error_count) ||
3493 __get_user(kurb->signr, &uurb->signr))
3494 return -EFAULT;
3495
3496 kurb->usercontext = 0; /* unused currently */
3497
3498 return 0;
3499 }
3500
3501 /* Just put back the values which usbdevfs actually changes. */
3502 static int put_urb32(struct usbdevfs_urb *kurb,
3503 struct usbdevfs_urb32 *uurb)
3504 {
3505 if (put_user(kurb->status, &uurb->status) ||
3506 __put_user(kurb->actual_length, &uurb->actual_length) ||
3507 __put_user(kurb->error_count, &uurb->error_count))
3508 return -EFAULT;
3509
3510 if (kurb->number_of_packets != 0) {
3511 int i;
3512
3513 for (i = 0; i < kurb->number_of_packets; i++) {
3514 if (__put_user(kurb->iso_frame_desc[i].actual_length,
3515 &uurb->iso_frame_desc[i].actual_length) ||
3516 __put_user(kurb->iso_frame_desc[i].status,
3517 &uurb->iso_frame_desc[i].status))
3518 return -EFAULT;
3519 }
3520 }
3521
3522 return 0;
3523 }
3524
3525 static int get_urb32_isoframes(struct usbdevfs_urb *kurb,
3526 struct usbdevfs_urb32 *uurb)
3527 {
3528 unsigned int totlen;
3529 int i;
3530
3531 if (kurb->type != USBDEVFS_URB_TYPE_ISO) {
3532 kurb->number_of_packets = 0;
3533 return 0;
3534 }
3535
3536 if (kurb->number_of_packets < 1 ||
3537 kurb->number_of_packets > 128)
3538 return -EINVAL;
3539
3540 if (copy_from_user(&kurb->iso_frame_desc[0],
3541 &uurb->iso_frame_desc[0],
3542 sizeof(struct usbdevfs_iso_packet_desc) *
3543 kurb->number_of_packets))
3544 return -EFAULT;
3545
3546 totlen = 0;
3547 for (i = 0; i < kurb->number_of_packets; i++) {
3548 unsigned int this_len;
3549
3550 this_len = kurb->iso_frame_desc[i].length;
3551 if (this_len > 1023)
3552 return -EINVAL;
3553
3554 totlen += this_len;
3555 }
3556
3557 if (totlen > 32768)
3558 return -EINVAL;
3559
3560 kurb->buffer_length = totlen;
3561
3562 return 0;
3563 }
3564
3565 static int do_usbdevfs_urb(unsigned int fd, unsigned int cmd, unsigned long arg)
3566 {
3567 struct usbdevfs_urb *kurb;
3568 struct usbdevfs_urb32 *uurb;
3569 mm_segment_t old_fs;
3570 __u32 udata;
3571 void *uptr, *kptr;
3572 unsigned int buflen;
3573 int err;
3574
3575 uurb = (struct usbdevfs_urb32 *) arg;
3576
3577 err = -ENOMEM;
3578 kurb = kmalloc(sizeof(struct usbdevfs_urb) +
3579 (sizeof(struct usbdevfs_iso_packet_desc) * 128),
3580 GFP_KERNEL);
3581 if (!kurb)
3582 goto out;
3583
3584 err = -EFAULT;
3585 if (get_urb32(kurb, uurb))
3586 goto out;
3587
3588 err = get_urb32_isoframes(kurb, uurb);
3589 if (err)
3590 goto out;
3591
3592 err = -EFAULT;
3593 if (__get_user(udata, &uurb->buffer))
3594 goto out;
3595 uptr = (void *) A(udata);
3596
3597 buflen = kurb->buffer_length;
3598
3599 err = verify_area(VERIFY_WRITE, uptr, buflen);
3600 if (err)
3601 goto out;
3602
3603 old_fs = get_fs();
3604 set_fs(KERNEL_DS);
3605 err = sys_ioctl(fd, USBDEVFS_SUBMITURB, (unsigned long) kurb);
3606 set_fs(old_fs);
3607
3608 if (err >= 0) {
3609 /* XXX Shit, this doesn't work for async URBs :-( XXX */
3610 if (put_urb32(kurb, uurb)) {
3611 err = -EFAULT;
3612 }
3613 }
3614
3615 out:
3616 kfree(kurb);
3617 return err;
3618 }
3619 #endif
3620
3621 #define USBDEVFS_REAPURB32 _IOW('U', 12, u32)
3622 #define USBDEVFS_REAPURBNDELAY32 _IOW('U', 13, u32)
3623
do_usbdevfs_reapurb(unsigned int fd,unsigned int cmd,unsigned long arg)3624 static int do_usbdevfs_reapurb(unsigned int fd, unsigned int cmd, unsigned long arg)
3625 {
3626 mm_segment_t old_fs;
3627 void *kptr;
3628 int err;
3629
3630 old_fs = get_fs();
3631 set_fs(KERNEL_DS);
3632 err = sys_ioctl(fd,
3633 (cmd == USBDEVFS_REAPURB32 ?
3634 USBDEVFS_REAPURB :
3635 USBDEVFS_REAPURBNDELAY),
3636 (unsigned long) &kptr);
3637 set_fs(old_fs);
3638
3639 if (err >= 0 &&
3640 put_user(((u32)(long)kptr), (u32 *) A(arg)))
3641 err = -EFAULT;
3642
3643 return err;
3644 }
3645
3646 struct usbdevfs_disconnectsignal32 {
3647 unsigned int signr;
3648 u32 context;
3649 };
3650
3651 #define USBDEVFS_DISCSIGNAL32 _IOR('U', 14, struct usbdevfs_disconnectsignal32)
3652
do_usbdevfs_discsignal(unsigned int fd,unsigned int cmd,unsigned long arg)3653 static int do_usbdevfs_discsignal(unsigned int fd, unsigned int cmd, unsigned long arg)
3654 {
3655 struct usbdevfs_disconnectsignal kdis;
3656 struct usbdevfs_disconnectsignal32 *udis;
3657 mm_segment_t old_fs;
3658 u32 uctx;
3659 int err;
3660
3661 udis = (struct usbdevfs_disconnectsignal32 *) arg;
3662
3663 if (get_user(kdis.signr, &udis->signr) ||
3664 __get_user(uctx, &udis->context))
3665 return -EFAULT;
3666
3667 kdis.context = (void *) (long)uctx;
3668
3669 old_fs = get_fs();
3670 set_fs(KERNEL_DS);
3671 err = sys_ioctl(fd, USBDEVFS_DISCSIGNAL, (unsigned long) &kdis);
3672 set_fs(old_fs);
3673
3674 return err;
3675 }
3676
3677 struct mtd_oob_buf32 {
3678 u32 start;
3679 u32 length;
3680 u32 ptr; /* unsigned char* */
3681 };
3682
3683 #define MEMWRITEOOB32 _IOWR('M',3,struct mtd_oob_buf32)
3684 #define MEMREADOOB32 _IOWR('M',4,struct mtd_oob_buf32)
3685
3686 static inline int
mtd_rw_oob(unsigned int fd,unsigned int cmd,unsigned long arg)3687 mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg)
3688 {
3689 mm_segment_t old_fs = get_fs();
3690 struct mtd_oob_buf32 *uarg = (struct mtd_oob_buf32 *)arg;
3691 struct mtd_oob_buf karg;
3692 u32 tmp;
3693 int ret;
3694
3695 if (get_user(karg.start, &uarg->start) ||
3696 get_user(karg.length, &uarg->length) ||
3697 get_user(tmp, &uarg->ptr))
3698 return -EFAULT;
3699
3700 karg.ptr = A(tmp);
3701 if (verify_area(VERIFY_WRITE, karg.ptr, karg.length))
3702 return -EFAULT;
3703
3704 set_fs(KERNEL_DS);
3705 if (MEMREADOOB32 == cmd)
3706 ret = sys_ioctl(fd, MEMREADOOB, (unsigned long)&karg);
3707 else if (MEMWRITEOOB32 == cmd)
3708 ret = sys_ioctl(fd, MEMWRITEOOB, (unsigned long)&karg);
3709 else
3710 ret = -EINVAL;
3711 set_fs(old_fs);
3712
3713 if (0 == ret && cmd == MEMREADOOB32) {
3714 ret = put_user(karg.start, &uarg->start);
3715 ret |= put_user(karg.length, &uarg->length);
3716 }
3717
3718 return ret;
3719 }
3720
3721 /* Fix sizeof(sizeof()) breakage */
3722 #define BLKELVGET_32 _IOR(0x12,106,int)
3723 #define BLKELVSET_32 _IOW(0x12,107,int)
3724 #define BLKBSZGET_32 _IOR(0x12,112,int)
3725 #define BLKBSZSET_32 _IOW(0x12,113,int)
3726 #define BLKGETSIZE64_32 _IOR(0x12,114,int)
3727
do_blkelvget(unsigned int fd,unsigned int cmd,unsigned long arg)3728 static int do_blkelvget(unsigned int fd, unsigned int cmd, unsigned long arg)
3729 {
3730 return sys_ioctl(fd, BLKELVGET, arg);
3731 }
3732
do_blkelvset(unsigned int fd,unsigned int cmd,unsigned long arg)3733 static int do_blkelvset(unsigned int fd, unsigned int cmd, unsigned long arg)
3734 {
3735 return sys_ioctl(fd, BLKELVSET, arg);
3736 }
3737
do_blkbszget(unsigned int fd,unsigned int cmd,unsigned long arg)3738 static int do_blkbszget(unsigned int fd, unsigned int cmd, unsigned long arg)
3739 {
3740 return sys_ioctl(fd, BLKBSZGET, arg);
3741 }
3742
do_blkbszset(unsigned int fd,unsigned int cmd,unsigned long arg)3743 static int do_blkbszset(unsigned int fd, unsigned int cmd, unsigned long arg)
3744 {
3745 return sys_ioctl(fd, BLKBSZSET, arg);
3746 }
3747
do_blkgetsize64(unsigned int fd,unsigned int cmd,unsigned long arg)3748 static int do_blkgetsize64(unsigned int fd, unsigned int cmd,
3749 unsigned long arg)
3750 {
3751 return sys_ioctl(fd, BLKGETSIZE64, arg);
3752 }
3753
3754 struct ioctl_trans {
3755 unsigned long cmd;
3756 unsigned long handler;
3757 unsigned long next;
3758 };
3759
3760 #define COMPATIBLE_IOCTL(cmd) { cmd, (unsigned long)sys_ioctl, 0 }
3761
3762 #define HANDLE_IOCTL(cmd,handler) { cmd, (unsigned long)handler, 0 }
3763
3764 #define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
3765 #define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, __kernel_uid_t32)
3766
3767 static struct ioctl_trans ioctl_translations[] = {
3768 /* List here explicitly which ioctl's need translation,
3769 * all others default to calling sys_ioctl().
3770 */
3771 /* Big T */
3772 COMPATIBLE_IOCTL(TCGETA),
3773 COMPATIBLE_IOCTL(TCSETA),
3774 COMPATIBLE_IOCTL(TCSETAW),
3775 COMPATIBLE_IOCTL(TCSETAF),
3776 COMPATIBLE_IOCTL(TCSBRK),
3777 COMPATIBLE_IOCTL(TCSBRKP),
3778 COMPATIBLE_IOCTL(TCXONC),
3779 COMPATIBLE_IOCTL(TCFLSH),
3780 COMPATIBLE_IOCTL(TCGETS),
3781 COMPATIBLE_IOCTL(TCSETS),
3782 COMPATIBLE_IOCTL(TCSETSW),
3783 COMPATIBLE_IOCTL(TCSETSF),
3784 COMPATIBLE_IOCTL(TIOCLINUX),
3785 COMPATIBLE_IOCTL(TIOCSTART),
3786 /* Little t */
3787 COMPATIBLE_IOCTL(TIOCGETD),
3788 COMPATIBLE_IOCTL(TIOCSETD),
3789 COMPATIBLE_IOCTL(TIOCEXCL),
3790 COMPATIBLE_IOCTL(TIOCNXCL),
3791 COMPATIBLE_IOCTL(TIOCCONS),
3792 COMPATIBLE_IOCTL(TIOCGSOFTCAR),
3793 COMPATIBLE_IOCTL(TIOCSSOFTCAR),
3794 COMPATIBLE_IOCTL(TIOCSWINSZ),
3795 COMPATIBLE_IOCTL(TIOCGWINSZ),
3796 COMPATIBLE_IOCTL(TIOCMGET),
3797 COMPATIBLE_IOCTL(TIOCMBIC),
3798 COMPATIBLE_IOCTL(TIOCMBIS),
3799 COMPATIBLE_IOCTL(TIOCMSET),
3800 COMPATIBLE_IOCTL(TIOCPKT),
3801 COMPATIBLE_IOCTL(TIOCNOTTY),
3802 COMPATIBLE_IOCTL(TIOCSTI),
3803 COMPATIBLE_IOCTL(TIOCOUTQ),
3804 COMPATIBLE_IOCTL(TIOCSPGRP),
3805 COMPATIBLE_IOCTL(TIOCGPGRP),
3806 COMPATIBLE_IOCTL(TIOCSCTTY),
3807 COMPATIBLE_IOCTL(TIOCGPTN),
3808 COMPATIBLE_IOCTL(TIOCSPTLCK),
3809 COMPATIBLE_IOCTL(TIOCGSERIAL),
3810 COMPATIBLE_IOCTL(TIOCSSERIAL),
3811 COMPATIBLE_IOCTL(TIOCSERGETLSR),
3812 COMPATIBLE_IOCTL(TIOCSLTC),
3813 COMPATIBLE_IOCTL(TIOCMIWAIT),
3814 COMPATIBLE_IOCTL(TIOCGICOUNT),
3815 /* Big F */
3816 COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO),
3817 COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO),
3818 COMPATIBLE_IOCTL(FBIOPAN_DISPLAY),
3819 COMPATIBLE_IOCTL(FBIOGET_FCURSORINFO),
3820 COMPATIBLE_IOCTL(FBIOGET_VCURSORINFO),
3821 COMPATIBLE_IOCTL(FBIOPUT_VCURSORINFO),
3822 COMPATIBLE_IOCTL(FBIOGET_CURSORSTATE),
3823 COMPATIBLE_IOCTL(FBIOPUT_CURSORSTATE),
3824 COMPATIBLE_IOCTL(FBIOGET_CON2FBMAP),
3825 COMPATIBLE_IOCTL(FBIOPUT_CON2FBMAP),
3826 #if 0
3827 COMPATIBLE_IOCTL(FBIOBLANK),
3828 #endif
3829 /* Little f */
3830 COMPATIBLE_IOCTL(FIOCLEX),
3831 COMPATIBLE_IOCTL(FIONCLEX),
3832 COMPATIBLE_IOCTL(FIOASYNC),
3833 COMPATIBLE_IOCTL(FIONBIO),
3834 COMPATIBLE_IOCTL(FIONREAD), /* This is also TIOCINQ */
3835 /* 0x00 */
3836 COMPATIBLE_IOCTL(FIBMAP),
3837 COMPATIBLE_IOCTL(FIGETBSZ),
3838 /* 0x03 -- HD/IDE ioctl's used by hdparm and friends.
3839 * Some need translations, these do not.
3840 */
3841 COMPATIBLE_IOCTL(HDIO_GET_IDENTITY),
3842 COMPATIBLE_IOCTL(HDIO_SET_DMA),
3843 COMPATIBLE_IOCTL(HDIO_SET_KEEPSETTINGS),
3844 COMPATIBLE_IOCTL(HDIO_SET_UNMASKINTR),
3845 COMPATIBLE_IOCTL(HDIO_SET_NOWERR),
3846 COMPATIBLE_IOCTL(HDIO_SET_32BIT),
3847 COMPATIBLE_IOCTL(HDIO_SET_MULTCOUNT),
3848 COMPATIBLE_IOCTL(HDIO_DRIVE_CMD),
3849 COMPATIBLE_IOCTL(HDIO_SET_PIO_MODE),
3850 COMPATIBLE_IOCTL(HDIO_SCAN_HWIF),
3851 COMPATIBLE_IOCTL(HDIO_SET_NICE),
3852 /* 0x02 -- Floppy ioctls */
3853 COMPATIBLE_IOCTL(FDMSGON),
3854 COMPATIBLE_IOCTL(FDMSGOFF),
3855 COMPATIBLE_IOCTL(FDSETEMSGTRESH),
3856 COMPATIBLE_IOCTL(FDFLUSH),
3857 COMPATIBLE_IOCTL(FDWERRORCLR),
3858 COMPATIBLE_IOCTL(FDSETMAXERRS),
3859 COMPATIBLE_IOCTL(FDGETMAXERRS),
3860 COMPATIBLE_IOCTL(FDGETDRVTYP),
3861 COMPATIBLE_IOCTL(FDEJECT),
3862 COMPATIBLE_IOCTL(FDCLRPRM),
3863 COMPATIBLE_IOCTL(FDFMTBEG),
3864 COMPATIBLE_IOCTL(FDFMTEND),
3865 COMPATIBLE_IOCTL(FDRESET),
3866 COMPATIBLE_IOCTL(FDTWADDLE),
3867 COMPATIBLE_IOCTL(FDFMTTRK),
3868 COMPATIBLE_IOCTL(FDRAWCMD),
3869 /* 0x12 */
3870 COMPATIBLE_IOCTL(BLKROSET),
3871 COMPATIBLE_IOCTL(BLKROGET),
3872 COMPATIBLE_IOCTL(BLKRRPART),
3873 COMPATIBLE_IOCTL(BLKFLSBUF),
3874 COMPATIBLE_IOCTL(BLKRASET),
3875 COMPATIBLE_IOCTL(BLKFRASET),
3876 COMPATIBLE_IOCTL(BLKSECTSET),
3877 COMPATIBLE_IOCTL(BLKSSZGET),
3878 COMPATIBLE_IOCTL(BLKBSZGET),
3879 COMPATIBLE_IOCTL(BLKBSZSET),
3880 COMPATIBLE_IOCTL(BLKGETSIZE64),
3881
3882 /* RAID */
3883 COMPATIBLE_IOCTL(RAID_VERSION),
3884 COMPATIBLE_IOCTL(RAID_AUTORUN),
3885 COMPATIBLE_IOCTL(GET_ARRAY_INFO),
3886 COMPATIBLE_IOCTL(GET_DISK_INFO),
3887 COMPATIBLE_IOCTL(PRINT_RAID_DEBUG),
3888 COMPATIBLE_IOCTL(CLEAR_ARRAY),
3889 COMPATIBLE_IOCTL(ADD_NEW_DISK),
3890 COMPATIBLE_IOCTL(HOT_REMOVE_DISK),
3891 COMPATIBLE_IOCTL(SET_ARRAY_INFO),
3892 COMPATIBLE_IOCTL(SET_DISK_INFO),
3893 COMPATIBLE_IOCTL(WRITE_RAID_INFO),
3894 COMPATIBLE_IOCTL(UNPROTECT_ARRAY),
3895 COMPATIBLE_IOCTL(PROTECT_ARRAY),
3896 COMPATIBLE_IOCTL(HOT_ADD_DISK),
3897 COMPATIBLE_IOCTL(SET_DISK_FAULTY),
3898 COMPATIBLE_IOCTL(RUN_ARRAY),
3899 COMPATIBLE_IOCTL(START_ARRAY),
3900 COMPATIBLE_IOCTL(STOP_ARRAY),
3901 COMPATIBLE_IOCTL(STOP_ARRAY_RO),
3902 COMPATIBLE_IOCTL(RESTART_ARRAY_RW),
3903 /* Big K */
3904 COMPATIBLE_IOCTL(PIO_FONT),
3905 COMPATIBLE_IOCTL(GIO_FONT),
3906 COMPATIBLE_IOCTL(KDSIGACCEPT),
3907 COMPATIBLE_IOCTL(KDGETKEYCODE),
3908 COMPATIBLE_IOCTL(KDSETKEYCODE),
3909 COMPATIBLE_IOCTL(KIOCSOUND),
3910 COMPATIBLE_IOCTL(KDMKTONE),
3911 COMPATIBLE_IOCTL(KDGKBTYPE),
3912 COMPATIBLE_IOCTL(KDSETMODE),
3913 COMPATIBLE_IOCTL(KDGETMODE),
3914 COMPATIBLE_IOCTL(KDSKBMODE),
3915 COMPATIBLE_IOCTL(KDGKBMODE),
3916 COMPATIBLE_IOCTL(KDSKBMETA),
3917 COMPATIBLE_IOCTL(KDGKBMETA),
3918 COMPATIBLE_IOCTL(KDGKBENT),
3919 COMPATIBLE_IOCTL(KDSKBENT),
3920 COMPATIBLE_IOCTL(KDGKBSENT),
3921 COMPATIBLE_IOCTL(KDSKBSENT),
3922 COMPATIBLE_IOCTL(KDGKBDIACR),
3923 COMPATIBLE_IOCTL(KDKBDREP),
3924 COMPATIBLE_IOCTL(KDSKBDIACR),
3925 COMPATIBLE_IOCTL(KDGKBLED),
3926 COMPATIBLE_IOCTL(KDSKBLED),
3927 COMPATIBLE_IOCTL(KDGETLED),
3928 COMPATIBLE_IOCTL(KDSETLED),
3929 COMPATIBLE_IOCTL(GIO_SCRNMAP),
3930 COMPATIBLE_IOCTL(PIO_SCRNMAP),
3931 COMPATIBLE_IOCTL(GIO_UNISCRNMAP),
3932 COMPATIBLE_IOCTL(PIO_UNISCRNMAP),
3933 COMPATIBLE_IOCTL(PIO_FONTRESET),
3934 COMPATIBLE_IOCTL(PIO_UNIMAPCLR),
3935 /* Big S */
3936 COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN),
3937 COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST),
3938 COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI),
3939 COMPATIBLE_IOCTL(SCSI_IOCTL_DOORLOCK),
3940 COMPATIBLE_IOCTL(SCSI_IOCTL_DOORUNLOCK),
3941 COMPATIBLE_IOCTL(SCSI_IOCTL_TEST_UNIT_READY),
3942 COMPATIBLE_IOCTL(SCSI_IOCTL_TAGGED_ENABLE),
3943 COMPATIBLE_IOCTL(SCSI_IOCTL_TAGGED_DISABLE),
3944 COMPATIBLE_IOCTL(SCSI_IOCTL_GET_BUS_NUMBER),
3945 COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND),
3946 /* Big T */
3947 COMPATIBLE_IOCTL(TUNSETNOCSUM),
3948 COMPATIBLE_IOCTL(TUNSETDEBUG),
3949 COMPATIBLE_IOCTL(TUNSETIFF),
3950 COMPATIBLE_IOCTL(TUNSETPERSIST),
3951 COMPATIBLE_IOCTL(TUNSETOWNER),
3952 /* Big V */
3953 COMPATIBLE_IOCTL(VT_SETMODE),
3954 COMPATIBLE_IOCTL(VT_GETMODE),
3955 COMPATIBLE_IOCTL(VT_GETSTATE),
3956 COMPATIBLE_IOCTL(VT_OPENQRY),
3957 COMPATIBLE_IOCTL(VT_ACTIVATE),
3958 COMPATIBLE_IOCTL(VT_WAITACTIVE),
3959 COMPATIBLE_IOCTL(VT_RELDISP),
3960 COMPATIBLE_IOCTL(VT_DISALLOCATE),
3961 COMPATIBLE_IOCTL(VT_RESIZE),
3962 COMPATIBLE_IOCTL(VT_RESIZEX),
3963 COMPATIBLE_IOCTL(VT_LOCKSWITCH),
3964 COMPATIBLE_IOCTL(VT_UNLOCKSWITCH),
3965 /* Little v, the video4linux ioctls */
3966 COMPATIBLE_IOCTL(VIDIOCGCAP),
3967 COMPATIBLE_IOCTL(VIDIOCGCHAN),
3968 COMPATIBLE_IOCTL(VIDIOCSCHAN),
3969 COMPATIBLE_IOCTL(VIDIOCGPICT),
3970 COMPATIBLE_IOCTL(VIDIOCSPICT),
3971 COMPATIBLE_IOCTL(VIDIOCCAPTURE),
3972 COMPATIBLE_IOCTL(VIDIOCKEY),
3973 COMPATIBLE_IOCTL(VIDIOCGAUDIO),
3974 COMPATIBLE_IOCTL(VIDIOCSAUDIO),
3975 COMPATIBLE_IOCTL(VIDIOCSYNC),
3976 COMPATIBLE_IOCTL(VIDIOCMCAPTURE),
3977 COMPATIBLE_IOCTL(VIDIOCGMBUF),
3978 COMPATIBLE_IOCTL(VIDIOCGUNIT),
3979 COMPATIBLE_IOCTL(VIDIOCGCAPTURE),
3980 COMPATIBLE_IOCTL(VIDIOCSCAPTURE),
3981 /* BTTV specific... */
3982 COMPATIBLE_IOCTL(_IOW('v', BASE_VIDIOCPRIVATE+0, char [256])),
3983 COMPATIBLE_IOCTL(_IOR('v', BASE_VIDIOCPRIVATE+1, char [256])),
3984 COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int)),
3985 COMPATIBLE_IOCTL(_IOW('v' , BASE_VIDIOCPRIVATE+3, char [16])), /* struct bttv_pll_info */
3986 COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+4, int)),
3987 COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+5, int)),
3988 COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+6, int)),
3989 COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+7, int)),
3990 /* Little p (/dev/rtc, /dev/envctrl, etc.) */
3991 COMPATIBLE_IOCTL(_IOR('p', 20, int[7])), /* RTCGET */
3992 COMPATIBLE_IOCTL(_IOW('p', 21, int[7])), /* RTCSET */
3993 COMPATIBLE_IOCTL(RTC_AIE_ON),
3994 COMPATIBLE_IOCTL(RTC_AIE_OFF),
3995 COMPATIBLE_IOCTL(RTC_UIE_ON),
3996 COMPATIBLE_IOCTL(RTC_UIE_OFF),
3997 COMPATIBLE_IOCTL(RTC_PIE_ON),
3998 COMPATIBLE_IOCTL(RTC_PIE_OFF),
3999 COMPATIBLE_IOCTL(RTC_WIE_ON),
4000 COMPATIBLE_IOCTL(RTC_WIE_OFF),
4001 COMPATIBLE_IOCTL(RTC_ALM_SET),
4002 COMPATIBLE_IOCTL(RTC_ALM_READ),
4003 COMPATIBLE_IOCTL(RTC_RD_TIME),
4004 COMPATIBLE_IOCTL(RTC_SET_TIME),
4005 COMPATIBLE_IOCTL(RTC_WKALM_SET),
4006 COMPATIBLE_IOCTL(RTC_WKALM_RD),
4007 /* Little m */
4008 COMPATIBLE_IOCTL(MTIOCTOP),
4009 /* Socket level stuff */
4010 COMPATIBLE_IOCTL(FIOSETOWN),
4011 COMPATIBLE_IOCTL(SIOCSPGRP),
4012 COMPATIBLE_IOCTL(FIOGETOWN),
4013 COMPATIBLE_IOCTL(SIOCGPGRP),
4014 COMPATIBLE_IOCTL(SIOCATMARK),
4015 COMPATIBLE_IOCTL(SIOCSIFLINK),
4016 COMPATIBLE_IOCTL(SIOCSIFENCAP),
4017 COMPATIBLE_IOCTL(SIOCGIFENCAP),
4018 COMPATIBLE_IOCTL(SIOCSIFBR),
4019 COMPATIBLE_IOCTL(SIOCGIFBR),
4020 COMPATIBLE_IOCTL(SIOCSARP),
4021 COMPATIBLE_IOCTL(SIOCGARP),
4022 COMPATIBLE_IOCTL(SIOCDARP),
4023 COMPATIBLE_IOCTL(SIOCSRARP),
4024 COMPATIBLE_IOCTL(SIOCGRARP),
4025 COMPATIBLE_IOCTL(SIOCDRARP),
4026 COMPATIBLE_IOCTL(SIOCADDDLCI),
4027 COMPATIBLE_IOCTL(SIOCDELDLCI),
4028 COMPATIBLE_IOCTL(SIOCGIFVLAN),
4029 COMPATIBLE_IOCTL(SIOCSIFVLAN),
4030 /* SG stuff */
4031 COMPATIBLE_IOCTL(SG_SET_TIMEOUT),
4032 COMPATIBLE_IOCTL(SG_GET_TIMEOUT),
4033 COMPATIBLE_IOCTL(SG_EMULATED_HOST),
4034 COMPATIBLE_IOCTL(SG_SET_TRANSFORM),
4035 COMPATIBLE_IOCTL(SG_GET_TRANSFORM),
4036 COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE),
4037 COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE),
4038 COMPATIBLE_IOCTL(SG_GET_SCSI_ID),
4039 COMPATIBLE_IOCTL(SG_SET_FORCE_LOW_DMA),
4040 COMPATIBLE_IOCTL(SG_GET_LOW_DMA),
4041 COMPATIBLE_IOCTL(SG_SET_FORCE_PACK_ID),
4042 COMPATIBLE_IOCTL(SG_GET_PACK_ID),
4043 COMPATIBLE_IOCTL(SG_GET_NUM_WAITING),
4044 COMPATIBLE_IOCTL(SG_SET_DEBUG),
4045 COMPATIBLE_IOCTL(SG_GET_SG_TABLESIZE),
4046 COMPATIBLE_IOCTL(SG_GET_COMMAND_Q),
4047 COMPATIBLE_IOCTL(SG_SET_COMMAND_Q),
4048 COMPATIBLE_IOCTL(SG_GET_VERSION_NUM),
4049 COMPATIBLE_IOCTL(SG_NEXT_CMD_LEN),
4050 COMPATIBLE_IOCTL(SG_SCSI_RESET),
4051 COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE),
4052 COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN),
4053 COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN),
4054 /* PPP stuff */
4055 COMPATIBLE_IOCTL(PPPIOCGFLAGS),
4056 COMPATIBLE_IOCTL(PPPIOCSFLAGS),
4057 COMPATIBLE_IOCTL(PPPIOCGASYNCMAP),
4058 COMPATIBLE_IOCTL(PPPIOCSASYNCMAP),
4059 COMPATIBLE_IOCTL(PPPIOCGUNIT),
4060 COMPATIBLE_IOCTL(PPPIOCGRASYNCMAP),
4061 COMPATIBLE_IOCTL(PPPIOCSRASYNCMAP),
4062 COMPATIBLE_IOCTL(PPPIOCGMRU),
4063 COMPATIBLE_IOCTL(PPPIOCSMRU),
4064 COMPATIBLE_IOCTL(PPPIOCSMAXCID),
4065 COMPATIBLE_IOCTL(PPPIOCGXASYNCMAP),
4066 COMPATIBLE_IOCTL(LPGETSTATUS),
4067 COMPATIBLE_IOCTL(PPPIOCSXASYNCMAP),
4068 COMPATIBLE_IOCTL(PPPIOCXFERUNIT),
4069 COMPATIBLE_IOCTL(PPPIOCGNPMODE),
4070 COMPATIBLE_IOCTL(PPPIOCSNPMODE),
4071 COMPATIBLE_IOCTL(PPPIOCGDEBUG),
4072 COMPATIBLE_IOCTL(PPPIOCSDEBUG),
4073 COMPATIBLE_IOCTL(PPPIOCNEWUNIT),
4074 COMPATIBLE_IOCTL(PPPIOCATTACH),
4075 COMPATIBLE_IOCTL(PPPIOCDETACH),
4076 COMPATIBLE_IOCTL(PPPIOCSMRRU),
4077 COMPATIBLE_IOCTL(PPPIOCCONNECT),
4078 COMPATIBLE_IOCTL(PPPIOCDISCONN),
4079 COMPATIBLE_IOCTL(PPPIOCATTCHAN),
4080 COMPATIBLE_IOCTL(PPPIOCGCHAN),
4081 /* PPPOX */
4082 COMPATIBLE_IOCTL(PPPOEIOCSFWD),
4083 COMPATIBLE_IOCTL(PPPOEIOCDFWD),
4084 /* CDROM stuff */
4085 COMPATIBLE_IOCTL(CDROMPAUSE),
4086 COMPATIBLE_IOCTL(CDROMRESUME),
4087 COMPATIBLE_IOCTL(CDROMPLAYMSF),
4088 COMPATIBLE_IOCTL(CDROMPLAYTRKIND),
4089 COMPATIBLE_IOCTL(CDROMREADCOOKED),
4090 COMPATIBLE_IOCTL(CDROMREADMODE1),
4091 COMPATIBLE_IOCTL(CDROMREADMODE2),
4092 COMPATIBLE_IOCTL(CDROMREADRAW),
4093 COMPATIBLE_IOCTL(CDROMREADTOCHDR),
4094 COMPATIBLE_IOCTL(CDROMREADTOCENTRY),
4095 COMPATIBLE_IOCTL(CDROMSTOP),
4096 COMPATIBLE_IOCTL(CDROMSTART),
4097 COMPATIBLE_IOCTL(CDROMEJECT),
4098 COMPATIBLE_IOCTL(CDROMVOLCTRL),
4099 COMPATIBLE_IOCTL(CDROMSUBCHNL),
4100 COMPATIBLE_IOCTL(CDROMEJECT_SW),
4101 COMPATIBLE_IOCTL(CDROMMULTISESSION),
4102 COMPATIBLE_IOCTL(CDROM_GET_MCN),
4103 COMPATIBLE_IOCTL(CDROMRESET),
4104 COMPATIBLE_IOCTL(CDROMVOLREAD),
4105 COMPATIBLE_IOCTL(CDROMSEEK),
4106 COMPATIBLE_IOCTL(CDROMPLAYBLK),
4107 COMPATIBLE_IOCTL(CDROMCLOSETRAY),
4108 COMPATIBLE_IOCTL(CDROM_SET_OPTIONS),
4109 COMPATIBLE_IOCTL(CDROM_CLEAR_OPTIONS),
4110 COMPATIBLE_IOCTL(CDROM_SELECT_SPEED),
4111 COMPATIBLE_IOCTL(CDROM_SELECT_DISC),
4112 COMPATIBLE_IOCTL(CDROM_MEDIA_CHANGED),
4113 COMPATIBLE_IOCTL(CDROM_DRIVE_STATUS),
4114 COMPATIBLE_IOCTL(CDROM_DISC_STATUS),
4115 COMPATIBLE_IOCTL(CDROM_CHANGER_NSLOTS),
4116 COMPATIBLE_IOCTL(CDROM_LOCKDOOR),
4117 COMPATIBLE_IOCTL(CDROM_DEBUG),
4118 COMPATIBLE_IOCTL(CDROM_GET_CAPABILITY),
4119 /* DVD ioctls */
4120 COMPATIBLE_IOCTL(DVD_READ_STRUCT),
4121 COMPATIBLE_IOCTL(DVD_WRITE_STRUCT),
4122 COMPATIBLE_IOCTL(DVD_AUTH),
4123 /* Big L */
4124 COMPATIBLE_IOCTL(LOOP_SET_FD),
4125 COMPATIBLE_IOCTL(LOOP_CLR_FD),
4126 /* Big Q for sound/OSS */
4127 COMPATIBLE_IOCTL(SNDCTL_SEQ_RESET),
4128 COMPATIBLE_IOCTL(SNDCTL_SEQ_SYNC),
4129 COMPATIBLE_IOCTL(SNDCTL_SYNTH_INFO),
4130 COMPATIBLE_IOCTL(SNDCTL_SEQ_CTRLRATE),
4131 COMPATIBLE_IOCTL(SNDCTL_SEQ_GETOUTCOUNT),
4132 COMPATIBLE_IOCTL(SNDCTL_SEQ_GETINCOUNT),
4133 COMPATIBLE_IOCTL(SNDCTL_SEQ_PERCMODE),
4134 COMPATIBLE_IOCTL(SNDCTL_FM_LOAD_INSTR),
4135 COMPATIBLE_IOCTL(SNDCTL_SEQ_TESTMIDI),
4136 COMPATIBLE_IOCTL(SNDCTL_SEQ_RESETSAMPLES),
4137 COMPATIBLE_IOCTL(SNDCTL_SEQ_NRSYNTHS),
4138 COMPATIBLE_IOCTL(SNDCTL_SEQ_NRMIDIS),
4139 COMPATIBLE_IOCTL(SNDCTL_MIDI_INFO),
4140 COMPATIBLE_IOCTL(SNDCTL_SEQ_THRESHOLD),
4141 COMPATIBLE_IOCTL(SNDCTL_SYNTH_MEMAVL),
4142 COMPATIBLE_IOCTL(SNDCTL_FM_4OP_ENABLE),
4143 COMPATIBLE_IOCTL(SNDCTL_SEQ_PANIC),
4144 COMPATIBLE_IOCTL(SNDCTL_SEQ_OUTOFBAND),
4145 COMPATIBLE_IOCTL(SNDCTL_SEQ_GETTIME),
4146 COMPATIBLE_IOCTL(SNDCTL_SYNTH_ID),
4147 COMPATIBLE_IOCTL(SNDCTL_SYNTH_CONTROL),
4148 COMPATIBLE_IOCTL(SNDCTL_SYNTH_REMOVESAMPLE),
4149 /* Big T for sound/OSS */
4150 COMPATIBLE_IOCTL(SNDCTL_TMR_TIMEBASE),
4151 COMPATIBLE_IOCTL(SNDCTL_TMR_START),
4152 COMPATIBLE_IOCTL(SNDCTL_TMR_STOP),
4153 COMPATIBLE_IOCTL(SNDCTL_TMR_CONTINUE),
4154 COMPATIBLE_IOCTL(SNDCTL_TMR_TEMPO),
4155 COMPATIBLE_IOCTL(SNDCTL_TMR_SOURCE),
4156 COMPATIBLE_IOCTL(SNDCTL_TMR_METRONOME),
4157 COMPATIBLE_IOCTL(SNDCTL_TMR_SELECT),
4158 /* Little m for sound/OSS */
4159 COMPATIBLE_IOCTL(SNDCTL_MIDI_PRETIME),
4160 COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUMODE),
4161 COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUCMD),
4162 /* Big P for sound/OSS */
4163 COMPATIBLE_IOCTL(SNDCTL_DSP_RESET),
4164 COMPATIBLE_IOCTL(SNDCTL_DSP_SYNC),
4165 COMPATIBLE_IOCTL(SNDCTL_DSP_SPEED),
4166 COMPATIBLE_IOCTL(SNDCTL_DSP_STEREO),
4167 COMPATIBLE_IOCTL(SNDCTL_DSP_GETBLKSIZE),
4168 COMPATIBLE_IOCTL(SNDCTL_DSP_CHANNELS),
4169 COMPATIBLE_IOCTL(SOUND_PCM_WRITE_FILTER),
4170 COMPATIBLE_IOCTL(SNDCTL_DSP_POST),
4171 COMPATIBLE_IOCTL(SNDCTL_DSP_SUBDIVIDE),
4172 COMPATIBLE_IOCTL(SNDCTL_DSP_SETFRAGMENT),
4173 COMPATIBLE_IOCTL(SNDCTL_DSP_GETFMTS),
4174 COMPATIBLE_IOCTL(SNDCTL_DSP_SETFMT),
4175 COMPATIBLE_IOCTL(SNDCTL_DSP_GETOSPACE),
4176 COMPATIBLE_IOCTL(SNDCTL_DSP_GETISPACE),
4177 COMPATIBLE_IOCTL(SNDCTL_DSP_NONBLOCK),
4178 COMPATIBLE_IOCTL(SNDCTL_DSP_GETCAPS),
4179 COMPATIBLE_IOCTL(SNDCTL_DSP_GETTRIGGER),
4180 COMPATIBLE_IOCTL(SNDCTL_DSP_SETTRIGGER),
4181 COMPATIBLE_IOCTL(SNDCTL_DSP_GETIPTR),
4182 COMPATIBLE_IOCTL(SNDCTL_DSP_GETOPTR),
4183 /* SNDCTL_DSP_MAPINBUF, XXX needs translation */
4184 /* SNDCTL_DSP_MAPOUTBUF, XXX needs translation */
4185 COMPATIBLE_IOCTL(SNDCTL_DSP_SETSYNCRO),
4186 COMPATIBLE_IOCTL(SNDCTL_DSP_SETDUPLEX),
4187 COMPATIBLE_IOCTL(SNDCTL_DSP_GETODELAY),
4188 COMPATIBLE_IOCTL(SNDCTL_DSP_PROFILE),
4189 COMPATIBLE_IOCTL(SOUND_PCM_READ_RATE),
4190 COMPATIBLE_IOCTL(SOUND_PCM_READ_CHANNELS),
4191 COMPATIBLE_IOCTL(SOUND_PCM_READ_BITS),
4192 COMPATIBLE_IOCTL(SOUND_PCM_READ_FILTER),
4193 /* Big C for sound/OSS */
4194 COMPATIBLE_IOCTL(SNDCTL_COPR_RESET),
4195 COMPATIBLE_IOCTL(SNDCTL_COPR_LOAD),
4196 COMPATIBLE_IOCTL(SNDCTL_COPR_RDATA),
4197 COMPATIBLE_IOCTL(SNDCTL_COPR_RCODE),
4198 COMPATIBLE_IOCTL(SNDCTL_COPR_WDATA),
4199 COMPATIBLE_IOCTL(SNDCTL_COPR_WCODE),
4200 COMPATIBLE_IOCTL(SNDCTL_COPR_RUN),
4201 COMPATIBLE_IOCTL(SNDCTL_COPR_HALT),
4202 COMPATIBLE_IOCTL(SNDCTL_COPR_SENDMSG),
4203 COMPATIBLE_IOCTL(SNDCTL_COPR_RCVMSG),
4204 /* Big M for sound/OSS */
4205 COMPATIBLE_IOCTL(SOUND_MIXER_READ_VOLUME),
4206 COMPATIBLE_IOCTL(SOUND_MIXER_READ_BASS),
4207 COMPATIBLE_IOCTL(SOUND_MIXER_READ_TREBLE),
4208 COMPATIBLE_IOCTL(SOUND_MIXER_READ_SYNTH),
4209 COMPATIBLE_IOCTL(SOUND_MIXER_READ_PCM),
4210 COMPATIBLE_IOCTL(SOUND_MIXER_READ_SPEAKER),
4211 COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE),
4212 COMPATIBLE_IOCTL(SOUND_MIXER_READ_MIC),
4213 COMPATIBLE_IOCTL(SOUND_MIXER_READ_CD),
4214 COMPATIBLE_IOCTL(SOUND_MIXER_READ_IMIX),
4215 COMPATIBLE_IOCTL(SOUND_MIXER_READ_ALTPCM),
4216 COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECLEV),
4217 COMPATIBLE_IOCTL(SOUND_MIXER_READ_IGAIN),
4218 COMPATIBLE_IOCTL(SOUND_MIXER_READ_OGAIN),
4219 COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE1),
4220 COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE2),
4221 COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE3),
4222 COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL1)),
4223 COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL2)),
4224 COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL3)),
4225 COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEIN)),
4226 COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEOUT)),
4227 COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_VIDEO)),
4228 COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_RADIO)),
4229 COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_MONITOR)),
4230 COMPATIBLE_IOCTL(SOUND_MIXER_READ_MUTE),
4231 /* SOUND_MIXER_READ_ENHANCE, same value as READ_MUTE */
4232 /* SOUND_MIXER_READ_LOUD, same value as READ_MUTE */
4233 COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECSRC),
4234 COMPATIBLE_IOCTL(SOUND_MIXER_READ_DEVMASK),
4235 COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECMASK),
4236 COMPATIBLE_IOCTL(SOUND_MIXER_READ_STEREODEVS),
4237 COMPATIBLE_IOCTL(SOUND_MIXER_READ_CAPS),
4238 COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_VOLUME),
4239 COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_BASS),
4240 COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_TREBLE),
4241 COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SYNTH),
4242 COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_PCM),
4243 COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SPEAKER),
4244 COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE),
4245 COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MIC),
4246 COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_CD),
4247 COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IMIX),
4248 COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_ALTPCM),
4249 COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECLEV),
4250 COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IGAIN),
4251 COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_OGAIN),
4252 COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE1),
4253 COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE2),
4254 COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE3),
4255 COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL1)),
4256 COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL2)),
4257 COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL3)),
4258 COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEIN)),
4259 COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEOUT)),
4260 COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_VIDEO)),
4261 COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_RADIO)),
4262 COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_MONITOR)),
4263 COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MUTE),
4264 /* SOUND_MIXER_WRITE_ENHANCE, same value as WRITE_MUTE */
4265 /* SOUND_MIXER_WRITE_LOUD, same value as WRITE_MUTE */
4266 COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECSRC),
4267 COMPATIBLE_IOCTL(SOUND_MIXER_INFO),
4268 COMPATIBLE_IOCTL(SOUND_OLD_MIXER_INFO),
4269 COMPATIBLE_IOCTL(SOUND_MIXER_ACCESS),
4270 COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE1),
4271 COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE2),
4272 COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE3),
4273 COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE4),
4274 COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE5),
4275 COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS),
4276 COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS),
4277 COMPATIBLE_IOCTL(OSS_GETVERSION),
4278 /* AUTOFS */
4279 COMPATIBLE_IOCTL(AUTOFS_IOC_READY),
4280 COMPATIBLE_IOCTL(AUTOFS_IOC_FAIL),
4281 COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC),
4282 COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER),
4283 COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE),
4284 COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI),
4285 COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOSUBVER),
4286 COMPATIBLE_IOCTL(AUTOFS_IOC_ASKREGHOST),
4287 COMPATIBLE_IOCTL(AUTOFS_IOC_TOGGLEREGHOST),
4288 COMPATIBLE_IOCTL(AUTOFS_IOC_ASKUMOUNT),
4289 /* DEVFS */
4290 COMPATIBLE_IOCTL(DEVFSDIOC_GET_PROTO_REV),
4291 COMPATIBLE_IOCTL(DEVFSDIOC_SET_EVENT_MASK),
4292 COMPATIBLE_IOCTL(DEVFSDIOC_RELEASE_EVENT_QUEUE),
4293 COMPATIBLE_IOCTL(DEVFSDIOC_SET_DEBUG_MASK),
4294 /* Raw devices */
4295 COMPATIBLE_IOCTL(RAW_SETBIND),
4296 COMPATIBLE_IOCTL(RAW_GETBIND),
4297 /* SMB ioctls which do not need any translations */
4298 COMPATIBLE_IOCTL(SMB_IOC_NEWCONN),
4299 /* Little a */
4300 COMPATIBLE_IOCTL(ATMSIGD_CTRL),
4301 COMPATIBLE_IOCTL(ATMARPD_CTRL),
4302 COMPATIBLE_IOCTL(ATMLEC_CTRL),
4303 COMPATIBLE_IOCTL(ATMLEC_MCAST),
4304 COMPATIBLE_IOCTL(ATMLEC_DATA),
4305 COMPATIBLE_IOCTL(ATM_SETSC),
4306 COMPATIBLE_IOCTL(SIOCSIFATMTCP),
4307 COMPATIBLE_IOCTL(SIOCMKCLIP),
4308 COMPATIBLE_IOCTL(ATMARP_MKIP),
4309 COMPATIBLE_IOCTL(ATMARP_SETENTRY),
4310 COMPATIBLE_IOCTL(ATMARP_ENCAP),
4311 COMPATIBLE_IOCTL(ATMTCP_CREATE),
4312 COMPATIBLE_IOCTL(ATMTCP_REMOVE),
4313 COMPATIBLE_IOCTL(ATMMPC_CTRL),
4314 COMPATIBLE_IOCTL(ATMMPC_DATA),
4315 #if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
4316 /* 0xfe - lvm */
4317 COMPATIBLE_IOCTL(VG_SET_EXTENDABLE),
4318 COMPATIBLE_IOCTL(VG_STATUS_GET_COUNT),
4319 COMPATIBLE_IOCTL(VG_STATUS_GET_NAMELIST),
4320 COMPATIBLE_IOCTL(VG_REMOVE),
4321 COMPATIBLE_IOCTL(VG_RENAME),
4322 COMPATIBLE_IOCTL(VG_REDUCE),
4323 COMPATIBLE_IOCTL(PE_LOCK_UNLOCK),
4324 COMPATIBLE_IOCTL(PV_FLUSH),
4325 COMPATIBLE_IOCTL(LVM_LOCK_LVM),
4326 COMPATIBLE_IOCTL(LVM_GET_IOP_VERSION),
4327 #ifdef LVM_TOTAL_RESET
4328 COMPATIBLE_IOCTL(LVM_RESET),
4329 #endif
4330 COMPATIBLE_IOCTL(LV_SET_ACCESS),
4331 COMPATIBLE_IOCTL(LV_SET_STATUS),
4332 COMPATIBLE_IOCTL(LV_SET_ALLOCATION),
4333 COMPATIBLE_IOCTL(LE_REMAP),
4334 COMPATIBLE_IOCTL(LV_BMAP),
4335 COMPATIBLE_IOCTL(LV_SNAPSHOT_USE_RATE),
4336 #endif /* LVM */
4337 #if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
4338 COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC),
4339 COMPATIBLE_IOCTL(DRM_IOCTL_IRQ_BUSID),
4340 COMPATIBLE_IOCTL(DRM_IOCTL_AUTH_MAGIC),
4341 COMPATIBLE_IOCTL(DRM_IOCTL_BLOCK),
4342 COMPATIBLE_IOCTL(DRM_IOCTL_UNBLOCK),
4343 COMPATIBLE_IOCTL(DRM_IOCTL_CONTROL),
4344 COMPATIBLE_IOCTL(DRM_IOCTL_ADD_BUFS),
4345 COMPATIBLE_IOCTL(DRM_IOCTL_MARK_BUFS),
4346 COMPATIBLE_IOCTL(DRM_IOCTL_ADD_CTX),
4347 COMPATIBLE_IOCTL(DRM_IOCTL_RM_CTX),
4348 COMPATIBLE_IOCTL(DRM_IOCTL_MOD_CTX),
4349 COMPATIBLE_IOCTL(DRM_IOCTL_GET_CTX),
4350 COMPATIBLE_IOCTL(DRM_IOCTL_SWITCH_CTX),
4351 COMPATIBLE_IOCTL(DRM_IOCTL_NEW_CTX),
4352 COMPATIBLE_IOCTL(DRM_IOCTL_ADD_DRAW),
4353 COMPATIBLE_IOCTL(DRM_IOCTL_RM_DRAW),
4354 COMPATIBLE_IOCTL(DRM_IOCTL_LOCK),
4355 COMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK),
4356 COMPATIBLE_IOCTL(DRM_IOCTL_FINISH),
4357 #endif /* DRM */
4358 /* elevator */
4359 COMPATIBLE_IOCTL(BLKELVGET),
4360 COMPATIBLE_IOCTL(BLKELVSET),
4361 /* Big W */
4362 /* WIOC_GETSUPPORT not yet implemented -E */
4363 COMPATIBLE_IOCTL(WDIOC_GETSTATUS),
4364 COMPATIBLE_IOCTL(WDIOC_GETBOOTSTATUS),
4365 COMPATIBLE_IOCTL(WDIOC_GETTEMP),
4366 COMPATIBLE_IOCTL(WDIOC_SETOPTIONS),
4367 COMPATIBLE_IOCTL(WDIOC_KEEPALIVE),
4368 /* Big R */
4369 COMPATIBLE_IOCTL(RNDGETENTCNT),
4370 COMPATIBLE_IOCTL(RNDADDTOENTCNT),
4371 COMPATIBLE_IOCTL(RNDGETPOOL),
4372 COMPATIBLE_IOCTL(RNDADDENTROPY),
4373 COMPATIBLE_IOCTL(RNDZAPENTCNT),
4374 COMPATIBLE_IOCTL(RNDCLEARPOOL),
4375 /* Bluetooth ioctls */
4376 COMPATIBLE_IOCTL(HCIDEVUP),
4377 COMPATIBLE_IOCTL(HCIDEVDOWN),
4378 COMPATIBLE_IOCTL(HCIDEVRESET),
4379 COMPATIBLE_IOCTL(HCIDEVRESTAT),
4380 COMPATIBLE_IOCTL(HCIGETDEVINFO),
4381 COMPATIBLE_IOCTL(HCIGETDEVLIST),
4382 COMPATIBLE_IOCTL(HCISETRAW),
4383 COMPATIBLE_IOCTL(HCISETSCAN),
4384 COMPATIBLE_IOCTL(HCISETAUTH),
4385 COMPATIBLE_IOCTL(HCIINQUIRY),
4386 COMPATIBLE_IOCTL(PCIIOC_CONTROLLER),
4387 COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO),
4388 COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM),
4389 COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE),
4390 /* USB */
4391 COMPATIBLE_IOCTL(USBDEVFS_RESETEP),
4392 COMPATIBLE_IOCTL(USBDEVFS_SETINTERFACE),
4393 COMPATIBLE_IOCTL(USBDEVFS_SETCONFIGURATION),
4394 COMPATIBLE_IOCTL(USBDEVFS_GETDRIVER),
4395 COMPATIBLE_IOCTL(USBDEVFS_DISCARDURB),
4396 COMPATIBLE_IOCTL(USBDEVFS_CLAIMINTERFACE),
4397 COMPATIBLE_IOCTL(USBDEVFS_RELEASEINTERFACE),
4398 COMPATIBLE_IOCTL(USBDEVFS_CONNECTINFO),
4399 COMPATIBLE_IOCTL(USBDEVFS_HUB_PORTINFO),
4400 COMPATIBLE_IOCTL(USBDEVFS_RESET),
4401 COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT),
4402 /* MTD */
4403 COMPATIBLE_IOCTL(MEMGETINFO),
4404 COMPATIBLE_IOCTL(MEMERASE),
4405 COMPATIBLE_IOCTL(MEMLOCK),
4406 COMPATIBLE_IOCTL(MEMUNLOCK),
4407 COMPATIBLE_IOCTL(MEMGETREGIONCOUNT),
4408 COMPATIBLE_IOCTL(MEMGETREGIONINFO),
4409 /* NBD */
4410 COMPATIBLE_IOCTL(NBD_SET_SOCK),
4411 COMPATIBLE_IOCTL(NBD_SET_BLKSIZE),
4412 COMPATIBLE_IOCTL(NBD_SET_SIZE),
4413 COMPATIBLE_IOCTL(NBD_DO_IT),
4414 COMPATIBLE_IOCTL(NBD_CLEAR_SOCK),
4415 COMPATIBLE_IOCTL(NBD_CLEAR_QUE),
4416 COMPATIBLE_IOCTL(NBD_PRINT_DEBUG),
4417 COMPATIBLE_IOCTL(NBD_SET_SIZE_BLOCKS),
4418 COMPATIBLE_IOCTL(NBD_DISCONNECT),
4419 /* Remove *PRIVATE in 2.5 */
4420 COMPATIBLE_IOCTL(SIOCDEVPRIVATE),
4421 COMPATIBLE_IOCTL(SIOCDEVPRIVATE+1),
4422 COMPATIBLE_IOCTL(SIOCDEVPRIVATE+2),
4423 COMPATIBLE_IOCTL(SIOCGMIIPHY),
4424 COMPATIBLE_IOCTL(SIOCGMIIREG),
4425 COMPATIBLE_IOCTL(SIOCSMIIREG),
4426 /* And these ioctls need translation */
4427 HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob),
4428 HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob),
4429 #ifdef CONFIG_NET
4430 HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32),
4431 #endif
4432 HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf),
4433 HANDLE_IOCTL(SIOCGIFFLAGS, dev_ifsioc),
4434 HANDLE_IOCTL(SIOCSIFFLAGS, dev_ifsioc),
4435 HANDLE_IOCTL(SIOCGIFMETRIC, dev_ifsioc),
4436 HANDLE_IOCTL(SIOCSIFMETRIC, dev_ifsioc),
4437 HANDLE_IOCTL(SIOCGIFMTU, dev_ifsioc),
4438 HANDLE_IOCTL(SIOCSIFMTU, dev_ifsioc),
4439 HANDLE_IOCTL(SIOCGIFMEM, dev_ifsioc),
4440 HANDLE_IOCTL(SIOCSIFMEM, dev_ifsioc),
4441 HANDLE_IOCTL(SIOCGIFHWADDR, dev_ifsioc),
4442 HANDLE_IOCTL(SIOCSIFHWADDR, dev_ifsioc),
4443 HANDLE_IOCTL(SIOCADDMULTI, dev_ifsioc),
4444 HANDLE_IOCTL(SIOCDELMULTI, dev_ifsioc),
4445 HANDLE_IOCTL(SIOCGIFINDEX, dev_ifsioc),
4446 HANDLE_IOCTL(SIOCGIFMAP, dev_ifsioc),
4447 HANDLE_IOCTL(SIOCSIFMAP, dev_ifsioc),
4448 HANDLE_IOCTL(SIOCGIFADDR, dev_ifsioc),
4449 HANDLE_IOCTL(SIOCSIFADDR, dev_ifsioc),
4450 HANDLE_IOCTL(SIOCGIFBRDADDR, dev_ifsioc),
4451 HANDLE_IOCTL(SIOCSIFBRDADDR, dev_ifsioc),
4452 HANDLE_IOCTL(SIOCGIFDSTADDR, dev_ifsioc),
4453 HANDLE_IOCTL(SIOCSIFDSTADDR, dev_ifsioc),
4454 HANDLE_IOCTL(SIOCGIFNETMASK, dev_ifsioc),
4455 HANDLE_IOCTL(SIOCSIFNETMASK, dev_ifsioc),
4456 HANDLE_IOCTL(SIOCSIFPFLAGS, dev_ifsioc),
4457 HANDLE_IOCTL(SIOCGIFPFLAGS, dev_ifsioc),
4458 HANDLE_IOCTL(SIOCGIFTXQLEN, dev_ifsioc),
4459 HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc),
4460 HANDLE_IOCTL(SIOCETHTOOL, ethtool_ioctl),
4461 HANDLE_IOCTL(SIOCBONDENSLAVE, bond_ioctl),
4462 HANDLE_IOCTL(SIOCBONDRELEASE, bond_ioctl),
4463 HANDLE_IOCTL(SIOCBONDSETHWADDR, bond_ioctl),
4464 HANDLE_IOCTL(SIOCBONDSLAVEINFOQUERY, bond_ioctl),
4465 HANDLE_IOCTL(SIOCBONDINFOQUERY, bond_ioctl),
4466 HANDLE_IOCTL(SIOCBONDCHANGEACTIVE, bond_ioctl),
4467 HANDLE_IOCTL(SIOCADDRT, routing_ioctl),
4468 HANDLE_IOCTL(SIOCDELRT, routing_ioctl),
4469 /* Note SIOCRTMSG is no longer, so this is safe and
4470 * the user would have seen just an -EINVAL anyways. */
4471 HANDLE_IOCTL(SIOCRTMSG, ret_einval),
4472 HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp),
4473 HANDLE_IOCTL(HDIO_GETGEO, hdio_getgeo),
4474 HANDLE_IOCTL(HDIO_GETGEO_BIG, hdio_getgeo_big),
4475 HANDLE_IOCTL(HDIO_GETGEO_BIG_RAW, hdio_getgeo_big),
4476 HANDLE_IOCTL(BLKRAGET, w_long),
4477 HANDLE_IOCTL(BLKGETSIZE, w_long),
4478 HANDLE_IOCTL(0x1260, broken_blkgetsize),
4479 HANDLE_IOCTL(BLKFRAGET, w_long),
4480 HANDLE_IOCTL(BLKSECTGET, w_long),
4481 HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans),
4482 HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans),
4483 HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans),
4484 HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans),
4485 HANDLE_IOCTL(HDIO_GET_32BIT, hdio_ioctl_trans),
4486 HANDLE_IOCTL(HDIO_GET_MULTCOUNT, hdio_ioctl_trans),
4487 HANDLE_IOCTL(HDIO_GET_NOWERR, hdio_ioctl_trans),
4488 HANDLE_IOCTL(HDIO_GET_NICE, hdio_ioctl_trans),
4489 HANDLE_IOCTL(FDSETPRM32, fd_ioctl_trans),
4490 HANDLE_IOCTL(FDDEFPRM32, fd_ioctl_trans),
4491 HANDLE_IOCTL(FDGETPRM32, fd_ioctl_trans),
4492 HANDLE_IOCTL(FDSETDRVPRM32, fd_ioctl_trans),
4493 HANDLE_IOCTL(FDGETDRVPRM32, fd_ioctl_trans),
4494 HANDLE_IOCTL(FDGETDRVSTAT32, fd_ioctl_trans),
4495 HANDLE_IOCTL(FDPOLLDRVSTAT32, fd_ioctl_trans),
4496 HANDLE_IOCTL(FDGETFDCSTAT32, fd_ioctl_trans),
4497 HANDLE_IOCTL(FDWERRORGET32, fd_ioctl_trans),
4498 HANDLE_IOCTL(SG_IO,sg_ioctl_trans),
4499 HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans),
4500 HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans),
4501 HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans),
4502 HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans),
4503 HANDLE_IOCTL(MTIOCGETCONFIG32, mt_ioctl_trans),
4504 HANDLE_IOCTL(MTIOCSETCONFIG32, mt_ioctl_trans),
4505 HANDLE_IOCTL(CDROMREADAUDIO, cdrom_ioctl_trans),
4506 HANDLE_IOCTL(CDROMREADALL, cdrom_ioctl_trans),
4507 HANDLE_IOCTL(CDROM_SEND_PACKET, cdrom_ioctl_trans),
4508 HANDLE_IOCTL(LOOP_SET_STATUS, loop_status),
4509 HANDLE_IOCTL(LOOP_GET_STATUS, loop_status),
4510 HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout),
4511 #ifdef CONFIG_VT
4512 HANDLE_IOCTL(PIO_FONTX, do_fontx_ioctl),
4513 HANDLE_IOCTL(GIO_FONTX, do_fontx_ioctl),
4514 HANDLE_IOCTL(PIO_UNIMAP, do_unimap_ioctl),
4515 HANDLE_IOCTL(GIO_UNIMAP, do_unimap_ioctl),
4516 HANDLE_IOCTL(KDFONTOP, do_kdfontop_ioctl),
4517 HANDLE_IOCTL(FBIOGET_FSCREENINFO, do_fbioget_fscreeninfo_ioctl),
4518 HANDLE_IOCTL(FBIOGETCMAP, do_fbiogetcmap_ioctl),
4519 HANDLE_IOCTL(FBIOPUTCMAP, do_fbioputcmap_ioctl),
4520 #endif
4521 HANDLE_IOCTL(EXT2_IOC32_GETFLAGS, do_ext2_ioctl),
4522 HANDLE_IOCTL(EXT2_IOC32_SETFLAGS, do_ext2_ioctl),
4523 HANDLE_IOCTL(EXT2_IOC32_GETVERSION, do_ext2_ioctl),
4524 HANDLE_IOCTL(EXT2_IOC32_SETVERSION, do_ext2_ioctl),
4525 HANDLE_IOCTL(VIDIOCGTUNER32, do_video_ioctl),
4526 HANDLE_IOCTL(VIDIOCSTUNER32, do_video_ioctl),
4527 HANDLE_IOCTL(VIDIOCGWIN32, do_video_ioctl),
4528 HANDLE_IOCTL(VIDIOCSWIN32, do_video_ioctl),
4529 HANDLE_IOCTL(VIDIOCGFBUF32, do_video_ioctl),
4530 HANDLE_IOCTL(VIDIOCSFBUF32, do_video_ioctl),
4531 HANDLE_IOCTL(VIDIOCGFREQ32, do_video_ioctl),
4532 HANDLE_IOCTL(VIDIOCSFREQ32, do_video_ioctl),
4533 /* One SMB ioctl needs translations. */
4534 HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid),
4535 HANDLE_IOCTL(ATM_GETLINKRATE32, do_atm_ioctl),
4536 HANDLE_IOCTL(ATM_GETNAMES32, do_atm_ioctl),
4537 HANDLE_IOCTL(ATM_GETTYPE32, do_atm_ioctl),
4538 HANDLE_IOCTL(ATM_GETESI32, do_atm_ioctl),
4539 HANDLE_IOCTL(ATM_GETADDR32, do_atm_ioctl),
4540 HANDLE_IOCTL(ATM_RSTADDR32, do_atm_ioctl),
4541 HANDLE_IOCTL(ATM_ADDADDR32, do_atm_ioctl),
4542 HANDLE_IOCTL(ATM_DELADDR32, do_atm_ioctl),
4543 HANDLE_IOCTL(ATM_GETCIRANGE32, do_atm_ioctl),
4544 HANDLE_IOCTL(ATM_SETCIRANGE32, do_atm_ioctl),
4545 HANDLE_IOCTL(ATM_SETESI32, do_atm_ioctl),
4546 HANDLE_IOCTL(ATM_SETESIF32, do_atm_ioctl),
4547 HANDLE_IOCTL(ATM_GETSTAT32, do_atm_ioctl),
4548 HANDLE_IOCTL(ATM_GETSTATZ32, do_atm_ioctl),
4549 HANDLE_IOCTL(ATM_GETLOOP32, do_atm_ioctl),
4550 HANDLE_IOCTL(ATM_SETLOOP32, do_atm_ioctl),
4551 HANDLE_IOCTL(ATM_QUERYLOOP32, do_atm_ioctl),
4552 HANDLE_IOCTL(SONET_GETSTAT, do_atm_ioctl),
4553 HANDLE_IOCTL(SONET_GETSTATZ, do_atm_ioctl),
4554 HANDLE_IOCTL(SONET_GETDIAG, do_atm_ioctl),
4555 HANDLE_IOCTL(SONET_SETDIAG, do_atm_ioctl),
4556 HANDLE_IOCTL(SONET_CLRDIAG, do_atm_ioctl),
4557 HANDLE_IOCTL(SONET_SETFRAMING, do_atm_ioctl),
4558 HANDLE_IOCTL(SONET_GETFRAMING, do_atm_ioctl),
4559 HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl),
4560 #if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
4561 HANDLE_IOCTL(VG_STATUS, do_lvm_ioctl),
4562 HANDLE_IOCTL(VG_CREATE_OLD, do_lvm_ioctl),
4563 HANDLE_IOCTL(VG_CREATE, do_lvm_ioctl),
4564 HANDLE_IOCTL(VG_EXTEND, do_lvm_ioctl),
4565 HANDLE_IOCTL(LV_CREATE, do_lvm_ioctl),
4566 HANDLE_IOCTL(LV_REMOVE, do_lvm_ioctl),
4567 HANDLE_IOCTL(LV_EXTEND, do_lvm_ioctl),
4568 HANDLE_IOCTL(LV_REDUCE, do_lvm_ioctl),
4569 HANDLE_IOCTL(LV_RENAME, do_lvm_ioctl),
4570 HANDLE_IOCTL(LV_STATUS_BYNAME, do_lvm_ioctl),
4571 HANDLE_IOCTL(LV_STATUS_BYINDEX, do_lvm_ioctl),
4572 HANDLE_IOCTL(LV_STATUS_BYDEV, do_lvm_ioctl),
4573 HANDLE_IOCTL(PV_CHANGE, do_lvm_ioctl),
4574 HANDLE_IOCTL(PV_STATUS, do_lvm_ioctl),
4575 #endif /* LVM */
4576 #if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
4577 HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version),
4578 HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique),
4579 HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique),
4580 HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap),
4581 HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs),
4582 HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs),
4583 HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs),
4584 HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma),
4585 HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx),
4586 #endif /* DRM */
4587 HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control),
4588 HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk),
4589 /*HANDLE_IOCTL(USBDEVFS_SUBMITURB32, do_usbdevfs_urb)*/
4590 HANDLE_IOCTL(USBDEVFS_REAPURB32, do_usbdevfs_reapurb),
4591 HANDLE_IOCTL(USBDEVFS_REAPURBNDELAY32, do_usbdevfs_reapurb),
4592 HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal),
4593 /* take care of sizeof(sizeof()) breakage */
4594 /* elevator */
4595 HANDLE_IOCTL(BLKELVGET_32, do_blkelvget),
4596 HANDLE_IOCTL(BLKELVSET_32, do_blkelvset),
4597 /* block stuff */
4598 HANDLE_IOCTL(BLKBSZGET_32, do_blkbszget),
4599 HANDLE_IOCTL(BLKBSZSET_32, do_blkbszset),
4600 HANDLE_IOCTL(BLKGETSIZE64_32, do_blkgetsize64),
4601 };
4602
4603 unsigned long ioctl32_hash_table[1024];
4604
ioctl32_hash(unsigned long cmd)4605 static inline unsigned long ioctl32_hash(unsigned long cmd)
4606 {
4607 return ((cmd >> 6) ^ (cmd >> 4) ^ cmd) & 0x3ff;
4608 }
4609
ioctl32_insert_translation(struct ioctl_trans * trans)4610 static void ioctl32_insert_translation(struct ioctl_trans *trans)
4611 {
4612 unsigned long hash;
4613 struct ioctl_trans *t;
4614
4615 hash = ioctl32_hash (trans->cmd);
4616 if (!ioctl32_hash_table[hash])
4617 ioctl32_hash_table[hash] = (long)trans;
4618 else {
4619 t = (struct ioctl_trans *)ioctl32_hash_table[hash];
4620 while (t->next)
4621 t = (struct ioctl_trans *)(long)t->next;
4622 trans->next = 0;
4623 t->next = (long)trans;
4624 }
4625 }
4626
init_sys32_ioctl(void)4627 static int __init init_sys32_ioctl(void)
4628 {
4629 int i, size = sizeof(ioctl_translations) / sizeof(struct ioctl_trans);
4630 for (i=0; i < size ;i++)
4631 ioctl32_insert_translation(&ioctl_translations[i]);
4632 return 0;
4633 }
4634
4635 __initcall(init_sys32_ioctl);
4636
4637 static struct ioctl_trans *additional_ioctls;
4638
4639 /* Always call these with kernel lock held! */
4640
register_ioctl32_conversion(unsigned int cmd,int (* handler)(unsigned int,unsigned int,unsigned long,struct file *))4641 int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *))
4642 {
4643 int i;
4644 if (!additional_ioctls) {
4645 additional_ioctls = module_map(PAGE_SIZE);
4646 if (!additional_ioctls)
4647 return -ENOMEM;
4648 memset(additional_ioctls, 0, PAGE_SIZE);
4649 }
4650 for (i = 0; i < PAGE_SIZE/sizeof(struct ioctl_trans); i++)
4651 if (!additional_ioctls[i].cmd)
4652 break;
4653 if (i == PAGE_SIZE/sizeof(struct ioctl_trans))
4654 return -ENOMEM;
4655 additional_ioctls[i].cmd = cmd;
4656 if (!handler)
4657 additional_ioctls[i].handler = (long)sys_ioctl;
4658 else
4659 additional_ioctls[i].handler = (long)handler;
4660 ioctl32_insert_translation(&additional_ioctls[i]);
4661 return 0;
4662 }
4663
unregister_ioctl32_conversion(unsigned int cmd)4664 int unregister_ioctl32_conversion(unsigned int cmd)
4665 {
4666 unsigned long hash = ioctl32_hash(cmd);
4667 struct ioctl_trans *t, *t1;
4668
4669 t = (struct ioctl_trans *)ioctl32_hash_table[hash];
4670 if (!t) return -EINVAL;
4671 if (t->cmd == cmd && t >= additional_ioctls &&
4672 (unsigned long)t < ((unsigned long)additional_ioctls) + PAGE_SIZE) {
4673 ioctl32_hash_table[hash] = t->next;
4674 t->cmd = 0;
4675 return 0;
4676 } else while (t->next) {
4677 t1 = (struct ioctl_trans *)t->next;
4678 if (t1->cmd == cmd && t1 >= additional_ioctls &&
4679 (unsigned long)t1 < ((unsigned long)additional_ioctls) + PAGE_SIZE) {
4680 t1->cmd = 0;
4681 t->next = t1->next;
4682 return 0;
4683 }
4684 t = t1;
4685 }
4686 return -EINVAL;
4687 }
4688
sys32_ioctl(unsigned int fd,unsigned int cmd,unsigned long arg)4689 asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
4690 {
4691 struct file * filp;
4692 int error = -EBADF;
4693 int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
4694 struct ioctl_trans *t;
4695
4696 filp = fget(fd);
4697 if (!filp)
4698 goto out2;
4699
4700 if (!filp->f_op || !filp->f_op->ioctl) {
4701 error = sys_ioctl (fd, cmd, arg);
4702 goto out;
4703 }
4704
4705 t = (struct ioctl_trans *)ioctl32_hash_table [ioctl32_hash (cmd)];
4706
4707 while (t && t->cmd != cmd)
4708 t = (struct ioctl_trans *)t->next;
4709 if (t) {
4710 handler = (void *)t->handler;
4711 error = handler(fd, cmd, arg, filp);
4712 } else {
4713 static int count = 0;
4714 if (++count <= 20)
4715 printk("sys32_ioctl(%s:%d): Unknown cmd fd(%d) "
4716 "cmd(%08x) arg(%08x)\n",
4717 current->comm, current->pid,
4718 (int)fd, (unsigned int)cmd, (unsigned int)arg);
4719 error = -EINVAL;
4720 }
4721 out:
4722 fput(filp);
4723 out2:
4724 return error;
4725 }
4726