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