irixioctl.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*
  2. * irixioctl.c: A fucking mess...
  3. *
  4. * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  5. */
  6. #include <linux/kernel.h>
  7. #include <linux/sched.h>
  8. #include <linux/fs.h>
  9. #include <linux/mm.h>
  10. #include <linux/smp.h>
  11. #include <linux/smp_lock.h>
  12. #include <linux/sockios.h>
  13. #include <linux/syscalls.h>
  14. #include <linux/tty.h>
  15. #include <linux/file.h>
  16. #include <linux/rcupdate.h>
  17. #include <asm/uaccess.h>
  18. #include <asm/ioctl.h>
  19. #include <asm/ioctls.h>
  20. #undef DEBUG_IOCTLS
  21. #undef DEBUG_MISSING_IOCTL
  22. struct irix_termios {
  23. tcflag_t c_iflag, c_oflag, c_cflag, c_lflag;
  24. cc_t c_cc[NCCS];
  25. };
  26. extern void start_tty(struct tty_struct *tty);
  27. static struct tty_struct *get_tty(int fd)
  28. {
  29. struct file *filp;
  30. struct tty_struct *ttyp = NULL;
  31. rcu_read_lock();
  32. filp = fcheck(fd);
  33. if(filp && filp->private_data) {
  34. ttyp = (struct tty_struct *) filp->private_data;
  35. if(ttyp->magic != TTY_MAGIC)
  36. ttyp =NULL;
  37. }
  38. rcu_read_unlock();
  39. return ttyp;
  40. }
  41. static struct tty_struct *get_real_tty(struct tty_struct *tp)
  42. {
  43. if (tp->driver->type == TTY_DRIVER_TYPE_PTY &&
  44. tp->driver->subtype == PTY_TYPE_MASTER)
  45. return tp->link;
  46. else
  47. return tp;
  48. }
  49. asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
  50. {
  51. struct tty_struct *tp, *rtp;
  52. mm_segment_t old_fs;
  53. int error = 0;
  54. #ifdef DEBUG_IOCTLS
  55. printk("[%s:%d] irix_ioctl(%d, ", current->comm, current->pid, fd);
  56. #endif
  57. switch(cmd) {
  58. case 0x00005401:
  59. #ifdef DEBUG_IOCTLS
  60. printk("TCGETA, %08lx) ", arg);
  61. #endif
  62. error = sys_ioctl(fd, TCGETA, arg);
  63. break;
  64. case 0x0000540d: {
  65. struct termios kt;
  66. struct irix_termios *it = (struct irix_termios *) arg;
  67. #ifdef DEBUG_IOCTLS
  68. printk("TCGETS, %08lx) ", arg);
  69. #endif
  70. if(!access_ok(VERIFY_WRITE, it, sizeof(*it))) {
  71. error = -EFAULT;
  72. break;
  73. }
  74. old_fs = get_fs(); set_fs(get_ds());
  75. error = sys_ioctl(fd, TCGETS, (unsigned long) &kt);
  76. set_fs(old_fs);
  77. if (error)
  78. break;
  79. __put_user(kt.c_iflag, &it->c_iflag);
  80. __put_user(kt.c_oflag, &it->c_oflag);
  81. __put_user(kt.c_cflag, &it->c_cflag);
  82. __put_user(kt.c_lflag, &it->c_lflag);
  83. for(error = 0; error < NCCS; error++)
  84. __put_user(kt.c_cc[error], &it->c_cc[error]);
  85. error = 0;
  86. break;
  87. }
  88. case 0x0000540e: {
  89. struct termios kt;
  90. struct irix_termios *it = (struct irix_termios *) arg;
  91. #ifdef DEBUG_IOCTLS
  92. printk("TCSETS, %08lx) ", arg);
  93. #endif
  94. if (!access_ok(VERIFY_READ, it, sizeof(*it))) {
  95. error = -EFAULT;
  96. break;
  97. }
  98. old_fs = get_fs(); set_fs(get_ds());
  99. error = sys_ioctl(fd, TCGETS, (unsigned long) &kt);
  100. set_fs(old_fs);
  101. if(error)
  102. break;
  103. __get_user(kt.c_iflag, &it->c_iflag);
  104. __get_user(kt.c_oflag, &it->c_oflag);
  105. __get_user(kt.c_cflag, &it->c_cflag);
  106. __get_user(kt.c_lflag, &it->c_lflag);
  107. for(error = 0; error < NCCS; error++)
  108. __get_user(kt.c_cc[error], &it->c_cc[error]);
  109. old_fs = get_fs(); set_fs(get_ds());
  110. error = sys_ioctl(fd, TCSETS, (unsigned long) &kt);
  111. set_fs(old_fs);
  112. break;
  113. }
  114. case 0x0000540f:
  115. #ifdef DEBUG_IOCTLS
  116. printk("TCSETSW, %08lx) ", arg);
  117. #endif
  118. error = sys_ioctl(fd, TCSETSW, arg);
  119. break;
  120. case 0x00005471:
  121. #ifdef DEBUG_IOCTLS
  122. printk("TIOCNOTTY, %08lx) ", arg);
  123. #endif
  124. error = sys_ioctl(fd, TIOCNOTTY, arg);
  125. break;
  126. case 0x00007416:
  127. #ifdef DEBUG_IOCTLS
  128. printk("TIOCGSID, %08lx) ", arg);
  129. #endif
  130. tp = get_tty(fd);
  131. if(!tp) {
  132. error = -EINVAL;
  133. break;
  134. }
  135. rtp = get_real_tty(tp);
  136. #ifdef DEBUG_IOCTLS
  137. printk("rtp->session=%d ", rtp->session);
  138. #endif
  139. error = put_user(rtp->session, (unsigned long *) arg);
  140. break;
  141. case 0x746e:
  142. /* TIOCSTART, same effect as hitting ^Q */
  143. #ifdef DEBUG_IOCTLS
  144. printk("TIOCSTART, %08lx) ", arg);
  145. #endif
  146. tp = get_tty(fd);
  147. if(!tp) {
  148. error = -EINVAL;
  149. break;
  150. }
  151. rtp = get_real_tty(tp);
  152. start_tty(rtp);
  153. break;
  154. case 0x20006968:
  155. #ifdef DEBUG_IOCTLS
  156. printk("SIOCGETLABEL, %08lx) ", arg);
  157. #endif
  158. error = -ENOPKG;
  159. break;
  160. case 0x40047477:
  161. #ifdef DEBUG_IOCTLS
  162. printk("TIOCGPGRP, %08lx) ", arg);
  163. #endif
  164. error = sys_ioctl(fd, TIOCGPGRP, arg);
  165. #ifdef DEBUG_IOCTLS
  166. printk("arg=%d ", *(int *)arg);
  167. #endif
  168. break;
  169. case 0x40087468:
  170. #ifdef DEBUG_IOCTLS
  171. printk("TIOCGWINSZ, %08lx) ", arg);
  172. #endif
  173. error = sys_ioctl(fd, TIOCGWINSZ, arg);
  174. break;
  175. case 0x8004667e:
  176. #ifdef DEBUG_IOCTLS
  177. printk("FIONBIO, %08lx) arg=%d ", arg, *(int *)arg);
  178. #endif
  179. error = sys_ioctl(fd, FIONBIO, arg);
  180. break;
  181. case 0x80047476:
  182. #ifdef DEBUG_IOCTLS
  183. printk("TIOCSPGRP, %08lx) arg=%d ", arg, *(int *)arg);
  184. #endif
  185. error = sys_ioctl(fd, TIOCSPGRP, arg);
  186. break;
  187. case 0x8020690c:
  188. #ifdef DEBUG_IOCTLS
  189. printk("SIOCSIFADDR, %08lx) arg=%d ", arg, *(int *)arg);
  190. #endif
  191. error = sys_ioctl(fd, SIOCSIFADDR, arg);
  192. break;
  193. case 0x80206910:
  194. #ifdef DEBUG_IOCTLS
  195. printk("SIOCSIFFLAGS, %08lx) arg=%d ", arg, *(int *)arg);
  196. #endif
  197. error = sys_ioctl(fd, SIOCSIFFLAGS, arg);
  198. break;
  199. case 0xc0206911:
  200. #ifdef DEBUG_IOCTLS
  201. printk("SIOCGIFFLAGS, %08lx) arg=%d ", arg, *(int *)arg);
  202. #endif
  203. error = sys_ioctl(fd, SIOCGIFFLAGS, arg);
  204. break;
  205. case 0xc020691b:
  206. #ifdef DEBUG_IOCTLS
  207. printk("SIOCGIFMETRIC, %08lx) arg=%d ", arg, *(int *)arg);
  208. #endif
  209. error = sys_ioctl(fd, SIOCGIFMETRIC, arg);
  210. break;
  211. default: {
  212. #ifdef DEBUG_MISSING_IOCTL
  213. char *msg = "Unimplemented IOCTL cmd tell linux@engr.sgi.com\n";
  214. #ifdef DEBUG_IOCTLS
  215. printk("UNIMP_IOCTL, %08lx)\n", arg);
  216. #endif
  217. old_fs = get_fs(); set_fs(get_ds());
  218. sys_write(2, msg, strlen(msg));
  219. set_fs(old_fs);
  220. printk("[%s:%d] Does unimplemented IRIX ioctl cmd %08lx\n",
  221. current->comm, current->pid, cmd);
  222. do_exit(255);
  223. #else
  224. error = sys_ioctl (fd, cmd, arg);
  225. #endif
  226. }
  227. };
  228. #ifdef DEBUG_IOCTLS
  229. printk("error=%d\n", error);
  230. #endif
  231. return error;
  232. }