irixioctl.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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/sockios.h>
  12. #include <linux/syscalls.h>
  13. #include <linux/tty.h>
  14. #include <linux/file.h>
  15. #include <linux/rcupdate.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. asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
  26. {
  27. struct tty_struct *tp, *rtp;
  28. mm_segment_t old_fs;
  29. int i, error = 0;
  30. #ifdef DEBUG_IOCTLS
  31. printk("[%s:%d] irix_ioctl(%d, ", current->comm, current->pid, fd);
  32. #endif
  33. switch(cmd) {
  34. case 0x00005401:
  35. #ifdef DEBUG_IOCTLS
  36. printk("TCGETA, %08lx) ", arg);
  37. #endif
  38. error = sys_ioctl(fd, TCGETA, arg);
  39. break;
  40. case 0x0000540d: {
  41. struct termios kt;
  42. struct irix_termios __user *it =
  43. (struct irix_termios __user *) arg;
  44. #ifdef DEBUG_IOCTLS
  45. printk("TCGETS, %08lx) ", arg);
  46. #endif
  47. if (!access_ok(VERIFY_WRITE, it, sizeof(*it))) {
  48. error = -EFAULT;
  49. break;
  50. }
  51. old_fs = get_fs(); set_fs(get_ds());
  52. error = sys_ioctl(fd, TCGETS, (unsigned long) &kt);
  53. set_fs(old_fs);
  54. if (error)
  55. break;
  56. error = __put_user(kt.c_iflag, &it->c_iflag);
  57. error |= __put_user(kt.c_oflag, &it->c_oflag);
  58. error |= __put_user(kt.c_cflag, &it->c_cflag);
  59. error |= __put_user(kt.c_lflag, &it->c_lflag);
  60. for (i = 0; i < NCCS; i++)
  61. error |= __put_user(kt.c_cc[i], &it->c_cc[i]);
  62. break;
  63. }
  64. case 0x0000540e: {
  65. struct termios kt;
  66. struct irix_termios *it = (struct irix_termios *) arg;
  67. #ifdef DEBUG_IOCTLS
  68. printk("TCSETS, %08lx) ", arg);
  69. #endif
  70. if (!access_ok(VERIFY_READ, 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. error = __get_user(kt.c_iflag, &it->c_iflag);
  80. error |= __get_user(kt.c_oflag, &it->c_oflag);
  81. error |= __get_user(kt.c_cflag, &it->c_cflag);
  82. error |= __get_user(kt.c_lflag, &it->c_lflag);
  83. for (i = 0; i < NCCS; i++)
  84. error |= __get_user(kt.c_cc[i], &it->c_cc[i]);
  85. if (error)
  86. break;
  87. old_fs = get_fs(); set_fs(get_ds());
  88. error = sys_ioctl(fd, TCSETS, (unsigned long) &kt);
  89. set_fs(old_fs);
  90. break;
  91. }
  92. case 0x0000540f:
  93. #ifdef DEBUG_IOCTLS
  94. printk("TCSETSW, %08lx) ", arg);
  95. #endif
  96. error = sys_ioctl(fd, TCSETSW, arg);
  97. break;
  98. case 0x00005471:
  99. #ifdef DEBUG_IOCTLS
  100. printk("TIOCNOTTY, %08lx) ", arg);
  101. #endif
  102. error = sys_ioctl(fd, TIOCNOTTY, arg);
  103. break;
  104. case 0x00007416: {
  105. pid_t pid;
  106. #ifdef DEBUG_IOCTLS
  107. printk("TIOCGSID, %08lx) ", arg);
  108. #endif
  109. old_fs = get_fs(); set_fs(get_ds());
  110. error = sys_ioctl(fd, TIOCGSID, (unsigned long)&pid);
  111. set_fs(old_fs);
  112. if (!error)
  113. error = put_user(pid, (unsigned long __user *) arg);
  114. break;
  115. }
  116. case 0x746e:
  117. /* TIOCSTART, same effect as hitting ^Q */
  118. #ifdef DEBUG_IOCTLS
  119. printk("TIOCSTART, %08lx) ", arg);
  120. #endif
  121. error = sys_ioctl(fd, TCXONC, TCOON);
  122. break;
  123. case 0x20006968:
  124. #ifdef DEBUG_IOCTLS
  125. printk("SIOCGETLABEL, %08lx) ", arg);
  126. #endif
  127. error = -ENOPKG;
  128. break;
  129. case 0x40047477:
  130. #ifdef DEBUG_IOCTLS
  131. printk("TIOCGPGRP, %08lx) ", arg);
  132. #endif
  133. error = sys_ioctl(fd, TIOCGPGRP, arg);
  134. #ifdef DEBUG_IOCTLS
  135. printk("arg=%d ", *(int *)arg);
  136. #endif
  137. break;
  138. case 0x40087468:
  139. #ifdef DEBUG_IOCTLS
  140. printk("TIOCGWINSZ, %08lx) ", arg);
  141. #endif
  142. error = sys_ioctl(fd, TIOCGWINSZ, arg);
  143. break;
  144. case 0x8004667e:
  145. error = sys_ioctl(fd, FIONBIO, arg);
  146. break;
  147. case 0x80047476:
  148. error = sys_ioctl(fd, TIOCSPGRP, arg);
  149. break;
  150. case 0x8020690c:
  151. error = sys_ioctl(fd, SIOCSIFADDR, arg);
  152. break;
  153. case 0x80206910:
  154. error = sys_ioctl(fd, SIOCSIFFLAGS, arg);
  155. break;
  156. case 0xc0206911:
  157. error = sys_ioctl(fd, SIOCGIFFLAGS, arg);
  158. break;
  159. case 0xc020691b:
  160. error = sys_ioctl(fd, SIOCGIFMETRIC, arg);
  161. break;
  162. default: {
  163. #ifdef DEBUG_MISSING_IOCTL
  164. char *msg = "Unimplemented IOCTL cmd tell linux-mips@linux-mips.org\n";
  165. #ifdef DEBUG_IOCTLS
  166. printk("UNIMP_IOCTL, %08lx)\n", arg);
  167. #endif
  168. old_fs = get_fs(); set_fs(get_ds());
  169. sys_write(2, msg, strlen(msg));
  170. set_fs(old_fs);
  171. printk("[%s:%d] Does unimplemented IRIX ioctl cmd %08lx\n",
  172. current->comm, current->pid, cmd);
  173. do_exit(255);
  174. #else
  175. error = sys_ioctl(fd, cmd, arg);
  176. #endif
  177. }
  178. };
  179. #ifdef DEBUG_IOCTLS
  180. printk("error=%d\n", error);
  181. #endif
  182. return error;
  183. }