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