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