console.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /* $Id: console.c,v 1.25 2001/10/30 04:54:22 davem Exp $
  2. * console.c: Routines that deal with sending and receiving IO
  3. * to/from the current console device using the PROM.
  4. *
  5. * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
  6. * Copyright (C) 1998 Pete Zaitcev <zaitcev@yahoo.com>
  7. */
  8. #include <linux/types.h>
  9. #include <linux/kernel.h>
  10. #include <linux/sched.h>
  11. #include <asm/openprom.h>
  12. #include <asm/sun4prom.h>
  13. #include <asm/oplib.h>
  14. #include <asm/system.h>
  15. #include <linux/string.h>
  16. extern void restore_current(void);
  17. static char con_name_jmc[] = "/obio/su@"; /* "/obio/su@0,3002f8"; */
  18. #define CON_SIZE_JMC (sizeof(con_name_jmc))
  19. /* Non blocking get character from console input device, returns -1
  20. * if no input was taken. This can be used for polling.
  21. */
  22. int
  23. prom_nbgetchar(void)
  24. {
  25. static char inc;
  26. int i = -1;
  27. unsigned long flags;
  28. spin_lock_irqsave(&prom_lock, flags);
  29. switch(prom_vers) {
  30. case PROM_V0:
  31. case PROM_SUN4:
  32. i = (*(romvec->pv_nbgetchar))();
  33. break;
  34. case PROM_V2:
  35. case PROM_V3:
  36. if( (*(romvec->pv_v2devops).v2_dev_read)(*romvec->pv_v2bootargs.fd_stdin , &inc, 0x1) == 1) {
  37. i = inc;
  38. } else {
  39. i = -1;
  40. }
  41. break;
  42. default:
  43. i = -1;
  44. break;
  45. };
  46. restore_current();
  47. spin_unlock_irqrestore(&prom_lock, flags);
  48. return i; /* Ugh, we could spin forever on unsupported proms ;( */
  49. }
  50. /* Non blocking put character to console device, returns -1 if
  51. * unsuccessful.
  52. */
  53. int
  54. prom_nbputchar(char c)
  55. {
  56. static char outc;
  57. unsigned long flags;
  58. int i = -1;
  59. spin_lock_irqsave(&prom_lock, flags);
  60. switch(prom_vers) {
  61. case PROM_V0:
  62. case PROM_SUN4:
  63. i = (*(romvec->pv_nbputchar))(c);
  64. break;
  65. case PROM_V2:
  66. case PROM_V3:
  67. outc = c;
  68. if( (*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout, &outc, 0x1) == 1)
  69. i = 0;
  70. else
  71. i = -1;
  72. break;
  73. default:
  74. i = -1;
  75. break;
  76. };
  77. restore_current();
  78. spin_unlock_irqrestore(&prom_lock, flags);
  79. return i; /* Ugh, we could spin forever on unsupported proms ;( */
  80. }
  81. /* Blocking version of get character routine above. */
  82. char
  83. prom_getchar(void)
  84. {
  85. int character;
  86. while((character = prom_nbgetchar()) == -1) ;
  87. return (char) character;
  88. }
  89. /* Blocking version of put character routine above. */
  90. void
  91. prom_putchar(char c)
  92. {
  93. while(prom_nbputchar(c) == -1) ;
  94. return;
  95. }
  96. /* Query for input device type */
  97. enum prom_input_device
  98. prom_query_input_device(void)
  99. {
  100. unsigned long flags;
  101. int st_p;
  102. char propb[64];
  103. char *p;
  104. int propl;
  105. switch(prom_vers) {
  106. case PROM_V0:
  107. case PROM_V2:
  108. case PROM_SUN4:
  109. default:
  110. switch(*romvec->pv_stdin) {
  111. case PROMDEV_KBD: return PROMDEV_IKBD;
  112. case PROMDEV_TTYA: return PROMDEV_ITTYA;
  113. case PROMDEV_TTYB: return PROMDEV_ITTYB;
  114. default:
  115. return PROMDEV_I_UNK;
  116. };
  117. case PROM_V3:
  118. spin_lock_irqsave(&prom_lock, flags);
  119. st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdin);
  120. restore_current();
  121. spin_unlock_irqrestore(&prom_lock, flags);
  122. if(prom_node_has_property(st_p, "keyboard"))
  123. return PROMDEV_IKBD;
  124. if (prom_getproperty(st_p, "name", propb, sizeof(propb)) != -1) {
  125. if(strncmp(propb, "keyboard", sizeof("serial")) == 0)
  126. return PROMDEV_IKBD;
  127. }
  128. if (prom_getproperty(st_p, "device_type", propb, sizeof(propb)) != -1) {
  129. if(strncmp(propb, "serial", sizeof("serial")))
  130. return PROMDEV_I_UNK;
  131. }
  132. propl = prom_getproperty(prom_root_node, "stdin-path", propb, sizeof(propb));
  133. if(propl > 2) {
  134. p = propb;
  135. while(*p) p++; p -= 2;
  136. if(p[0] == ':') {
  137. if(p[1] == 'a')
  138. return PROMDEV_ITTYA;
  139. else if(p[1] == 'b')
  140. return PROMDEV_ITTYB;
  141. }
  142. }
  143. return PROMDEV_I_UNK;
  144. }
  145. }
  146. /* Query for output device type */
  147. enum prom_output_device
  148. prom_query_output_device(void)
  149. {
  150. unsigned long flags;
  151. int st_p;
  152. char propb[64];
  153. char *p;
  154. int propl;
  155. switch(prom_vers) {
  156. case PROM_V0:
  157. case PROM_SUN4:
  158. switch(*romvec->pv_stdin) {
  159. case PROMDEV_SCREEN: return PROMDEV_OSCREEN;
  160. case PROMDEV_TTYA: return PROMDEV_OTTYA;
  161. case PROMDEV_TTYB: return PROMDEV_OTTYB;
  162. };
  163. break;
  164. case PROM_V2:
  165. case PROM_V3:
  166. spin_lock_irqsave(&prom_lock, flags);
  167. st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdout);
  168. restore_current();
  169. spin_unlock_irqrestore(&prom_lock, flags);
  170. propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb));
  171. if (propl == sizeof("display") &&
  172. strncmp("display", propb, sizeof("display")) == 0)
  173. {
  174. return PROMDEV_OSCREEN;
  175. }
  176. if(prom_vers == PROM_V3) {
  177. if(propl >= 0 &&
  178. strncmp("serial", propb, sizeof("serial")) != 0)
  179. return PROMDEV_O_UNK;
  180. propl = prom_getproperty(prom_root_node, "stdout-path",
  181. propb, sizeof(propb));
  182. if(propl == CON_SIZE_JMC &&
  183. strncmp(propb, con_name_jmc, CON_SIZE_JMC) == 0)
  184. return PROMDEV_OTTYA;
  185. if(propl > 2) {
  186. p = propb;
  187. while(*p) p++; p-= 2;
  188. if(p[0]==':') {
  189. if(p[1] == 'a')
  190. return PROMDEV_OTTYA;
  191. else if(p[1] == 'b')
  192. return PROMDEV_OTTYB;
  193. }
  194. }
  195. } else {
  196. switch(*romvec->pv_stdin) {
  197. case PROMDEV_TTYA: return PROMDEV_OTTYA;
  198. case PROMDEV_TTYB: return PROMDEV_OTTYB;
  199. };
  200. }
  201. break;
  202. default:
  203. ;
  204. };
  205. return PROMDEV_O_UNK;
  206. }