sunos_ioctl32.c 7.5 KB

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