patch-2.3.99-pre6 linux/arch/ia64/kdb/kdb_io.c
Next file: linux/arch/ia64/kdb/kdb_traps.c
Previous file: linux/arch/ia64/kdb/kdb_bt.c
Back to the patch index
Back to the overall index
- Lines: 351
- Date:
Wed Dec 31 16:00:00 1969
- Orig file:
v2.3.99-pre5/linux/arch/ia64/kdb/kdb_io.c
- Orig date:
Thu Feb 10 17:11:03 2000
diff -u --recursive --new-file v2.3.99-pre5/linux/arch/ia64/kdb/kdb_io.c linux/arch/ia64/kdb/kdb_io.c
@@ -1,350 +0,0 @@
-/*
- * Kernel Debugger Console I/O handler
- *
- * Copyright (C) 1999 Silicon Graphics, Inc.
- * Copyright (C) Scott Lurndal (slurn@engr.sgi.com)
- * Copyright (C) Scott Foehner (sfoehner@engr.sgi.com)
- * Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com)
- *
- * Written March 1999 by Scott Lurndal at Silicon Graphics, Inc.
- *
- * Modifications from:
- * Chuck Fleckenstein 1999/07/20
- * Move kdb_info struct declaration to this file
- * for cases where serial support is not compiled into
- * the kernel.
- *
- * Masahiro Adegawa 1999/07/20
- * Handle some peculiarities of japanese 86/106
- * keyboards.
- *
- * marc@mucom.co.il 1999/07/20
- * Catch buffer overflow for serial input.
- *
- * Scott Foehner
- * Port to ia64
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/console.h>
-#include <linux/serial_reg.h>
-#include <linux/spinlock.h>
-
-#include <asm/io.h>
-
-#include "pc_keyb.h"
-
-int kdb_port = 0;
-
-/*
- * This module contains code to read characters from the keyboard or a serial
- * port.
- *
- * It is used by the kernel debugger, and is polled, not interrupt driven.
- *
- */
-
-/*
- * send: Send a byte to the keyboard controller. Used primarily to
- * alter LED settings.
- */
-
-static void
-kdb_kbdsend(unsigned char byte)
-{
- while (inb(KBD_STATUS_REG) & KBD_STAT_IBF)
- ;
- outb(KBD_DATA_REG, byte);
-}
-
-static void
-kdb_kbdsetled(int leds)
-{
- kdb_kbdsend(KBD_CMD_SET_LEDS);
- kdb_kbdsend((unsigned char)leds);
-}
-
-static void
-console_read (char *buffer, size_t bufsize)
-{
- struct console *in;
- struct console *out;
- char *cp, ch;
-
- for (in = console_drivers; in; in = in->next) {
- if ((in->flags & CON_ENABLED) && (in->read || in->wait_key))
- break;
- }
- for (out = console_drivers; out; out = out->next) {
- if ((out->flags & CON_ENABLED) && out->write)
- break;
- }
-
- if ((!in->read && !in->wait_key) || !out->write) {
- panic("kdb_io: can't do console i/o!");
- }
-
- if (in->read) {
- /* this is untested... */
- (*in->read)(in, buffer, bufsize);
- return;
- }
-
- bufsize -= 2; /* leave room for CR & NUL terminator */
- cp = buffer;
- while (1) {
- ch = (*in->wait_key)(in);
- switch (ch) {
- case '\b':
- if (cp > buffer) {
- --cp, ++bufsize;
- (*out->write)(out, "\b \b", 3);
- }
- break;
-
- case '\025':
- while (cp > buffer) {
- --cp, ++bufsize;
- (*out->write)(out, "\b \b", 3);
- }
- break;
-
- case '\r':
- case '\n':
- (*out->write)(out, "\r\n", 2);
- *cp++ = '\n';
- *cp++ = '\0';
- return;
-
- default:
- if (bufsize > 0) {
- (*out->write)(out, &ch, 1);
- --bufsize;
- *cp++ = ch;
- }
- break;
- }
- }
-}
-
-char *
-kdb_getscancode(char *buffer, size_t bufsize)
-{
- /*
- * XXX Shouldn't kdb _always_ use console based I/O? That's what the console
- * abstraction is for, after all... ---davidm
- */
-#ifdef CONFIG_IA64_HP_SIM
- extern spinlock_t console_lock;
- unsigned long flags;
-
- spin_lock_irqsave(&console_lock, flags);
- console_read(buffer, bufsize);
- spin_unlock_irqrestore(&console_lock, flags);
- return buffer;
-#else /* !CONFIG_IA64_HP_SIM */
- char *cp = buffer;
- int scancode, scanstatus;
- static int shift_lock = 0; /* CAPS LOCK state (0-off, 1-on) */
- static int shift_key = 0; /* Shift next keypress */
- static int ctrl_key = 0;
- static int leds = 2; /* Num lock */
- u_short keychar;
- extern u_short plain_map[], shift_map[], ctrl_map[];
-
- bufsize -= 2; /* Reserve space for newline and null byte */
-
- /*
- * If we came in via a serial console, we allow that to
- * be the input window for kdb.
- */
- if (kdb_port != 0) {
- char ch;
- int status;
-#define serial_inp(info, offset) inb((info) + (offset))
-#define serial_out(info, offset, v) outb((v), (info) + (offset))
-
- while(1) {
- while ((status = serial_inp(kdb_port, UART_LSR))
- & UART_LSR_DR) {
-readchar:
- ch = serial_inp(kdb_port, UART_RX);
- if (ch == 8) { /* BS */
- if (cp > buffer) {
- --cp, bufsize++;
- printk("%c %c", 0x08, 0x08);
- }
- continue;
- }
- serial_out(kdb_port, UART_TX, ch);
- if (ch == 13) { /* CR */
- *cp++ = '\n';
- *cp++ = '\0';
- serial_out(kdb_port, UART_TX, 10);
- return(buffer);
- }
- /*
- * Discard excess characters
- */
- if (bufsize > 0) {
- *cp++ = ch;
- bufsize--;
- }
- }
- while (((status = serial_inp(kdb_port, UART_LSR))
- & UART_LSR_DR) == 0);
- }
- }
-
- while (1) {
-
- /*
- * Wait for a valid scancode
- */
-
- while ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0)
- ;
-
- /*
- * Fetch the scancode
- */
- scancode = inb(KBD_DATA_REG);
- scanstatus = inb(KBD_STATUS_REG);
-
- /*
- * Ignore mouse events.
- */
- if (scanstatus & KBD_STAT_MOUSE_OBF)
- continue;
-
- /*
- * Ignore release, trigger on make
- * (except for shift keys, where we want to
- * keep the shift state so long as the key is
- * held down).
- */
-
- if (((scancode&0x7f) == 0x2a)
- || ((scancode&0x7f) == 0x36)) {
- /*
- * Next key may use shift table
- */
- if ((scancode & 0x80) == 0) {
- shift_key=1;
- } else {
- shift_key=0;
- }
- continue;
- }
-
- if ((scancode&0x7f) == 0x1d) {
- /*
- * Left ctrl key
- */
- if ((scancode & 0x80) == 0) {
- ctrl_key = 1;
- } else {
- ctrl_key = 0;
- }
- continue;
- }
-
- if ((scancode & 0x80) != 0)
- continue;
-
- scancode &= 0x7f;
-
- /*
- * Translate scancode
- */
-
- if (scancode == 0x3a) {
- /*
- * Toggle caps lock
- */
- shift_lock ^= 1;
- leds ^= 0x4; /* toggle caps lock led */
-
- kdb_kbdsetled(leds);
- continue;
- }
-
- if (scancode == 0x0e) {
- /*
- * Backspace
- */
- if (cp > buffer) {
- --cp, bufsize++;
-
- /*
- * XXX - erase character on screen
- */
- printk("%c %c", 0x08, 0x08);
- }
- continue;
- }
-
- if (scancode == 0xe0) {
- continue;
- }
-
- /*
- * For Japanese 86/106 keyboards
- * See comment in drivers/char/pc_keyb.c.
- * - Masahiro Adegawa
- */
- if (scancode == 0x73) {
- scancode = 0x59;
- } else if (scancode == 0x7d) {
- scancode = 0x7c;
- }
-
- if (!shift_lock && !shift_key) {
- keychar = plain_map[scancode];
- } else if (shift_lock || shift_key) {
- keychar = shift_map[scancode];
- } else if (ctrl_key) {
- keychar = ctrl_map[scancode];
- } else {
- keychar = 0x0020;
- printk("Unknown state/scancode (%d)\n", scancode);
- }
-
- if ((scancode & 0x7f) == 0x1c) {
- /*
- * enter key. All done.
- */
- printk("\n");
- break;
- }
-
- /*
- * echo the character.
- */
- printk("%c", keychar&0xff);
-
- if (bufsize) {
- --bufsize;
- *cp++ = keychar&0xff;
- } else {
- printk("buffer overflow\n");
- break;
- }
-
- }
-
- *cp++ = '\n'; /* White space for parser */
- *cp++ = '\0'; /* String termination */
-
-#if defined(NOTNOW)
- cp = buffer;
- while (*cp) {
- printk("char 0x%x\n", *cp++);
- }
-#endif
-
- return buffer;
-#endif /* !CONFIG_IA64_HP_SIM */
-}
-
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)