1/* $Id: sunos_ioctl.c,v 1.1.1.1 2008/10/15 03:26:18 james26_jang Exp $ 2 * sunos_ioctl.c: The Linux Operating system: SunOS ioctl compatibility. 3 * 4 * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) 5 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) 6 */ 7 8#include <asm/uaccess.h> 9 10#include <linux/sched.h> 11#include <linux/errno.h> 12#include <linux/string.h> 13#include <linux/termios.h> 14#include <linux/ioctl.h> 15#include <linux/route.h> 16#include <linux/sockios.h> 17#include <linux/if.h> 18#include <linux/netdevice.h> 19#include <linux/if_arp.h> 20#include <linux/fs.h> 21#include <linux/mm.h> 22#include <linux/smp.h> 23#include <linux/smp_lock.h> 24#include <linux/file.h> 25#include <asm/kbio.h> 26 27 28/* NR_OPEN is now larger and dynamic in recent kernels. */ 29#define SUNOS_NR_OPEN 256 30 31extern asmlinkage int sys_ioctl(unsigned int, unsigned int, unsigned long); 32extern asmlinkage int sys_setsid(void); 33 34asmlinkage int sunos_ioctl (int fd, unsigned long cmd, unsigned long arg) 35{ 36 int ret = -EBADF; 37 38 if (fd >= SUNOS_NR_OPEN || !fcheck(fd)) 39 goto out; 40 41 /* First handle an easy compat. case for tty ldisc. */ 42 if(cmd == TIOCSETD) { 43 int *p, ntty = N_TTY, tmp; 44 mm_segment_t oldfs; 45 46 p = (int *) arg; 47 ret = -EFAULT; 48 if(get_user(tmp, p)) 49 goto out; 50 if(tmp == 2) { 51 oldfs = get_fs(); 52 set_fs(KERNEL_DS); 53 ret = sys_ioctl(fd, cmd, (int) &ntty); 54 set_fs(oldfs); 55 ret = (ret == -EINVAL ? -EOPNOTSUPP : ret); 56 goto out; 57 } 58 } 59 60 /* Binary compatibility is good American knowhow fuckin' up. */ 61 if(cmd == TIOCNOTTY) { 62 ret = sys_setsid(); 63 goto out; 64 } 65 66 /* SunOS networking ioctls. */ 67 switch (cmd) { 68 case _IOW('r', 10, struct rtentry): 69 ret = sys_ioctl(fd, SIOCADDRT, arg); 70 goto out; 71 case _IOW('r', 11, struct rtentry): 72 ret = sys_ioctl(fd, SIOCDELRT, arg); 73 goto out; 74 case _IOW('i', 12, struct ifreq): 75 ret = sys_ioctl(fd, SIOCSIFADDR, arg); 76 goto out; 77 case _IOWR('i', 13, struct ifreq): 78 ret = sys_ioctl(fd, SIOCGIFADDR, arg); 79 goto out; 80 case _IOW('i', 14, struct ifreq): 81 ret = sys_ioctl(fd, SIOCSIFDSTADDR, arg); 82 goto out; 83 case _IOWR('i', 15, struct ifreq): 84 ret = sys_ioctl(fd, SIOCGIFDSTADDR, arg); 85 goto out; 86 case _IOW('i', 16, struct ifreq): 87 ret = sys_ioctl(fd, SIOCSIFFLAGS, arg); 88 goto out; 89 case _IOWR('i', 17, struct ifreq): 90 ret = sys_ioctl(fd, SIOCGIFFLAGS, arg); 91 goto out; 92 case _IOW('i', 18, struct ifreq): 93 ret = sys_ioctl(fd, SIOCSIFMEM, arg); 94 goto out; 95 case _IOWR('i', 19, struct ifreq): 96 ret = sys_ioctl(fd, SIOCGIFMEM, arg); 97 goto out; 98 case _IOWR('i', 20, struct ifconf): 99 ret = sys_ioctl(fd, SIOCGIFCONF, arg); 100 goto out; 101 case _IOW('i', 21, struct ifreq): /* SIOCSIFMTU */ 102 ret = sys_ioctl(fd, SIOCSIFMTU, arg); 103 goto out; 104 case _IOWR('i', 22, struct ifreq): /* SIOCGIFMTU */ 105 ret = sys_ioctl(fd, SIOCGIFMTU, arg); 106 goto out; 107 108 case _IOWR('i', 23, struct ifreq): 109 ret = sys_ioctl(fd, SIOCGIFBRDADDR, arg); 110 goto out; 111 case _IOW('i', 24, struct ifreq): 112 ret = sys_ioctl(fd, SIOCSIFBRDADDR, arg); 113 goto out; 114 case _IOWR('i', 25, struct ifreq): 115 ret = sys_ioctl(fd, SIOCGIFNETMASK, arg); 116 goto out; 117 case _IOW('i', 26, struct ifreq): 118 ret = sys_ioctl(fd, SIOCSIFNETMASK, arg); 119 goto out; 120 case _IOWR('i', 27, struct ifreq): 121 ret = sys_ioctl(fd, SIOCGIFMETRIC, arg); 122 goto out; 123 case _IOW('i', 28, struct ifreq): 124 ret = sys_ioctl(fd, SIOCSIFMETRIC, arg); 125 goto out; 126 127 case _IOW('i', 30, struct arpreq): 128 ret = sys_ioctl(fd, SIOCSARP, arg); 129 goto out; 130 case _IOWR('i', 31, struct arpreq): 131 ret = sys_ioctl(fd, SIOCGARP, arg); 132 goto out; 133 case _IOW('i', 32, struct arpreq): 134 ret = sys_ioctl(fd, SIOCDARP, arg); 135 goto out; 136 137 case _IOW('i', 40, struct ifreq): /* SIOCUPPER */ 138 case _IOW('i', 41, struct ifreq): /* SIOCLOWER */ 139 case _IOW('i', 44, struct ifreq): /* SIOCSETSYNC */ 140 case _IOW('i', 45, struct ifreq): /* SIOCGETSYNC */ 141 case _IOW('i', 46, struct ifreq): /* SIOCSSDSTATS */ 142 case _IOW('i', 47, struct ifreq): /* SIOCSSESTATS */ 143 case _IOW('i', 48, struct ifreq): /* SIOCSPROMISC */ 144 ret = -EOPNOTSUPP; 145 goto out; 146 147 case _IOW('i', 49, struct ifreq): 148 ret = sys_ioctl(fd, SIOCADDMULTI, arg); 149 goto out; 150 case _IOW('i', 50, struct ifreq): 151 ret = sys_ioctl(fd, SIOCDELMULTI, arg); 152 goto out; 153 154 /* FDDI interface ioctls, unsupported. */ 155 156 case _IOW('i', 51, struct ifreq): /* SIOCFDRESET */ 157 case _IOW('i', 52, struct ifreq): /* SIOCFDSLEEP */ 158 case _IOW('i', 53, struct ifreq): /* SIOCSTRTFMWAR */ 159 case _IOW('i', 54, struct ifreq): /* SIOCLDNSTRTFW */ 160 case _IOW('i', 55, struct ifreq): /* SIOCGETFDSTAT */ 161 case _IOW('i', 56, struct ifreq): /* SIOCFDNMIINT */ 162 case _IOW('i', 57, struct ifreq): /* SIOCFDEXUSER */ 163 case _IOW('i', 58, struct ifreq): /* SIOCFDGNETMAP */ 164 case _IOW('i', 59, struct ifreq): /* SIOCFDGIOCTL */ 165 printk("FDDI ioctl, returning EOPNOTSUPP\n"); 166 ret = -EOPNOTSUPP; 167 goto out; 168 169 case _IOW('t', 125, int): 170 /* More stupid tty sunos ioctls, just 171 * say it worked. 172 */ 173 ret = 0; 174 goto out; 175 /* Non posix grp */ 176 case _IOW('t', 118, int): { 177 int oldval, newval, *ptr; 178 179 cmd = TIOCSPGRP; 180 ptr = (int *) arg; 181 ret = -EFAULT; 182 if(get_user(oldval, ptr)) 183 goto out; 184 ret = sys_ioctl(fd, cmd, arg); 185 __get_user(newval, ptr); 186 if(newval == -1) { 187 __put_user(oldval, ptr); 188 ret = -EIO; 189 } 190 if(ret == -ENOTTY) 191 ret = -EIO; 192 goto out; 193 } 194 195 case _IOR('t', 119, int): { 196 int oldval, newval, *ptr; 197 198 cmd = TIOCGPGRP; 199 ptr = (int *) arg; 200 ret = -EFAULT; 201 if(get_user(oldval, ptr)) 202 goto out; 203 ret = sys_ioctl(fd, cmd, arg); 204 __get_user(newval, ptr); 205 if(newval == -1) { 206 __put_user(oldval, ptr); 207 ret = -EIO; 208 } 209 if(ret == -ENOTTY) 210 ret = -EIO; 211 goto out; 212 } 213 } 214 215 216 ret = sys_ioctl(fd, cmd, arg); 217 /* so stupid... */ 218 ret = (ret == -EINVAL ? -EOPNOTSUPP : ret); 219out: 220 return ret; 221} 222 223 224