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