Ok. I didn't make 2.4.0 in 2000. Tough. I tried, but we had some
[davej-history.git] / arch / parisc / kernel / pdc_cons.c
blobf2d45862bfd41192a08f4e5ab5ce8b536145e162
1 #include <linux/config.h>
2 #include <linux/kernel.h>
3 #include <linux/console.h>
4 #include <linux/string.h>
5 #include <linux/init.h>
6 #include <linux/delay.h>
7 #include <linux/interrupt.h>
8 #include <asm/page.h>
9 #include <asm/types.h>
10 #include <asm/system.h>
11 #include <asm/pdc.h> /* for iodc_call() proto and friends */
12 #include <asm/real.h>
14 static int __attribute__((aligned(8))) iodc_retbuf[32];
15 static char __attribute__((aligned(64))) iodc_dbuf[4096];
18 * pdc_putc:
19 * Console character print using IODC.
21 * Note that only these special chars are architected for console IODC io:
22 * BEL, BS, CR, and LF. Others are passed through.
23 * Since the HP console requires CR+LF to perform a 'newline', we translate
24 * "\n" to "\r\n".
27 static int posx; /* for simple TAB-Simulation... */
29 /* XXX Should we spinlock posx usage */
31 void pdc_putc(unsigned char c)
33 unsigned int n;
34 unsigned long flags;
36 switch (c) {
37 case '\n':
38 iodc_dbuf[0] = '\r';
39 iodc_dbuf[1] = '\n';
40 n = 2;
41 posx = 0;
42 break;
43 case '\t':
44 pdc_putc(' ');
45 while (posx & 7) /* expand TAB */
46 pdc_putc(' ');
47 return; /* return since IODC can't handle this */
48 case '\b':
49 posx-=2; /* BS */
50 default:
51 iodc_dbuf[0] = c;
52 n = 1;
53 posx++;
54 break;
57 real32_call(PAGE0->mem_cons.iodc_io,
58 (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
59 PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
60 __pa(iodc_retbuf), 0, __pa(iodc_dbuf), n, 0);
64 static void pdc_console_write(struct console *co, const char *s, unsigned count)
66 while(count--)
67 pdc_putc(*s++);
70 int pdc_console_wait_key(struct console *co)
72 int ch = 'X';
73 int status;
75 /* Bail if no console input device. */
76 if (!PAGE0->mem_kbd.iodc_io)
77 return 0;
79 /* wait for a keyboard (rs232)-input */
80 do {
81 unsigned long flags;
83 save_flags(flags);
84 cli();
85 status = real32_call(PAGE0->mem_kbd.iodc_io,
86 (unsigned long)PAGE0->mem_kbd.hpa, ENTRY_IO_CIN,
87 PAGE0->mem_kbd.spa, __pa(PAGE0->mem_kbd.dp.layers),
88 __pa(iodc_retbuf), 0, __pa(iodc_dbuf), 1, 0);
89 restore_flags(flags);
90 ch = *iodc_dbuf; /* save the character directly to ch */
91 } while (*iodc_retbuf == 0); /* wait for a key */
92 return ch;
95 int pdc_getc(void)
97 return pdc_console_wait_key(NULL);
100 static int pdc_console_setup(struct console *co, char *options)
102 return 0;
105 static struct console pdc_cons = {
106 name: "ttyB",
107 write: pdc_console_write,
108 read: NULL,
109 device: NULL,
110 wait_key: pdc_console_wait_key,
111 unblank: NULL,
112 setup: pdc_console_setup,
113 flags: CON_PRINTBUFFER|CON_ENABLED, // |CON_CONSDEV,
114 index: -1,
117 static int pdc_console_initialized;
119 void pdc_console_init(void)
121 if (pdc_console_initialized)
122 return;
123 ++pdc_console_initialized;
125 /* If the console is duplex then copy the COUT parameters to CIN. */
126 if (PAGE0->mem_cons.cl_class == CL_DUPLEX)
127 memcpy(&PAGE0->mem_kbd, &PAGE0->mem_cons, sizeof(PAGE0->mem_cons));
129 pdc_console_write(0, "PDC Console Initialized\n", 24);
130 /* register the pdc console */
131 register_console(&pdc_cons);
135 /* Unregister the pdc console with the printk console layer */
136 void pdc_console_die(void)
138 printk("Switching from PDC console\n");
139 if (!pdc_console_initialized)
140 return;
141 --pdc_console_initialized;
143 #ifdef CONFIG_VT_CONSOLE
145 /* fixme (needed?): Wait for console-tasklet to finish !*/
146 extern struct tasklet_struct console_tasklet;
147 tasklet_schedule(&console_tasklet);
149 #endif
151 unregister_console(&pdc_cons);
156 * Used for emergencies. Currently only used if an HPMC occurs. If an
157 * HPMC occurs, it is possible that the current console may not be
158 * properly initialed after the PDC IO reset. This routine unregisters all
159 * of the current consoles, reinitializes the pdc console and
160 * registers it.
163 void pdc_console_restart(void)
165 struct console *console;
166 extern int log_size;
168 if (pdc_console_initialized)
169 return;
171 while ((console = console_drivers) != (struct console *)0)
172 unregister_console(console_drivers);
174 log_size = 0;
175 pdc_console_init();
176 printk("Switched to PDC console\n");
177 return;