aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/prom
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-07-20 19:59:26 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-20 19:59:26 -0400
commitc73fcc846c91f53fd2c67fd9c6c04888a9e5892e (patch)
tree31faa68b4176636756926535a0f50ff780973275 /arch/sparc/prom
parentede13d81b4dda409a6d271b34b8e2ec9383e255d (diff)
[SPARC]: Fix serial console device detection.
The current scheme works on static interpretation of text names, which is wrong. The output-device setting, for example, must be resolved via an alias or similar to a full path name to the console device. Paths also contain an optional set of 'options', which starts with a colon at the end of the path. The option area is used to specify which of two serial ports ('a' or 'b') the path refers to when a device node drives multiple ports. 'a' is assumed if the option specification is missing. This was caught by the UltraSPARC-T1 simulator. The 'output-device' property was set to 'ttya' and we didn't pick upon the fact that this is an OBP alias set to '/virtual-devices/console'. Instead we saw it as the first serial console device, instead of the hypervisor console. The infrastructure is now there to take advantage of this to resolve the console correctly even in multi-head situations in fbcon too. Thanks to Greg Onufer for the bug report. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/prom')
-rw-r--r--arch/sparc/prom/console.c116
-rw-r--r--arch/sparc/prom/misc.c4
2 files changed, 2 insertions, 118 deletions
diff --git a/arch/sparc/prom/console.c b/arch/sparc/prom/console.c
index 4e6e41d3291d..8d1cfb0d5068 100644
--- a/arch/sparc/prom/console.c
+++ b/arch/sparc/prom/console.c
@@ -102,119 +102,3 @@ prom_putchar(char c)
102 while(prom_nbputchar(c) == -1) ; 102 while(prom_nbputchar(c) == -1) ;
103 return; 103 return;
104} 104}
105
106/* Query for input device type */
107enum prom_input_device
108prom_query_input_device(void)
109{
110 unsigned long flags;
111 int st_p;
112 char propb[64];
113 char *p;
114 int propl;
115
116 switch(prom_vers) {
117 case PROM_V0:
118 case PROM_V2:
119 case PROM_SUN4:
120 default:
121 switch(*romvec->pv_stdin) {
122 case PROMDEV_KBD: return PROMDEV_IKBD;
123 case PROMDEV_TTYA: return PROMDEV_ITTYA;
124 case PROMDEV_TTYB: return PROMDEV_ITTYB;
125 default:
126 return PROMDEV_I_UNK;
127 };
128 case PROM_V3:
129 spin_lock_irqsave(&prom_lock, flags);
130 st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdin);
131 restore_current();
132 spin_unlock_irqrestore(&prom_lock, flags);
133 if(prom_node_has_property(st_p, "keyboard"))
134 return PROMDEV_IKBD;
135 if (prom_getproperty(st_p, "name", propb, sizeof(propb)) != -1) {
136 if(strncmp(propb, "keyboard", sizeof("serial")) == 0)
137 return PROMDEV_IKBD;
138 }
139 if (prom_getproperty(st_p, "device_type", propb, sizeof(propb)) != -1) {
140 if(strncmp(propb, "serial", sizeof("serial")))
141 return PROMDEV_I_UNK;
142 }
143 propl = prom_getproperty(prom_root_node, "stdin-path", propb, sizeof(propb));
144 if(propl > 2) {
145 p = propb;
146 while(*p) p++; p -= 2;
147 if(p[0] == ':') {
148 if(p[1] == 'a')
149 return PROMDEV_ITTYA;
150 else if(p[1] == 'b')
151 return PROMDEV_ITTYB;
152 }
153 }
154 return PROMDEV_I_UNK;
155 }
156}
157
158/* Query for output device type */
159
160enum prom_output_device
161prom_query_output_device(void)
162{
163 unsigned long flags;
164 int st_p;
165 char propb[64];
166 char *p;
167 int propl;
168
169 switch(prom_vers) {
170 case PROM_V0:
171 case PROM_SUN4:
172 switch(*romvec->pv_stdin) {
173 case PROMDEV_SCREEN: return PROMDEV_OSCREEN;
174 case PROMDEV_TTYA: return PROMDEV_OTTYA;
175 case PROMDEV_TTYB: return PROMDEV_OTTYB;
176 };
177 break;
178 case PROM_V2:
179 case PROM_V3:
180 spin_lock_irqsave(&prom_lock, flags);
181 st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdout);
182 restore_current();
183 spin_unlock_irqrestore(&prom_lock, flags);
184 propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb));
185 if (propl == sizeof("display") &&
186 strncmp("display", propb, sizeof("display")) == 0)
187 {
188 return PROMDEV_OSCREEN;
189 }
190 if(prom_vers == PROM_V3) {
191 if(propl >= 0 &&
192 strncmp("serial", propb, sizeof("serial")) != 0)
193 return PROMDEV_O_UNK;
194 propl = prom_getproperty(prom_root_node, "stdout-path",
195 propb, sizeof(propb));
196 if(propl == CON_SIZE_JMC &&
197 strncmp(propb, con_name_jmc, CON_SIZE_JMC) == 0)
198 return PROMDEV_OTTYA;
199 if(propl > 2) {
200 p = propb;
201 while(*p) p++; p-= 2;
202 if(p[0]==':') {
203 if(p[1] == 'a')
204 return PROMDEV_OTTYA;
205 else if(p[1] == 'b')
206 return PROMDEV_OTTYB;
207 }
208 }
209 } else {
210 switch(*romvec->pv_stdin) {
211 case PROMDEV_TTYA: return PROMDEV_OTTYA;
212 case PROMDEV_TTYB: return PROMDEV_OTTYB;
213 };
214 }
215 break;
216 default:
217 ;
218 };
219 return PROMDEV_O_UNK;
220}
diff --git a/arch/sparc/prom/misc.c b/arch/sparc/prom/misc.c
index 1942c7c05cb1..37cff5f54704 100644
--- a/arch/sparc/prom/misc.c
+++ b/arch/sparc/prom/misc.c
@@ -58,7 +58,7 @@ prom_cmdline(void)
58 extern void install_linux_ticker(void); 58 extern void install_linux_ticker(void);
59 unsigned long flags; 59 unsigned long flags;
60 60
61 if(!serial_console && prom_palette) 61 if (prom_palette)
62 prom_palette (1); 62 prom_palette (1);
63 spin_lock_irqsave(&prom_lock, flags); 63 spin_lock_irqsave(&prom_lock, flags);
64 install_obp_ticker(); 64 install_obp_ticker();
@@ -69,7 +69,7 @@ prom_cmdline(void)
69#ifdef CONFIG_SUN_AUXIO 69#ifdef CONFIG_SUN_AUXIO
70 set_auxio(AUXIO_LED, 0); 70 set_auxio(AUXIO_LED, 0);
71#endif 71#endif
72 if(!serial_console && prom_palette) 72 if (prom_palette)
73 prom_palette (0); 73 prom_palette (0);
74} 74}
75 75