Merge branch 'kdb-merge' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb
* 'kdb-merge' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb: (25 commits) kdb,debug_core: Allow the debug core to receive a panic notification MAINTAINERS: update kgdb, kdb, and debug_core info debug_core,kdb: Allow the debug core to process a recursive debug entry printk,kdb: capture printk() when in kdb shell kgdboc,kdb: Allow kdb to work on a non open console port kgdb: Add the ability to schedule a breakpoint via a tasklet mips,kgdb: kdb low level trap catch and stack trace powerpc,kgdb: Introduce low level trap catching x86,kgdb: Add low level debug hook kgdb: remove post_primary_code references kgdb,docs: Update the kgdb docs to include kdb kgdboc,keyboard: Keyboard driver for kdb with kgdb kgdb: gdb "monitor" -> kdb passthrough sparc,sunzilog: Add console polling support for sunzilog serial driver sh,sh-sci: Use NO_POLL_CHAR in the SCIF polled console code kgdb,8250,pl011: Return immediately from console poll kgdb: core changes to support kdb kdb: core for kgdb back end (2 of 2) kdb: core for kgdb back end (1 of 2) kgdb,blackfin: Add in kgdb_arch_set_pc for blackfin ...
This commit is contained in:
@@ -1891,8 +1891,8 @@ static int serial8250_get_poll_char(struct uart_port *port)
|
||||
struct uart_8250_port *up = (struct uart_8250_port *)port;
|
||||
unsigned char lsr = serial_inp(up, UART_LSR);
|
||||
|
||||
while (!(lsr & UART_LSR_DR))
|
||||
lsr = serial_inp(up, UART_LSR);
|
||||
if (!(lsr & UART_LSR_DR))
|
||||
return NO_POLL_CHAR;
|
||||
|
||||
return serial_inp(up, UART_RX);
|
||||
}
|
||||
|
||||
@@ -342,9 +342,9 @@ static int pl010_get_poll_char(struct uart_port *port)
|
||||
struct uart_amba_port *uap = (struct uart_amba_port *)port;
|
||||
unsigned int status;
|
||||
|
||||
do {
|
||||
status = readw(uap->port.membase + UART01x_FR);
|
||||
} while (status & UART01x_FR_RXFE);
|
||||
status = readw(uap->port.membase + UART01x_FR);
|
||||
if (status & UART01x_FR_RXFE)
|
||||
return NO_POLL_CHAR;
|
||||
|
||||
return readw(uap->port.membase + UART01x_DR);
|
||||
}
|
||||
|
||||
+68
-7
@@ -14,7 +14,9 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/kgdb.h>
|
||||
#include <linux/kdb.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/console.h>
|
||||
|
||||
#define MAX_CONFIG_LEN 40
|
||||
|
||||
@@ -32,6 +34,40 @@ static struct kparam_string kps = {
|
||||
static struct tty_driver *kgdb_tty_driver;
|
||||
static int kgdb_tty_line;
|
||||
|
||||
#ifdef CONFIG_KDB_KEYBOARD
|
||||
static int kgdboc_register_kbd(char **cptr)
|
||||
{
|
||||
if (strncmp(*cptr, "kbd", 3) == 0) {
|
||||
if (kdb_poll_idx < KDB_POLL_FUNC_MAX) {
|
||||
kdb_poll_funcs[kdb_poll_idx] = kdb_get_kbd_char;
|
||||
kdb_poll_idx++;
|
||||
if (cptr[0][3] == ',')
|
||||
*cptr += 4;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void kgdboc_unregister_kbd(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < kdb_poll_idx; i++) {
|
||||
if (kdb_poll_funcs[i] == kdb_get_kbd_char) {
|
||||
kdb_poll_idx--;
|
||||
kdb_poll_funcs[i] = kdb_poll_funcs[kdb_poll_idx];
|
||||
kdb_poll_funcs[kdb_poll_idx] = NULL;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else /* ! CONFIG_KDB_KEYBOARD */
|
||||
#define kgdboc_register_kbd(x) 0
|
||||
#define kgdboc_unregister_kbd()
|
||||
#endif /* ! CONFIG_KDB_KEYBOARD */
|
||||
|
||||
static int kgdboc_option_setup(char *opt)
|
||||
{
|
||||
if (strlen(opt) > MAX_CONFIG_LEN) {
|
||||
@@ -45,25 +81,51 @@ static int kgdboc_option_setup(char *opt)
|
||||
|
||||
__setup("kgdboc=", kgdboc_option_setup);
|
||||
|
||||
static void cleanup_kgdboc(void)
|
||||
{
|
||||
kgdboc_unregister_kbd();
|
||||
if (configured == 1)
|
||||
kgdb_unregister_io_module(&kgdboc_io_ops);
|
||||
}
|
||||
|
||||
static int configure_kgdboc(void)
|
||||
{
|
||||
struct tty_driver *p;
|
||||
int tty_line = 0;
|
||||
int err;
|
||||
char *cptr = config;
|
||||
struct console *cons;
|
||||
|
||||
err = kgdboc_option_setup(config);
|
||||
if (err || !strlen(config) || isspace(config[0]))
|
||||
goto noconfig;
|
||||
|
||||
err = -ENODEV;
|
||||
kgdboc_io_ops.is_console = 0;
|
||||
kgdb_tty_driver = NULL;
|
||||
|
||||
p = tty_find_polling_driver(config, &tty_line);
|
||||
if (kgdboc_register_kbd(&cptr))
|
||||
goto do_register;
|
||||
|
||||
p = tty_find_polling_driver(cptr, &tty_line);
|
||||
if (!p)
|
||||
goto noconfig;
|
||||
|
||||
cons = console_drivers;
|
||||
while (cons) {
|
||||
int idx;
|
||||
if (cons->device && cons->device(cons, &idx) == p &&
|
||||
idx == tty_line) {
|
||||
kgdboc_io_ops.is_console = 1;
|
||||
break;
|
||||
}
|
||||
cons = cons->next;
|
||||
}
|
||||
|
||||
kgdb_tty_driver = p;
|
||||
kgdb_tty_line = tty_line;
|
||||
|
||||
do_register:
|
||||
err = kgdb_register_io_module(&kgdboc_io_ops);
|
||||
if (err)
|
||||
goto noconfig;
|
||||
@@ -75,6 +137,7 @@ static int configure_kgdboc(void)
|
||||
noconfig:
|
||||
config[0] = 0;
|
||||
configured = 0;
|
||||
cleanup_kgdboc();
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -88,20 +151,18 @@ static int __init init_kgdboc(void)
|
||||
return configure_kgdboc();
|
||||
}
|
||||
|
||||
static void cleanup_kgdboc(void)
|
||||
{
|
||||
if (configured == 1)
|
||||
kgdb_unregister_io_module(&kgdboc_io_ops);
|
||||
}
|
||||
|
||||
static int kgdboc_get_char(void)
|
||||
{
|
||||
if (!kgdb_tty_driver)
|
||||
return -1;
|
||||
return kgdb_tty_driver->ops->poll_get_char(kgdb_tty_driver,
|
||||
kgdb_tty_line);
|
||||
}
|
||||
|
||||
static void kgdboc_put_char(u8 chr)
|
||||
{
|
||||
if (!kgdb_tty_driver)
|
||||
return;
|
||||
kgdb_tty_driver->ops->poll_put_char(kgdb_tty_driver,
|
||||
kgdb_tty_line, chr);
|
||||
}
|
||||
|
||||
@@ -151,7 +151,11 @@ static int sci_poll_get_char(struct uart_port *port)
|
||||
handle_error(port);
|
||||
continue;
|
||||
}
|
||||
} while (!(status & SCxSR_RDxF(port)));
|
||||
break;
|
||||
} while (1);
|
||||
|
||||
if (!(status & SCxSR_RDxF(port)))
|
||||
return NO_POLL_CHAR;
|
||||
|
||||
c = sci_in(port, SCxRDR);
|
||||
|
||||
|
||||
@@ -102,6 +102,8 @@ struct uart_sunzilog_port {
|
||||
#endif
|
||||
};
|
||||
|
||||
static void sunzilog_putchar(struct uart_port *port, int ch);
|
||||
|
||||
#define ZILOG_CHANNEL_FROM_PORT(PORT) ((struct zilog_channel __iomem *)((PORT)->membase))
|
||||
#define UART_ZILOG(PORT) ((struct uart_sunzilog_port *)(PORT))
|
||||
|
||||
@@ -996,6 +998,50 @@ static int sunzilog_verify_port(struct uart_port *port, struct serial_struct *se
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CONSOLE_POLL
|
||||
static int sunzilog_get_poll_char(struct uart_port *port)
|
||||
{
|
||||
unsigned char ch, r1;
|
||||
struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port;
|
||||
struct zilog_channel __iomem *channel
|
||||
= ZILOG_CHANNEL_FROM_PORT(&up->port);
|
||||
|
||||
|
||||
r1 = read_zsreg(channel, R1);
|
||||
if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) {
|
||||
writeb(ERR_RES, &channel->control);
|
||||
ZSDELAY();
|
||||
ZS_WSYNC(channel);
|
||||
}
|
||||
|
||||
ch = readb(&channel->control);
|
||||
ZSDELAY();
|
||||
|
||||
/* This funny hack depends upon BRK_ABRT not interfering
|
||||
* with the other bits we care about in R1.
|
||||
*/
|
||||
if (ch & BRK_ABRT)
|
||||
r1 |= BRK_ABRT;
|
||||
|
||||
if (!(ch & Rx_CH_AV))
|
||||
return NO_POLL_CHAR;
|
||||
|
||||
ch = readb(&channel->data);
|
||||
ZSDELAY();
|
||||
|
||||
ch &= up->parity_mask;
|
||||
return ch;
|
||||
}
|
||||
|
||||
static void sunzilog_put_poll_char(struct uart_port *port,
|
||||
unsigned char ch)
|
||||
{
|
||||
struct uart_sunzilog_port *up = (struct uart_sunzilog_port *)port;
|
||||
|
||||
sunzilog_putchar(&up->port, ch);
|
||||
}
|
||||
#endif /* CONFIG_CONSOLE_POLL */
|
||||
|
||||
static struct uart_ops sunzilog_pops = {
|
||||
.tx_empty = sunzilog_tx_empty,
|
||||
.set_mctrl = sunzilog_set_mctrl,
|
||||
@@ -1013,6 +1059,10 @@ static struct uart_ops sunzilog_pops = {
|
||||
.request_port = sunzilog_request_port,
|
||||
.config_port = sunzilog_config_port,
|
||||
.verify_port = sunzilog_verify_port,
|
||||
#ifdef CONFIG_CONSOLE_POLL
|
||||
.poll_get_char = sunzilog_get_poll_char,
|
||||
.poll_put_char = sunzilog_put_poll_char,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int uart_chip_count;
|
||||
|
||||
Reference in New Issue
Block a user