sunos_ioctl32.c 7.5 KB

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