sunos_ioctl32.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:8k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* $Id: sunos_ioctl32.c,v 1.11 2000/07/30 23:12:24 davem Exp $
  2.  * sunos_ioctl32.c: SunOS ioctl compatability on sparc64.
  3.  *
  4.  * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
  5.  * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
  6.  */
  7. #include <asm/uaccess.h>
  8. #include <linux/sched.h>
  9. #include <linux/errno.h>
  10. #include <linux/string.h>
  11. #include <linux/termios.h>
  12. #include <linux/ioctl.h>
  13. #include <linux/route.h>
  14. #include <linux/sockios.h>
  15. #include <linux/if.h>
  16. #include <linux/netdevice.h>
  17. #include <linux/if_arp.h>
  18. #include <linux/fs.h>
  19. #include <linux/file.h>
  20. #include <linux/mm.h>
  21. #include <linux/smp.h>
  22. #include <linux/smp_lock.h>
  23. #include <asm/kbio.h>
  24. /* Use this to get at 32-bit user passed pointers. */
  25. #define A(__x)
  26. ({ unsigned long __ret;
  27. __asm__ ("srl %0, 0, %0"
  28.  : "=r" (__ret)
  29.  : "0" (__x));
  30. __ret;
  31. })
  32. #define SUNOS_NR_OPEN 256
  33. struct rtentry32 {
  34.         u32    rt_pad1;
  35.         struct sockaddr rt_dst;         /* target address               */
  36.         struct sockaddr rt_gateway;     /* gateway addr (RTF_GATEWAY)   */
  37.         struct sockaddr rt_genmask;     /* target network mask (IP)     */
  38.         unsigned short  rt_flags;
  39.         short           rt_pad2;
  40.         u32    rt_pad3;
  41.         unsigned char   rt_tos;
  42.         unsigned char   rt_class;
  43.         short           rt_pad4;
  44.         short           rt_metric;      /* +1 for binary compatibility! */
  45.         /* char * */ u32 rt_dev;        /* forcing the device at add    */
  46.         u32    rt_mtu;         /* per route MTU/Window         */
  47.         u32    rt_window;      /* Window clamping              */
  48.         unsigned short  rt_irtt;        /* Initial RTT                  */
  49. };
  50. struct ifmap32 {
  51. u32 mem_start;
  52. u32 mem_end;
  53. unsigned short base_addr;
  54. unsigned char irq;
  55. unsigned char dma;
  56. unsigned char port;
  57. };
  58. struct ifreq32 {
  59. #define IFHWADDRLEN     6
  60. #define IFNAMSIZ        16
  61.         union {
  62.                 char    ifrn_name[IFNAMSIZ];            /* if name, e.g. "en0" */
  63.         } ifr_ifrn;
  64.         union {
  65.                 struct  sockaddr ifru_addr;
  66.                 struct  sockaddr ifru_dstaddr;
  67.                 struct  sockaddr ifru_broadaddr;
  68.                 struct  sockaddr ifru_netmask;
  69.                 struct  sockaddr ifru_hwaddr;
  70.                 short   ifru_flags;
  71.                 int     ifru_ivalue;
  72.                 int     ifru_mtu;
  73.                 struct  ifmap32 ifru_map;
  74.                 char    ifru_slave[IFNAMSIZ];   /* Just fits the size */
  75.                 __kernel_caddr_t32 ifru_data;
  76.         } ifr_ifru;
  77. };
  78. struct ifconf32 {
  79.         int     ifc_len;                        /* size of buffer       */
  80.         __kernel_caddr_t32  ifcbuf;
  81. };
  82. extern asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
  83. extern asmlinkage int sys32_ioctl(unsigned int, unsigned int, u32);
  84. extern asmlinkage int sys_setsid(void);
  85. asmlinkage int sunos_ioctl (int fd, u32 cmd, u32 arg)
  86. {
  87. int ret = -EBADF;
  88. if(fd >= SUNOS_NR_OPEN)
  89. goto out;
  90. if(!fcheck(fd))
  91. goto out;
  92. if(cmd == TIOCSETD) {
  93. mm_segment_t old_fs = get_fs();
  94. int *p, ntty = N_TTY;
  95. int tmp;
  96. p = (int *)A(arg);
  97. ret = -EFAULT;
  98. if(get_user(tmp, p))
  99. goto out;
  100. if(tmp == 2) {
  101. set_fs(KERNEL_DS);
  102. ret = sys_ioctl(fd, cmd, (unsigned long) &ntty);
  103. set_fs(old_fs);
  104. ret = (ret == -EINVAL ? -EOPNOTSUPP : ret);
  105. goto out;
  106. }
  107. }
  108. if(cmd == TIOCNOTTY) {
  109. ret = sys_setsid();
  110. goto out;
  111. }
  112. switch(cmd) {
  113. case _IOW('r', 10, struct rtentry32):
  114. ret = sys32_ioctl(fd, SIOCADDRT, arg);
  115. goto out;
  116. case _IOW('r', 11, struct rtentry32):
  117. ret = sys32_ioctl(fd, SIOCDELRT, arg);
  118. goto out;
  119. case _IOW('i', 12, struct ifreq32):
  120. ret = sys32_ioctl(fd, SIOCSIFADDR, arg);
  121. goto out;
  122. case _IOWR('i', 13, struct ifreq32):
  123. ret = sys32_ioctl(fd, SIOCGIFADDR, arg);
  124. goto out;
  125. case _IOW('i', 14, struct ifreq32):
  126. ret = sys32_ioctl(fd, SIOCSIFDSTADDR, arg);
  127. goto out;
  128. case _IOWR('i', 15, struct ifreq32):
  129. ret = sys32_ioctl(fd, SIOCGIFDSTADDR, arg);
  130. goto out;
  131. case _IOW('i', 16, struct ifreq32):
  132. ret = sys32_ioctl(fd, SIOCSIFFLAGS, arg);
  133. goto out;
  134. case _IOWR('i', 17, struct ifreq32):
  135. ret = sys32_ioctl(fd, SIOCGIFFLAGS, arg);
  136. goto out;
  137. case _IOW('i', 18, struct ifreq32):
  138. ret = sys32_ioctl(fd, SIOCSIFMEM, arg);
  139. goto out;
  140. case _IOWR('i', 19, struct ifreq32):
  141. ret = sys32_ioctl(fd, SIOCGIFMEM, arg);
  142. goto out;
  143. case _IOWR('i', 20, struct ifconf32):
  144. ret = sys32_ioctl(fd, SIOCGIFCONF, arg);
  145. goto out;
  146. case _IOW('i', 21, struct ifreq): /* SIOCSIFMTU */
  147. ret = sys_ioctl(fd, SIOCSIFMTU, arg);
  148. goto out;
  149. case _IOWR('i', 22, struct ifreq): /* SIOCGIFMTU */
  150. ret = sys_ioctl(fd, SIOCGIFMTU, arg);
  151. goto out;
  152. case _IOWR('i', 23, struct ifreq32):
  153. ret = sys32_ioctl(fd, SIOCGIFBRDADDR, arg);
  154. goto out;
  155. case _IOW('i', 24, struct ifreq32):
  156. ret = sys32_ioctl(fd, SIOCSIFBRDADDR, arg);
  157. goto out;
  158. case _IOWR('i', 25, struct ifreq32):
  159. ret = sys32_ioctl(fd, SIOCGIFNETMASK, arg);
  160. goto out;
  161. case _IOW('i', 26, struct ifreq32):
  162. ret = sys32_ioctl(fd, SIOCSIFNETMASK, arg);
  163. goto out;
  164. case _IOWR('i', 27, struct ifreq32):
  165. ret = sys32_ioctl(fd, SIOCGIFMETRIC, arg);
  166. goto out;
  167. case _IOW('i', 28, struct ifreq32):
  168. ret = sys32_ioctl(fd, SIOCSIFMETRIC, arg);
  169. goto out;
  170. case _IOW('i', 30, struct arpreq):
  171. ret = sys32_ioctl(fd, SIOCSARP, arg);
  172. goto out;
  173. case _IOWR('i', 31, struct arpreq):
  174. ret = sys32_ioctl(fd, SIOCGARP, arg);
  175. goto out;
  176. case _IOW('i', 32, struct arpreq):
  177. ret = sys32_ioctl(fd, SIOCDARP, arg);
  178. goto out;
  179. case _IOW('i', 40, struct ifreq32): /* SIOCUPPER */
  180. case _IOW('i', 41, struct ifreq32): /* SIOCLOWER */
  181. case _IOW('i', 44, struct ifreq32): /* SIOCSETSYNC */
  182. case _IOW('i', 45, struct ifreq32): /* SIOCGETSYNC */
  183. case _IOW('i', 46, struct ifreq32): /* SIOCSSDSTATS */
  184. case _IOW('i', 47, struct ifreq32): /* SIOCSSESTATS */
  185. case _IOW('i', 48, struct ifreq32): /* SIOCSPROMISC */
  186. ret = -EOPNOTSUPP;
  187. goto out;
  188. case _IOW('i', 49, struct ifreq32):
  189. ret = sys32_ioctl(fd, SIOCADDMULTI, arg);
  190. goto out;
  191. case _IOW('i', 50, struct ifreq32):
  192. ret = sys32_ioctl(fd, SIOCDELMULTI, arg);
  193. goto out;
  194. /* FDDI interface ioctls, unsupported. */
  195. case _IOW('i', 51, struct ifreq32): /* SIOCFDRESET */
  196. case _IOW('i', 52, struct ifreq32): /* SIOCFDSLEEP */
  197. case _IOW('i', 53, struct ifreq32): /* SIOCSTRTFMWAR */
  198. case _IOW('i', 54, struct ifreq32): /* SIOCLDNSTRTFW */
  199. case _IOW('i', 55, struct ifreq32): /* SIOCGETFDSTAT */
  200. case _IOW('i', 56, struct ifreq32): /* SIOCFDNMIINT */
  201. case _IOW('i', 57, struct ifreq32): /* SIOCFDEXUSER */
  202. case _IOW('i', 58, struct ifreq32): /* SIOCFDGNETMAP */
  203. case _IOW('i', 59, struct ifreq32): /* SIOCFDGIOCTL */
  204. printk("FDDI ioctl, returning EOPNOTSUPPn");
  205. ret = -EOPNOTSUPP;
  206. goto out;
  207. case _IOW('t', 125, int):
  208. /* More stupid tty sunos ioctls, just
  209.  * say it worked.
  210.  */
  211. ret = 0;
  212. goto out;
  213. /* Non posix grp */
  214. case _IOW('t', 118, int): {
  215. int oldval, newval, *ptr;
  216. cmd = TIOCSPGRP;
  217. ptr = (int *) A(arg);
  218. ret = -EFAULT;
  219. if(get_user(oldval, ptr))
  220. goto out;
  221. ret = sys32_ioctl(fd, cmd, arg);
  222. __get_user(newval, ptr);
  223. if(newval == -1) {
  224. __put_user(oldval, ptr);
  225. ret = -EIO;
  226. }
  227. if(ret == -ENOTTY)
  228. ret = -EIO;
  229. goto out;
  230. }
  231. case _IOR('t', 119, int): {
  232. int oldval, newval, *ptr;
  233. cmd = TIOCGPGRP;
  234. ptr = (int *) A(arg);
  235. ret = -EFAULT;
  236. if(get_user(oldval, ptr))
  237. goto out;
  238. ret = sys32_ioctl(fd, cmd, arg);
  239. __get_user(newval, ptr);
  240. if(newval == -1) {
  241. __put_user(oldval, ptr);
  242. ret = -EIO;
  243. }
  244. if(ret == -ENOTTY)
  245. ret = -EIO;
  246. goto out;
  247. }
  248. };
  249. ret = sys32_ioctl(fd, cmd, arg);
  250. /* so stupid... */
  251. ret = (ret == -EINVAL ? -EOPNOTSUPP : ret);
  252. out:
  253. return ret;
  254. }