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