2 * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
5 * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
6 * Author(s): Gerhard Tonn (ton@de.ibm.com)
8 * Heavily inspired by the 32-bit Sparc compat code which is
9 * Copyright (C) 2000 Silicon Graphics, Inc.
10 * Written by Ulf Carlsson (ulfc@engr.sgi.com)
14 #include <linux/types.h>
15 #include <linux/kernel.h>
17 #include <linux/sched.h>
19 #include <linux/init.h>
20 #include <linux/file.h>
23 #include <linux/netdevice.h>
24 #include <linux/route.h>
25 #include <linux/ext2_fs.h>
26 #include <linux/hdreg.h>
27 #include <linux/if_bonding.h>
28 #include <linux/loop.h>
29 #include <linux/blkpg.h>
30 #include <linux/blk.h>
31 #include <linux/elevator.h>
32 #include <linux/raw.h>
33 #include <asm/types.h>
34 #include <asm/uaccess.h>
36 #include <asm/sockios.h>
37 #include "../../../drivers/s390/char/tubio.h"
41 long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
43 struct hd_geometry32 {
45 unsigned char sectors;
46 unsigned short cylinders;
50 static inline int hd_geometry_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
52 struct hd_geometry32 *hg32 = (struct hd_geometry32 *) A(arg);
53 struct hd_geometry hg;
55 mm_segment_t old_fs = get_fs();
58 ret = sys_ioctl (fd, cmd, (long)&hg);
64 ret = put_user (hg.heads, &(hg32->heads));
65 ret |= __put_user (hg.sectors, &(hg32->sectors));
66 ret |= __put_user (hg.cylinders, &(hg32->cylinders));
67 ret |= __put_user (hg.start, &(hg32->start));
77 #define EXT2_IOC32_GETFLAGS _IOR('f', 1, int)
78 #define EXT2_IOC32_SETFLAGS _IOW('f', 2, int)
79 #define EXT2_IOC32_GETVERSION _IOR('v', 1, int)
80 #define EXT2_IOC32_SETVERSION _IOW('v', 2, int)
83 unsigned int mem_start;
85 unsigned short base_addr;
95 char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
98 struct sockaddr ifru_addr;
99 struct sockaddr ifru_dstaddr;
100 struct sockaddr ifru_broadaddr;
101 struct sockaddr ifru_netmask;
102 struct sockaddr ifru_hwaddr;
106 struct ifmap32 ifru_map;
107 char ifru_slave[IFNAMSIZ]; /* Just fits the size */
108 char ifru_newname[IFNAMSIZ];
114 int ifc_len; /* size of buffer */
118 static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg)
120 struct ireq32 *uir32 = (struct ireq32 *) A(arg);
121 struct net_device *dev;
122 struct ifreq32 ifr32;
124 if (copy_from_user(&ifr32, uir32, sizeof(struct ifreq32)))
127 read_lock(&dev_base_lock);
128 dev = __dev_get_by_index(ifr32.ifr_ifindex);
130 read_unlock(&dev_base_lock);
134 strcpy(ifr32.ifr_name, dev->name);
135 read_unlock(&dev_base_lock);
137 if (copy_to_user(uir32, &ifr32, sizeof(struct ifreq32)))
143 static inline int dev_ifconf(unsigned int fd, unsigned int cmd,
146 struct ioconf32 *uifc32 = (struct ioconf32 *) A(arg);
147 struct ifconf32 ifc32;
149 struct ifreq32 *ifr32;
155 if (copy_from_user(&ifc32, uifc32, sizeof(struct ifconf32)))
158 if(ifc32.ifcbuf == 0) {
163 ifc.ifc_len = ((ifc32.ifc_len / sizeof (struct ifreq32))) *
164 sizeof (struct ifreq);
165 ifc.ifc_buf = kmalloc (ifc.ifc_len, GFP_KERNEL);
170 ifr32 = (struct ifreq32 *) A(ifc32.ifcbuf);
171 len = ifc32.ifc_len / sizeof (struct ifreq32);
173 if (copy_from_user(ifr++, ifr32++, sizeof (struct ifreq32))) {
181 err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc);
187 ifr32 = (struct ifreq32 *) A(ifc32.ifcbuf);
188 len = ifc.ifc_len / sizeof (struct ifreq);
189 ifc32.ifc_len = len * sizeof (struct ifreq32);
192 if (copy_to_user(ifr32++, ifr++, sizeof (struct ifreq32))) {
198 if (copy_to_user(uifc32, &ifc32, sizeof(struct ifconf32))) {
203 if(ifc.ifc_buf != NULL)
208 static int bond_ioctl(unsigned long fd, unsigned int cmd, unsigned long arg)
215 if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
217 ifr.ifr_data = (__kernel_caddr_t)get_free_page(GFP_KERNEL);
222 case SIOCBONDENSLAVE:
223 case SIOCBONDRELEASE:
224 case SIOCBONDSETHWADDR:
225 case SIOCBONDCHANGEACTIVE:
226 len = IFNAMSIZ * sizeof(char);
228 case SIOCBONDSLAVEINFOQUERY:
229 len = sizeof(struct ifslave);
231 case SIOCBONDINFOQUERY:
232 len = sizeof(struct ifbond);
239 __get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
240 if (copy_from_user(ifr.ifr_data, (char *)A(data), len)) {
247 err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
250 len = copy_to_user((char *)A(data), ifr.ifr_data, len);
256 free_page((unsigned long)ifr.ifr_data);
260 static inline int dev_ifsioc(unsigned int fd, unsigned int cmd,
263 struct ifreq32 *uifr = (struct ifreq32 *) A(arg);
270 err = copy_from_user(&ifr, uifr, sizeof(ifr.ifr_name));
271 err |= __get_user(ifr.ifr_map.mem_start, &(uifr->ifr_ifru.ifru_map.mem_start));
272 err |= __get_user(ifr.ifr_map.mem_end, &(uifr->ifr_ifru.ifru_map.mem_end));
273 err |= __get_user(ifr.ifr_map.base_addr, &(uifr->ifr_ifru.ifru_map.base_addr));
274 err |= __get_user(ifr.ifr_map.irq, &(uifr->ifr_ifru.ifru_map.irq));
275 err |= __get_user(ifr.ifr_map.dma, &(uifr->ifr_ifru.ifru_map.dma));
276 err |= __get_user(ifr.ifr_map.port, &(uifr->ifr_ifru.ifru_map.port));
281 if (copy_from_user(&ifr, uifr, sizeof(struct ifreq32)))
287 err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
302 if (copy_to_user(uifr, &ifr, sizeof(struct ifreq32)))
306 err = copy_to_user(uifr, &ifr, sizeof(ifr.ifr_name));
307 err |= __put_user(ifr.ifr_map.mem_start, &(uifr->ifr_ifru.ifru_map.mem_start));
308 err |= __put_user(ifr.ifr_map.mem_end, &(uifr->ifr_ifru.ifru_map.mem_end));
309 err |= __put_user(ifr.ifr_map.base_addr, &(uifr->ifr_ifru.ifru_map.base_addr));
310 err |= __put_user(ifr.ifr_map.irq, &(uifr->ifr_ifru.ifru_map.irq));
311 err |= __put_user(ifr.ifr_map.dma, &(uifr->ifr_ifru.ifru_map.dma));
312 err |= __put_user(ifr.ifr_map.port, &(uifr->ifr_ifru.ifru_map.port));
323 unsigned int rt_pad1;
324 struct sockaddr rt_dst; /* target address */
325 struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */
326 struct sockaddr rt_genmask; /* target network mask (IP) */
327 unsigned short rt_flags;
329 unsigned int rt_pad3;
330 unsigned int rt_pad4;
331 short rt_metric; /* +1 for binary compatibility! */
332 unsigned int rt_dev; /* forcing the device at add */
333 unsigned int rt_mtu; /* per route MTU/Window */
335 #define rt_mss rt_mtu /* Compatibility :-( */
337 unsigned int rt_window; /* Window clamping */
338 unsigned short rt_irtt; /* Initial RTT */
341 static inline int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
343 struct rtentry32 *ur = (struct rtentry32 *) A(arg);
348 mm_segment_t old_fs = get_fs();
350 ret = copy_from_user (&r.rt_dst, &(ur->rt_dst), 3 * sizeof(struct sockaddr));
351 ret |= __get_user (r.rt_flags, &(ur->rt_flags));
352 ret |= __get_user (r.rt_metric, &(ur->rt_metric));
353 ret |= __get_user (r.rt_mtu, &(ur->rt_mtu));
354 ret |= __get_user (r.rt_window, &(ur->rt_window));
355 ret |= __get_user (r.rt_irtt, &(ur->rt_irtt));
356 ret |= __get_user (rtdev, &(ur->rt_dev));
358 ret |= copy_from_user (devname, (char *) A(rtdev), 15);
359 r.rt_dev = devname; devname[15] = 0;
365 ret = sys_ioctl (fd, cmd, (long)&r);
370 static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
372 /* These are just misnamed, they actually get/put from/to user an int */
374 case EXT2_IOC32_GETFLAGS: cmd = EXT2_IOC_GETFLAGS; break;
375 case EXT2_IOC32_SETFLAGS: cmd = EXT2_IOC_SETFLAGS; break;
376 case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break;
377 case EXT2_IOC32_SETVERSION: cmd = EXT2_IOC_SETVERSION; break;
379 return sys_ioctl(fd, cmd, arg);
383 int lo_number; /* ioctl r/o */
384 __kernel_dev_t32 lo_device; /* ioctl r/o */
385 unsigned int lo_inode; /* ioctl r/o */
386 __kernel_dev_t32 lo_rdevice; /* ioctl r/o */
389 int lo_encrypt_key_size; /* ioctl w/o */
390 int lo_flags; /* ioctl r/o */
391 char lo_name[LO_NAME_SIZE];
392 unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
393 unsigned int lo_init[2];
397 static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg)
399 mm_segment_t old_fs = get_fs();
404 case LOOP_SET_STATUS:
405 err = get_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number);
406 err |= __get_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);
407 err |= __get_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode);
408 err |= __get_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice);
409 err |= __copy_from_user((char *)&l.lo_offset, (char *)&((struct loop_info32 *)arg)->lo_offset,
410 8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
415 err = sys_ioctl (fd, cmd, (unsigned long)&l);
419 case LOOP_GET_STATUS:
421 err = sys_ioctl (fd, cmd, (unsigned long)&l);
424 err = put_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number);
425 err |= __put_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);
426 err |= __put_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode);
427 err |= __put_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice);
428 err |= __copy_to_user((char *)&((struct loop_info32 *)arg)->lo_offset,
429 (char *)&l.lo_offset, (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
435 static int count = 0;
437 printk("%s: Unknown loop ioctl cmd, fd(%d) "
438 "cmd(%08x) arg(%08lx)\n",
439 __FUNCTION__, fd, cmd, arg);
446 struct blkpg_ioctl_arg32 {
453 static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, struct blkpg_ioctl_arg32 *arg)
455 struct blkpg_ioctl_arg a;
456 struct blkpg_partition p;
458 mm_segment_t old_fs = get_fs();
460 err = get_user(a.op, &arg->op);
461 err |= __get_user(a.flags, &arg->flags);
462 err |= __get_user(a.datalen, &arg->datalen);
463 err |= __get_user((long)a.data, &arg->data);
466 case BLKPG_ADD_PARTITION:
467 case BLKPG_DEL_PARTITION:
468 if (a.datalen < sizeof(struct blkpg_partition))
470 if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition)))
474 err = sys_ioctl(fd, cmd, (unsigned long)&a);
483 static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
485 mm_segment_t old_fs = get_fs();
490 err = sys_ioctl(fd, cmd, (unsigned long)&val);
492 if (!err && put_user((unsigned int) val, (u32 *)arg))
497 struct ioctl32_handler {
499 int (*function)(unsigned int, unsigned int, unsigned long);
502 struct ioctl32_list {
503 struct ioctl32_handler handler;
504 struct ioctl32_list *next;
507 #define IOCTL32_DEFAULT(cmd) { { cmd, (void *) sys_ioctl }, 0 }
508 #define IOCTL32_HANDLER(cmd, handler) { { cmd, (void *) handler }, 0 }
510 static struct ioctl32_list ioctl32_handler_table[] = {
511 IOCTL32_DEFAULT(FIBMAP),
512 IOCTL32_DEFAULT(FIGETBSZ),
514 IOCTL32_DEFAULT(DASDAPIVER),
515 IOCTL32_DEFAULT(BIODASDDISABLE),
516 IOCTL32_DEFAULT(BIODASDENABLE),
517 IOCTL32_DEFAULT(BIODASDRSRV),
518 IOCTL32_DEFAULT(BIODASDRLSE),
519 IOCTL32_DEFAULT(BIODASDSLCK),
520 IOCTL32_DEFAULT(BIODASDINFO),
521 IOCTL32_DEFAULT(BIODASDFMT),
523 IOCTL32_DEFAULT(BLKROSET),
524 IOCTL32_DEFAULT(BLKROGET),
525 IOCTL32_DEFAULT(BLKRRPART),
526 IOCTL32_DEFAULT(BLKFLSBUF),
527 IOCTL32_DEFAULT(BLKRASET),
528 IOCTL32_DEFAULT(BLKFRASET),
529 IOCTL32_DEFAULT(BLKSECTSET),
530 IOCTL32_DEFAULT(BLKSSZGET),
531 IOCTL32_DEFAULT(BLKBSZGET),
532 IOCTL32_DEFAULT(BLKGETSIZE64),
534 IOCTL32_DEFAULT(BLKELVGET),
535 IOCTL32_DEFAULT(BLKELVSET),
537 IOCTL32_HANDLER(HDIO_GETGEO, hd_geometry_ioctl),
539 IOCTL32_DEFAULT(TUBICMD),
540 IOCTL32_DEFAULT(TUBOCMD),
541 IOCTL32_DEFAULT(TUBGETI),
542 IOCTL32_DEFAULT(TUBGETO),
543 IOCTL32_DEFAULT(TUBSETMOD),
544 IOCTL32_DEFAULT(TUBGETMOD),
545 IOCTL32_DEFAULT(TCGETA),
546 IOCTL32_DEFAULT(TCSETA),
547 IOCTL32_DEFAULT(TCSETAW),
548 IOCTL32_DEFAULT(TCSETAF),
549 IOCTL32_DEFAULT(TCSBRK),
550 IOCTL32_DEFAULT(TCSBRKP),
551 IOCTL32_DEFAULT(TCXONC),
552 IOCTL32_DEFAULT(TCFLSH),
553 IOCTL32_DEFAULT(TCGETS),
554 IOCTL32_DEFAULT(TCSETS),
555 IOCTL32_DEFAULT(TCSETSW),
556 IOCTL32_DEFAULT(TCSETSF),
557 IOCTL32_DEFAULT(TIOCLINUX),
559 IOCTL32_DEFAULT(TIOCGETD),
560 IOCTL32_DEFAULT(TIOCSETD),
561 IOCTL32_DEFAULT(TIOCEXCL),
562 IOCTL32_DEFAULT(TIOCNXCL),
563 IOCTL32_DEFAULT(TIOCCONS),
564 IOCTL32_DEFAULT(TIOCGSOFTCAR),
565 IOCTL32_DEFAULT(TIOCSSOFTCAR),
566 IOCTL32_DEFAULT(TIOCSWINSZ),
567 IOCTL32_DEFAULT(TIOCGWINSZ),
568 IOCTL32_DEFAULT(TIOCMGET),
569 IOCTL32_DEFAULT(TIOCMBIC),
570 IOCTL32_DEFAULT(TIOCMBIS),
571 IOCTL32_DEFAULT(TIOCMSET),
572 IOCTL32_DEFAULT(TIOCPKT),
573 IOCTL32_DEFAULT(TIOCNOTTY),
574 IOCTL32_DEFAULT(TIOCSTI),
575 IOCTL32_DEFAULT(TIOCOUTQ),
576 IOCTL32_DEFAULT(TIOCSPGRP),
577 IOCTL32_DEFAULT(TIOCGPGRP),
578 IOCTL32_DEFAULT(TIOCSCTTY),
579 IOCTL32_DEFAULT(TIOCGPTN),
580 IOCTL32_DEFAULT(TIOCSPTLCK),
581 IOCTL32_DEFAULT(TIOCGSERIAL),
582 IOCTL32_DEFAULT(TIOCSSERIAL),
583 IOCTL32_DEFAULT(TIOCSERGETLSR),
585 IOCTL32_DEFAULT(FIOCLEX),
586 IOCTL32_DEFAULT(FIONCLEX),
587 IOCTL32_DEFAULT(FIOASYNC),
588 IOCTL32_DEFAULT(FIONBIO),
589 IOCTL32_DEFAULT(FIONREAD),
591 IOCTL32_DEFAULT(PIO_FONT),
592 IOCTL32_DEFAULT(GIO_FONT),
593 IOCTL32_DEFAULT(KDSIGACCEPT),
594 IOCTL32_DEFAULT(KDGETKEYCODE),
595 IOCTL32_DEFAULT(KDSETKEYCODE),
596 IOCTL32_DEFAULT(KIOCSOUND),
597 IOCTL32_DEFAULT(KDMKTONE),
598 IOCTL32_DEFAULT(KDGKBTYPE),
599 IOCTL32_DEFAULT(KDSETMODE),
600 IOCTL32_DEFAULT(KDGETMODE),
601 IOCTL32_DEFAULT(KDSKBMODE),
602 IOCTL32_DEFAULT(KDGKBMODE),
603 IOCTL32_DEFAULT(KDSKBMETA),
604 IOCTL32_DEFAULT(KDGKBMETA),
605 IOCTL32_DEFAULT(KDGKBENT),
606 IOCTL32_DEFAULT(KDSKBENT),
607 IOCTL32_DEFAULT(KDGKBSENT),
608 IOCTL32_DEFAULT(KDSKBSENT),
609 IOCTL32_DEFAULT(KDGKBDIACR),
610 IOCTL32_DEFAULT(KDSKBDIACR),
611 IOCTL32_DEFAULT(KDGKBLED),
612 IOCTL32_DEFAULT(KDSKBLED),
613 IOCTL32_DEFAULT(KDGETLED),
614 IOCTL32_DEFAULT(KDSETLED),
615 IOCTL32_DEFAULT(GIO_SCRNMAP),
616 IOCTL32_DEFAULT(PIO_SCRNMAP),
617 IOCTL32_DEFAULT(GIO_UNISCRNMAP),
618 IOCTL32_DEFAULT(PIO_UNISCRNMAP),
619 IOCTL32_DEFAULT(PIO_FONTRESET),
620 IOCTL32_DEFAULT(PIO_UNIMAPCLR),
622 IOCTL32_DEFAULT(VT_SETMODE),
623 IOCTL32_DEFAULT(VT_GETMODE),
624 IOCTL32_DEFAULT(VT_GETSTATE),
625 IOCTL32_DEFAULT(VT_OPENQRY),
626 IOCTL32_DEFAULT(VT_ACTIVATE),
627 IOCTL32_DEFAULT(VT_WAITACTIVE),
628 IOCTL32_DEFAULT(VT_RELDISP),
629 IOCTL32_DEFAULT(VT_DISALLOCATE),
630 IOCTL32_DEFAULT(VT_RESIZE),
631 IOCTL32_DEFAULT(VT_RESIZEX),
632 IOCTL32_DEFAULT(VT_LOCKSWITCH),
633 IOCTL32_DEFAULT(VT_UNLOCKSWITCH),
635 IOCTL32_DEFAULT(SIOCGSTAMP),
637 IOCTL32_DEFAULT(LOOP_SET_FD),
638 IOCTL32_DEFAULT(LOOP_CLR_FD),
640 IOCTL32_DEFAULT(SIOCATMARK),
641 IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32),
642 IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf),
643 IOCTL32_HANDLER(SIOCGIFFLAGS, dev_ifsioc),
644 IOCTL32_HANDLER(SIOCSIFFLAGS, dev_ifsioc),
645 IOCTL32_HANDLER(SIOCGIFMETRIC, dev_ifsioc),
646 IOCTL32_HANDLER(SIOCSIFMETRIC, dev_ifsioc),
647 IOCTL32_HANDLER(SIOCGIFMTU, dev_ifsioc),
648 IOCTL32_HANDLER(SIOCSIFMTU, dev_ifsioc),
649 IOCTL32_HANDLER(SIOCGIFMEM, dev_ifsioc),
650 IOCTL32_HANDLER(SIOCSIFMEM, dev_ifsioc),
651 IOCTL32_HANDLER(SIOCGIFHWADDR, dev_ifsioc),
652 IOCTL32_HANDLER(SIOCSIFHWADDR, dev_ifsioc),
653 IOCTL32_HANDLER(SIOCADDMULTI, dev_ifsioc),
654 IOCTL32_HANDLER(SIOCDELMULTI, dev_ifsioc),
655 IOCTL32_HANDLER(SIOCGIFINDEX, dev_ifsioc),
656 IOCTL32_HANDLER(SIOCGIFMAP, dev_ifsioc),
657 IOCTL32_HANDLER(SIOCSIFMAP, dev_ifsioc),
658 IOCTL32_HANDLER(SIOCGIFADDR, dev_ifsioc),
659 IOCTL32_HANDLER(SIOCSIFADDR, dev_ifsioc),
660 IOCTL32_HANDLER(SIOCGIFBRDADDR, dev_ifsioc),
661 IOCTL32_HANDLER(SIOCSIFBRDADDR, dev_ifsioc),
662 IOCTL32_HANDLER(SIOCGIFDSTADDR, dev_ifsioc),
663 IOCTL32_HANDLER(SIOCSIFDSTADDR, dev_ifsioc),
664 IOCTL32_HANDLER(SIOCGIFNETMASK, dev_ifsioc),
665 IOCTL32_HANDLER(SIOCSIFNETMASK, dev_ifsioc),
666 IOCTL32_HANDLER(SIOCSIFPFLAGS, dev_ifsioc),
667 IOCTL32_HANDLER(SIOCGIFPFLAGS, dev_ifsioc),
668 IOCTL32_HANDLER(SIOCGIFTXQLEN, dev_ifsioc),
669 IOCTL32_HANDLER(SIOCSIFTXQLEN, dev_ifsioc),
670 IOCTL32_HANDLER(SIOCADDRT, routing_ioctl),
671 IOCTL32_HANDLER(SIOCDELRT, routing_ioctl),
673 IOCTL32_HANDLER(SIOCBONDENSLAVE, bond_ioctl),
674 IOCTL32_HANDLER(SIOCBONDRELEASE, bond_ioctl),
675 IOCTL32_HANDLER(SIOCBONDSETHWADDR, bond_ioctl),
676 IOCTL32_HANDLER(SIOCBONDSLAVEINFOQUERY, bond_ioctl),
677 IOCTL32_HANDLER(SIOCBONDINFOQUERY, bond_ioctl),
678 IOCTL32_HANDLER(SIOCBONDCHANGEACTIVE, bond_ioctl),
680 IOCTL32_HANDLER(EXT2_IOC32_GETFLAGS, do_ext2_ioctl),
681 IOCTL32_HANDLER(EXT2_IOC32_SETFLAGS, do_ext2_ioctl),
682 IOCTL32_HANDLER(EXT2_IOC32_GETVERSION, do_ext2_ioctl),
683 IOCTL32_HANDLER(EXT2_IOC32_SETVERSION, do_ext2_ioctl),
685 IOCTL32_HANDLER(LOOP_SET_STATUS, loop_status),
686 IOCTL32_HANDLER(LOOP_GET_STATUS, loop_status),
689 IOCTL32_DEFAULT(RAW_SETBIND),
690 IOCTL32_DEFAULT(RAW_GETBIND),
692 IOCTL32_HANDLER(BLKRAGET, w_long),
693 IOCTL32_HANDLER(BLKGETSIZE, w_long),
694 IOCTL32_HANDLER(BLKFRAGET, w_long),
695 IOCTL32_HANDLER(BLKSECTGET, w_long),
696 IOCTL32_HANDLER(BLKPG, blkpg_ioctl_trans)
700 #define NR_IOCTL32_HANDLERS (sizeof(ioctl32_handler_table) / \
701 sizeof(ioctl32_handler_table[0]))
703 static struct ioctl32_list *ioctl32_hash_table[1024];
705 static inline int ioctl32_hash(unsigned int cmd)
707 return ((cmd >> 6) ^ (cmd >> 4) ^ cmd) & 0x3ff;
710 int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
712 int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
714 struct ioctl32_list *l;
717 l = ioctl32_hash_table[ioctl32_hash(cmd)];
725 if (!filp->f_op || !filp->f_op->ioctl) {
726 error = sys_ioctl (fd, cmd, arg);
730 while (l && l->handler.cmd != cmd)
734 handler = (void *)l->handler.function;
735 error = handler(fd, cmd, arg, filp);
738 printk("unknown ioctl: %08x\n", cmd);
745 static void ioctl32_insert(struct ioctl32_list *entry)
747 int hash = ioctl32_hash(entry->handler.cmd);
750 if (!ioctl32_hash_table[hash])
751 ioctl32_hash_table[hash] = entry;
753 struct ioctl32_list *l;
754 l = ioctl32_hash_table[hash];
761 int register_ioctl32_conversion(unsigned int cmd,
762 int (*handler)(unsigned int, unsigned int,
763 unsigned long, struct file *))
765 struct ioctl32_list *l, *new;
768 hash = ioctl32_hash(cmd);
769 for (l = ioctl32_hash_table[hash]; l != NULL; l = l->next)
770 if (l->handler.cmd == cmd)
772 new = kmalloc(sizeof(struct ioctl32_list), GFP_KERNEL);
775 new->handler.cmd = cmd;
776 new->handler.function = (void *) handler;
781 int unregister_ioctl32_conversion(unsigned int cmd)
783 struct ioctl32_list *p, *l;
786 hash = ioctl32_hash(cmd);
788 for (l = ioctl32_hash_table[hash]; l != NULL; l = l->next) {
789 if (l->handler.cmd == cmd)
796 ioctl32_hash_table[hash] = l->next;
803 static int __init init_ioctl32(void)
806 for (i = 0; i < NR_IOCTL32_HANDLERS; i++)
807 ioctl32_insert(&ioctl32_handler_table[i]);
811 __initcall(init_ioctl32);