1/* 2 * ioctl32.c: Conversion between 32bit and 64bit native ioctls. 3 * 4 * Copyright (C) 2000 Silicon Graphics, Inc. 5 * Written by Ulf Carlsson (ulfc@engr.sgi.com) 6 * Copyright (C) 2000 Ralf Baechle 7 * Copyright (C) 2002 Maciej W. Rozycki 8 * 9 * Mostly stolen from the sparc64 ioctl32 implementation. 10 */ 11#include <linux/config.h> 12#include <linux/types.h> 13#include <linux/kernel.h> 14#include <linux/sched.h> 15#include <linux/if.h> 16#include <linux/mm.h> 17#include <linux/mtio.h> 18#include <linux/init.h> 19#include <linux/file.h> 20#include <linux/fs.h> 21#include <linux/ppp_defs.h> 22#include <linux/if_ppp.h> 23#include <linux/if_pppox.h> 24#include <linux/cdrom.h> 25#include <linux/loop.h> 26#include <linux/fb.h> 27#include <linux/vt.h> 28#include <linux/kd.h> 29#include <linux/netdevice.h> 30#include <linux/kernprof.h> 31#include <linux/route.h> 32#include <linux/hdreg.h> 33#include <linux/blkpg.h> 34#include <linux/blkdev.h> 35#include <linux/elevator.h> 36#include <linux/auto_fs.h> 37#include <linux/auto_fs4.h> 38#include <linux/ext2_fs.h> 39#include <linux/raid/md_u.h> 40 41#include <scsi/scsi.h> 42#undef __KERNEL__ /* This file was born to be ugly ... */ 43#include <scsi/scsi_ioctl.h> 44#define __KERNEL__ 45#include <scsi/sg.h> 46 47#include <asm/types.h> 48#include <asm/uaccess.h> 49 50#include <linux/rtc.h> 51 52long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); 53 54static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg) 55{ 56 mm_segment_t old_fs = get_fs(); 57 int err; 58 unsigned long val; 59 60 set_fs (KERNEL_DS); 61 err = sys_ioctl(fd, cmd, (unsigned long)&val); 62 set_fs (old_fs); 63 if (!err && put_user((unsigned int) val, (u32 *)arg)) 64 return -EFAULT; 65 return err; 66} 67 68static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg) 69{ 70 mm_segment_t old_fs = get_fs(); 71 int err; 72 unsigned long val; 73 74 if (get_user(val, (u32 *)arg)) 75 return -EFAULT; 76 set_fs(KERNEL_DS); 77 err = sys_ioctl(fd, cmd, (unsigned long)&val); 78 set_fs (old_fs); 79 if (!err && put_user(val, (u32 *)arg)) 80 return -EFAULT; 81 return err; 82} 83 84#define A(__x) ((unsigned long)(__x)) 85 86 87#ifdef CONFIG_FB 88 89struct fb_fix_screeninfo32 { 90 char id[16]; /* identification string eg "TT Builtin" */ 91 __u32 smem_start; /* Start of frame buffer mem */ 92 /* (physical address) */ 93 __u32 smem_len; /* Length of frame buffer mem */ 94 __u32 type; /* see FB_TYPE_* */ 95 __u32 type_aux; /* Interleave for interleaved Planes */ 96 __u32 visual; /* see FB_VISUAL_* */ 97 __u16 xpanstep; /* zero if no hardware panning */ 98 __u16 ypanstep; /* zero if no hardware panning */ 99 __u16 ywrapstep; /* zero if no hardware ywrap */ 100 __u32 line_length; /* length of a line in bytes */ 101 __u32 mmio_start; /* Start of Memory Mapped I/O */ 102 /* (physical address) */ 103 __u32 mmio_len; /* Length of Memory Mapped I/O */ 104 __u32 accel; /* Type of acceleration available */ 105 __u16 reserved[3]; /* Reserved for future compatibility */ 106}; 107 108static int do_fbioget_fscreeninfo_ioctl(unsigned int fd, unsigned int cmd, 109 unsigned long arg) 110{ 111 mm_segment_t old_fs = get_fs(); 112 struct fb_fix_screeninfo fix; 113 struct fb_fix_screeninfo32 *fix32 = (struct fb_fix_screeninfo32 *)arg; 114 int err; 115 116 set_fs(KERNEL_DS); 117 err = sys_ioctl(fd, cmd, (unsigned long)&fix); 118 set_fs(old_fs); 119 120 if (err == 0) { 121 err = __copy_to_user((char *)fix32->id, (char *)fix.id, 122 sizeof(fix.id)); 123 err |= __put_user((__u32)(unsigned long)fix.smem_start, 124 &fix32->smem_start); 125 err |= __put_user(fix.smem_len, &fix32->smem_len); 126 err |= __put_user(fix.type, &fix32->type); 127 err |= __put_user(fix.type_aux, &fix32->type_aux); 128 err |= __put_user(fix.visual, &fix32->visual); 129 err |= __put_user(fix.xpanstep, &fix32->xpanstep); 130 err |= __put_user(fix.ypanstep, &fix32->ypanstep); 131 err |= __put_user(fix.ywrapstep, &fix32->ywrapstep); 132 err |= __put_user(fix.line_length, &fix32->line_length); 133 err |= __put_user((__u32)(unsigned long)fix.mmio_start, 134 &fix32->mmio_start); 135 err |= __put_user(fix.mmio_len, &fix32->mmio_len); 136 err |= __put_user(fix.accel, &fix32->accel); 137 err |= __copy_to_user((char *)fix32->reserved, 138 (char *)fix.reserved, 139 sizeof(fix.reserved)); 140 if (err) 141 err = -EFAULT; 142 } 143 144 return err; 145} 146 147struct fb_cmap32 { 148 __u32 start; /* First entry */ 149 __u32 len; /* Number of entries */ 150 __u32 red; /* Red values */ 151 __u32 green; 152 __u32 blue; 153 __u32 transp; /* transparency, can be NULL */ 154}; 155 156static int do_fbiocmap_ioctl(unsigned int fd, unsigned int cmd, 157 unsigned long arg) 158{ 159 mm_segment_t old_fs = get_fs(); 160 u32 red = 0, green = 0, blue = 0, transp = 0; 161 struct fb_cmap cmap; 162 struct fb_cmap32 *cmap32 = (struct fb_cmap32 *)arg; 163 int err; 164 165 memset(&cmap, 0, sizeof(cmap)); 166 167 err = __get_user(cmap.start, &cmap32->start); 168 err |= __get_user(cmap.len, &cmap32->len); 169 err |= __get_user(red, &cmap32->red); 170 err |= __get_user(green, &cmap32->green); 171 err |= __get_user(blue, &cmap32->blue); 172 err |= __get_user(transp, &cmap32->transp); 173 if (err) 174 return -EFAULT; 175 176 err = -ENOMEM; 177 cmap.red = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL); 178 if (!cmap.red) 179 goto out; 180 cmap.green = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL); 181 if (!cmap.green) 182 goto out; 183 cmap.blue = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL); 184 if (!cmap.blue) 185 goto out; 186 if (transp) { 187 cmap.transp = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL); 188 if (!cmap.transp) 189 goto out; 190 } 191 192 if (cmd == FBIOPUTCMAP) { 193 err = __copy_from_user(cmap.red, (char *)A(red), 194 cmap.len * sizeof(__u16)); 195 err |= __copy_from_user(cmap.green, (char *)A(green), 196 cmap.len * sizeof(__u16)); 197 err |= __copy_from_user(cmap.blue, (char *)A(blue), 198 cmap.len * sizeof(__u16)); 199 if (cmap.transp) 200 err |= __copy_from_user(cmap.transp, (char *)A(transp), 201 cmap.len * sizeof(__u16)); 202 if (err) { 203 err = -EFAULT; 204 goto out; 205 } 206 } 207 208 set_fs(KERNEL_DS); 209 err = sys_ioctl(fd, cmd, (unsigned long)&cmap); 210 set_fs(old_fs); 211 if (err) 212 goto out; 213 214 if (cmd == FBIOGETCMAP) { 215 err = __copy_to_user((char *)A(red), cmap.red, 216 cmap.len * sizeof(__u16)); 217 err |= __copy_to_user((char *)A(green), cmap.blue, 218 cmap.len * sizeof(__u16)); 219 err |= __copy_to_user((char *)A(blue), cmap.blue, 220 cmap.len * sizeof(__u16)); 221 if (cmap.transp) 222 err |= __copy_to_user((char *)A(transp), cmap.transp, 223 cmap.len * sizeof(__u16)); 224 if (err) { 225 err = -EFAULT; 226 goto out; 227 } 228 } 229 230out: 231 if (cmap.red) 232 kfree(cmap.red); 233 if (cmap.green) 234 kfree(cmap.green); 235 if (cmap.blue) 236 kfree(cmap.blue); 237 if (cmap.transp) 238 kfree(cmap.transp); 239 240 return err; 241} 242 243#endif /* CONFIG_FB */ 244 245 246struct timeval32 { 247 int tv_sec; 248 int tv_usec; 249}; 250 251static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg) 252{ 253 struct timeval32 *up = (struct timeval32 *)arg; 254 struct timeval ktv; 255 mm_segment_t old_fs = get_fs(); 256 int err; 257 258 set_fs(KERNEL_DS); 259 err = sys_ioctl(fd, cmd, (unsigned long)&ktv); 260 set_fs(old_fs); 261 if (!err) { 262 err = put_user(ktv.tv_sec, &up->tv_sec); 263 err |= __put_user(ktv.tv_usec, &up->tv_usec); 264 } 265 266 return err; 267} 268 269#define EXT2_IOC32_GETFLAGS _IOR('f', 1, int) 270#define EXT2_IOC32_SETFLAGS _IOW('f', 2, int) 271#define EXT2_IOC32_GETVERSION _IOR('v', 1, int) 272#define EXT2_IOC32_SETVERSION _IOW('v', 2, int) 273 274struct ifmap32 { 275 unsigned int mem_start; 276 unsigned int mem_end; 277 unsigned short base_addr; 278 unsigned char irq; 279 unsigned char dma; 280 unsigned char port; 281}; 282 283struct ifreq32 { 284#define IFHWADDRLEN 6 285#define IFNAMSIZ 16 286 union { 287 char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */ 288 } ifr_ifrn; 289 union { 290 struct sockaddr ifru_addr; 291 struct sockaddr ifru_dstaddr; 292 struct sockaddr ifru_broadaddr; 293 struct sockaddr ifru_netmask; 294 struct sockaddr ifru_hwaddr; 295 short ifru_flags; 296 int ifru_ivalue; 297 int ifru_mtu; 298 struct ifmap32 ifru_map; 299 char ifru_slave[IFNAMSIZ]; /* Just fits the size */ 300 char ifru_newname[IFNAMSIZ]; 301 __kernel_caddr_t32 ifru_data; 302 } ifr_ifru; 303}; 304 305struct ifconf32 { 306 int ifc_len; /* size of buffer */ 307 __kernel_caddr_t32 ifcbuf; 308}; 309 310#ifdef CONFIG_NET 311 312static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg) 313{ 314 struct ireq32 *uir32 = (struct ireq32 *)arg; 315 struct net_device *dev; 316 struct ifreq32 ifr32; 317 318 if (copy_from_user(&ifr32, uir32, sizeof(struct ifreq32))) 319 return -EFAULT; 320 321 read_lock(&dev_base_lock); 322 dev = __dev_get_by_index(ifr32.ifr_ifindex); 323 if (!dev) { 324 read_unlock(&dev_base_lock); 325 return -ENODEV; 326 } 327 328 strcpy(ifr32.ifr_name, dev->name); 329 read_unlock(&dev_base_lock); 330 331 if (copy_to_user(uir32, &ifr32, sizeof(struct ifreq32))) 332 return -EFAULT; 333 334 return 0; 335} 336 337static inline int dev_ifconf(unsigned int fd, unsigned int cmd, 338 unsigned long arg) 339{ 340 struct ioconf32 *uifc32 = (struct ioconf32 *)arg; 341 struct ifconf32 ifc32; 342 struct ifconf ifc; 343 struct ifreq32 *ifr32; 344 struct ifreq *ifr; 345 mm_segment_t old_fs; 346 int len; 347 int err; 348 349 if (copy_from_user(&ifc32, uifc32, sizeof(struct ifconf32))) 350 return -EFAULT; 351 352 if(ifc32.ifcbuf == 0) { 353 ifc32.ifc_len = 0; 354 ifc.ifc_len = 0; 355 ifc.ifc_buf = NULL; 356 } else { 357 ifc.ifc_len = ((ifc32.ifc_len / sizeof (struct ifreq32))) * 358 sizeof (struct ifreq); 359 ifc.ifc_buf = kmalloc (ifc.ifc_len, GFP_KERNEL); 360 if (!ifc.ifc_buf) 361 return -ENOMEM; 362 } 363 ifr = ifc.ifc_req; 364 ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf); 365 len = ifc32.ifc_len / sizeof (struct ifreq32); 366 while (len--) { 367 if (copy_from_user(ifr++, ifr32++, sizeof (struct ifreq32))) { 368 err = -EFAULT; 369 goto out; 370 } 371 } 372 373 old_fs = get_fs(); 374 set_fs (KERNEL_DS); 375 err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc); 376 set_fs (old_fs); 377 if (err) 378 goto out; 379 380 ifr = ifc.ifc_req; 381 ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf); 382 len = ifc.ifc_len / sizeof (struct ifreq); 383 ifc32.ifc_len = len * sizeof (struct ifreq32); 384 385 while (len--) { 386 if (copy_to_user(ifr32++, ifr++, sizeof (struct ifreq32))) { 387 err = -EFAULT; 388 goto out; 389 } 390 } 391 392 if (copy_to_user(uifc32, &ifc32, sizeof(struct ifconf32))) { 393 err = -EFAULT; 394 goto out; 395 } 396out: 397 if(ifc.ifc_buf != NULL) 398 kfree (ifc.ifc_buf); 399 return err; 400} 401 402static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg) 403{ 404 struct ifreq ifr; 405 mm_segment_t old_fs; 406 int err; 407 408 switch (cmd) { 409 case SIOCSIFMAP: 410 err = copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(ifr.ifr_name)); 411 err |= __get_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start)); 412 err |= __get_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end)); 413 err |= __get_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr)); 414 err |= __get_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq)); 415 err |= __get_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma)); 416 err |= __get_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port)); 417 if (err) 418 return -EFAULT; 419 break; 420 default: 421 if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32))) 422 return -EFAULT; 423 break; 424 } 425 old_fs = get_fs(); 426 set_fs (KERNEL_DS); 427 err = sys_ioctl (fd, cmd, (unsigned long)&ifr); 428 set_fs (old_fs); 429 if (!err) { 430 switch (cmd) { 431 case SIOCGIFFLAGS: 432 case SIOCGIFMETRIC: 433 case SIOCGIFMTU: 434 case SIOCGIFMEM: 435 case SIOCGIFHWADDR: 436 case SIOCGIFINDEX: 437 case SIOCGIFADDR: 438 case SIOCGIFBRDADDR: 439 case SIOCGIFDSTADDR: 440 case SIOCGIFNETMASK: 441 case SIOCGIFTXQLEN: 442 if (copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(struct ifreq32))) 443 return -EFAULT; 444 break; 445 case SIOCGIFMAP: 446 err = copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(ifr.ifr_name)); 447 err |= __put_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start)); 448 err |= __put_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end)); 449 err |= __put_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr)); 450 err |= __put_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq)); 451 err |= __put_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma)); 452 err |= __put_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port)); 453 if (err) 454 err = -EFAULT; 455 break; 456 } 457 } 458 return err; 459} 460 461struct rtentry32 462{ 463 unsigned int rt_pad1; 464 struct sockaddr rt_dst; /* target address */ 465 struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */ 466 struct sockaddr rt_genmask; /* target network mask (IP) */ 467 unsigned short rt_flags; 468 short rt_pad2; 469 unsigned int rt_pad3; 470 unsigned int rt_pad4; 471 short rt_metric; /* +1 for binary compatibility! */ 472 unsigned int rt_dev; /* forcing the device at add */ 473 unsigned int rt_mtu; /* per route MTU/Window */ 474#ifndef __KERNEL__ 475#define rt_mss rt_mtu /* Compatibility :-( */ 476#endif 477 unsigned int rt_window; /* Window clamping */ 478 unsigned short rt_irtt; /* Initial RTT */ 479}; 480 481static inline int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) 482{ 483 struct rtentry32 *ur = (struct rtentry32 *)arg; 484 struct rtentry r; 485 char devname[16]; 486 u32 rtdev; 487 int ret; 488 mm_segment_t old_fs = get_fs(); 489 490 ret = copy_from_user (&r.rt_dst, &(ur->rt_dst), 3 * sizeof(struct sockaddr)); 491 ret |= __get_user (r.rt_flags, &(ur->rt_flags)); 492 ret |= __get_user (r.rt_metric, &(ur->rt_metric)); 493 ret |= __get_user (r.rt_mtu, &(ur->rt_mtu)); 494 ret |= __get_user (r.rt_window, &(ur->rt_window)); 495 ret |= __get_user (r.rt_irtt, &(ur->rt_irtt)); 496 ret |= __get_user (rtdev, &(ur->rt_dev)); 497 if (rtdev) { 498 ret |= copy_from_user (devname, (char *)A(rtdev), 15); 499 r.rt_dev = devname; devname[15] = 0; 500 } else 501 r.rt_dev = 0; 502 if (ret) 503 return -EFAULT; 504 set_fs (KERNEL_DS); 505 ret = sys_ioctl (fd, cmd, (long)&r); 506 set_fs (old_fs); 507 return ret; 508} 509 510#endif /* CONFIG_NET */ 511 512static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) 513{ 514 /* These are just misnamed, they actually get/put from/to user an int */ 515 switch (cmd) { 516 case EXT2_IOC32_GETFLAGS: cmd = EXT2_IOC_GETFLAGS; break; 517 case EXT2_IOC32_SETFLAGS: cmd = EXT2_IOC_SETFLAGS; break; 518 case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break; 519 case EXT2_IOC32_SETVERSION: cmd = EXT2_IOC_SETVERSION; break; 520 } 521 return sys_ioctl(fd, cmd, arg); 522} 523 524struct hd_geometry32 { 525 unsigned char heads; 526 unsigned char sectors; 527 unsigned short cylinders; 528 u32 start; 529}; 530 531static int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg) 532{ 533 mm_segment_t old_fs = get_fs(); 534 struct hd_geometry geo; 535 int err; 536 537 set_fs (KERNEL_DS); 538 err = sys_ioctl(fd, HDIO_GETGEO, (unsigned long)&geo); 539 set_fs (old_fs); 540 if (!err) { 541 err = copy_to_user ((struct hd_geometry32 *)arg, &geo, 4); 542 err |= __put_user (geo.start, &(((struct hd_geometry32 *)arg)->start)); 543 } 544 545 return err ? -EFAULT : 0; 546} 547 548static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) 549{ 550 mm_segment_t old_fs = get_fs(); 551 unsigned long kval; 552 unsigned int *uvp; 553 int error; 554 555 set_fs(KERNEL_DS); 556 error = sys_ioctl(fd, cmd, (long)&kval); 557 set_fs(old_fs); 558 559 if (error == 0) { 560 uvp = (unsigned int *)arg; 561 if (put_user(kval, uvp)) 562 error = -EFAULT; 563 } 564 565 return error; 566} 567 568static int ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg) 569{ 570 return -EINVAL; 571} 572 573struct blkpg_ioctl_arg32 { 574 int op; 575 int flags; 576 int datalen; 577 u32 data; 578}; 579 580static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, 581 struct blkpg_ioctl_arg32 *arg) 582{ 583 struct blkpg_ioctl_arg a; 584 struct blkpg_partition p; 585 int err; 586 mm_segment_t old_fs = get_fs(); 587 588 err = get_user(a.op, &arg->op); 589 err |= __get_user(a.flags, &arg->flags); 590 err |= __get_user(a.datalen, &arg->datalen); 591 err |= __get_user((long)a.data, &arg->data); 592 if (err) return err; 593 switch (a.op) { 594 case BLKPG_ADD_PARTITION: 595 case BLKPG_DEL_PARTITION: 596 if (a.datalen < sizeof(struct blkpg_partition)) 597 return -EINVAL; 598 if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition))) 599 return -EFAULT; 600 a.data = &p; 601 set_fs (KERNEL_DS); 602 err = sys_ioctl(fd, cmd, (unsigned long)&a); 603 set_fs (old_fs); 604 default: 605 return -EINVAL; 606 } 607 return err; 608} 609 610struct mtget32 { 611 __u32 mt_type; 612 __u32 mt_resid; 613 __u32 mt_dsreg; 614 __u32 mt_gstat; 615 __u32 mt_erreg; 616 __kernel_daddr_t32 mt_fileno; 617 __kernel_daddr_t32 mt_blkno; 618}; 619#define MTIOCGET32 _IOR('m', 2, struct mtget32) 620 621struct mtpos32 { 622 __u32 mt_blkno; 623}; 624#define MTIOCPOS32 _IOR('m', 3, struct mtpos32) 625 626struct mtconfiginfo32 { 627 __u32 mt_type; 628 __u32 ifc_type; 629 __u16 irqnr; 630 __u16 dmanr; 631 __u16 port; 632 __u32 debug; 633 __u32 have_dens:1; 634 __u32 have_bsf:1; 635 __u32 have_fsr:1; 636 __u32 have_bsr:1; 637 __u32 have_eod:1; 638 __u32 have_seek:1; 639 __u32 have_tell:1; 640 __u32 have_ras1:1; 641 __u32 have_ras2:1; 642 __u32 have_ras3:1; 643 __u32 have_qfa:1; 644 __u32 pad1:5; 645 char reserved[10]; 646}; 647#define MTIOCGETCONFIG32 _IOR('m', 4, struct mtconfiginfo32) 648#define MTIOCSETCONFIG32 _IOW('m', 5, struct mtconfiginfo32) 649 650static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) 651{ 652 mm_segment_t old_fs = get_fs(); 653 struct mtconfiginfo info; 654 struct mtget get; 655 struct mtpos pos; 656 unsigned long kcmd; 657 void *karg; 658 int err = 0; 659 660 switch(cmd) { 661 case MTIOCPOS32: 662 kcmd = MTIOCPOS; 663 karg = &pos; 664 break; 665 case MTIOCGET32: 666 kcmd = MTIOCGET; 667 karg = &get; 668 break; 669 case MTIOCGETCONFIG32: 670 kcmd = MTIOCGETCONFIG; 671 karg = &info; 672 break; 673 case MTIOCSETCONFIG32: 674 kcmd = MTIOCSETCONFIG; 675 karg = &info; 676 err = __get_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type); 677 err |= __get_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type); 678 err |= __get_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr); 679 err |= __get_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr); 680 err |= __get_user(info.port, &((struct mtconfiginfo32 *)arg)->port); 681 err |= __get_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug); 682 err |= __copy_from_user((char *)&info.debug + sizeof(info.debug), 683 (char *)&((struct mtconfiginfo32 *)arg)->debug 684 + sizeof(((struct mtconfiginfo32 *)arg)->debug), sizeof(__u32)); 685 if (err) 686 return -EFAULT; 687 break; 688 default: 689 do { 690 static int count = 0; 691 if (++count <= 20) 692 printk("mt_ioctl: Unknown cmd fd(%d) " 693 "cmd(%08x) arg(%08x)\n", 694 (int)fd, (unsigned int)cmd, (unsigned int)arg); 695 } while(0); 696 return -EINVAL; 697 } 698 set_fs (KERNEL_DS); 699 err = sys_ioctl (fd, kcmd, (unsigned long)karg); 700 set_fs (old_fs); 701 if (err) 702 return err; 703 switch (cmd) { 704 case MTIOCPOS32: 705 err = __put_user(pos.mt_blkno, &((struct mtpos32 *)arg)->mt_blkno); 706 break; 707 case MTIOCGET32: 708 err = __put_user(get.mt_type, &((struct mtget32 *)arg)->mt_type); 709 err |= __put_user(get.mt_resid, &((struct mtget32 *)arg)->mt_resid); 710 err |= __put_user(get.mt_dsreg, &((struct mtget32 *)arg)->mt_dsreg); 711 err |= __put_user(get.mt_gstat, &((struct mtget32 *)arg)->mt_gstat); 712 err |= __put_user(get.mt_erreg, &((struct mtget32 *)arg)->mt_erreg); 713 err |= __put_user(get.mt_fileno, &((struct mtget32 *)arg)->mt_fileno); 714 err |= __put_user(get.mt_blkno, &((struct mtget32 *)arg)->mt_blkno); 715 break; 716 case MTIOCGETCONFIG32: 717 err = __put_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type); 718 err |= __put_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type); 719 err |= __put_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr); 720 err |= __put_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr); 721 err |= __put_user(info.port, &((struct mtconfiginfo32 *)arg)->port); 722 err |= __put_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug); 723 err |= __copy_to_user((char *)&((struct mtconfiginfo32 *)arg)->debug 724 + sizeof(((struct mtconfiginfo32 *)arg)->debug), 725 (char *)&info.debug + sizeof(info.debug), sizeof(__u32)); 726 break; 727 case MTIOCSETCONFIG32: 728 break; 729 } 730 return err ? -EFAULT: 0; 731} 732 733#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int) 734 735static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg) 736{ 737 return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg); 738} 739 740struct ioctl32_handler { 741 unsigned int cmd; 742 int (*function)(unsigned int, unsigned int, unsigned long); 743}; 744 745struct ioctl32_list { 746 struct ioctl32_handler handler; 747 struct ioctl32_list *next; 748}; 749 750#define IOCTL32_DEFAULT(cmd) { { cmd, (void *) sys_ioctl }, 0 } 751#define IOCTL32_HANDLER(cmd, handler) { { cmd, (void *) handler }, 0 } 752 753static struct ioctl32_list ioctl32_handler_table[] = { 754 IOCTL32_DEFAULT(TCGETA), 755 IOCTL32_DEFAULT(TCSETA), 756 IOCTL32_DEFAULT(TCSETAW), 757 IOCTL32_DEFAULT(TCSETAF), 758 IOCTL32_DEFAULT(TCSBRK), 759 IOCTL32_DEFAULT(TCXONC), 760 IOCTL32_DEFAULT(TCFLSH), 761 IOCTL32_DEFAULT(TCGETS), 762 IOCTL32_DEFAULT(TCSETS), 763 IOCTL32_DEFAULT(TCSETSW), 764 IOCTL32_DEFAULT(TCSETSF), 765 IOCTL32_DEFAULT(TIOCLINUX), 766 767 IOCTL32_DEFAULT(TIOCGETD), 768 IOCTL32_DEFAULT(TIOCSETD), 769 IOCTL32_DEFAULT(TIOCEXCL), 770 IOCTL32_DEFAULT(TIOCNXCL), 771 IOCTL32_DEFAULT(TIOCCONS), 772 IOCTL32_DEFAULT(TIOCGSOFTCAR), 773 IOCTL32_DEFAULT(TIOCSSOFTCAR), 774 IOCTL32_DEFAULT(TIOCSWINSZ), 775 IOCTL32_DEFAULT(TIOCGWINSZ), 776 IOCTL32_DEFAULT(TIOCMGET), 777 IOCTL32_DEFAULT(TIOCMBIC), 778 IOCTL32_DEFAULT(TIOCMBIS), 779 IOCTL32_DEFAULT(TIOCMSET), 780 IOCTL32_DEFAULT(TIOCPKT), 781 IOCTL32_DEFAULT(TIOCNOTTY), 782 IOCTL32_DEFAULT(TIOCSTI), 783 IOCTL32_DEFAULT(TIOCOUTQ), 784 IOCTL32_DEFAULT(TIOCSPGRP), 785 IOCTL32_DEFAULT(TIOCGPGRP), 786 IOCTL32_DEFAULT(TIOCSCTTY), 787 IOCTL32_DEFAULT(TIOCGPTN), 788 IOCTL32_DEFAULT(TIOCSPTLCK), 789 IOCTL32_DEFAULT(TIOCGSERIAL), 790 IOCTL32_DEFAULT(TIOCSSERIAL), 791 IOCTL32_DEFAULT(TIOCSERGETLSR), 792 793 IOCTL32_DEFAULT(FIOCLEX), 794 IOCTL32_DEFAULT(FIONCLEX), 795 IOCTL32_DEFAULT(FIOASYNC), 796 IOCTL32_DEFAULT(FIONBIO), 797 IOCTL32_DEFAULT(FIONREAD), 798 799#ifdef CONFIG_FB 800 /* Big F */ 801 IOCTL32_DEFAULT(FBIOGET_VSCREENINFO), 802 IOCTL32_DEFAULT(FBIOPUT_VSCREENINFO), 803 IOCTL32_HANDLER(FBIOGET_FSCREENINFO, do_fbioget_fscreeninfo_ioctl), 804 IOCTL32_HANDLER(FBIOGETCMAP, do_fbiocmap_ioctl), 805 IOCTL32_HANDLER(FBIOPUTCMAP, do_fbiocmap_ioctl), 806 IOCTL32_DEFAULT(FBIOPAN_DISPLAY), 807#endif /* CONFIG_FB */ 808 809 /* Big K */ 810 IOCTL32_DEFAULT(PIO_FONT), 811 IOCTL32_DEFAULT(GIO_FONT), 812 IOCTL32_DEFAULT(KDSIGACCEPT), 813 IOCTL32_DEFAULT(KDGETKEYCODE), 814 IOCTL32_DEFAULT(KDSETKEYCODE), 815 IOCTL32_DEFAULT(KIOCSOUND), 816 IOCTL32_DEFAULT(KDMKTONE), 817 IOCTL32_DEFAULT(KDGKBTYPE), 818 IOCTL32_DEFAULT(KDSETMODE), 819 IOCTL32_DEFAULT(KDGETMODE), 820 IOCTL32_DEFAULT(KDSKBMODE), 821 IOCTL32_DEFAULT(KDGKBMODE), 822 IOCTL32_DEFAULT(KDSKBMETA), 823 IOCTL32_DEFAULT(KDGKBMETA), 824 IOCTL32_DEFAULT(KDGKBENT), 825 IOCTL32_DEFAULT(KDSKBENT), 826 IOCTL32_DEFAULT(KDGKBSENT), 827 IOCTL32_DEFAULT(KDSKBSENT), 828 IOCTL32_DEFAULT(KDGKBDIACR), 829 IOCTL32_DEFAULT(KDSKBDIACR), 830 IOCTL32_DEFAULT(KDKBDREP), 831 IOCTL32_DEFAULT(KDGKBLED), 832 IOCTL32_DEFAULT(KDSKBLED), 833 IOCTL32_DEFAULT(KDGETLED), 834 IOCTL32_DEFAULT(KDSETLED), 835 IOCTL32_DEFAULT(GIO_SCRNMAP), 836 IOCTL32_DEFAULT(PIO_SCRNMAP), 837 IOCTL32_DEFAULT(GIO_UNISCRNMAP), 838 IOCTL32_DEFAULT(PIO_UNISCRNMAP), 839 IOCTL32_DEFAULT(PIO_FONTRESET), 840 IOCTL32_DEFAULT(PIO_UNIMAPCLR), 841 842 /* Big S */ 843 IOCTL32_DEFAULT(SCSI_IOCTL_GET_IDLUN), 844 IOCTL32_DEFAULT(SCSI_IOCTL_DOORLOCK), 845 IOCTL32_DEFAULT(SCSI_IOCTL_DOORUNLOCK), 846 IOCTL32_DEFAULT(SCSI_IOCTL_TEST_UNIT_READY), 847 IOCTL32_DEFAULT(SCSI_IOCTL_TAGGED_ENABLE), 848 IOCTL32_DEFAULT(SCSI_IOCTL_TAGGED_DISABLE), 849 IOCTL32_DEFAULT(SCSI_IOCTL_GET_BUS_NUMBER), 850 IOCTL32_DEFAULT(SCSI_IOCTL_SEND_COMMAND), 851 852 /* Big V */ 853 IOCTL32_DEFAULT(VT_SETMODE), 854 IOCTL32_DEFAULT(VT_GETMODE), 855 IOCTL32_DEFAULT(VT_GETSTATE), 856 IOCTL32_DEFAULT(VT_OPENQRY), 857 IOCTL32_DEFAULT(VT_ACTIVATE), 858 IOCTL32_DEFAULT(VT_WAITACTIVE), 859 IOCTL32_DEFAULT(VT_RELDISP), 860 IOCTL32_DEFAULT(VT_DISALLOCATE), 861 IOCTL32_DEFAULT(VT_RESIZE), 862 IOCTL32_DEFAULT(VT_RESIZEX), 863 IOCTL32_DEFAULT(VT_LOCKSWITCH), 864 IOCTL32_DEFAULT(VT_UNLOCKSWITCH), 865 866#ifdef CONFIG_NET 867 /* Socket level stuff */ 868 IOCTL32_DEFAULT(FIOSETOWN), 869 IOCTL32_DEFAULT(SIOCSPGRP), 870 IOCTL32_DEFAULT(FIOGETOWN), 871 IOCTL32_DEFAULT(SIOCGPGRP), 872 IOCTL32_DEFAULT(SIOCATMARK), 873 IOCTL32_DEFAULT(SIOCSIFLINK), 874 IOCTL32_DEFAULT(SIOCSIFENCAP), 875 IOCTL32_DEFAULT(SIOCGIFENCAP), 876 IOCTL32_DEFAULT(SIOCSIFBR), 877 IOCTL32_DEFAULT(SIOCGIFBR), 878 IOCTL32_DEFAULT(SIOCSARP), 879 IOCTL32_DEFAULT(SIOCGARP), 880 IOCTL32_DEFAULT(SIOCDARP), 881 IOCTL32_DEFAULT(SIOCSRARP), 882 IOCTL32_DEFAULT(SIOCGRARP), 883 IOCTL32_DEFAULT(SIOCDRARP), 884 IOCTL32_DEFAULT(SIOCADDDLCI), 885 IOCTL32_DEFAULT(SIOCDELDLCI), 886 /* SG stuff */ 887 IOCTL32_DEFAULT(SG_SET_TIMEOUT), 888 IOCTL32_DEFAULT(SG_GET_TIMEOUT), 889 IOCTL32_DEFAULT(SG_EMULATED_HOST), 890 IOCTL32_DEFAULT(SG_SET_TRANSFORM), 891 IOCTL32_DEFAULT(SG_GET_TRANSFORM), 892 IOCTL32_DEFAULT(SG_SET_RESERVED_SIZE), 893 IOCTL32_DEFAULT(SG_GET_RESERVED_SIZE), 894 IOCTL32_DEFAULT(SG_GET_SCSI_ID), 895 IOCTL32_DEFAULT(SG_SET_FORCE_LOW_DMA), 896 IOCTL32_DEFAULT(SG_GET_LOW_DMA), 897 IOCTL32_DEFAULT(SG_SET_FORCE_PACK_ID), 898 IOCTL32_DEFAULT(SG_GET_PACK_ID), 899 IOCTL32_DEFAULT(SG_GET_NUM_WAITING), 900 IOCTL32_DEFAULT(SG_SET_DEBUG), 901 IOCTL32_DEFAULT(SG_GET_SG_TABLESIZE), 902 IOCTL32_DEFAULT(SG_GET_COMMAND_Q), 903 IOCTL32_DEFAULT(SG_SET_COMMAND_Q), 904 IOCTL32_DEFAULT(SG_GET_VERSION_NUM), 905 IOCTL32_DEFAULT(SG_NEXT_CMD_LEN), 906 IOCTL32_DEFAULT(SG_SCSI_RESET), 907 IOCTL32_DEFAULT(SG_IO), 908 IOCTL32_DEFAULT(SG_GET_REQUEST_TABLE), 909 IOCTL32_DEFAULT(SG_SET_KEEP_ORPHAN), 910 IOCTL32_DEFAULT(SG_GET_KEEP_ORPHAN), 911 /* PPP stuff */ 912 IOCTL32_DEFAULT(PPPIOCGFLAGS), 913 IOCTL32_DEFAULT(PPPIOCSFLAGS), 914 IOCTL32_DEFAULT(PPPIOCGASYNCMAP), 915 IOCTL32_DEFAULT(PPPIOCSASYNCMAP), 916 IOCTL32_DEFAULT(PPPIOCGUNIT), 917 IOCTL32_DEFAULT(PPPIOCGRASYNCMAP), 918 IOCTL32_DEFAULT(PPPIOCSRASYNCMAP), 919 IOCTL32_DEFAULT(PPPIOCGMRU), 920 IOCTL32_DEFAULT(PPPIOCSMRU), 921 IOCTL32_DEFAULT(PPPIOCSMAXCID), 922 IOCTL32_DEFAULT(PPPIOCGXASYNCMAP), 923 IOCTL32_DEFAULT(PPPIOCSXASYNCMAP), 924 IOCTL32_DEFAULT(PPPIOCXFERUNIT), 925 IOCTL32_DEFAULT(PPPIOCGNPMODE), 926 IOCTL32_DEFAULT(PPPIOCSNPMODE), 927 IOCTL32_DEFAULT(PPPIOCGDEBUG), 928 IOCTL32_DEFAULT(PPPIOCSDEBUG), 929 IOCTL32_DEFAULT(PPPIOCNEWUNIT), 930 IOCTL32_DEFAULT(PPPIOCATTACH), 931 IOCTL32_DEFAULT(PPPIOCGCHAN), 932 /* PPPOX */ 933 IOCTL32_DEFAULT(PPPOEIOCSFWD), 934 IOCTL32_DEFAULT(PPPOEIOCDFWD), 935 /* CDROM stuff */ 936 IOCTL32_DEFAULT(CDROMPAUSE), 937 IOCTL32_DEFAULT(CDROMRESUME), 938 IOCTL32_DEFAULT(CDROMPLAYMSF), 939 IOCTL32_DEFAULT(CDROMPLAYTRKIND), 940 IOCTL32_DEFAULT(CDROMREADTOCHDR), 941 IOCTL32_DEFAULT(CDROMREADTOCENTRY), 942 IOCTL32_DEFAULT(CDROMSTOP), 943 IOCTL32_DEFAULT(CDROMSTART), 944 IOCTL32_DEFAULT(CDROMEJECT), 945 IOCTL32_DEFAULT(CDROMVOLCTRL), 946 IOCTL32_DEFAULT(CDROMSUBCHNL), 947 IOCTL32_DEFAULT(CDROMEJECT_SW), 948 IOCTL32_DEFAULT(CDROMMULTISESSION), 949 IOCTL32_DEFAULT(CDROM_GET_MCN), 950 IOCTL32_DEFAULT(CDROMRESET), 951 IOCTL32_DEFAULT(CDROMVOLREAD), 952 IOCTL32_DEFAULT(CDROMSEEK), 953 IOCTL32_DEFAULT(CDROMPLAYBLK), 954 IOCTL32_DEFAULT(CDROMCLOSETRAY), 955 IOCTL32_DEFAULT(CDROM_SET_OPTIONS), 956 IOCTL32_DEFAULT(CDROM_CLEAR_OPTIONS), 957 IOCTL32_DEFAULT(CDROM_SELECT_SPEED), 958 IOCTL32_DEFAULT(CDROM_SELECT_DISC), 959 IOCTL32_DEFAULT(CDROM_MEDIA_CHANGED), 960 IOCTL32_DEFAULT(CDROM_DRIVE_STATUS), 961 IOCTL32_DEFAULT(CDROM_DISC_STATUS), 962 IOCTL32_DEFAULT(CDROM_CHANGER_NSLOTS), 963 IOCTL32_DEFAULT(CDROM_LOCKDOOR), 964 IOCTL32_DEFAULT(CDROM_DEBUG), 965 IOCTL32_DEFAULT(CDROM_GET_CAPABILITY), 966 /* DVD ioctls */ 967 IOCTL32_DEFAULT(DVD_READ_STRUCT), 968 IOCTL32_DEFAULT(DVD_WRITE_STRUCT), 969 IOCTL32_DEFAULT(DVD_AUTH), 970 /* Big L */ 971 IOCTL32_DEFAULT(LOOP_SET_FD), 972 IOCTL32_DEFAULT(LOOP_CLR_FD), 973 974 /* And these ioctls need translation */ 975 IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32), 976 IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf), 977 IOCTL32_HANDLER(SIOCGIFFLAGS, dev_ifsioc), 978 IOCTL32_HANDLER(SIOCSIFFLAGS, dev_ifsioc), 979 IOCTL32_HANDLER(SIOCGIFMETRIC, dev_ifsioc), 980 IOCTL32_HANDLER(SIOCSIFMETRIC, dev_ifsioc), 981 IOCTL32_HANDLER(SIOCGIFMTU, dev_ifsioc), 982 IOCTL32_HANDLER(SIOCSIFMTU, dev_ifsioc), 983 IOCTL32_HANDLER(SIOCGIFMEM, dev_ifsioc), 984 IOCTL32_HANDLER(SIOCSIFMEM, dev_ifsioc), 985 IOCTL32_HANDLER(SIOCGIFHWADDR, dev_ifsioc), 986 IOCTL32_HANDLER(SIOCSIFHWADDR, dev_ifsioc), 987 IOCTL32_HANDLER(SIOCADDMULTI, dev_ifsioc), 988 IOCTL32_HANDLER(SIOCDELMULTI, dev_ifsioc), 989 IOCTL32_HANDLER(SIOCGIFINDEX, dev_ifsioc), 990 IOCTL32_HANDLER(SIOCGIFMAP, dev_ifsioc), 991 IOCTL32_HANDLER(SIOCSIFMAP, dev_ifsioc), 992 IOCTL32_HANDLER(SIOCGIFADDR, dev_ifsioc), 993 IOCTL32_HANDLER(SIOCSIFADDR, dev_ifsioc), 994 IOCTL32_HANDLER(SIOCGIFBRDADDR, dev_ifsioc), 995 IOCTL32_HANDLER(SIOCSIFBRDADDR, dev_ifsioc), 996 IOCTL32_HANDLER(SIOCGIFDSTADDR, dev_ifsioc), 997 IOCTL32_HANDLER(SIOCSIFDSTADDR, dev_ifsioc), 998 IOCTL32_HANDLER(SIOCGIFNETMASK, dev_ifsioc), 999 IOCTL32_HANDLER(SIOCSIFNETMASK, dev_ifsioc), 1000 IOCTL32_HANDLER(SIOCSIFPFLAGS, dev_ifsioc), 1001 IOCTL32_HANDLER(SIOCGIFPFLAGS, dev_ifsioc), 1002 IOCTL32_HANDLER(SIOCGPPPSTATS, dev_ifsioc), 1003 IOCTL32_HANDLER(SIOCGPPPCSTATS, dev_ifsioc), 1004 IOCTL32_HANDLER(SIOCGPPPVER, dev_ifsioc), 1005 IOCTL32_HANDLER(SIOCGIFTXQLEN, dev_ifsioc), 1006 IOCTL32_HANDLER(SIOCSIFTXQLEN, dev_ifsioc), 1007 IOCTL32_HANDLER(SIOCADDRT, routing_ioctl), 1008 IOCTL32_HANDLER(SIOCDELRT, routing_ioctl), 1009 /* 1010 * Note SIOCRTMSG is no longer, so this is safe and * the user would 1011 * have seen just an -EINVAL anyways. 1012 */ 1013 IOCTL32_HANDLER(SIOCRTMSG, ret_einval), 1014 IOCTL32_HANDLER(SIOCGSTAMP, do_siocgstamp), 1015 1016#endif /* CONFIG_NET */ 1017 1018 IOCTL32_DEFAULT(PROF_START), 1019 IOCTL32_DEFAULT(PROF_STOP), 1020 IOCTL32_DEFAULT(PROF_RESET), 1021 IOCTL32_DEFAULT(PROF_SET_SAMPLE_FREQ), 1022 IOCTL32_DEFAULT(PROF_GET_SAMPLE_FREQ), 1023 IOCTL32_DEFAULT(PROF_GET_PC_RES), 1024 IOCTL32_DEFAULT(PROF_GET_ON_OFF_STATE), 1025 IOCTL32_DEFAULT(PROF_SET_DOMAIN), 1026 IOCTL32_DEFAULT(PROF_GET_DOMAIN), 1027 IOCTL32_DEFAULT(PROF_SET_MODE), 1028 IOCTL32_DEFAULT(PROF_GET_MODE), 1029 IOCTL32_DEFAULT(PROF_SET_PERFCTR_EVENT), 1030 IOCTL32_DEFAULT(PROF_GET_PERFCTR_EVENT), 1031 IOCTL32_DEFAULT(PROF_SET_ENABLE_MAP), 1032 IOCTL32_DEFAULT(PROF_GET_ENABLE_MAP), 1033 IOCTL32_DEFAULT(PROF_SET_PID), 1034 IOCTL32_DEFAULT(PROF_GET_PID), 1035 1036 IOCTL32_HANDLER(EXT2_IOC32_GETFLAGS, do_ext2_ioctl), 1037 IOCTL32_HANDLER(EXT2_IOC32_SETFLAGS, do_ext2_ioctl), 1038 IOCTL32_HANDLER(EXT2_IOC32_GETVERSION, do_ext2_ioctl), 1039 IOCTL32_HANDLER(EXT2_IOC32_SETVERSION, do_ext2_ioctl), 1040 1041 IOCTL32_HANDLER(HDIO_GETGEO, hdio_getgeo), /* hdreg.h ioctls */ 1042 IOCTL32_HANDLER(HDIO_GET_UNMASKINTR, hdio_ioctl_trans), 1043 IOCTL32_HANDLER(HDIO_GET_MULTCOUNT, hdio_ioctl_trans), 1044 // HDIO_OBSOLETE_IDENTITY 1045 IOCTL32_HANDLER(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans), 1046 IOCTL32_HANDLER(HDIO_GET_32BIT, hdio_ioctl_trans), 1047 IOCTL32_HANDLER(HDIO_GET_NOWERR, hdio_ioctl_trans), 1048 IOCTL32_HANDLER(HDIO_GET_DMA, hdio_ioctl_trans), 1049 IOCTL32_HANDLER(HDIO_GET_NICE, hdio_ioctl_trans), 1050 IOCTL32_DEFAULT(HDIO_GET_IDENTITY), 1051 IOCTL32_DEFAULT(HDIO_DRIVE_RESET), 1052 // HDIO_TRISTATE_HWIF /* not implemented */ 1053 // HDIO_DRIVE_TASK /* To do, need specs */ 1054 IOCTL32_DEFAULT(HDIO_DRIVE_CMD), 1055 IOCTL32_DEFAULT(HDIO_SET_MULTCOUNT), 1056 IOCTL32_DEFAULT(HDIO_SET_UNMASKINTR), 1057 IOCTL32_DEFAULT(HDIO_SET_KEEPSETTINGS), 1058 IOCTL32_DEFAULT(HDIO_SET_32BIT), 1059 IOCTL32_DEFAULT(HDIO_SET_NOWERR), 1060 IOCTL32_DEFAULT(HDIO_SET_DMA), 1061 IOCTL32_DEFAULT(HDIO_SET_PIO_MODE), 1062 IOCTL32_DEFAULT(HDIO_SCAN_HWIF), 1063 IOCTL32_DEFAULT(HDIO_SET_NICE), 1064 //HDIO_UNREGISTER_HWIF 1065 1066 IOCTL32_DEFAULT(BLKROSET), /* fs.h ioctls */ 1067 IOCTL32_DEFAULT(BLKROGET), 1068 IOCTL32_DEFAULT(BLKRRPART), 1069 IOCTL32_HANDLER(BLKGETSIZE, w_long), 1070 1071 IOCTL32_DEFAULT(BLKFLSBUF), 1072 IOCTL32_DEFAULT(BLKRASET), 1073 IOCTL32_HANDLER(BLKRAGET, w_long), 1074 IOCTL32_DEFAULT(BLKFRASET), 1075 IOCTL32_HANDLER(BLKFRAGET, w_long), 1076 IOCTL32_DEFAULT(BLKSECTSET), 1077 IOCTL32_HANDLER(BLKSECTGET, w_long), 1078 IOCTL32_DEFAULT(BLKSSZGET), 1079 IOCTL32_HANDLER(BLKPG, blkpg_ioctl_trans), 1080 IOCTL32_DEFAULT(BLKELVGET), 1081 IOCTL32_DEFAULT(BLKELVSET), 1082 IOCTL32_DEFAULT(BLKBSZGET), 1083 IOCTL32_DEFAULT(BLKBSZSET), 1084 1085#ifdef CONFIG_MD 1086 /* status */ 1087 IOCTL32_DEFAULT(RAID_VERSION), 1088 IOCTL32_DEFAULT(GET_ARRAY_INFO), 1089 IOCTL32_DEFAULT(GET_DISK_INFO), 1090 IOCTL32_DEFAULT(PRINT_RAID_DEBUG), 1091 IOCTL32_DEFAULT(RAID_AUTORUN), 1092 1093 /* configuration */ 1094 IOCTL32_DEFAULT(CLEAR_ARRAY), 1095 IOCTL32_DEFAULT(ADD_NEW_DISK), 1096 IOCTL32_DEFAULT(HOT_REMOVE_DISK), 1097 IOCTL32_DEFAULT(SET_ARRAY_INFO), 1098 IOCTL32_DEFAULT(SET_DISK_INFO), 1099 IOCTL32_DEFAULT(WRITE_RAID_INFO), 1100 IOCTL32_DEFAULT(UNPROTECT_ARRAY), 1101 IOCTL32_DEFAULT(PROTECT_ARRAY), 1102 IOCTL32_DEFAULT(HOT_ADD_DISK), 1103 IOCTL32_DEFAULT(SET_DISK_FAULTY), 1104 1105 /* usage */ 1106 IOCTL32_DEFAULT(RUN_ARRAY), 1107 IOCTL32_DEFAULT(START_ARRAY), 1108 IOCTL32_DEFAULT(STOP_ARRAY), 1109 IOCTL32_DEFAULT(STOP_ARRAY_RO), 1110 IOCTL32_DEFAULT(RESTART_ARRAY_RW), 1111#endif /* CONFIG_MD */ 1112 1113 IOCTL32_DEFAULT(MTIOCTOP), /* mtio.h ioctls */ 1114 IOCTL32_HANDLER(MTIOCGET32, mt_ioctl_trans), 1115 IOCTL32_HANDLER(MTIOCPOS32, mt_ioctl_trans), 1116 IOCTL32_HANDLER(MTIOCGETCONFIG32, mt_ioctl_trans), 1117 IOCTL32_HANDLER(MTIOCSETCONFIG32, mt_ioctl_trans), 1118 // MTIOCRDFTSEG 1119 // MTIOCWRFTSEG 1120 // MTIOCVOLINFO 1121 // MTIOCGETSIZE 1122 // MTIOCFTFORMAT 1123 // MTIOCFTCMD 1124 1125 IOCTL32_DEFAULT(AUTOFS_IOC_READY), /* auto_fs.h ioctls */ 1126 IOCTL32_DEFAULT(AUTOFS_IOC_FAIL), 1127 IOCTL32_DEFAULT(AUTOFS_IOC_CATATONIC), 1128 IOCTL32_DEFAULT(AUTOFS_IOC_PROTOVER), 1129 IOCTL32_HANDLER(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout), 1130 IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE), 1131 IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE_MULTI), 1132 1133 /* Little p (/dev/rtc, /dev/envctrl, etc.) */ 1134 IOCTL32_DEFAULT(_IOR('p', 20, int[7])), /* RTCGET */ 1135 IOCTL32_DEFAULT(_IOW('p', 21, int[7])), /* RTCSET */ 1136 IOCTL32_DEFAULT(RTC_AIE_ON), 1137 IOCTL32_DEFAULT(RTC_AIE_OFF), 1138 IOCTL32_DEFAULT(RTC_UIE_ON), 1139 IOCTL32_DEFAULT(RTC_UIE_OFF), 1140 IOCTL32_DEFAULT(RTC_PIE_ON), 1141 IOCTL32_DEFAULT(RTC_PIE_OFF), 1142 IOCTL32_DEFAULT(RTC_WIE_ON), 1143 IOCTL32_DEFAULT(RTC_WIE_OFF), 1144 IOCTL32_DEFAULT(RTC_ALM_SET), 1145 IOCTL32_DEFAULT(RTC_ALM_READ), 1146 IOCTL32_DEFAULT(RTC_RD_TIME), 1147 IOCTL32_DEFAULT(RTC_SET_TIME), 1148 IOCTL32_DEFAULT(RTC_WKALM_SET), 1149 IOCTL32_DEFAULT(RTC_WKALM_RD) 1150}; 1151 1152#define NR_IOCTL32_HANDLERS (sizeof(ioctl32_handler_table) / \ 1153 sizeof(ioctl32_handler_table[0])) 1154 1155static struct ioctl32_list *ioctl32_hash_table[1024]; 1156 1157static inline int ioctl32_hash(unsigned int cmd) 1158{ 1159 return ((cmd >> 6) ^ (cmd >> 4) ^ cmd) & 0x3ff; 1160} 1161 1162int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned int arg) 1163{ 1164 int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp); 1165 struct file *filp; 1166 struct ioctl32_list *l; 1167 int error; 1168 1169 l = ioctl32_hash_table[ioctl32_hash(cmd)]; 1170 1171 error = -EBADF; 1172 1173 filp = fget(fd); 1174 if (!filp) 1175 return error; 1176 1177 if (!filp->f_op || !filp->f_op->ioctl) { 1178 error = sys_ioctl (fd, cmd, arg); 1179 goto out; 1180 } 1181 1182 while (l && l->handler.cmd != cmd) 1183 l = l->next; 1184 1185 if (l) { 1186 handler = (void *)l->handler.function; 1187 error = handler(fd, cmd, arg, filp); 1188 } else { 1189 error = -EINVAL; 1190 printk("unknown ioctl: %08x\n", cmd); 1191 } 1192out: 1193 fput(filp); 1194 return error; 1195} 1196 1197static void ioctl32_insert(struct ioctl32_list *entry) 1198{ 1199 int hash = ioctl32_hash(entry->handler.cmd); 1200 if (!ioctl32_hash_table[hash]) 1201 ioctl32_hash_table[hash] = entry; 1202 else { 1203 struct ioctl32_list *l; 1204 l = ioctl32_hash_table[hash]; 1205 while (l->next) 1206 l = l->next; 1207 l->next = entry; 1208 entry->next = 0; 1209 } 1210} 1211 1212static int __init init_ioctl32(void) 1213{ 1214 int i; 1215 for (i = 0; i < NR_IOCTL32_HANDLERS; i++) 1216 ioctl32_insert(&ioctl32_handler_table[i]); 1217 return 0; 1218} 1219 1220__initcall(init_ioctl32); 1221