1 /* $Id: console.c,v 1.10 1996/12/18 06:46:54 tridge 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 */ 7 8 #include <linux/types.h> 9 #include <linux/kernel.h> 10 #include <linux/sched.h> 11 #include <asm/openprom.h> 12 #include <asm/oplib.h> 13 #include <asm/system.h> 14 #include <linux/string.h> 15 16 /* Non blocking get character from console input device, returns -1 17 * if no input was taken. This can be used for polling. 18 */ 19 int 20 prom_nbgetchar(void) 21 { 22 int i = -1; 23 unsigned long flags; 24 25 local_irq_save(flags); 26 i = (*(romvec->pv_nbgetchar))(); 27 local_irq_restore(flags); 28 return i; /* Ugh, we could spin forever on unsupported proms ;( */ 29 } 30 31 /* Non blocking put character to console device, returns -1 if 32 * unsuccessful. 33 */ 34 int 35 prom_nbputchar(char c) 36 { 37 unsigned long flags; 38 int i = -1; 39 40 local_irq_save(flags); 41 i = (*(romvec->pv_nbputchar))(c); 42 local_irq_restore(flags); 43 return i; /* Ugh, we could spin forever on unsupported proms ;( */ 44 } 45 46 /* Blocking version of get character routine above. */ 47 char 48 prom_getchar(void) 49 { 50 int character; 51 while((character = prom_nbgetchar()) == -1) ; 52 return (char) character; 53 } 54 55 /* Blocking version of put character routine above. */ 56 void 57 prom_putchar(char c) 58 { 59 while(prom_nbputchar(c) == -1) ; 60 return; 61 } 62 63 /* Query for input device type */ 64 #if 0 65 enum prom_input_device 66 prom_query_input_device() 67 { 68 unsigned long flags; 69 int st_p; 70 char propb[64]; 71 char *p; 72 73 switch(prom_vers) { 74 case PROM_V0: 75 case PROM_V2: 76 default: 77 switch(*romvec->pv_stdin) { 78 case PROMDEV_KBD: return PROMDEV_IKBD; 79 case PROMDEV_TTYA: return PROMDEV_ITTYA; 80 case PROMDEV_TTYB: return PROMDEV_ITTYB; 81 default: 82 return PROMDEV_I_UNK; 83 }; 84 case PROM_V3: 85 case PROM_P1275: 86 local_irq_save(flags); 87 st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdin); 88 __asm__ __volatile__("ld [%0], %%g6\n\t" : : 89 "r" (¤t_set[smp_processor_id()]) : 90 "memory"); 91 local_irq_restore(flags); 92 if(prom_node_has_property(st_p, "keyboard")) 93 return PROMDEV_IKBD; 94 prom_getproperty(st_p, "device_type", propb, sizeof(propb)); 95 if(strncmp(propb, "serial", sizeof("serial"))) 96 return PROMDEV_I_UNK; 97 prom_getproperty(prom_root_node, "stdin-path", propb, sizeof(propb)); 98 p = propb; 99 while(*p) p++; p -= 2; 100 if(p[0] == ':') { 101 if(p[1] == 'a') 102 return PROMDEV_ITTYA; 103 else if(p[1] == 'b') 104 return PROMDEV_ITTYB; 105 } 106 return PROMDEV_I_UNK; 107 case PROM_AP1000: 108 return PROMDEV_I_UNK; 109 }; 110 } 111 #endif 112 113 /* Query for output device type */ 114 115 #if 0 116 enum prom_output_device 117 prom_query_output_device() 118 { 119 unsigned long flags; 120 int st_p; 121 char propb[64]; 122 char *p; 123 int propl; 124 125 switch(prom_vers) { 126 case PROM_V0: 127 switch(*romvec->pv_stdin) { 128 case PROMDEV_SCREEN: return PROMDEV_OSCREEN; 129 case PROMDEV_TTYA: return PROMDEV_OTTYA; 130 case PROMDEV_TTYB: return PROMDEV_OTTYB; 131 }; 132 break; 133 case PROM_V2: 134 case PROM_V3: 135 case PROM_P1275: 136 local_irq_save(flags); 137 st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdout); 138 __asm__ __volatile__("ld [%0], %%g6\n\t" : : 139 "r" (¤t_set[smp_processor_id()]) : 140 "memory"); 141 local_irq_restore(flags); 142 propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb)); 143 if (propl >= 0 && propl == sizeof("display") && 144 strncmp("display", propb, sizeof("display")) == 0) 145 { 146 return PROMDEV_OSCREEN; 147 } 148 if(prom_vers == PROM_V3) { 149 if(strncmp("serial", propb, sizeof("serial"))) 150 return PROMDEV_O_UNK; 151 prom_getproperty(prom_root_node, "stdout-path", propb, sizeof(propb)); 152 p = propb; 153 while(*p) p++; p -= 2; 154 if(p[0]==':') { 155 if(p[1] == 'a') 156 return PROMDEV_OTTYA; 157 else if(p[1] == 'b') 158 return PROMDEV_OTTYB; 159 } 160 return PROMDEV_O_UNK; 161 } else { 162 /* This works on SS-2 (an early OpenFirmware) still. */ 163 switch(*romvec->pv_stdin) { 164 case PROMDEV_TTYA: return PROMDEV_OTTYA; 165 case PROMDEV_TTYB: return PROMDEV_OTTYB; 166 }; 167 } 168 break; 169 case PROM_AP1000: 170 return PROMDEV_I_UNK; 171 }; 172 return PROMDEV_O_UNK; 173 } 174 #endif 175