console.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:5k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  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()
  99. {
  100. unsigned long flags;
  101. int st_p;
  102. char propb[64];
  103. char *p;
  104. switch(prom_vers) {
  105. case PROM_V0:
  106. case PROM_V2:
  107. case PROM_SUN4:
  108. default:
  109. switch(*romvec->pv_stdin) {
  110. case PROMDEV_KBD: return PROMDEV_IKBD;
  111. case PROMDEV_TTYA: return PROMDEV_ITTYA;
  112. case PROMDEV_TTYB: return PROMDEV_ITTYB;
  113. default:
  114. return PROMDEV_I_UNK;
  115. };
  116. case PROM_V3:
  117. spin_lock_irqsave(&prom_lock, flags);
  118. st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdin);
  119. restore_current();
  120. spin_unlock_irqrestore(&prom_lock, flags);
  121. if(prom_node_has_property(st_p, "keyboard"))
  122. return PROMDEV_IKBD;
  123. if (prom_getproperty(st_p, "name", propb, sizeof(propb)) != -1) {
  124. if(strncmp(propb, "keyboard", sizeof("serial")) == 0)
  125. return PROMDEV_IKBD;
  126. }
  127. if (prom_getproperty(st_p, "device_type", propb, sizeof(propb)) != -1) {
  128. if(strncmp(propb, "serial", sizeof("serial")))
  129. return PROMDEV_I_UNK;
  130. }
  131. prom_getproperty(prom_root_node, "stdin-path", propb, sizeof(propb));
  132. p = propb;
  133. while(*p) p++; p -= 2;
  134. if(p[0] == ':') {
  135. if(p[1] == 'a')
  136. return PROMDEV_ITTYA;
  137. else if(p[1] == 'b')
  138. return PROMDEV_ITTYB;
  139. }
  140. return PROMDEV_I_UNK;
  141. }
  142. }
  143. /* Query for output device type */
  144. enum prom_output_device
  145. prom_query_output_device()
  146. {
  147. unsigned long flags;
  148. int st_p;
  149. char propb[64];
  150. char *p;
  151. int propl;
  152. switch(prom_vers) {
  153. case PROM_V0:
  154. case PROM_SUN4:
  155. switch(*romvec->pv_stdin) {
  156. case PROMDEV_SCREEN: return PROMDEV_OSCREEN;
  157. case PROMDEV_TTYA: return PROMDEV_OTTYA;
  158. case PROMDEV_TTYB: return PROMDEV_OTTYB;
  159. };
  160. break;
  161. case PROM_V2:
  162. case PROM_V3:
  163. spin_lock_irqsave(&prom_lock, flags);
  164. st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdout);
  165. restore_current();
  166. spin_unlock_irqrestore(&prom_lock, flags);
  167. propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb));
  168. if (propl >= 0 && propl == sizeof("display") &&
  169. strncmp("display", propb, sizeof("display")) == 0)
  170. {
  171. return PROMDEV_OSCREEN;
  172. }
  173. if(prom_vers == PROM_V3) {
  174. if(propl >= 0 &&
  175.     strncmp("serial", propb, sizeof("serial")) != 0)
  176. return PROMDEV_O_UNK;
  177. prom_getproperty(prom_root_node, "stdout-path", propb, sizeof(propb));
  178. if(strncmp(propb, con_name_jmc, CON_SIZE_JMC) == 0)
  179. return PROMDEV_OTTYA;
  180. p = propb;
  181. while(*p) p++; p -= 2;
  182. if(p[0]==':') {
  183. if(p[1] == 'a')
  184. return PROMDEV_OTTYA;
  185. else if(p[1] == 'b')
  186. return PROMDEV_OTTYB;
  187. }
  188. } else {
  189. switch(*romvec->pv_stdin) {
  190. case PROMDEV_TTYA: return PROMDEV_OTTYA;
  191. case PROMDEV_TTYB: return PROMDEV_OTTYB;
  192. };
  193. }
  194. break;
  195. default:
  196. ;
  197. };
  198. return PROMDEV_O_UNK;
  199. }