spin_unlock_irqrestore(&pdc_lock, flags);
}
+/* locked by pdc_console_lock */
+static int __attribute__((aligned(8))) iodc_retbuf[32];
+static char __attribute__((aligned(64))) iodc_dbuf[4096];
/**
* pdc_iodc_print - Console print using IODC.
* Since the HP console requires CR+LF to perform a 'newline', we translate
* "\n" to "\r\n".
*/
-int pdc_iodc_print(unsigned char *str, unsigned count)
+int pdc_iodc_print(const unsigned char *str, unsigned count)
{
- /* XXX Should we spinlock posx usage */
static int posx; /* for simple TAB-Simulation... */
- int __attribute__((aligned(8))) iodc_retbuf[32];
- char __attribute__((aligned(64))) iodc_dbuf[4096];
unsigned int i;
unsigned long flags;
- memset(iodc_dbuf, 0, 4096);
- for (i = 0; i < count && i < 2048;) {
+ for (i = 0; i < count && i < 79;) {
switch(str[i]) {
case '\n':
iodc_dbuf[i+0] = '\r';
iodc_dbuf[i+1] = '\n';
i += 2;
posx = 0;
- break;
+ goto print;
case '\t':
while (posx & 7) {
iodc_dbuf[i] = ' ';
}
}
+ /* if we're at the end of line, and not already inserting a newline,
+ * insert one anyway. iodc console doesn't claim to support >79 char
+ * lines. don't account for this in the return value.
+ */
+ if (i == 79 && iodc_dbuf[i-1] != '\n') {
+ iodc_dbuf[i+0] = '\r';
+ iodc_dbuf[i+1] = '\n';
+ }
+
+print:
spin_lock_irqsave(&pdc_lock, flags);
real32_call(PAGE0->mem_cons.iodc_io,
(unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
*/
int pdc_iodc_getc(void)
{
- unsigned long flags;
- static int __attribute__((aligned(8))) iodc_retbuf[32];
- static char __attribute__((aligned(64))) iodc_dbuf[4096];
int ch;
int status;
+ unsigned long flags;
/* Bail if no console input device. */
if (!PAGE0->mem_kbd.iodc_io)
#include <linux/tty.h>
#include <asm/pdc.h> /* for iodc_call() proto and friends */
+static spinlock_t pdc_console_lock = SPIN_LOCK_UNLOCKED;
static void pdc_console_write(struct console *co, const char *s, unsigned count)
{
- pdc_iodc_print(s, count);
+ int i = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&pdc_console_lock, flags);
+ do {
+ i += pdc_iodc_print(s + i, count - i);
+ } while (i < count);
+ spin_unlock_irqrestore(&pdc_console_lock, flags);
}
int pdc_console_poll_key(struct console *co)
{
- return pdc_iodc_getc();
+ int c;
+ unsigned long flags;
+
+ spin_lock_irqsave(&pdc_console_lock, flags);
+ c = pdc_iodc_getc();
+ spin_unlock_irqrestore(&pdc_console_lock, flags);
+
+ return c;
}
static int pdc_console_setup(struct console *co, char *options)
void pdc_io_reset(void);
void pdc_io_reset_devices(void);
int pdc_iodc_getc(void);
-int pdc_iodc_print(unsigned char *str, unsigned count);
+int pdc_iodc_print(const unsigned char *str, unsigned count);
void pdc_emergency_unlock(void);
int pdc_sti_call(unsigned long func, unsigned long flags,