File: /usr/src/linux/arch/sparc64/kernel/ioctl32.c
1 /* $Id: ioctl32.c,v 1.125 2001/09/18 22:29:05 davem Exp $
2 * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
3 *
4 * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
5 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
6 *
7 * These routines maintain argument size conversion between 32bit and 64bit
8 * ioctls.
9 */
10
11 #include <linux/config.h>
12 #include <linux/types.h>
13 #include <linux/kernel.h>
14 #include <linux/sched.h>
15 #include <linux/smp.h>
16 #include <linux/smp_lock.h>
17 #include <linux/ioctl.h>
18 #include <linux/if.h>
19 #include <linux/slab.h>
20 #include <linux/hdreg.h>
21 #include <linux/raid/md.h>
22 #include <linux/kd.h>
23 #include <linux/route.h>
24 #include <linux/in6.h>
25 #include <linux/ipv6_route.h>
26 #include <linux/skbuff.h>
27 #include <linux/netlink.h>
28 #include <linux/vt.h>
29 #include <linux/fs.h>
30 #include <linux/file.h>
31 #include <linux/fd.h>
32 #include <linux/ppp_defs.h>
33 #include <linux/if_ppp.h>
34 #include <linux/if_pppox.h>
35 #include <linux/mtio.h>
36 #include <linux/cdrom.h>
37 #include <linux/loop.h>
38 #include <linux/auto_fs.h>
39 #include <linux/devfs_fs.h>
40 #include <linux/tty.h>
41 #include <linux/vt_kern.h>
42 #include <linux/fb.h>
43 #include <linux/ext2_fs.h>
44 #include <linux/videodev.h>
45 #include <linux/netdevice.h>
46 #include <linux/raw.h>
47 #include <linux/smb_fs.h>
48 #include <linux/blkpg.h>
49 #include <linux/blk.h>
50 #include <linux/elevator.h>
51 #include <linux/rtc.h>
52 #include <linux/pci.h>
53 #if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
54 #include <linux/lvm.h>
55 #endif /* LVM */
56
57 #include <scsi/scsi.h>
58 /* Ugly hack. */
59 #undef __KERNEL__
60 #include <scsi/scsi_ioctl.h>
61 #define __KERNEL__
62 #include <scsi/sg.h>
63
64 #include <asm/types.h>
65 #include <asm/uaccess.h>
66 #include <asm/fbio.h>
67 #include <asm/kbio.h>
68 #include <asm/vuid_event.h>
69 #include <asm/openpromio.h>
70 #include <asm/envctrl.h>
71 #include <asm/audioio.h>
72 #include <linux/ethtool.h>
73 #include <linux/mii.h>
74 #include <asm/display7seg.h>
75 #include <asm/watchdog.h>
76 #include <asm/module.h>
77 #include <linux/soundcard.h>
78
79 #include <linux/atm.h>
80 #include <linux/atmarp.h>
81 #include <linux/atmclip.h>
82 #include <linux/atmdev.h>
83 #include <linux/atmioc.h>
84 #include <linux/atmlec.h>
85 #include <linux/atmmpc.h>
86 #include <linux/atmsvc.h>
87 #include <linux/atm_tcp.h>
88 #include <linux/sonet.h>
89 #include <linux/atm_suni.h>
90 #include <linux/mtd/mtd.h>
91
92 #include <net/bluetooth/bluetooth.h>
93 #include <net/bluetooth/hci.h>
94
95 #include <linux/usb.h>
96 #include <linux/usbdevice_fs.h>
97 #include <linux/nbd.h>
98
99 /* Use this to get at 32-bit user passed pointers.
100 See sys_sparc32.c for description about these. */
101 #define A(__x) ((unsigned long)(__x))
102 #define AA(__x) \
103 ({ unsigned long __ret; \
104 __asm__ ("srl %0, 0, %0" \
105 : "=r" (__ret) \
106 : "0" (__x)); \
107 __ret; \
108 })
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
116 extern asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
117
118 static 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
132 static 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
148 static 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
160 struct video_tuner32 {
161 s32 tuner;
162 u8 name[32];
163 u32 rangelow, rangehigh;
164 u32 flags;
165 u16 mode, signal;
166 };
167
168 static 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
184 static 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
200 struct video_buffer32 {
201 /* void * */ u32 base;
202 s32 height, width, depth, bytesperline;
203 };
204
205 static 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
219 static 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
232 struct video_clip32 {
233 s32 x, y, width, height;
234 /* struct video_clip32 * */ u32 next;
235 };
236
237 struct video_window32 {
238 u32 x, y, width, height, chromakey, flags;
239 /* struct video_clip32 * */ u32 clips;
240 s32 clipcount;
241 };
242
243 static 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
252 static 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
298 cleanup_and_err:
299 free_kvideo_clips(kp);
300 return err;
301 }
302
303 /* You get back everything except the clips... */
304 static 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
326 static 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 }
397 out:
398 return err;
399 }
400
401 struct timeval32 {
402 int tv_sec;
403 int tv_usec;
404 };
405
406 static 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
423 struct 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
432 struct 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
454 struct ifconf32 {
455 int ifc_len; /* size of buffer */
456 __kernel_caddr_t32 ifcbuf;
457 };
458
459 static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg)
460 {
461 struct net_device *dev;
462 struct ifreq32 ifr32;
463 int err;
464
465 if (copy_from_user(&ifr32, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
466 return -EFAULT;
467
468 dev = dev_get_by_index(ifr32.ifr_ifindex);
469 if (!dev)
470 return -ENODEV;
471
472 strcpy(ifr32.ifr_name, dev->name);
473
474 err = copy_to_user((struct ifreq32 *)arg, &ifr32, sizeof(struct ifreq32));
475 return (err ? -EFAULT : 0);
476 }
477
478 static inline int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
479 {
480 struct ifconf32 ifc32;
481 struct ifconf ifc;
482 struct ifreq32 *ifr32;
483 struct ifreq *ifr;
484 mm_segment_t old_fs;
485 unsigned int i, j;
486 int err;
487
488 if (copy_from_user(&ifc32, (struct ifconf32 *)arg, sizeof(struct ifconf32)))
489 return -EFAULT;
490
491 if(ifc32.ifcbuf == 0) {
492 ifc32.ifc_len = 0;
493 ifc.ifc_len = 0;
494 ifc.ifc_buf = NULL;
495 } else {
496 ifc.ifc_len = ((ifc32.ifc_len / sizeof (struct ifreq32)) + 1) *
497 sizeof (struct ifreq);
498 ifc.ifc_buf = kmalloc (ifc.ifc_len, GFP_KERNEL);
499 if (!ifc.ifc_buf)
500 return -ENOMEM;
501 }
502 ifr = ifc.ifc_req;
503 ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf);
504 for (i = 0; i < ifc32.ifc_len; i += sizeof (struct ifreq32)) {
505 if (copy_from_user(ifr++, ifr32++, sizeof (struct ifreq32))) {
506 kfree (ifc.ifc_buf);
507 return -EFAULT;
508 }
509 }
510 old_fs = get_fs(); set_fs (KERNEL_DS);
511 err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc);
512 set_fs (old_fs);
513 if (!err) {
514 ifr = ifc.ifc_req;
515 ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf);
516 for (i = 0, j = 0; i < ifc32.ifc_len && j < ifc.ifc_len;
517 i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) {
518 if (copy_to_user(ifr32++, ifr++, sizeof (struct ifreq32))) {
519 err = -EFAULT;
520 break;
521 }
522 }
523 if (!err) {
524 if (ifc32.ifcbuf == 0) {
525 /* Translate from 64-bit structure multiple to
526 * a 32-bit one.
527 */
528 i = ifc.ifc_len;
529 i = ((i / sizeof(struct ifreq)) * sizeof(struct ifreq32));
530 ifc32.ifc_len = i;
531 } else {
532 if (i <= ifc32.ifc_len)
533 ifc32.ifc_len = i;
534 else
535 ifc32.ifc_len = i - sizeof (struct ifreq32);
536 }
537 if (copy_to_user((struct ifconf32 *)arg, &ifc32, sizeof(struct ifconf32)))
538 err = -EFAULT;
539 }
540 }
541 if(ifc.ifc_buf != NULL)
542 kfree (ifc.ifc_buf);
543 return err;
544 }
545
546 static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
547 {
548 struct ifreq ifr;
549 mm_segment_t old_fs;
550 int err, len;
551 u32 data, ethcmd;
552
553 if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
554 return -EFAULT;
555 ifr.ifr_data = (__kernel_caddr_t)get_free_page(GFP_KERNEL);
556 if (!ifr.ifr_data)
557 return -EAGAIN;
558
559 __get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
560
561 if (get_user(ethcmd, (u32 *)A(data))) {
562 err = -EFAULT;
563 goto out;
564 }
565 switch (ethcmd) {
566 case ETHTOOL_GDRVINFO: len = sizeof(struct ethtool_drvinfo); break;
567 case ETHTOOL_GSET:
568 case ETHTOOL_SSET:
569 default: len = sizeof(struct ethtool_cmd); break;
570 }
571
572 if (copy_from_user(ifr.ifr_data, (char *)A(data), len)) {
573 err = -EFAULT;
574 goto out;
575 }
576
577 old_fs = get_fs();
578 set_fs (KERNEL_DS);
579 err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
580 set_fs (old_fs);
581 if (!err) {
582 u32 data;
583
584 __get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
585 len = copy_to_user((char *)A(data), ifr.ifr_data, len);
586 if (len)
587 err = -EFAULT;
588 }
589
590 out:
591 free_page((unsigned long)ifr.ifr_data);
592 return err;
593 }
594
595 static int mii_ioctl(unsigned long fd, unsigned int cmd, unsigned long arg)
596 {
597 struct ifreq ifr;
598 mm_segment_t old_fs;
599 int err;
600 u32 data;
601
602 if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
603 return -EFAULT;
604 ifr.ifr_data = (__kernel_caddr_t) kmalloc(sizeof(struct mii_ioctl_data),
605 GFP_KERNEL);
606 if (!ifr.ifr_data)
607 return -EAGAIN;
608
609 __get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
610 if (copy_from_user(ifr.ifr_data, (char *)A(data),
611 sizeof(struct mii_ioctl_data))) {
612 err = -EFAULT;
613 goto out;
614 }
615
616 old_fs = get_fs();
617 set_fs(KERNEL_DS);
618 err = sys_ioctl(fd, cmd, (unsigned long)&ifr);
619 set_fs(old_fs);
620
621 if (!err) {
622 if (copy_to_user((char *)A(data),
623 ifr.ifr_data,
624 sizeof(struct mii_ioctl_data)))
625 err = -EFAULT;
626 }
627
628 out:
629 kfree(ifr.ifr_data);
630 return err;
631 }
632
633 static inline int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
634 {
635 struct ifreq ifr;
636 mm_segment_t old_fs;
637 int err;
638
639 switch (cmd) {
640 case SIOCSIFMAP:
641 err = copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(ifr.ifr_name));
642 err |= __get_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));
643 err |= __get_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));
644 err |= __get_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));
645 err |= __get_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));
646 err |= __get_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));
647 err |= __get_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));
648 if (err)
649 return -EFAULT;
650 break;
651 case SIOCGPPPSTATS:
652 case SIOCGPPPCSTATS:
653 case SIOCGPPPVER:
654 if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
655 return -EFAULT;
656 ifr.ifr_data = (__kernel_caddr_t)get_free_page(GFP_KERNEL);
657 if (!ifr.ifr_data)
658 return -EAGAIN;
659 break;
660 default:
661 if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
662 return -EFAULT;
663 break;
664 }
665 old_fs = get_fs();
666 set_fs (KERNEL_DS);
667 err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
668 set_fs (old_fs);
669 if (!err) {
670 switch (cmd) {
671 case SIOCGIFFLAGS:
672 case SIOCGIFMETRIC:
673 case SIOCGIFMTU:
674 case SIOCGIFMEM:
675 case SIOCGIFHWADDR:
676 case SIOCGIFINDEX:
677 case SIOCGIFADDR:
678 case SIOCGIFBRDADDR:
679 case SIOCGIFDSTADDR:
680 case SIOCGIFNETMASK:
681 case SIOCGIFTXQLEN:
682 if (copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(struct ifreq32)))
683 return -EFAULT;
684 break;
685 case SIOCGPPPSTATS:
686 case SIOCGPPPCSTATS:
687 case SIOCGPPPVER:
688 {
689 u32 data;
690 int len;
691
692 __get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
693 if(cmd == SIOCGPPPVER)
694 len = strlen((char *)ifr.ifr_data) + 1;
695 else if(cmd == SIOCGPPPCSTATS)
696 len = sizeof(struct ppp_comp_stats);
697 else
698 len = sizeof(struct ppp_stats);
699
700 len = copy_to_user((char *)A(data), ifr.ifr_data, len);
701 free_page((unsigned long)ifr.ifr_data);
702 if(len)
703 return -EFAULT;
704 break;
705 }
706 case SIOCGIFMAP:
707 err = copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(ifr.ifr_name));
708 err |= __put_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));
709 err |= __put_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));
710 err |= __put_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));
711 err |= __put_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));
712 err |= __put_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));
713 err |= __put_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));
714 if (err)
715 err = -EFAULT;
716 break;
717 }
718 } else {
719 switch (cmd) {
720 case SIOCGPPPSTATS:
721 case SIOCGPPPCSTATS:
722 case SIOCGPPPVER:
723 free_page((unsigned long)ifr.ifr_data);
724 break;
725 }
726 }
727 return err;
728 }
729
730 struct rtentry32 {
731 u32 rt_pad1;
732 struct sockaddr rt_dst; /* target address */
733 struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */
734 struct sockaddr rt_genmask; /* target network mask (IP) */
735 unsigned short rt_flags;
736 short rt_pad2;
737 u32 rt_pad3;
738 unsigned char rt_tos;
739 unsigned char rt_class;
740 short rt_pad4;
741 short rt_metric; /* +1 for binary compatibility! */
742 /* char * */ u32 rt_dev; /* forcing the device at add */
743 u32 rt_mtu; /* per route MTU/Window */
744 u32 rt_window; /* Window clamping */
745 unsigned short rt_irtt; /* Initial RTT */
746
747 };
748
749 struct in6_rtmsg32 {
750 struct in6_addr rtmsg_dst;
751 struct in6_addr rtmsg_src;
752 struct in6_addr rtmsg_gateway;
753 u32 rtmsg_type;
754 u16 rtmsg_dst_len;
755 u16 rtmsg_src_len;
756 u32 rtmsg_metric;
757 u32 rtmsg_info;
758 u32 rtmsg_flags;
759 s32 rtmsg_ifindex;
760 };
761
762 extern struct socket *sockfd_lookup(int fd, int *err);
763
764 static inline 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 return ret;
813 }
814
815 struct hd_geometry32 {
816 unsigned char heads;
817 unsigned char sectors;
818 unsigned short cylinders;
819 u32 start;
820 };
821
822 static inline int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg)
823 {
824 mm_segment_t old_fs = get_fs();
825 struct hd_geometry geo;
826 int err;
827
828 set_fs (KERNEL_DS);
829 err = sys_ioctl(fd, HDIO_GETGEO, (unsigned long)&geo);
830 set_fs (old_fs);
831 if (!err) {
832 err = copy_to_user ((struct hd_geometry32 *)arg, &geo, 4);
833 err |= __put_user (geo.start, &(((struct hd_geometry32 *)arg)->start));
834 }
835 return err ? -EFAULT : 0;
836 }
837
838 struct fbcmap32 {
839 int index; /* first element (0 origin) */
840 int count;
841 u32 red;
842 u32 green;
843 u32 blue;
844 };
845
846 #define FBIOPUTCMAP32 _IOW('F', 3, struct fbcmap32)
847 #define FBIOGETCMAP32 _IOW('F', 4, struct fbcmap32)
848
849 static inline int fbiogetputcmap(unsigned int fd, unsigned int cmd, unsigned long arg)
850 {
851 struct fbcmap f;
852 int ret;
853 char red[256], green[256], blue[256];
854 u32 r, g, b;
855 mm_segment_t old_fs = get_fs();
856
857 ret = get_user(f.index, &(((struct fbcmap32 *)arg)->index));
858 ret |= __get_user(f.count, &(((struct fbcmap32 *)arg)->count));
859 ret |= __get_user(r, &(((struct fbcmap32 *)arg)->red));
860 ret |= __get_user(g, &(((struct fbcmap32 *)arg)->green));
861 ret |= __get_user(b, &(((struct fbcmap32 *)arg)->blue));
862 if (ret)
863 return -EFAULT;
864 if ((f.index < 0) || (f.index > 255)) return -EINVAL;
865 if (f.index + f.count > 256)
866 f.count = 256 - f.index;
867 if (cmd == FBIOPUTCMAP32) {
868 ret = copy_from_user (red, (char *)A(r), f.count);
869 ret |= copy_from_user (green, (char *)A(g), f.count);
870 ret |= copy_from_user (blue, (char *)A(b), f.count);
871 if (ret)
872 return -EFAULT;
873 }
874 f.red = red; f.green = green; f.blue = blue;
875 set_fs (KERNEL_DS);
876 ret = sys_ioctl (fd, (cmd == FBIOPUTCMAP32) ? FBIOPUTCMAP_SPARC : FBIOGETCMAP_SPARC, (long)&f);
877 set_fs (old_fs);
878 if (!ret && cmd == FBIOGETCMAP32) {
879 ret = copy_to_user ((char *)A(r), red, f.count);
880 ret |= copy_to_user ((char *)A(g), green, f.count);
881 ret |= copy_to_user ((char *)A(b), blue, f.count);
882 }
883 return ret ? -EFAULT : 0;
884 }
885
886 struct fbcursor32 {
887 short set; /* what to set, choose from the list above */
888 short enable; /* cursor on/off */
889 struct fbcurpos pos; /* cursor position */
890 struct fbcurpos hot; /* cursor hot spot */
891 struct fbcmap32 cmap; /* color map info */
892 struct fbcurpos size; /* cursor bit map size */
893 u32 image; /* cursor image bits */
894 u32 mask; /* cursor mask bits */
895 };
896
897 #define FBIOSCURSOR32 _IOW('F', 24, struct fbcursor32)
898 #define FBIOGCURSOR32 _IOW('F', 25, struct fbcursor32)
899
900 static inline int fbiogscursor(unsigned int fd, unsigned int cmd, unsigned long arg)
901 {
902 struct fbcursor f;
903 int ret;
904 char red[2], green[2], blue[2];
905 char image[128], mask[128];
906 u32 r, g, b;
907 u32 m, i;
908 mm_segment_t old_fs = get_fs();
909
910 ret = copy_from_user (&f, (struct fbcursor32 *)arg, 2 * sizeof (short) + 2 * sizeof(struct fbcurpos));
911 ret |= __get_user(f.size.fbx, &(((struct fbcursor32 *)arg)->size.fbx));
912 ret |= __get_user(f.size.fby, &(((struct fbcursor32 *)arg)->size.fby));
913 ret |= __get_user(f.cmap.index, &(((struct fbcursor32 *)arg)->cmap.index));
914 ret |= __get_user(f.cmap.count, &(((struct fbcursor32 *)arg)->cmap.count));
915 ret |= __get_user(r, &(((struct fbcursor32 *)arg)->cmap.red));
916 ret |= __get_user(g, &(((struct fbcursor32 *)arg)->cmap.green));
917 ret |= __get_user(b, &(((struct fbcursor32 *)arg)->cmap.blue));
918 ret |= __get_user(m, &(((struct fbcursor32 *)arg)->mask));
919 ret |= __get_user(i, &(((struct fbcursor32 *)arg)->image));
920 if (ret)
921 return -EFAULT;
922 if (f.set & FB_CUR_SETCMAP) {
923 if ((uint) f.size.fby > 32)
924 return -EINVAL;
925 ret = copy_from_user (mask, (char *)A(m), f.size.fby * 4);
926 ret |= copy_from_user (image, (char *)A(i), f.size.fby * 4);
927 if (ret)
928 return -EFAULT;
929 f.image = image; f.mask = mask;
930 }
931 if (f.set & FB_CUR_SETCMAP) {
932 ret = copy_from_user (red, (char *)A(r), 2);
933 ret |= copy_from_user (green, (char *)A(g), 2);
934 ret |= copy_from_user (blue, (char *)A(b), 2);
935 if (ret)
936 return -EFAULT;
937 f.cmap.red = red; f.cmap.green = green; f.cmap.blue = blue;
938 }
939 set_fs (KERNEL_DS);
940 ret = sys_ioctl (fd, FBIOSCURSOR, (long)&f);
941 set_fs (old_fs);
942 return ret;
943 }
944
945 struct fb_fix_screeninfo32 {
946 char id[16];
947 __kernel_caddr_t32 smem_start;
948 __u32 smem_len;
949 __u32 type;
950 __u32 type_aux;
951 __u32 visual;
952 __u16 xpanstep;
953 __u16 ypanstep;
954 __u16 ywrapstep;
955 __u32 line_length;
956 __kernel_caddr_t32 mmio_start;
957 __u32 mmio_len;
958 __u32 accel;
959 __u16 reserved[3];
960 };
961
962 struct fb_cmap32 {
963 __u32 start;
964 __u32 len;
965 __kernel_caddr_t32 red;
966 __kernel_caddr_t32 green;
967 __kernel_caddr_t32 blue;
968 __kernel_caddr_t32 transp;
969 };
970
971 static int fb_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
972 {
973 mm_segment_t old_fs = get_fs();
974 u32 red = 0, green = 0, blue = 0, transp = 0;
975 struct fb_fix_screeninfo fix;
976 struct fb_cmap cmap;
977 void *karg;
978 int err = 0;
979
980 memset(&cmap, 0, sizeof(cmap));
981 switch (cmd) {
982 case FBIOGET_FSCREENINFO:
983 karg = &fix;
984 break;
985 case FBIOGETCMAP:
986 case FBIOPUTCMAP:
987 karg = &cmap;
988 err = __get_user(cmap.start, &((struct fb_cmap32 *)arg)->start);
989 err |= __get_user(cmap.len, &((struct fb_cmap32 *)arg)->len);
990 err |= __get_user(red, &((struct fb_cmap32 *)arg)->red);
991 err |= __get_user(green, &((struct fb_cmap32 *)arg)->green);
992 err |= __get_user(blue, &((struct fb_cmap32 *)arg)->blue);
993 err |= __get_user(transp, &((struct fb_cmap32 *)arg)->transp);
994 if (err) {
995 err = -EFAULT;
996 goto out;
997 }
998 err = -ENOMEM;
999 cmap.red = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL);
1000 if (!cmap.red)
1001 goto out;
1002 cmap.green = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL);
1003 if (!cmap.green)
1004 goto out;
1005 cmap.blue = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL);
1006 if (!cmap.blue)
1007 goto out;
1008 if (transp) {
1009 cmap.transp = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL);
1010 if (!cmap.transp)
1011 goto out;
1012 }
1013
1014 if (cmd == FBIOGETCMAP)
1015 break;
1016
1017 err = __copy_from_user(cmap.red, (char *)A(red), cmap.len * sizeof(__u16));
1018 err |= __copy_from_user(cmap.green, (char *)A(green), cmap.len * sizeof(__u16));
1019 err |= __copy_from_user(cmap.blue, (char *)A(blue), cmap.len * sizeof(__u16));
1020 if (cmap.transp) err |= __copy_from_user(cmap.transp, (char *)A(transp), cmap.len * sizeof(__u16));
1021 if (err) {
1022 err = -EFAULT;
1023 goto out;
1024 }
1025 break;
1026 default:
1027 do {
1028 static int count = 0;
1029 if (++count <= 20)
1030 printk("%s: Unknown fb ioctl cmd fd(%d) "
1031 "cmd(%08x) arg(%08lx)\n",
1032 __FUNCTION__, fd, cmd, arg);
1033 } while(0);
1034 return -ENOSYS;
1035 }
1036 set_fs(KERNEL_DS);
1037 err = sys_ioctl(fd, cmd, (unsigned long)karg);
1038 set_fs(old_fs);
1039 if (err)
1040 goto out;
1041 switch (cmd) {
1042 case FBIOGET_FSCREENINFO:
1043 err = __copy_to_user((char *)((struct fb_fix_screeninfo32 *)arg)->id, (char *)fix.id, sizeof(fix.id));
1044 err |= __put_user((__u32)(unsigned long)fix.smem_start, &((struct fb_fix_screeninfo32 *)arg)->smem_start);
1045 err |= __put_user(fix.smem_len, &((struct fb_fix_screeninfo32 *)arg)->smem_len);
1046 err |= __put_user(fix.type, &((struct fb_fix_screeninfo32 *)arg)->type);
1047 err |= __put_user(fix.type_aux, &((struct fb_fix_screeninfo32 *)arg)->type_aux);
1048 err |= __put_user(fix.visual, &((struct fb_fix_screeninfo32 *)arg)->visual);
1049 err |= __put_user(fix.xpanstep, &((struct fb_fix_screeninfo32 *)arg)->xpanstep);
1050 err |= __put_user(fix.ypanstep, &((struct fb_fix_screeninfo32 *)arg)->ypanstep);
1051 err |= __put_user(fix.ywrapstep, &((struct fb_fix_screeninfo32 *)arg)->ywrapstep);
1052 err |= __put_user(fix.line_length, &((struct fb_fix_screeninfo32 *)arg)->line_length);
1053 err |= __put_user((__u32)(unsigned long)fix.mmio_start, &((struct fb_fix_screeninfo32 *)arg)->mmio_start);
1054 err |= __put_user(fix.mmio_len, &((struct fb_fix_screeninfo32 *)arg)->mmio_len);
1055 err |= __put_user(fix.accel, &((struct fb_fix_screeninfo32 *)arg)->accel);
1056 err |= __copy_to_user((char *)((struct fb_fix_screeninfo32 *)arg)->reserved, (char *)fix.reserved, sizeof(fix.reserved));
1057 break;
1058 case FBIOGETCMAP:
1059 err = __copy_to_user((char *)A(red), cmap.red, cmap.len * sizeof(__u16));
1060 err |= __copy_to_user((char *)A(green), cmap.blue, cmap.len * sizeof(__u16));
1061 err |= __copy_to_user((char *)A(blue), cmap.blue, cmap.len * sizeof(__u16));
1062 if (cmap.transp)
1063 err |= __copy_to_user((char *)A(transp), cmap.transp, cmap.len * sizeof(__u16));
1064 break;
1065 case FBIOPUTCMAP:
1066 break;
1067 }
1068 if (err)
1069 err = -EFAULT;
1070
1071 out: if (cmap.red) kfree(cmap.red);
1072 if (cmap.green) kfree(cmap.green);
1073 if (cmap.blue) kfree(cmap.blue);
1074 if (cmap.transp) kfree(cmap.transp);
1075 return err;
1076 }
1077
1078 static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
1079 {
1080 mm_segment_t old_fs = get_fs();
1081 unsigned long kval;
1082 unsigned int *uvp;
1083 int error;
1084
1085 set_fs(KERNEL_DS);
1086 error = sys_ioctl(fd, cmd, (long)&kval);
1087 set_fs(old_fs);
1088
1089 if(error == 0) {
1090 uvp = (unsigned int *)arg;
1091 if(put_user(kval, uvp))
1092 error = -EFAULT;
1093 }
1094 return error;
1095 }
1096
1097 struct floppy_struct32 {
1098 unsigned int size;
1099 unsigned int sect;
1100 unsigned int head;
1101 unsigned int track;
1102 unsigned int stretch;
1103 unsigned char gap;
1104 unsigned char rate;
1105 unsigned char spec1;
1106 unsigned char fmt_gap;
1107 const __kernel_caddr_t32 name;
1108 };
1109
1110 struct floppy_drive_params32 {
1111 char cmos;
1112 u32 max_dtr;
1113 u32 hlt;
1114 u32 hut;
1115 u32 srt;
1116 u32 spinup;
1117 u32 spindown;
1118 unsigned char spindown_offset;
1119 unsigned char select_delay;
1120 unsigned char rps;
1121 unsigned char tracks;
1122 u32 timeout;
1123 unsigned char interleave_sect;
1124 struct floppy_max_errors max_errors;
1125 char flags;
1126 char read_track;
1127 short autodetect[8];
1128 int checkfreq;
1129 int native_format;
1130 };
1131
1132 struct floppy_drive_struct32 {
1133 signed char flags;
1134 u32 spinup_date;
1135 u32 select_date;
1136 u32 first_read_date;
1137 short probed_format;
1138 short track;
1139 short maxblock;
1140 short maxtrack;
1141 int generation;
1142 int keep_data;
1143 int fd_ref;
1144 int fd_device;
1145 int last_checked;
1146 __kernel_caddr_t32 dmabuf;
1147 int bufblocks;
1148 };
1149
1150 struct floppy_fdc_state32 {
1151 int spec1;
1152 int spec2;
1153 int dtr;
1154 unsigned char version;
1155 unsigned char dor;
1156 u32 address;
1157 unsigned int rawcmd:2;
1158 unsigned int reset:1;
1159 unsigned int need_configure:1;
1160 unsigned int perp_mode:2;
1161 unsigned int has_fifo:1;
1162 unsigned int driver_version;
1163 unsigned char track[4];
1164 };
1165
1166 struct floppy_write_errors32 {
1167 unsigned int write_errors;
1168 u32 first_error_sector;
1169 int first_error_generation;
1170 u32 last_error_sector;
1171 int last_error_generation;
1172 unsigned int badness;
1173 };
1174
1175 #define FDSETPRM32 _IOW(2, 0x42, struct floppy_struct32)
1176 #define FDDEFPRM32 _IOW(2, 0x43, struct floppy_struct32)
1177 #define FDGETPRM32 _IOR(2, 0x04, struct floppy_struct32)
1178 #define FDSETDRVPRM32 _IOW(2, 0x90, struct floppy_drive_params32)
1179 #define FDGETDRVPRM32 _IOR(2, 0x11, struct floppy_drive_params32)
1180 #define FDGETDRVSTAT32 _IOR(2, 0x12, struct floppy_drive_struct32)
1181 #define FDPOLLDRVSTAT32 _IOR(2, 0x13, struct floppy_drive_struct32)
1182 #define FDGETFDCSTAT32 _IOR(2, 0x15, struct floppy_fdc_state32)
1183 #define FDWERRORGET32 _IOR(2, 0x17, struct floppy_write_errors32)
1184
1185 static struct {
1186 unsigned int cmd32;
1187 unsigned int cmd;
1188 } fd_ioctl_trans_table[] = {
1189 { FDSETPRM32, FDSETPRM },
1190 { FDDEFPRM32, FDDEFPRM },
1191 { FDGETPRM32, FDGETPRM },
1192 { FDSETDRVPRM32, FDSETDRVPRM },
1193 { FDGETDRVPRM32, FDGETDRVPRM },
1194 { FDGETDRVSTAT32, FDGETDRVSTAT },
1195 { FDPOLLDRVSTAT32, FDPOLLDRVSTAT },
1196 { FDGETFDCSTAT32, FDGETFDCSTAT },
1197 { FDWERRORGET32, FDWERRORGET }
1198 };
1199
1200 #define NR_FD_IOCTL_TRANS (sizeof(fd_ioctl_trans_table)/sizeof(fd_ioctl_trans_table[0]))
1201
1202 static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
1203 {
1204 mm_segment_t old_fs = get_fs();
1205 void *karg = NULL;
1206 unsigned int kcmd = 0;
1207 int i, err;
1208
1209 for (i = 0; i < NR_FD_IOCTL_TRANS; i++)
1210 if (cmd == fd_ioctl_trans_table[i].cmd32) {
1211 kcmd = fd_ioctl_trans_table[i].cmd;
1212 break;
1213 }
1214 if (!kcmd)
1215 return -EINVAL;
1216
1217 switch (cmd) {
1218 case FDSETPRM32:
1219 case FDDEFPRM32:
1220 case FDGETPRM32:
1221 {
1222 struct floppy_struct *f;
1223
1224 f = karg = kmalloc(sizeof(struct floppy_struct), GFP_KERNEL);
1225 if (!karg)
1226 return -ENOMEM;
1227 if (cmd == FDGETPRM32)
1228 break;
1229 err = __get_user(f->size, &((struct floppy_struct32 *)arg)->size);
1230 err |= __get_user(f->sect, &((struct floppy_struct32 *)arg)->sect);
1231 err |= __get_user(f->head, &((struct floppy_struct32 *)arg)->head);
1232 err |= __get_user(f->track, &((struct floppy_struct32 *)arg)->track);
1233 err |= __get_user(f->stretch, &((struct floppy_struct32 *)arg)->stretch);
1234 err |= __get_user(f->gap, &((struct floppy_struct32 *)arg)->gap);
1235 err |= __get_user(f->rate, &((struct floppy_struct32 *)arg)->rate);
1236 err |= __get_user(f->spec1, &((struct floppy_struct32 *)arg)->spec1);
1237 err |= __get_user(f->fmt_gap, &((struct floppy_struct32 *)arg)->fmt_gap);
1238 err |= __get_user((u64)f->name, &((struct floppy_struct32 *)arg)->name);
1239 if (err) {
1240 err = -EFAULT;
1241 goto out;
1242 }
1243 break;
1244 }
1245 case FDSETDRVPRM32:
1246 case FDGETDRVPRM32:
1247 {
1248 struct floppy_drive_params *f;
1249
1250 f = karg = kmalloc(sizeof(struct floppy_drive_params), GFP_KERNEL);
1251 if (!karg)
1252 return -ENOMEM;
1253 if (cmd == FDGETDRVPRM32)
1254 break;
1255 err = __get_user(f->cmos, &((struct floppy_drive_params32 *)arg)->cmos);
1256 err |= __get_user(f->max_dtr, &((struct floppy_drive_params32 *)arg)->max_dtr);
1257 err |= __get_user(f->hlt, &((struct floppy_drive_params32 *)arg)->hlt);
1258 err |= __get_user(f->hut, &((struct floppy_drive_params32 *)arg)->hut);
1259 err |= __get_user(f->srt, &((struct floppy_drive_params32 *)arg)->srt);
1260 err |= __get_user(f->spinup, &((struct floppy_drive_params32 *)arg)->spinup);
1261 err |= __get_user(f->spindown, &((struct floppy_drive_params32 *)arg)->spindown);
1262 err |= __get_user(f->spindown_offset, &((struct floppy_drive_params32 *)arg)->spindown_offset);
1263 err |= __get_user(f->select_delay, &((struct floppy_drive_params32 *)arg)->select_delay);
1264 err |= __get_user(f->rps, &((struct floppy_drive_params32 *)arg)->rps);
1265 err |= __get_user(f->tracks, &((struct floppy_drive_params32 *)arg)->tracks);
1266 err |= __get_user(f->timeout, &((struct floppy_drive_params32 *)arg)->timeout);
1267 err |= __get_user(f->interleave_sect, &((struct floppy_drive_params32 *)arg)->interleave_sect);
1268 err |= __copy_from_user(&f->max_errors, &((struct floppy_drive_params32 *)arg)->max_errors, sizeof(f->max_errors));
1269 err |= __get_user(f->flags, &((struct floppy_drive_params32 *)arg)->flags);
1270 err |= __get_user(f->read_track, &((struct floppy_drive_params32 *)arg)->read_track);
1271 err |= __copy_from_user(f->autodetect, ((struct floppy_drive_params32 *)arg)->autodetect, sizeof(f->autodetect));
1272 err |= __get_user(f->checkfreq, &((struct floppy_drive_params32 *)arg)->checkfreq);
1273 err |= __get_user(f->native_format, &((struct floppy_drive_params32 *)arg)->native_format);
1274 if (err) {
1275 err = -EFAULT;
1276 goto out;
1277 }
1278 break;
1279 }
1280 case FDGETDRVSTAT32:
1281 case FDPOLLDRVSTAT32:
1282 karg = kmalloc(sizeof(struct floppy_drive_struct), GFP_KERNEL);
1283 if (!karg)
1284 return -ENOMEM;
1285 break;
1286 case FDGETFDCSTAT32:
1287 karg = kmalloc(sizeof(struct floppy_fdc_state), GFP_KERNEL);
1288 if (!karg)
1289 return -ENOMEM;
1290 break;
1291 case FDWERRORGET32:
1292 karg = kmalloc(sizeof(struct floppy_write_errors), GFP_KERNEL);
1293 if (!karg)
1294 return -ENOMEM;
1295 break;
1296 default:
1297 return -EINVAL;
1298 }
1299 set_fs (KERNEL_DS);
1300 err = sys_ioctl (fd, kcmd, (unsigned long)karg);
1301 set_fs (old_fs);
1302 if (err)
1303 goto out;
1304 switch (cmd) {
1305 case FDGETPRM32:
1306 {
1307 struct floppy_struct *f = karg;
1308
1309 err = __put_user(f->size, &((struct floppy_struct32 *)arg)->size);
1310 err |= __put_user(f->sect, &((struct floppy_struct32 *)arg)->sect);
1311 err |= __put_user(f->head, &((struct floppy_struct32 *)arg)->head);
1312 err |= __put_user(f->track, &((struct floppy_struct32 *)arg)->track);
1313 err |= __put_user(f->stretch, &((struct floppy_struct32 *)arg)->stretch);
1314 err |= __put_user(f->gap, &((struct floppy_struct32 *)arg)->gap);
1315 err |= __put_user(f->rate, &((struct floppy_struct32 *)arg)->rate);
1316 err |= __put_user(f->spec1, &((struct floppy_struct32 *)arg)->spec1);
1317 err |= __put_user(f->fmt_gap, &((struct floppy_struct32 *)arg)->fmt_gap);
1318 err |= __put_user((u64)f->name, &((struct floppy_struct32 *)arg)->name);
1319 break;
1320 }
1321 case FDGETDRVPRM32:
1322 {
1323 struct floppy_drive_params *f = karg;
1324
1325 err = __put_user(f->cmos, &((struct floppy_drive_params32 *)arg)->cmos);
1326 err |= __put_user(f->max_dtr, &((struct floppy_drive_params32 *)arg)->max_dtr);
1327 err |= __put_user(f->hlt, &((struct floppy_drive_params32 *)arg)->hlt);
1328 err |= __put_user(f->hut, &((struct floppy_drive_params32 *)arg)->hut);
1329 err |= __put_user(f->srt, &((struct floppy_drive_params32 *)arg)->srt);
1330 err |= __put_user(f->spinup, &((struct floppy_drive_params32 *)arg)->spinup);
1331 err |= __put_user(f->spindown, &((struct floppy_drive_params32 *)arg)->spindown);
1332 err |= __put_user(f->spindown_offset, &((struct floppy_drive_params32 *)arg)->spindown_offset);
1333 err |= __put_user(f->select_delay, &((struct floppy_drive_params32 *)arg)->select_delay);
1334 err |= __put_user(f->rps, &((struct floppy_drive_params32 *)arg)->rps);
1335 err |= __put_user(f->tracks, &((struct floppy_drive_params32 *)arg)->tracks);
1336 err |= __put_user(f->timeout, &((struct floppy_drive_params32 *)arg)->timeout);
1337 err |= __put_user(f->interleave_sect, &((struct floppy_drive_params32 *)arg)->interleave_sect);
1338 err |= __copy_to_user(&((struct floppy_drive_params32 *)arg)->max_errors, &f->max_errors, sizeof(f->max_errors));
1339 err |= __put_user(f->flags, &((struct floppy_drive_params32 *)arg)->flags);
1340 err |= __put_user(f->read_track, &((struct floppy_drive_params32 *)arg)->read_track);
1341 err |= __copy_to_user(((struct floppy_drive_params32 *)arg)->autodetect, f->autodetect, sizeof(f->autodetect));
1342 err |= __put_user(f->checkfreq, &((struct floppy_drive_params32 *)arg)->checkfreq);
1343 err |= __put_user(f->native_format, &((struct floppy_drive_params32 *)arg)->native_format);
1344 break;
1345 }
1346 case FDGETDRVSTAT32:
1347 case FDPOLLDRVSTAT32:
1348 {
1349 struct floppy_drive_struct *f = karg;
1350
1351 err = __put_user(f->flags, &((struct floppy_drive_struct32 *)arg)->flags);
1352 err |= __put_user(f->spinup_date, &((struct floppy_drive_struct32 *)arg)->spinup_date);
1353 err |= __put_user(f->select_date, &((struct floppy_drive_struct32 *)arg)->select_date);
1354 err |= __put_user(f->first_read_date, &((struct floppy_drive_struct32 *)arg)->first_read_date);
1355 err |= __put_user(f->probed_format, &((struct floppy_drive_struct32 *)arg)->probed_format);
1356 err |= __put_user(f->track, &((struct floppy_drive_struct32 *)arg)->track);
1357 err |= __put_user(f->maxblock, &((struct floppy_drive_struct32 *)arg)->maxblock);
1358 err |= __put_user(f->maxtrack, &((struct floppy_drive_struct32 *)arg)->maxtrack);
1359 err |= __put_user(f->generation, &((struct floppy_drive_struct32 *)arg)->generation);
1360 err |= __put_user(f->keep_data, &((struct floppy_drive_struct32 *)arg)->keep_data);
1361 err |= __put_user(f->fd_ref, &((struct floppy_drive_struct32 *)arg)->fd_ref);
1362 err |= __put_user(f->fd_device, &((struct floppy_drive_struct32 *)arg)->fd_device);
1363 err |= __put_user(f->last_checked, &((struct floppy_drive_struct32 *)arg)->last_checked);
1364 err |= __put_user((u64)f->dmabuf, &((struct floppy_drive_struct32 *)arg)->dmabuf);
1365 err |= __put_user((u64)f->bufblocks, &((struct floppy_drive_struct32 *)arg)->bufblocks);
1366 break;
1367 }
1368 case FDGETFDCSTAT32:
1369 {
1370 struct floppy_fdc_state *f = karg;
1371
1372 err = __put_user(f->spec1, &((struct floppy_fdc_state32 *)arg)->spec1);
1373 err |= __put_user(f->spec2, &((struct floppy_fdc_state32 *)arg)->spec2);
1374 err |= __put_user(f->dtr, &((struct floppy_fdc_state32 *)arg)->dtr);
1375 err |= __put_user(f->version, &((struct floppy_fdc_state32 *)arg)->version);
1376 err |= __put_user(f->dor, &((struct floppy_fdc_state32 *)arg)->dor);
1377 err |= __put_user(f->address, &((struct floppy_fdc_state32 *)arg)->address);
1378 err |= __copy_to_user((char *)&((struct floppy_fdc_state32 *)arg)->address
1379 + sizeof(((struct floppy_fdc_state32 *)arg)->address),
1380 (char *)&f->address + sizeof(f->address), sizeof(int));
1381 err |= __put_user(f->driver_version, &((struct floppy_fdc_state32 *)arg)->driver_version);
1382 err |= __copy_to_user(((struct floppy_fdc_state32 *)arg)->track, f->track, sizeof(f->track));
1383 break;
1384 }
1385 case FDWERRORGET32:
1386 {
1387 struct floppy_write_errors *f = karg;
1388
1389 err = __put_user(f->write_errors, &((struct floppy_write_errors32 *)arg)->write_errors);
1390 err |= __put_user(f->first_error_sector, &((struct floppy_write_errors32 *)arg)->first_error_sector);
1391 err |= __put_user(f->first_error_generation, &((struct floppy_write_errors32 *)arg)->first_error_generation);
1392 err |= __put_user(f->last_error_sector, &((struct floppy_write_errors32 *)arg)->last_error_sector);
1393 err |= __put_user(f->last_error_generation, &((struct floppy_write_errors32 *)arg)->last_error_generation);
1394 err |= __put_user(f->badness, &((struct floppy_write_errors32 *)arg)->badness);
1395 break;
1396 }
1397 default:
1398 break;
1399 }
1400 if (err)
1401 err = -EFAULT;
1402
1403 out: if (karg) kfree(karg);
1404 return err;
1405 }
1406
1407 struct ppp_option_data32 {
1408 __kernel_caddr_t32 ptr;
1409 __u32 length;
1410 int transmit;
1411 };
1412 #define PPPIOCSCOMPRESS32 _IOW('t', 77, struct ppp_option_data32)
1413
1414 struct ppp_idle32 {
1415 __kernel_time_t32 xmit_idle;
1416 __kernel_time_t32 recv_idle;
1417 };
1418 #define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32)
1419
1420 static int ppp_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
1421 {
1422 mm_segment_t old_fs = get_fs();
1423 struct ppp_option_data32 data32;
1424 struct ppp_option_data data;
1425 struct ppp_idle32 idle32;
1426 struct ppp_idle idle;
1427 unsigned int kcmd;
1428 void *karg;
1429 int err = 0;
1430
1431 switch (cmd) {
1432 case PPPIOCGIDLE32:
1433 kcmd = PPPIOCGIDLE;
1434 karg = &idle;
1435 break;
1436 case PPPIOCSCOMPRESS32:
1437 if (copy_from_user(&data32, (struct ppp_option_data32 *)arg, sizeof(struct ppp_option_data32)))
1438 return -EFAULT;
1439 data.ptr = kmalloc (data32.length, GFP_KERNEL);
1440 if (!data.ptr)
1441 return -ENOMEM;
1442 if (copy_from_user(data.ptr, (__u8 *)A(data32.ptr), data32.length)) {
1443 kfree(data.ptr);
1444 return -EFAULT;
1445 }
1446 data.length = data32.length;
1447 data.transmit = data32.transmit;
1448 kcmd = PPPIOCSCOMPRESS;
1449 karg = &data;
1450 break;
1451 default:
1452 do {
1453 static int count = 0;
1454 if (++count <= 20)
1455 printk("ppp_ioctl: Unknown cmd fd(%d) "
1456 "cmd(%08x) arg(%08x)\n",
1457 (int)fd, (unsigned int)cmd, (unsigned int)arg);
1458 } while(0);
1459 return -EINVAL;
1460 }
1461 set_fs (KERNEL_DS);
1462 err = sys_ioctl (fd, kcmd, (unsigned long)karg);
1463 set_fs (old_fs);
1464 switch (cmd) {
1465 case PPPIOCGIDLE32:
1466 if (err)
1467 return err;
1468 idle32.xmit_idle = idle.xmit_idle;
1469 idle32.recv_idle = idle.recv_idle;
1470 if (copy_to_user((struct ppp_idle32 *)arg, &idle32, sizeof(struct ppp_idle32)))
1471 return -EFAULT;
1472 break;
1473 case PPPIOCSCOMPRESS32:
1474 kfree(data.ptr);
1475 break;
1476 default:
1477 break;
1478 }
1479 return err;
1480 }
1481
1482
1483 struct mtget32 {
1484 __u32 mt_type;
1485 __u32 mt_resid;
1486 __u32 mt_dsreg;
1487 __u32 mt_gstat;
1488 __u32 mt_erreg;
1489 __kernel_daddr_t32 mt_fileno;
1490 __kernel_daddr_t32 mt_blkno;
1491 };
1492 #define MTIOCGET32 _IOR('m', 2, struct mtget32)
1493
1494 struct mtpos32 {
1495 __u32 mt_blkno;
1496 };
1497 #define MTIOCPOS32 _IOR('m', 3, struct mtpos32)
1498
1499 struct mtconfiginfo32 {
1500 __u32 mt_type;
1501 __u32 ifc_type;
1502 __u16 irqnr;
1503 __u16 dmanr;
1504 __u16 port;
1505 __u32 debug;
1506 __u32 have_dens:1;
1507 __u32 have_bsf:1;
1508 __u32 have_fsr:1;
1509 __u32 have_bsr:1;
1510 __u32 have_eod:1;
1511 __u32 have_seek:1;
1512 __u32 have_tell:1;
1513 __u32 have_ras1:1;
1514 __u32 have_ras2:1;
1515 __u32 have_ras3:1;
1516 __u32 have_qfa:1;
1517 __u32 pad1:5;
1518 char reserved[10];
1519 };
1520 #define MTIOCGETCONFIG32 _IOR('m', 4, struct mtconfiginfo32)
1521 #define MTIOCSETCONFIG32 _IOW('m', 5, struct mtconfiginfo32)
1522
1523 static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
1524 {
1525 mm_segment_t old_fs = get_fs();
1526 struct mtconfiginfo info;
1527 struct mtget get;
1528 struct mtpos pos;
1529 unsigned long kcmd;
1530 void *karg;
1531 int err = 0;
1532
1533 switch(cmd) {
1534 case MTIOCPOS32:
1535 kcmd = MTIOCPOS;
1536 karg = &pos;
1537 break;
1538 case MTIOCGET32:
1539 kcmd = MTIOCGET;
1540 karg = &get;
1541 break;
1542 case MTIOCGETCONFIG32:
1543 kcmd = MTIOCGETCONFIG;
1544 karg = &info;
1545 break;
1546 case MTIOCSETCONFIG32:
1547 kcmd = MTIOCSETCONFIG;
1548 karg = &info;
1549 err = __get_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type);
1550 err |= __get_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type);
1551 err |= __get_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr);
1552 err |= __get_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr);
1553 err |= __get_user(info.port, &((struct mtconfiginfo32 *)arg)->port);
1554 err |= __get_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug);
1555 err |= __copy_from_user((char *)&info.debug + sizeof(info.debug),
1556 (char *)&((struct mtconfiginfo32 *)arg)->debug
1557 + sizeof(((struct mtconfiginfo32 *)arg)->debug), sizeof(__u32));
1558 if (err)
1559 return -EFAULT;
1560 break;
1561 default:
1562 do {
1563 static int count = 0;
1564 if (++count <= 20)
1565 printk("mt_ioctl: Unknown cmd fd(%d) "
1566 "cmd(%08x) arg(%08x)\n",
1567 (int)fd, (unsigned int)cmd, (unsigned int)arg);
1568 } while(0);
1569 return -EINVAL;
1570 }
1571 set_fs (KERNEL_DS);
1572 err = sys_ioctl (fd, kcmd, (unsigned long)karg);
1573 set_fs (old_fs);
1574 if (err)
1575 return err;
1576 switch (cmd) {
1577 case MTIOCPOS32:
1578 err = __put_user(pos.mt_blkno, &((struct mtpos32 *)arg)->mt_blkno);
1579 break;
1580 case MTIOCGET32:
1581 err = __put_user(get.mt_type, &((struct mtget32 *)arg)->mt_type);
1582 err |= __put_user(get.mt_resid, &((struct mtget32 *)arg)->mt_resid);
1583 err |= __put_user(get.mt_dsreg, &((struct mtget32 *)arg)->mt_dsreg);
1584 err |= __put_user(get.mt_gstat, &((struct mtget32 *)arg)->mt_gstat);
1585 err |= __put_user(get.mt_erreg, &((struct mtget32 *)arg)->mt_erreg);
1586 err |= __put_user(get.mt_fileno, &((struct mtget32 *)arg)->mt_fileno);
1587 err |= __put_user(get.mt_blkno, &((struct mtget32 *)arg)->mt_blkno);
1588 break;
1589 case MTIOCGETCONFIG32:
1590 err = __put_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type);
1591 err |= __put_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type);
1592 err |= __put_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr);
1593 err |= __put_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr);
1594 err |= __put_user(info.port, &((struct mtconfiginfo32 *)arg)->port);
1595 err |= __put_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug);
1596 err |= __copy_to_user((char *)&((struct mtconfiginfo32 *)arg)->debug
1597 + sizeof(((struct mtconfiginfo32 *)arg)->debug),
1598 (char *)&info.debug + sizeof(info.debug), sizeof(__u32));
1599 break;
1600 case MTIOCSETCONFIG32:
1601 break;
1602 }
1603 return err ? -EFAULT: 0;
1604 }
1605
1606 struct cdrom_read32 {
1607 int cdread_lba;
1608 __kernel_caddr_t32 cdread_bufaddr;
1609 int cdread_buflen;
1610 };
1611
1612 struct cdrom_read_audio32 {
1613 union cdrom_addr addr;
1614 u_char addr_format;
1615 int nframes;
1616 __kernel_caddr_t32 buf;
1617 };
1618
1619 struct cdrom_generic_command32 {
1620 unsigned char cmd[CDROM_PACKET_SIZE];
1621 __kernel_caddr_t32 buffer;
1622 unsigned int buflen;
1623 int stat;
1624 __kernel_caddr_t32 sense;
1625 __kernel_caddr_t32 reserved[3];
1626 };
1627
1628 static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
1629 {
1630 mm_segment_t old_fs = get_fs();
1631 struct cdrom_read cdread;
1632 struct cdrom_read_audio cdreadaudio;
1633 struct cdrom_generic_command cgc;
1634 __kernel_caddr_t32 addr;
1635 char *data = 0;
1636 void *karg;
1637 int err = 0;
1638
1639 switch(cmd) {
1640 case CDROMREADMODE2:
1641 case CDROMREADMODE1:
1642 case CDROMREADRAW:
1643 case CDROMREADCOOKED:
1644 karg = &cdread;
1645 err = __get_user(cdread.cdread_lba, &((struct cdrom_read32 *)arg)->cdread_lba);
1646 err |= __get_user(addr, &((struct cdrom_read32 *)arg)->cdread_bufaddr);
1647 err |= __get_user(cdread.cdread_buflen, &((struct cdrom_read32 *)arg)->cdread_buflen);
1648 if (err)
1649 return -EFAULT;
1650 data = kmalloc(cdread.cdread_buflen, GFP_KERNEL);
1651 if (!data)
1652 return -ENOMEM;
1653 cdread.cdread_bufaddr = data;
1654 break;
1655 case CDROMREADAUDIO:
1656 karg = &cdreadaudio;
1657 err = copy_from_user(&cdreadaudio.addr, &((struct cdrom_read_audio32 *)arg)->addr, sizeof(cdreadaudio.addr));
1658 err |= __get_user(cdreadaudio.addr_format, &((struct cdrom_read_audio32 *)arg)->addr_format);
1659 err |= __get_user(cdreadaudio.nframes, &((struct cdrom_read_audio32 *)arg)->nframes);
1660 err |= __get_user(addr, &((struct cdrom_read_audio32 *)arg)->buf);
1661 if (err)
1662 return -EFAULT;
1663 data = kmalloc(cdreadaudio.nframes * 2352, GFP_KERNEL);
1664 if (!data)
1665 return -ENOMEM;
1666 cdreadaudio.buf = data;
1667 break;
1668 case CDROM_SEND_PACKET:
1669 karg = &cgc;
1670 err = copy_from_user(cgc.cmd, &((struct cdrom_generic_command32 *)arg)->cmd, sizeof(cgc.cmd));
1671 err |= __get_user(addr, &((struct cdrom_generic_command32 *)arg)->buffer);
1672 err |= __get_user(cgc.buflen, &((struct cdrom_generic_command32 *)arg)->buflen);
1673 if (err)
1674 return -EFAULT;
1675 if ((data = kmalloc(cgc.buflen, GFP_KERNEL)) == NULL)
1676 return -ENOMEM;
1677 cgc.buffer = data;
1678 break;
1679 default:
1680 do {
1681 static int count = 0;
1682 if (++count <= 20)
1683 printk("cdrom_ioctl: Unknown cmd fd(%d) "
1684 "cmd(%08x) arg(%08x)\n",
1685 (int)fd, (unsigned int)cmd, (unsigned int)arg);
1686 } while(0);
1687 return -EINVAL;
1688 }
1689 set_fs (KERNEL_DS);
1690 err = sys_ioctl (fd, cmd, (unsigned long)karg);
1691 set_fs (old_fs);
1692 if (err)
1693 goto out;
1694 switch (cmd) {
1695 case CDROMREADMODE2:
1696 case CDROMREADMODE1:
1697 case CDROMREADRAW:
1698 case CDROMREADCOOKED:
1699 err = copy_to_user((char *)A(addr), data, cdread.cdread_buflen);
1700 break;
1701 case CDROMREADAUDIO:
1702 err = copy_to_user((char *)A(addr), data, cdreadaudio.nframes * 2352);
1703 break;
1704 case CDROM_SEND_PACKET:
1705 err = copy_to_user((char *)A(addr), data, cgc.buflen);
1706 break;
1707 default:
1708 break;
1709 }
1710 out: if (data)
1711 kfree(data);
1712 return err ? -EFAULT : 0;
1713 }
1714
1715 struct loop_info32 {
1716 int lo_number; /* ioctl r/o */
1717 __kernel_dev_t32 lo_device; /* ioctl r/o */
1718 unsigned int lo_inode; /* ioctl r/o */
1719 __kernel_dev_t32 lo_rdevice; /* ioctl r/o */
1720 int lo_offset;
1721 int lo_encrypt_type;
1722 int lo_encrypt_key_size; /* ioctl w/o */
1723 int lo_flags; /* ioctl r/o */
1724 char lo_name[LO_NAME_SIZE];
1725 unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
1726 unsigned int lo_init[2];
1727 char reserved[4];
1728 };
1729
1730 static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg)
1731 {
1732 mm_segment_t old_fs = get_fs();
1733 struct loop_info l;
1734 int err = -EINVAL;
1735
1736 switch(cmd) {
1737 case LOOP_SET_STATUS:
1738 err = get_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number);
1739 err |= __get_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);
1740 err |= __get_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode);
1741 err |= __get_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice);
1742 err |= __copy_from_user((char *)&l.lo_offset, (char *)&((struct loop_info32 *)arg)->lo_offset,
1743 8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
1744 if (err) {
1745 err = -EFAULT;
1746 } else {
1747 set_fs (KERNEL_DS);
1748 err = sys_ioctl (fd, cmd, (unsigned long)&l);
1749 set_fs (old_fs);
1750 }
1751 break;
1752 case LOOP_GET_STATUS:
1753 set_fs (KERNEL_DS);
1754 err = sys_ioctl (fd, cmd, (unsigned long)&l);
1755 set_fs (old_fs);
1756 if (!err) {
1757 err = put_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number);
1758 err |= __put_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);
1759 err |= __put_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode);
1760 err |= __put_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice);
1761 err |= __copy_to_user((char *)&((struct loop_info32 *)arg)->lo_offset,
1762 (char *)&l.lo_offset, (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
1763 if (err)
1764 err = -EFAULT;
1765 }
1766 break;
1767 default: {
1768 static int count = 0;
1769 if (++count <= 20)
1770 printk("%s: Unknown loop ioctl cmd, fd(%d) "
1771 "cmd(%08x) arg(%08lx)\n",
1772 __FUNCTION__, fd, cmd, arg);
1773 }
1774 }
1775 return err;
1776 }
1777
1778 extern int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg);
1779
1780 static int vt_check(struct file *file)
1781 {
1782 struct tty_struct *tty;
1783 struct inode *inode = file->f_dentry->d_inode;
1784
1785 if (file->f_op->ioctl != tty_ioctl)
1786 return -EINVAL;
1787
1788 tty = (struct tty_struct *)file->private_data;
1789 if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl"))
1790 return -EINVAL;
1791
1792 if (tty->driver.ioctl != vt_ioctl)
1793 return -EINVAL;
1794
1795 /*
1796 * To have permissions to do most of the vt ioctls, we either have
1797 * to be the owner of the tty, or super-user.
1798 */
1799 if (current->tty == tty || suser())
1800 return 1;
1801 return 0;
1802 }
1803
1804 struct consolefontdesc32 {
1805 unsigned short charcount; /* characters in font (256 or 512) */
1806 unsigned short charheight; /* scan lines per character (1-32) */
1807 u32 chardata; /* font data in expanded form */
1808 };
1809
1810 static int do_fontx_ioctl(unsigned int fd, int cmd, struct consolefontdesc32 *user_cfd, struct file *file)
1811 {
1812 struct consolefontdesc cfdarg;
1813 struct console_font_op op;
1814 int i, perm;
1815
1816 perm = vt_check(file);
1817 if (perm < 0) return perm;
1818
1819 if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc32)))
1820 return -EFAULT;
1821
1822 cfdarg.chardata = (unsigned char *)A(((struct consolefontdesc32 *)&cfdarg)->chardata);
1823
1824 switch (cmd) {
1825 case PIO_FONTX:
1826 if (!perm)
1827 return -EPERM;
1828 op.op = KD_FONT_OP_SET;
1829 op.flags = 0;
1830 op.width = 8;
1831 op.height = cfdarg.charheight;
1832 op.charcount = cfdarg.charcount;
1833 op.data = cfdarg.chardata;
1834 return con_font_op(fg_console, &op);
1835 case GIO_FONTX:
1836 if (!cfdarg.chardata)
1837 return 0;
1838 op.op = KD_FONT_OP_GET;
1839 op.flags = 0;
1840 op.width = 8;
1841 op.height = cfdarg.charheight;
1842 op.charcount = cfdarg.charcount;
1843 op.data = cfdarg.chardata;
1844 i = con_font_op(fg_console, &op);
1845 if (i)
1846 return i;
1847 cfdarg.charheight = op.height;
1848 cfdarg.charcount = op.charcount;
1849 ((struct consolefontdesc32 *)&cfdarg)->chardata = (unsigned long)cfdarg.chardata;
1850 if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc32)))
1851 return -EFAULT;
1852 return 0;
1853 }
1854 return -EINVAL;
1855 }
1856
1857 struct console_font_op32 {
1858 unsigned int op; /* operation code KD_FONT_OP_* */
1859 unsigned int flags; /* KD_FONT_FLAG_* */
1860 unsigned int width, height; /* font size */
1861 unsigned int charcount;
1862 u32 data; /* font data with height fixed to 32 */
1863 };
1864
1865 static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, struct console_font_op32 *fontop, struct file *file)
1866 {
1867 struct console_font_op op;
1868 int perm = vt_check(file), i;
1869 struct vt_struct *vt;
1870
1871 if (perm < 0) return perm;
1872
1873 if (copy_from_user(&op, (void *) fontop, sizeof(struct console_font_op32)))
1874 return -EFAULT;
1875 if (!perm && op.op != KD_FONT_OP_GET)
1876 return -EPERM;
1877 op.data = (unsigned char *)A(((struct console_font_op32 *)&op)->data);
1878 op.flags |= KD_FONT_FLAG_OLD;
1879 vt = (struct vt_struct *)((struct tty_struct *)file->private_data)->driver_data;
1880 i = con_font_op(vt->vc_num, &op);
1881 if (i) return i;
1882 ((struct console_font_op32 *)&op)->data = (unsigned long)op.data;
1883 if (copy_to_user((void *) fontop, &op, sizeof(struct console_font_op32)))
1884 return -EFAULT;
1885 return 0;
1886 }
1887
1888 struct unimapdesc32 {
1889 unsigned short entry_ct;
1890 u32 entries;
1891 };
1892
1893 static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, struct unimapdesc32 *user_ud, struct file *file)
1894 {
1895 struct unimapdesc32 tmp;
1896 int perm = vt_check(file);
1897
1898 if (perm < 0) return perm;
1899 if (copy_from_user(&tmp, user_ud, sizeof tmp))
1900 return -EFAULT;
1901 switch (cmd) {
1902 case PIO_UNIMAP:
1903 if (!perm) return -EPERM;
1904 return con_set_unimap(fg_console, tmp.entry_ct, (struct unipair *)A(tmp.entries));
1905 case GIO_UNIMAP:
1906 return con_get_unimap(fg_console, tmp.entry_ct, &(user_ud->entry_ct), (struct unipair *)A(tmp.entries));
1907 }
1908 return 0;
1909 }
1910
1911 static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long arg)
1912 {
1913 mm_segment_t old_fs = get_fs();
1914 __kernel_uid_t kuid;
1915 int err;
1916
1917 cmd = SMB_IOC_GETMOUNTUID;
1918
1919 set_fs(KERNEL_DS);
1920 err = sys_ioctl(fd, cmd, (unsigned long)&kuid);
1921 set_fs(old_fs);
1922
1923 if (err >= 0)
1924 err = put_user(kuid, (__kernel_uid_t32 *)arg);
1925
1926 return err;
1927 }
1928
1929 struct atmif_sioc32 {
1930 int number;
1931 int length;
1932 __kernel_caddr_t32 arg;
1933 };
1934
1935 struct atm_iobuf32 {
1936 int length;
1937 __kernel_caddr_t32 buffer;
1938 };
1939
1940 #define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct atmif_sioc32)
1941 #define ATM_GETNAMES32 _IOW('a', ATMIOC_ITF+3, struct atm_iobuf32)
1942 #define ATM_GETTYPE32 _IOW('a', ATMIOC_ITF+4, struct atmif_sioc32)
1943 #define ATM_GETESI32 _IOW('a', ATMIOC_ITF+5, struct atmif_sioc32)
1944 #define ATM_GETADDR32 _IOW('a', ATMIOC_ITF+6, struct atmif_sioc32)
1945 #define ATM_RSTADDR32 _IOW('a', ATMIOC_ITF+7, struct atmif_sioc32)
1946 #define ATM_ADDADDR32 _IOW('a', ATMIOC_ITF+8, struct atmif_sioc32)
1947 #define ATM_DELADDR32 _IOW('a', ATMIOC_ITF+9, struct atmif_sioc32)
1948 #define ATM_GETCIRANGE32 _IOW('a', ATMIOC_ITF+10, struct atmif_sioc32)
1949 #define ATM_SETCIRANGE32 _IOW('a', ATMIOC_ITF+11, struct atmif_sioc32)
1950 #define ATM_SETESI32 _IOW('a', ATMIOC_ITF+12, struct atmif_sioc32)
1951 #define ATM_SETESIF32 _IOW('a', ATMIOC_ITF+13, struct atmif_sioc32)
1952 #define ATM_GETSTAT32 _IOW('a', ATMIOC_SARCOM+0, struct atmif_sioc32)
1953 #define ATM_GETSTATZ32 _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32)
1954 #define ATM_GETLOOP32 _IOW('a', ATMIOC_SARCOM+2, struct atmif_sioc32)
1955 #define ATM_SETLOOP32 _IOW('a', ATMIOC_SARCOM+3, struct atmif_sioc32)
1956 #define ATM_QUERYLOOP32 _IOW('a', ATMIOC_SARCOM+4, struct atmif_sioc32)
1957
1958 static struct {
1959 unsigned int cmd32;
1960 unsigned int cmd;
1961 } atm_ioctl_map[] = {
1962 { ATM_GETLINKRATE32, ATM_GETLINKRATE },
1963 { ATM_GETNAMES32, ATM_GETNAMES },
1964 { ATM_GETTYPE32, ATM_GETTYPE },
1965 { ATM_GETESI32, ATM_GETESI },
1966 { ATM_GETADDR32, ATM_GETADDR },
1967 { ATM_RSTADDR32, ATM_RSTADDR },
1968 { ATM_ADDADDR32, ATM_ADDADDR },
1969 { ATM_DELADDR32, ATM_DELADDR },
1970 { ATM_GETCIRANGE32, ATM_GETCIRANGE },
1971 { ATM_SETCIRANGE32, ATM_SETCIRANGE },
1972 { ATM_SETESI32, ATM_SETESI },
1973 { ATM_SETESIF32, ATM_SETESIF },
1974 { ATM_GETSTAT32, ATM_GETSTAT },
1975 { ATM_GETSTATZ32, ATM_GETSTATZ },
1976 { ATM_GETLOOP32, ATM_GETLOOP },
1977 { ATM_SETLOOP32, ATM_SETLOOP },
1978 { ATM_QUERYLOOP32, ATM_QUERYLOOP }
1979 };
1980
1981 #define NR_ATM_IOCTL (sizeof(atm_ioctl_map)/sizeof(atm_ioctl_map[0]))
1982
1983
1984 static int do_atm_iobuf(unsigned int fd, unsigned int cmd, unsigned long arg)
1985 {
1986 struct atm_iobuf32 iobuf32;
1987 struct atm_iobuf iobuf = { 0, NULL };
1988 mm_segment_t old_fs;
1989 int err;
1990
1991 err = copy_from_user(&iobuf32, (struct atm_iobuf32*)arg,
1992 sizeof(struct atm_iobuf32));
1993 if (err)
1994 return -EFAULT;
1995
1996 iobuf.length = iobuf32.length;
1997
1998 if (iobuf32.buffer == (__kernel_caddr_t32) NULL || iobuf32.length == 0) {
1999 iobuf.buffer = (void*)(unsigned long)iobuf32.buffer;
2000 } else {
2001 iobuf.buffer = kmalloc(iobuf.length, GFP_KERNEL);
2002 if (iobuf.buffer == NULL) {
2003 err = -ENOMEM;
2004 goto out;
2005 }
2006
2007 err = copy_from_user(iobuf.buffer, A(iobuf32.buffer), iobuf.length);
2008 if (err) {
2009 err = -EFAULT;
2010 goto out;
2011 }
2012 }
2013
2014 old_fs = get_fs(); set_fs (KERNEL_DS);
2015 err = sys_ioctl (fd, cmd, (unsigned long)&iobuf);
2016 set_fs (old_fs);
2017 if(err)
2018 goto out;
2019
2020 if(iobuf.buffer && iobuf.length > 0) {
2021 err = copy_to_user(A(iobuf32.buffer), iobuf.buffer, iobuf.length);
2022 if (err) {
2023 err = -EFAULT;
2024 goto out;
2025 }
2026 }
2027 err = __put_user(iobuf.length, &(((struct atm_iobuf32*)arg)->length));
2028
2029 out:
2030 if(iobuf32.buffer && iobuf32.length > 0)
2031 kfree(iobuf.buffer);
2032
2033 return err;
2034 }
2035
2036
2037 static int do_atmif_sioc(unsigned int fd, unsigned int cmd, unsigned long arg)
2038 {
2039 struct atmif_sioc32 sioc32;
2040 struct atmif_sioc sioc = { 0, 0, NULL };
2041 mm_segment_t old_fs;
2042 int err;
2043
2044 err = copy_from_user(&sioc32, (struct atmif_sioc32*)arg,
2045 sizeof(struct atmif_sioc32));
2046 if (err)
2047 return -EFAULT;
2048
2049 sioc.number = sioc32.number;
2050 sioc.length = sioc32.length;
2051
2052 if (sioc32.arg == (__kernel_caddr_t32) NULL || sioc32.length == 0) {
2053 sioc.arg = (void*)(unsigned long)sioc32.arg;
2054 } else {
2055 sioc.arg = kmalloc(sioc.length, GFP_KERNEL);
2056 if (sioc.arg == NULL) {
2057 err = -ENOMEM;
2058 goto out;
2059 }
2060
2061 err = copy_from_user(sioc.arg, A(sioc32.arg), sioc32.length);
2062 if (err) {
2063 err = -EFAULT;
2064 goto out;
2065 }
2066 }
2067
2068 old_fs = get_fs(); set_fs (KERNEL_DS);
2069 err = sys_ioctl (fd, cmd, (unsigned long)&sioc);
2070 set_fs (old_fs);
2071 if(err) {
2072 goto out;
2073 }
2074
2075 if(sioc.arg && sioc.length > 0) {
2076 err = copy_to_user(A(sioc32.arg), sioc.arg, sioc.length);
2077 if (err) {
2078 err = -EFAULT;
2079 goto out;
2080 }
2081 }
2082 err = __put_user(sioc.length, &(((struct atmif_sioc32*)arg)->length));
2083
2084 out:
2085 if(sioc32.arg && sioc32.length > 0)
2086 kfree(sioc.arg);
2087
2088 return err;
2089 }
2090
2091
2092 static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg)
2093 {
2094 int i;
2095 unsigned int cmd = 0;
2096
2097 switch (cmd32) {
2098 case SONET_GETSTAT:
2099 case SONET_GETSTATZ:
2100 case SONET_GETDIAG:
2101 case SONET_SETDIAG:
2102 case SONET_CLRDIAG:
2103 case SONET_SETFRAMING:
2104 case SONET_GETFRAMING:
2105 case SONET_GETFRSENSE:
2106 return do_atmif_sioc(fd, cmd32, arg);
2107 }
2108
2109 for (i = 0; i < NR_ATM_IOCTL; i++) {
2110 if (cmd32 == atm_ioctl_map[i].cmd32) {
2111 cmd = atm_ioctl_map[i].cmd;
2112 break;
2113 }
2114 }
2115 if (i == NR_ATM_IOCTL) {
2116 return -EINVAL;
2117 }
2118
2119 switch (cmd) {
2120 case ATM_GETNAMES:
2121 return do_atm_iobuf(fd, cmd, arg);
2122
2123 case ATM_GETLINKRATE:
2124 case ATM_GETTYPE:
2125 case ATM_GETESI:
2126 case ATM_GETADDR:
2127 case ATM_RSTADDR:
2128 case ATM_ADDADDR:
2129 case ATM_DELADDR:
2130 case ATM_GETCIRANGE:
2131 case ATM_SETCIRANGE:
2132 case ATM_SETESI:
2133 case ATM_SETESIF:
2134 case ATM_GETSTAT:
2135 case ATM_GETSTATZ:
2136 case ATM_GETLOOP:
2137 case ATM_SETLOOP:
2138 case ATM_QUERYLOOP:
2139 return do_atmif_sioc(fd, cmd, arg);
2140 }
2141
2142 return -EINVAL;
2143 }
2144
2145 #if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
2146 /* Ugh, LVM. Pitty it was not cleaned up before accepted :((. */
2147 typedef struct {
2148 uint8_t vg_name[NAME_LEN];
2149 uint32_t vg_number;
2150 uint32_t vg_access;
2151 uint32_t vg_status;
2152 uint32_t lv_max;
2153 uint32_t lv_cur;
2154 uint32_t lv_open;
2155 uint32_t pv_max;
2156 uint32_t pv_cur;
2157 uint32_t pv_act;
2158 uint32_t dummy;
2159 uint32_t vgda;
2160 uint32_t pe_size;
2161 uint32_t pe_total;
2162 uint32_t pe_allocated;
2163 uint32_t pvg_total;
2164 u32 proc;
2165 u32 pv[ABS_MAX_PV + 1];
2166 u32 lv[ABS_MAX_LV + 1];
2167 uint8_t vg_uuid[UUID_LEN+1]; /* volume group UUID */
2168 } vg32_t;
2169
2170 typedef struct {
2171 uint8_t id[2];
2172 uint16_t version;
2173 lvm_disk_data_t pv_on_disk;
2174 lvm_disk_data_t vg_on_disk;
2175 lvm_disk_data_t pv_namelist_on_disk;
2176 lvm_disk_data_t lv_on_disk;
2177 lvm_disk_data_t pe_on_disk;
2178 uint8_t pv_name[NAME_LEN];
2179 uint8_t vg_name[NAME_LEN];
2180 uint8_t system_id[NAME_LEN];
2181 kdev_t pv_dev;
2182 uint32_t pv_number;
2183 uint32_t pv_status;
2184 uint32_t pv_allocatable;
2185 uint32_t pv_size;
2186 uint32_t lv_cur;
2187 uint32_t pe_size;
2188 uint32_t pe_total;
2189 uint32_t pe_allocated;
2190 uint32_t pe_stale;
2191 u32 pe;
2192 u32 inode;
2193 uint8_t pv_uuid[UUID_LEN+1];
2194 } pv32_t;
2195
2196 typedef struct {
2197 char lv_name[NAME_LEN];
2198 u32 lv;
2199 } lv_req32_t;
2200
2201 typedef struct {
2202 u32 lv_index;
2203 u32 lv;
2204 /* Transfer size because user space and kernel space differ */
2205 uint16_t size;
2206 } lv_status_byindex_req32_t;
2207
2208 typedef struct {
2209 dev_t dev;
2210 u32 lv;
2211 } lv_status_bydev_req32_t;
2212
2213 typedef struct {
2214 uint8_t lv_name[NAME_LEN];
2215 kdev_t old_dev;
2216 kdev_t new_dev;
2217 u32 old_pe;
2218 u32 new_pe;
2219 } le_remap_req32_t;
2220
2221 typedef struct {
2222 char pv_name[NAME_LEN];
2223 u32 pv;
2224 } pv_status_req32_t;
2225
2226 typedef struct {
2227 uint8_t lv_name[NAME_LEN];
2228 uint8_t vg_name[NAME_LEN];
2229 uint32_t lv_access;
2230 uint32_t lv_status;
2231 uint32_t lv_open;
2232 kdev_t lv_dev;
2233 uint32_t lv_number;
2234 uint32_t lv_mirror_copies;
2235 uint32_t lv_recovery;
2236 uint32_t lv_schedule;
2237 uint32_t lv_size;
2238 u32 lv_current_pe;
2239 uint32_t lv_current_le;
2240 uint32_t lv_allocated_le;
2241 uint32_t lv_stripes;
2242 uint32_t lv_stripesize;
2243 uint32_t lv_badblock;
2244 uint32_t lv_allocation;
2245 uint32_t lv_io_timeout;
2246 uint32_t lv_read_ahead;
2247 /* delta to version 1 starts here */
2248 u32 lv_snapshot_org;
2249 u32 lv_snapshot_prev;
2250 u32 lv_snapshot_next;
2251 u32 lv_block_exception;
2252 uint32_t lv_remap_ptr;
2253 uint32_t lv_remap_end;
2254 uint32_t lv_chunk_size;
2255 uint32_t lv_snapshot_minor;
2256 char dummy[200];
2257 } lv32_t;
2258
2259 typedef struct {
2260 u32 hash[2];
2261 u32 rsector_org;
2262 kdev_t rdev_org;
2263 u32 rsector_new;
2264 kdev_t rdev_new;
2265 } lv_block_exception32_t;
2266
2267 static void put_lv_t(lv_t *l)
2268 {
2269 if (l->lv_current_pe) vfree(l->lv_current_pe);
2270 if (l->lv_block_exception) vfree(l->lv_block_exception);
2271 kfree(l);
2272 }
2273
2274 static lv_t *get_lv_t(u32 p, int *errp)
2275 {
2276 int err, i;
2277 u32 ptr1, ptr2;
2278 size_t size;
2279 lv_block_exception32_t *lbe32;
2280 lv_block_exception_t *lbe;
2281 lv32_t *ul = (lv32_t *)A(p);
2282 lv_t *l = (lv_t *)kmalloc(sizeof(lv_t), GFP_KERNEL);
2283 if (!l) {
2284 *errp = -ENOMEM;
2285 return NULL;
2286 }
2287 memset(l, 0, sizeof(lv_t));
2288 err = copy_from_user(l, ul, (long)&((lv32_t *)0)->lv_current_pe);
2289 err |= __copy_from_user(&l->lv_current_le, &ul->lv_current_le,
2290 ((long)&ul->lv_snapshot_org) - ((long)&ul->lv_current_le));
2291 err |= __copy_from_user(&l->lv_remap_ptr, &ul->lv_remap_ptr,
2292 ((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr));
2293 err |= __get_user(ptr1, &ul->lv_current_pe);
2294 err |= __get_user(ptr2, &ul->lv_block_exception);
2295 if (err) {
2296 kfree(l);
2297 *errp = -EFAULT;
2298 return NULL;
2299 }
2300 if (ptr1) {
2301 size = l->lv_allocated_le * sizeof(pe_t);
2302 l->lv_current_pe = vmalloc(size);
2303 if (l->lv_current_pe)
2304 err = copy_from_user(l->lv_current_pe, (void *)A(ptr1), size);
2305 }
2306 if (!err && ptr2) {
2307 size = l->lv_remap_end * sizeof(lv_block_exception_t);
2308 l->lv_block_exception = lbe = vmalloc(size);
2309 if (l->lv_block_exception) {
2310 lbe32 = (lv_block_exception32_t *)A(ptr2);
2311 memset(lbe, 0, size);
2312 for (i = 0; i < l->lv_remap_end; i++, lbe++, lbe32++) {
2313 err |= get_user(lbe->rsector_org, &lbe32->rsector_org);
2314 err |= __get_user(lbe->rdev_org, &lbe32->rdev_org);
2315 err |= __get_user(lbe->rsector_new, &lbe32->rsector_new);
2316 err |= __get_user(lbe->rdev_new, &lbe32->rdev_new);
2317
2318 }
2319 }
2320 }
2321 if (err || (ptr1 && !l->lv_current_pe) || (ptr2 && !l->lv_block_exception)) {
2322 if (!err)
2323 *errp = -ENOMEM;
2324 else
2325 *errp = -EFAULT;
2326 put_lv_t(l);
2327 return NULL;
2328 }
2329 return l;
2330 }
2331
2332 static int copy_lv_t(u32 ptr, lv_t *l)
2333 {
2334 int err;
2335 lv32_t *ul = (lv32_t *)A(ptr);
2336 u32 ptr1;
2337 size_t size;
2338
2339 err = get_user(ptr1, &ul->lv_current_pe);
2340 if (err)
2341 return -EFAULT;
2342 err = copy_to_user(ul, l, (long)&((lv32_t *)0)->lv_current_pe);
2343 err |= __copy_to_user(&ul->lv_current_le, &l->lv_current_le,
2344 ((long)&ul->lv_snapshot_org) - ((long)&ul->lv_current_le));
2345 err |= __copy_to_user(&ul->lv_remap_ptr, &l->lv_remap_ptr,
2346 ((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr));
2347 size = l->lv_allocated_le * sizeof(pe_t);
2348 if (ptr1)
2349 err |= __copy_to_user((void *)A(ptr1), l->lv_current_pe, size);
2350 return err ? -EFAULT : 0;
2351 }
2352
2353 static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
2354 {
2355 vg_t *v;
2356 union {
2357 lv_req_t lv_req;
2358 le_remap_req_t le_remap;
2359 lv_status_byindex_req_t lv_byindex;
2360 lv_status_bydev_req_t lv_bydev;
2361 pv_status_req_t pv_status;
2362 } u;
2363 pv_t p;
2364 int err;
2365 u32 ptr = 0;
2366 int i;
2367 mm_segment_t old_fs;
2368 void *karg = &u;
2369
2370 switch (cmd) {
2371 case VG_STATUS:
2372 v = kmalloc(sizeof(vg_t), GFP_KERNEL);
2373 if (!v) return -ENOMEM;
2374 karg = v;
2375 break;
2376 case VG_CREATE:
2377 v = kmalloc(sizeof(vg_t), GFP_KERNEL);
2378 if (!v) return -ENOMEM;
2379 if (copy_from_user(v, (void *)arg, (long)&((vg32_t *)0)->proc) ||
2380 __get_user(v->proc, &((vg32_t *)arg)->proc)) {
2381 kfree(v);
2382 return -EFAULT;
2383 }
2384 if (copy_from_user(v->vg_uuid, ((vg32_t *)arg)->vg_uuid, UUID_LEN+1)) {
2385 kfree(v);
2386 return -EFAULT;
2387 }
2388
2389 karg = v;
2390 memset(v->pv, 0, sizeof(v->pv) + sizeof(v->lv));
2391 if (v->pv_max > ABS_MAX_PV || v->lv_max > ABS_MAX_LV)
2392 return -EPERM;
2393 for (i = 0; i < v->pv_max; i++) {
2394 err = __get_user(ptr, &((vg32_t *)arg)->pv[i]);
2395 if (err) break;
2396 if (ptr) {
2397 v->pv[i] = kmalloc(sizeof(pv_t), GFP_KERNEL);
2398 if (!v->pv[i]) {
2399 err = -ENOMEM;
2400 break;
2401 }
2402 err = copy_from_user(v->pv[i], (void *)A(ptr), sizeof(pv32_t) - 8 - UUID_LEN+1);
2403 if (err) {
2404 err = -EFAULT;
2405 break;
2406 }
2407 err = copy_from_user(v->pv[i]->pv_uuid, ((pv32_t *)A(ptr))->pv_uuid, UUID_LEN+1);
2408 if (err) {
2409 err = -EFAULT;
2410 break;
2411 }
2412
2413
2414 v->pv[i]->pe = NULL; v->pv[i]->inode = NULL;
2415 }
2416 }
2417 if (!err) {
2418 for (i = 0; i < v->lv_max; i++) {
2419 err = __get_user(ptr, &((vg32_t *)arg)->lv[i]);
2420 if (err) break;
2421 if (ptr) {
2422 v->lv[i] = get_lv_t(ptr, &err);
2423 if (err) break;
2424 }
2425 }
2426 }
2427 break;
2428 case LV_CREATE:
2429 case LV_EXTEND:
2430 case LV_REDUCE:
2431 case LV_REMOVE:
2432 case LV_RENAME:
2433 case LV_STATUS_BYNAME:
2434 err = copy_from_user(&u.pv_status, arg, sizeof(u.pv_status.pv_name));
2435 if (err) return -EFAULT;
2436 if (cmd != LV_REMOVE) {
2437 err = __get_user(ptr, &((lv_req32_t *)arg)->lv);
2438 if (err) return err;
2439 u.lv_req.lv = get_lv_t(ptr, &err);
2440 } else
2441 u.lv_req.lv = NULL;
2442 break;
2443
2444
2445 case LV_STATUS_BYINDEX:
2446 err = get_user(u.lv_byindex.lv_index, &((lv_status_byindex_req32_t *)arg)->lv_index);
2447 err |= __get_user(ptr, &((lv_status_byindex_req32_t *)arg)->lv);
2448 if (err) return err;
2449 u.lv_byindex.lv = get_lv_t(ptr, &err);
2450 break;
2451 case LV_STATUS_BYDEV:
2452 err = get_user(u.lv_bydev.dev, &((lv_status_bydev_req32_t *)arg)->dev);
2453 u.lv_bydev.lv = get_lv_t(ptr, &err);
2454 if (err) return err;
2455 u.lv_bydev.lv = &p;
2456 p.pe = NULL; p.inode = NULL;
2457 break;
2458 case VG_EXTEND:
2459 err = copy_from_user(&p, (void *)arg, sizeof(pv32_t) - 8 - UUID_LEN+1);
2460 if (err) return -EFAULT;
2461 err = copy_from_user(p.pv_uuid, ((pv32_t *)arg)->pv_uuid, UUID_LEN+1);
2462 if (err) return -EFAULT;
2463 p.pe = NULL; p.inode = NULL;
2464 karg = &p;
2465 break;
2466 case PV_CHANGE:
2467 case PV_STATUS:
2468 err = copy_from_user(&u.pv_status, arg, sizeof(u.lv_req.lv_name));
2469 if (err) return -EFAULT;
2470 err = __get_user(ptr, &((pv_status_req32_t *)arg)->pv);
2471 if (err) return err;
2472 u.pv_status.pv = &p;
2473 if (cmd == PV_CHANGE) {
2474 err = copy_from_user(&p, (void *)A(ptr), sizeof(pv32_t) - 8 - UUID_LEN+1);
2475 if (err) return -EFAULT;
2476 p.pe = NULL; p.inode = NULL;
2477 }
2478 break;
2479 }
2480 old_fs = get_fs(); set_fs (KERNEL_DS);
2481 err = sys_ioctl (fd, cmd, (unsigned long)karg);
2482 set_fs (old_fs);
2483 switch (cmd) {
2484 case VG_STATUS:
2485 if (!err) {
2486 if (copy_to_user((void *)arg, v, (long)&((vg32_t *)0)->proc) ||
2487 clear_user(&((vg32_t *)arg)->proc, sizeof(vg32_t) - (long)&((vg32_t *)0)->proc))
2488 err = -EFAULT;
2489 }
2490 if (copy_to_user(((vg32_t *)arg)->vg_uuid, v->vg_uuid, UUID_LEN+1)) {
2491 err = -EFAULT;
2492 }
2493 kfree(v);
2494 break;
2495 case VG_CREATE:
2496 for (i = 0; i < v->pv_max; i++)
2497 if (v->pv[i]) kfree(v->pv[i]);
2498 for (i = 0; i < v->lv_max; i++)
2499 if (v->lv[i]) put_lv_t(v->lv[i]);
2500 kfree(v);
2501 break;
2502 case LV_STATUS_BYNAME:
2503 if (!err && u.lv_req.lv) err = copy_lv_t(ptr, u.lv_req.lv);
2504 /* Fall through */
2505 case LV_CREATE:
2506 case LV_EXTEND:
2507 case LV_REDUCE:
2508 if (u.lv_req.lv) put_lv_t(u.lv_req.lv);
2509 break;
2510 case LV_STATUS_BYINDEX:
2511 if (u.lv_byindex.lv) {
2512 if (!err) err = copy_lv_t(ptr, u.lv_byindex.lv);
2513 put_lv_t(u.lv_byindex.lv);
2514 }
2515 break;
2516 case PV_STATUS:
2517 if (!err) {
2518 err = copy_to_user((void *)A(ptr), &p, sizeof(pv32_t) - 8 - UUID_LEN+1);
2519 if (err) return -EFAULT;
2520 err = copy_to_user(((pv_t *)A(ptr))->pv_uuid, p.pv_uuid, UUID_LEN + 1);
2521 if (err) return -EFAULT;
2522 }
2523 break;
2524 case LV_STATUS_BYDEV:
2525 if (!err) {
2526 if (!err) err = copy_lv_t(ptr, u.lv_bydev.lv);
2527 put_lv_t(u.lv_byindex.lv);
2528 }
2529 break;
2530 }
2531 return err;
2532 }
2533 #endif
2534
2535 #if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
2536 /* This really belongs in include/linux/drm.h -DaveM */
2537 #include "../../../drivers/char/drm/drm.h"
2538
2539 typedef struct drm32_version {
2540 int version_major; /* Major version */
2541 int version_minor; /* Minor version */
2542 int version_patchlevel;/* Patch level */
2543 int name_len; /* Length of name buffer */
2544 u32 name; /* Name of driver */
2545 int date_len; /* Length of date buffer */
2546 u32 date; /* User-space buffer to hold date */
2547 int desc_len; /* Length of desc buffer */
2548 u32 desc; /* User-space buffer to hold desc */
2549 } drm32_version_t;
2550 #define DRM32_IOCTL_VERSION DRM_IOWR(0x00, drm32_version_t)
2551
2552 static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg)
2553 {
2554 drm32_version_t *uversion = (drm32_version_t *)arg;
2555 char *name_ptr, *date_ptr, *desc_ptr;
2556 u32 tmp1, tmp2, tmp3;
2557 drm_version_t kversion;
2558 mm_segment_t old_fs;
2559 int ret;
2560
2561 memset(&kversion, 0, sizeof(kversion));
2562 if (get_user(kversion.name_len, &uversion->name_len) ||
2563 get_user(kversion.date_len, &uversion->date_len) ||
2564 get_user(kversion.desc_len, &uversion->desc_len) ||
2565 get_user(tmp1, &uversion->name) ||
2566 get_user(tmp2, &uversion->date) ||
2567 get_user(tmp3, &uversion->desc))
2568 return -EFAULT;
2569
2570 name_ptr = (char *) A(tmp1);
2571 date_ptr = (char *) A(tmp2);
2572 desc_ptr = (char *) A(tmp3);
2573
2574 ret = -ENOMEM;
2575 if (kversion.name_len && name_ptr) {
2576 kversion.name = kmalloc(kversion.name_len, GFP_KERNEL);
2577 if (!kversion.name)
2578 goto out;
2579 }
2580 if (kversion.date_len && date_ptr) {
2581 kversion.date = kmalloc(kversion.date_len, GFP_KERNEL);
2582 if (!kversion.date)
2583 goto out;
2584 }
2585 if (kversion.desc_len && desc_ptr) {
2586 kversion.desc = kmalloc(kversion.desc_len, GFP_KERNEL);
2587 if (!kversion.desc)
2588 goto out;
2589 }
2590
2591 old_fs = get_fs();
2592 set_fs(KERNEL_DS);
2593 ret = sys_ioctl (fd, DRM_IOCTL_VERSION, (unsigned long)&kversion);
2594 set_fs(old_fs);
2595
2596 if (!ret) {
2597 if ((kversion.name &&
2598 copy_to_user(name_ptr, kversion.name, kversion.name_len)) ||
2599 (kversion.date &&
2600 copy_to_user(date_ptr, kversion.date, kversion.date_len)) ||
2601 (kversion.desc &&
2602 copy_to_user(desc_ptr, kversion.desc, kversion.desc_len)))
2603 ret = -EFAULT;
2604 if (put_user(kversion.version_major, &uversion->version_major) ||
2605 put_user(kversion.version_minor, &uversion->version_minor) ||
2606 put_user(kversion.version_patchlevel, &uversion->version_patchlevel) ||
2607 put_user(kversion.name_len, &uversion->name_len) ||
2608 put_user(kversion.date_len, &uversion->date_len) ||
2609 put_user(kversion.desc_len, &uversion->desc_len))
2610 ret = -EFAULT;
2611 }
2612
2613 out:
2614 if (kversion.name)
2615 kfree(kversion.name);
2616 if (kversion.date)
2617 kfree(kversion.date);
2618 if (kversion.desc)
2619 kfree(kversion.desc);
2620 return ret;
2621 }
2622
2623 typedef struct drm32_unique {
2624 int unique_len; /* Length of unique */
2625 u32 unique; /* Unique name for driver instantiation */
2626 } drm32_unique_t;
2627 #define DRM32_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm32_unique_t)
2628 #define DRM32_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm32_unique_t)
2629
2630 static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long arg)
2631 {
2632 drm32_unique_t *uarg = (drm32_unique_t *)arg;
2633 drm_unique_t karg;
2634 mm_segment_t old_fs;
2635 char *uptr;
2636 u32 tmp;
2637 int ret;
2638
2639 if (get_user(karg.unique_len, &uarg->unique_len))
2640 return -EFAULT;
2641 karg.unique = NULL;
2642
2643 if (get_user(tmp, &uarg->unique))
2644 return -EFAULT;
2645
2646 uptr = (char *) A(tmp);
2647
2648 if (uptr) {
2649 karg.unique = kmalloc(karg.unique_len, GFP_KERNEL);
2650 if (!karg.unique)
2651 return -ENOMEM;
2652 if (cmd == DRM32_IOCTL_SET_UNIQUE &&
2653 copy_from_user(karg.unique, uptr, karg.unique_len)) {
2654 kfree(karg.unique);
2655 return -EFAULT;
2656 }
2657 }
2658
2659 old_fs = get_fs();
2660 set_fs(KERNEL_DS);
2661 if (cmd == DRM32_IOCTL_GET_UNIQUE)
2662 ret = sys_ioctl (fd, DRM_IOCTL_GET_UNIQUE, (unsigned long)&karg);
2663 else
2664 ret = sys_ioctl (fd, DRM_IOCTL_SET_UNIQUE, (unsigned long)&karg);
2665 set_fs(old_fs);
2666
2667 if (!ret) {
2668 if (cmd == DRM32_IOCTL_GET_UNIQUE &&
2669 uptr != NULL &&
2670 copy_to_user(uptr, karg.unique, karg.unique_len))
2671 ret = -EFAULT;
2672 if (put_user(karg.unique_len, &uarg->unique_len))
2673 ret = -EFAULT;
2674 }
2675
2676 if (karg.unique != NULL)
2677 kfree(karg.unique);
2678
2679 return ret;
2680 }
2681
2682 typedef struct drm32_map {
2683 u32 offset; /* Requested physical address (0 for SAREA)*/
2684 u32 size; /* Requested physical size (bytes) */
2685 drm_map_type_t type; /* Type of memory to map */
2686 drm_map_flags_t flags; /* Flags */
2687 u32 handle; /* User-space: "Handle" to pass to mmap */
2688 /* Kernel-space: kernel-virtual address */
2689 int mtrr; /* MTRR slot used */
2690 /* Private data */
2691 } drm32_map_t;
2692 #define DRM32_IOCTL_ADD_MAP DRM_IOWR(0x15, drm32_map_t)
2693
2694 static int drm32_addmap(unsigned int fd, unsigned int cmd, unsigned long arg)
2695 {
2696 drm32_map_t *uarg = (drm32_map_t *) arg;
2697 drm_map_t karg;
2698 mm_segment_t old_fs;
2699 u32 tmp;
2700 int ret;
2701
2702 ret = get_user(karg.offset, &uarg->offset);
2703 ret |= get_user(karg.size, &uarg->size);
2704 ret |= get_user(karg.type, &uarg->type);
2705 ret |= get_user(karg.flags, &uarg->flags);
2706 ret |= get_user(tmp, &uarg->handle);
2707 ret |= get_user(karg.mtrr, &uarg->mtrr);
2708 if (ret)
2709 return -EFAULT;
2710
2711 karg.handle = (void *) A(tmp);
2712
2713 old_fs = get_fs();
2714 set_fs(KERNEL_DS);
2715 ret = sys_ioctl(fd, DRM_IOCTL_ADD_MAP, (unsigned long) &karg);
2716 set_fs(old_fs);
2717
2718 if (!ret) {
2719 ret = put_user(karg.offset, &uarg->offset);
2720 ret |= put_user(karg.size, &uarg->size);
2721 ret |= put_user(karg.type, &uarg->type);
2722 ret |= put_user(karg.flags, &uarg->flags);
2723 tmp = (u32) (long)karg.handle;
2724 ret |= put_user(tmp, &uarg->handle);
2725 ret |= put_user(karg.mtrr, &uarg->mtrr);
2726 if (ret)
2727 ret = -EFAULT;
2728 }
2729
2730 return ret;
2731 }
2732
2733 typedef struct drm32_buf_info {
2734 int count; /* Entries in list */
2735 u32 list; /* (drm_buf_desc_t *) */
2736 } drm32_buf_info_t;
2737 #define DRM32_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm32_buf_info_t)
2738
2739 static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
2740 {
2741 drm32_buf_info_t *uarg = (drm32_buf_info_t *)arg;
2742 drm_buf_desc_t *ulist;
2743 drm_buf_info_t karg;
2744 mm_segment_t old_fs;
2745 int orig_count, ret;
2746 u32 tmp;
2747
2748 if (get_user(karg.count, &uarg->count) ||
2749 get_user(tmp, &uarg->list))
2750 return -EFAULT;
2751
2752 ulist = (drm_buf_desc_t *) A(tmp);
2753
2754 orig_count = karg.count;
2755
2756 karg.list = kmalloc(karg.count * sizeof(drm_buf_desc_t), GFP_KERNEL);
2757 if (!karg.list)
2758 return -EFAULT;
2759
2760 old_fs = get_fs();
2761 set_fs(KERNEL_DS);
2762 ret = sys_ioctl(fd, DRM_IOCTL_INFO_BUFS, (unsigned long) &karg);
2763 set_fs(old_fs);
2764
2765 if (!ret) {
2766 if (karg.count <= orig_count &&
2767 (copy_to_user(ulist, karg.list,
2768 karg.count * sizeof(drm_buf_desc_t))))
2769 ret = -EFAULT;
2770 if (put_user(karg.count, &uarg->count))
2771 ret = -EFAULT;
2772 }
2773
2774 kfree(karg.list);
2775
2776 return ret;
2777 }
2778
2779 typedef struct drm32_buf_free {
2780 int count;
2781 u32 list; /* (int *) */
2782 } drm32_buf_free_t;
2783 #define DRM32_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm32_buf_free_t)
2784
2785 static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
2786 {
2787 drm32_buf_free_t *uarg = (drm32_buf_free_t *)arg;
2788 drm_buf_free_t karg;
2789 mm_segment_t old_fs;
2790 int *ulist;
2791 int ret;
2792 u32 tmp;
2793
2794 if (get_user(karg.count, &uarg->count) ||
2795 get_user(tmp, &uarg->list))
2796 return -EFAULT;
2797
2798 ulist = (int *) A(tmp);
2799
2800 karg.list = kmalloc(karg.count * sizeof(int), GFP_KERNEL);
2801 if (!karg.list)
2802 return -ENOMEM;
2803
2804 ret = -EFAULT;
2805 if (copy_from_user(karg.list, ulist, (karg.count * sizeof(int))))
2806 goto out;
2807
2808 old_fs = get_fs();
2809 set_fs(KERNEL_DS);
2810 ret = sys_ioctl(fd, DRM_IOCTL_FREE_BUFS, (unsigned long) &karg);
2811 set_fs(old_fs);
2812
2813 out:
2814 kfree(karg.list);
2815
2816 return ret;
2817 }
2818
2819 typedef struct drm32_buf_pub {
2820 int idx; /* Index into master buflist */
2821 int total; /* Buffer size */
2822 int used; /* Amount of buffer in use (for DMA) */
2823 u32 address; /* Address of buffer (void *) */
2824 } drm32_buf_pub_t;
2825
2826 typedef struct drm32_buf_map {
2827 int count; /* Length of buflist */
2828 u32 virtual; /* Mmaped area in user-virtual (void *) */
2829 u32 list; /* Buffer information (drm_buf_pub_t *) */
2830 } drm32_buf_map_t;
2831 #define DRM32_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm32_buf_map_t)
2832
2833 static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
2834 {
2835 drm32_buf_map_t *uarg = (drm32_buf_map_t *)arg;
2836 drm32_buf_pub_t *ulist;
2837 drm_buf_map_t karg;
2838 mm_segment_t old_fs;
2839 int orig_count, ret, i;
2840 u32 tmp1, tmp2;
2841
2842 if (get_user(karg.count, &uarg->count) ||
2843 get_user(tmp1, &uarg->virtual) ||
2844 get_user(tmp2, &uarg->list))
2845 return -EFAULT;
2846
2847 karg.virtual = (void *) A(tmp1);
2848 ulist = (drm32_buf_pub_t *) A(tmp2);
2849
2850 orig_count = karg.count;
2851
2852 karg.list = kmalloc(karg.count * sizeof(drm_buf_pub_t), GFP_KERNEL);
2853 if (!karg.list)
2854 return -ENOMEM;
2855
2856 ret = -EFAULT;
2857 for (i = 0; i < karg.count; i++) {
2858 if (get_user(karg.list[i].idx, &ulist[i].idx) ||
2859 get_user(karg.list[i].total, &ulist[i].total) ||
2860 get_user(karg.list[i].used, &ulist[i].used) ||
2861 get_user(tmp1, &ulist[i].address))
2862 goto out;
2863
2864 karg.list[i].address = (void *) A(tmp1);
2865 }
2866
2867 old_fs = get_fs();
2868 set_fs(KERNEL_DS);
2869 ret = sys_ioctl(fd, DRM_IOCTL_MAP_BUFS, (unsigned long) &karg);
2870 set_fs(old_fs);
2871
2872 if (!ret) {
2873 for (i = 0; i < orig_count; i++) {
2874 tmp1 = (u32) (long) karg.list[i].address;
2875 if (put_user(karg.list[i].idx, &ulist[i].idx) ||
2876 put_user(karg.list[i].total, &ulist[i].total) ||
2877 put_user(karg.list[i].used, &ulist[i].used) ||
2878 put_user(tmp1, &ulist[i].address)) {
2879 ret = -EFAULT;
2880 goto out;
2881 }
2882 }
2883 if (put_user(karg.count, &uarg->count))
2884 ret = -EFAULT;
2885 }
2886
2887 out:
2888 kfree(karg.list);
2889 return ret;
2890 }
2891
2892 typedef struct drm32_dma {
2893 /* Indices here refer to the offset into
2894 buflist in drm_buf_get_t. */
2895 int context; /* Context handle */
2896 int send_count; /* Number of buffers to send */
2897 u32 send_indices; /* List of handles to buffers (int *) */
2898 u32 send_sizes; /* Lengths of data to send (int *) */
2899 drm_dma_flags_t flags; /* Flags */
2900 int request_count; /* Number of buffers requested */
2901 int request_size; /* Desired size for buffers */
2902 u32 request_indices; /* Buffer information (int *) */
2903 u32 request_sizes; /* (int *) */
2904 int granted_count; /* Number of buffers granted */
2905 } drm32_dma_t;
2906 #define DRM32_IOCTL_DMA DRM_IOWR(0x29, drm32_dma_t)
2907
2908 /* RED PEN The DRM layer blindly dereferences the send/request
2909 * indice/size arrays even though they are userland
2910 * pointers. -DaveM
2911 */
2912 static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg)
2913 {
2914 drm32_dma_t *uarg = (drm32_dma_t *) arg;
2915 int *u_si, *u_ss, *u_ri, *u_rs;
2916 drm_dma_t karg;
2917 mm_segment_t old_fs;
2918 int ret;
2919 u32 tmp1, tmp2, tmp3, tmp4;
2920
2921 karg.send_indices = karg.send_sizes = NULL;
2922 karg.request_indices = karg.request_sizes = NULL;
2923
2924 if (get_user(karg.context, &uarg->context) ||
2925 get_user(karg.send_count, &uarg->send_count) ||
2926 get_user(tmp1, &uarg->send_indices) ||
2927 get_user(tmp2, &uarg->send_sizes) ||
2928 get_user(karg.flags, &uarg->flags) ||
2929 get_user(karg.request_count, &uarg->request_count) ||
2930 get_user(karg.request_size, &uarg->request_size) ||
2931 get_user(tmp3, &uarg->request_indices) ||
2932 get_user(tmp4, &uarg->request_sizes) ||
2933 get_user(karg.granted_count, &uarg->granted_count))
2934 return -EFAULT;
2935
2936 u_si = (int *) A(tmp1);
2937 u_ss = (int *) A(tmp2);
2938 u_ri = (int *) A(tmp3);
2939 u_rs = (int *) A(tmp4);
2940
2941 if (karg.send_count) {
2942 karg.send_indices = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
2943 karg.send_sizes = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
2944
2945 ret = -ENOMEM;
2946 if (!karg.send_indices || !karg.send_sizes)
2947 goto out;
2948
2949 ret = -EFAULT;
2950 if (copy_from_user(karg.send_indices, u_si,
2951 (karg.send_count * sizeof(int))) ||
2952 copy_from_user(karg.send_sizes, u_ss,
2953 (karg.send_count * sizeof(int))))
2954 goto out;
2955 }
2956
2957 if (karg.request_count) {
2958 karg.request_indices = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
2959 karg.request_sizes = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
2960
2961 ret = -ENOMEM;
2962 if (!karg.request_indices