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