File: pdc_cons.c

package info (click to toggle)
kernel-image-2.4.18-hppa 62.3
  • links: PTS
  • area: main
  • in suites: woody
  • size: 156,012 kB
  • ctags: 448,723
  • sloc: ansic: 2,586,445; asm: 145,047; makefile: 8,574; sh: 3,097; perl: 2,578; yacc: 1,177; tcl: 577; lex: 352; awk: 251; lisp: 218; sed: 72
file content (149 lines) | stat: -rw-r--r-- 3,442 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
 *  linux/arch/parisc/kernel/pdc_console.c
 *
 *  The PDC console is a simple console, which can be used for debugging 
 *  boot related problems on HP PA-RISC machines.
 *
 *  This code uses the ROM (=PDC) based functions to read and write characters
 *  from and to PDC's boot path.
 *  Since all character read from that path must be polled, this code never
 *  can or will be a fully functional linux console.
 */

/* Define EARLY_BOOTUP_DEBUG to debug kernel related boot problems. 
 * On production kernels EARLY_BOOTUP_DEBUG should be undefined. */
#undef EARLY_BOOTUP_DEBUG


#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/console.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <asm/page.h>
#include <asm/types.h>
#include <asm/system.h>
#include <asm/pdc.h>		/* for iodc_call() proto and friends */


static void pdc_console_write(struct console *co, const char *s, unsigned count)
{
	while(count--)
		pdc_iodc_putc(*s++);
}

void pdc_outc(unsigned char c)
{
	pdc_iodc_outc(c);
}


int pdc_console_poll_key(struct console *co)
{
	return pdc_iodc_getc();
}

static int pdc_console_setup(struct console *co, char *options)
{
	return 0;
}

#ifdef CONFIG_PDC_CONSOLE
static kdev_t pdc_console_device (struct console *c)
{
        return MKDEV(PDCCONS_MAJOR, 0);
}
#endif

#ifdef CONFIG_PDC_CONSOLE
#define PDC_CONSOLE_DEVICE pdc_console_device
#else
#define PDC_CONSOLE_DEVICE NULL
#endif

static struct console pdc_cons = {
	name:		"ttyB",
	write:		pdc_console_write,
	read:		NULL,
	device:		PDC_CONSOLE_DEVICE,
	wait_key:	NULL,
	unblank:	NULL,
	setup:		pdc_console_setup,
	flags:		CON_BOOT|CON_PRINTBUFFER|CON_ENABLED,
	index:		-1,
};

static int pdc_console_initialized;
extern unsigned long con_start;	/* kernel/printk.c */
extern unsigned long log_end;	/* kernel/printk.c */


static void pdc_console_init_force(void)
{
	if (pdc_console_initialized)
		return;
	++pdc_console_initialized;
	
	/* If the console is duplex then copy the COUT parameters to CIN. */
	if (PAGE0->mem_cons.cl_class == CL_DUPLEX)
		memcpy(&PAGE0->mem_kbd, &PAGE0->mem_cons, sizeof(PAGE0->mem_cons));

	/* register the pdc console */
	register_console(&pdc_cons);
}

void pdc_console_init(void)
{
#if defined(EARLY_BOOTUP_DEBUG) || defined(CONFIG_PDC_CONSOLE)
	pdc_console_init_force();
#endif
#ifdef EARLY_BOOTUP_DEBUG
	printk(KERN_INFO "Initialized PDC Console for debugging.\n");
#endif
}


/* Unregister the pdc console with the printk console layer */
void pdc_console_die(void)
{
	if (!pdc_console_initialized)
		return;
	--pdc_console_initialized;

	printk(KERN_INFO "Switching from PDC console\n");

	/* Don't repeat what we've already printed */
	con_start = log_end;

	unregister_console(&pdc_cons);
}


/*
 * Used for emergencies. Currently only used if an HPMC occurs. If an
 * HPMC occurs, it is possible that the current console may not be
 * properly initialed after the PDC IO reset. This routine unregisters all
 * of the current consoles, reinitializes the pdc console and
 * registers it.
 */

void pdc_console_restart(void)
{
	struct console *console;

	if (pdc_console_initialized)
		return;

	while ((console = console_drivers) != NULL)
		unregister_console(console_drivers);

	/* Don't repeat what we've already printed */
	con_start = log_end;
	
	/* force registering the pdc console */
	pdc_console_init_force();
}