[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Check the existence of serial port before using
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1221216227 -3600 # Node ID 982e6fce0e4796f53fe80891b3b0352d7b214ce4 # Parent 31e06b3ccf53ea3fc4a2e3f6ef2b2d630ed0b584 Check the existence of serial port before using Signed-off-by: Huacai Chen <huacai.chen@xxxxxxxxx> Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/common/gdbstub.c | 15 ++++++++++++--- xen/drivers/char/console.c | 14 +++++++++++--- xen/drivers/char/ns16550.c | 34 ++++++++++++++++++++++++++++++++++ xen/drivers/char/serial.c | 10 ++++------ 4 files changed, 61 insertions(+), 12 deletions(-) diff -r 31e06b3ccf53 -r 982e6fce0e47 xen/common/gdbstub.c --- a/xen/common/gdbstub.c Fri Sep 12 10:41:51 2008 +0100 +++ b/xen/common/gdbstub.c Fri Sep 12 11:43:47 2008 +0100 @@ -65,7 +65,7 @@ static void gdb_smp_pause(void); static void gdb_smp_pause(void); static void gdb_smp_resume(void); -static char opt_gdb[30] = "none"; +static char opt_gdb[30]; string_param("gdb", opt_gdb); static void gdbstub_console_puts(const char *str); @@ -625,10 +625,19 @@ void __init void __init initialise_gdb(void) { + if ( *opt_gdb == '\0' ) + return; + gdb_ctx->serhnd = serial_parse_handle(opt_gdb); - if ( gdb_ctx->serhnd != -1 ) - printk("GDB stub initialised.\n"); + if ( gdb_ctx->serhnd == -1 ) + { + printk("Bad gdb= option '%s'\n", opt_gdb); + return; + } + serial_start_sync(gdb_ctx->serhnd); + + printk("GDB stub initialised.\n"); } static void gdb_pause_this_cpu(void *unused) diff -r 31e06b3ccf53 -r 982e6fce0e47 xen/drivers/char/console.c --- a/xen/drivers/char/console.c Fri Sep 12 10:41:51 2008 +0100 +++ b/xen/drivers/char/console.c Fri Sep 12 11:43:47 2008 +0100 @@ -543,10 +543,18 @@ void __init init_console(void) { if ( *p == ',' ) p++; - if ( strncmp(p, "com", 3) == 0 ) - sercon_handle = serial_parse_handle(p); - else if ( strncmp(p, "vga", 3) == 0 ) + if ( !strncmp(p, "vga", 3) ) vga_init(); + else if ( strncmp(p, "com", 3) || + (sercon_handle = serial_parse_handle(p)) == -1 ) + { + char *q = strchr(p, ','); + if ( q != NULL ) + *q = '\0'; + printk("Bad console= option '%s'\n", p); + if ( q != NULL ) + *q = ','; + } } serial_set_rx_handler(sercon_handle, serial_rx); diff -r 31e06b3ccf53 -r 982e6fce0e47 xen/drivers/char/ns16550.c --- a/xen/drivers/char/ns16550.c Fri Sep 12 10:41:51 2008 +0100 +++ b/xen/drivers/char/ns16550.c Fri Sep 12 11:43:47 2008 +0100 @@ -82,6 +82,7 @@ static struct ns16550 { #define MCR_DTR 0x01 /* Data Terminal Ready */ #define MCR_RTS 0x02 /* Request to Send */ #define MCR_OUT2 0x08 /* OUT2: interrupt mask */ +#define MCR_LOOP 0x10 /* Enable loopback test mode */ /* Line Status Register */ #define LSR_DR 0x01 /* Data ready */ @@ -293,6 +294,37 @@ static int __init parse_parity_char(int return PARITY_SPACE; } return 0; +} + +static int check_existence(struct ns16550 *uart) +{ + unsigned char status, scratch, scratch2, scratch3; + + /* + * Do a simple existence test first; if we fail this, + * there's no point trying anything else. + */ + scratch = ns_read_reg(uart, IER); + ns_write_reg(uart, IER, 0); + + /* + * Mask out IER[7:4] bits for test as some UARTs (e.g. TL + * 16C754B) allow only to modify them if an EFR bit is set. + */ + scratch2 = ns_read_reg(uart, IER) & 0x0f; + ns_write_reg(uart, IER, 0x0F); + scratch3 = ns_read_reg(uart, IER) & 0x0f; + ns_write_reg(uart, IER, scratch); + if ( (scratch2 != 0) || (scratch3 != 0x0F) ) + return 0; + + /* + * Check to see if a UART is really there. + * Use loopback test mode. + */ + ns_write_reg(uart, MCR, MCR_LOOP | 0x0A); + status = ns_read_reg(uart, MSR) & 0xF0; + return (status == 0x90); } #define PARSE_ERR(_f, _a...) \ @@ -357,6 +389,8 @@ static void __init ns16550_parse_port_co PARSE_ERR("%d stop bits are unsupported.", uart->stop_bits); if ( uart->io_base == 0 ) PARSE_ERR("I/O base address must be specified."); + if ( !check_existence(uart) ) + PARSE_ERR("16550-compatible serial UART not present"); /* Register with generic serial driver. */ serial_register_uart(uart - ns16550_com, &ns16550_driver, uart); diff -r 31e06b3ccf53 -r 982e6fce0e47 xen/drivers/char/serial.c --- a/xen/drivers/char/serial.c Fri Sep 12 10:41:51 2008 +0100 +++ b/xen/drivers/char/serial.c Fri Sep 12 11:43:47 2008 +0100 @@ -258,11 +258,7 @@ int serial_parse_handle(char *conf) { int handle; - /* Silently fail if user has explicitly requested no serial I/O. */ - if ( strcmp(conf, "none") == 0 ) - return -1; - - if ( strncmp(conf, "com", 3) != 0 ) + if ( strncmp(conf, "com", 3) ) goto fail; switch ( conf[3] ) @@ -277,6 +273,9 @@ int serial_parse_handle(char *conf) goto fail; } + if ( !com[handle].driver ) + goto fail; + if ( conf[4] == 'H' ) handle |= SERHND_HI; else if ( conf[4] == 'L' ) @@ -287,7 +286,6 @@ int serial_parse_handle(char *conf) return handle; fail: - printk("ERROR: bad serial-interface specification '%s'\n", conf); return -1; } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |