irixioctl.c 5.5 KB

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