ia64/xen-unstable
changeset 18487:982e6fce0e47
Check the existence of serial port before using
Signed-off-by: Huacai Chen <huacai.chen@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Signed-off-by: Huacai Chen <huacai.chen@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Fri Sep 12 11:43:47 2008 +0100 (2008-09-12) |
parents | 31e06b3ccf53 |
children | e827c54462d3 |
files | xen/common/gdbstub.c xen/drivers/char/console.c xen/drivers/char/ns16550.c xen/drivers/char/serial.c |
line diff
1.1 --- a/xen/common/gdbstub.c Fri Sep 12 10:41:51 2008 +0100 1.2 +++ b/xen/common/gdbstub.c Fri Sep 12 11:43:47 2008 +0100 1.3 @@ -65,7 +65,7 @@ static atomic_t gdb_smp_paused_count; 1.4 static void gdb_smp_pause(void); 1.5 static void gdb_smp_resume(void); 1.6 1.7 -static char opt_gdb[30] = "none"; 1.8 +static char opt_gdb[30]; 1.9 string_param("gdb", opt_gdb); 1.10 1.11 static void gdbstub_console_puts(const char *str); 1.12 @@ -625,10 +625,19 @@ int 1.13 void __init 1.14 initialise_gdb(void) 1.15 { 1.16 + if ( *opt_gdb == '\0' ) 1.17 + return; 1.18 + 1.19 gdb_ctx->serhnd = serial_parse_handle(opt_gdb); 1.20 - if ( gdb_ctx->serhnd != -1 ) 1.21 - printk("GDB stub initialised.\n"); 1.22 + if ( gdb_ctx->serhnd == -1 ) 1.23 + { 1.24 + printk("Bad gdb= option '%s'\n", opt_gdb); 1.25 + return; 1.26 + } 1.27 + 1.28 serial_start_sync(gdb_ctx->serhnd); 1.29 + 1.30 + printk("GDB stub initialised.\n"); 1.31 } 1.32 1.33 static void gdb_pause_this_cpu(void *unused)
2.1 --- a/xen/drivers/char/console.c Fri Sep 12 10:41:51 2008 +0100 2.2 +++ b/xen/drivers/char/console.c Fri Sep 12 11:43:47 2008 +0100 2.3 @@ -543,10 +543,18 @@ void __init init_console(void) 2.4 { 2.5 if ( *p == ',' ) 2.6 p++; 2.7 - if ( strncmp(p, "com", 3) == 0 ) 2.8 - sercon_handle = serial_parse_handle(p); 2.9 - else if ( strncmp(p, "vga", 3) == 0 ) 2.10 + if ( !strncmp(p, "vga", 3) ) 2.11 vga_init(); 2.12 + else if ( strncmp(p, "com", 3) || 2.13 + (sercon_handle = serial_parse_handle(p)) == -1 ) 2.14 + { 2.15 + char *q = strchr(p, ','); 2.16 + if ( q != NULL ) 2.17 + *q = '\0'; 2.18 + printk("Bad console= option '%s'\n", p); 2.19 + if ( q != NULL ) 2.20 + *q = ','; 2.21 + } 2.22 } 2.23 2.24 serial_set_rx_handler(sercon_handle, serial_rx);
3.1 --- a/xen/drivers/char/ns16550.c Fri Sep 12 10:41:51 2008 +0100 3.2 +++ b/xen/drivers/char/ns16550.c Fri Sep 12 11:43:47 2008 +0100 3.3 @@ -82,6 +82,7 @@ static struct ns16550 { 3.4 #define MCR_DTR 0x01 /* Data Terminal Ready */ 3.5 #define MCR_RTS 0x02 /* Request to Send */ 3.6 #define MCR_OUT2 0x08 /* OUT2: interrupt mask */ 3.7 +#define MCR_LOOP 0x10 /* Enable loopback test mode */ 3.8 3.9 /* Line Status Register */ 3.10 #define LSR_DR 0x01 /* Data ready */ 3.11 @@ -295,6 +296,37 @@ static int __init parse_parity_char(int 3.12 return 0; 3.13 } 3.14 3.15 +static int check_existence(struct ns16550 *uart) 3.16 +{ 3.17 + unsigned char status, scratch, scratch2, scratch3; 3.18 + 3.19 + /* 3.20 + * Do a simple existence test first; if we fail this, 3.21 + * there's no point trying anything else. 3.22 + */ 3.23 + scratch = ns_read_reg(uart, IER); 3.24 + ns_write_reg(uart, IER, 0); 3.25 + 3.26 + /* 3.27 + * Mask out IER[7:4] bits for test as some UARTs (e.g. TL 3.28 + * 16C754B) allow only to modify them if an EFR bit is set. 3.29 + */ 3.30 + scratch2 = ns_read_reg(uart, IER) & 0x0f; 3.31 + ns_write_reg(uart, IER, 0x0F); 3.32 + scratch3 = ns_read_reg(uart, IER) & 0x0f; 3.33 + ns_write_reg(uart, IER, scratch); 3.34 + if ( (scratch2 != 0) || (scratch3 != 0x0F) ) 3.35 + return 0; 3.36 + 3.37 + /* 3.38 + * Check to see if a UART is really there. 3.39 + * Use loopback test mode. 3.40 + */ 3.41 + ns_write_reg(uart, MCR, MCR_LOOP | 0x0A); 3.42 + status = ns_read_reg(uart, MSR) & 0xF0; 3.43 + return (status == 0x90); 3.44 +} 3.45 + 3.46 #define PARSE_ERR(_f, _a...) \ 3.47 do { \ 3.48 printk( "ERROR: " _f "\n" , ## _a ); \ 3.49 @@ -357,6 +389,8 @@ static void __init ns16550_parse_port_co 3.50 PARSE_ERR("%d stop bits are unsupported.", uart->stop_bits); 3.51 if ( uart->io_base == 0 ) 3.52 PARSE_ERR("I/O base address must be specified."); 3.53 + if ( !check_existence(uart) ) 3.54 + PARSE_ERR("16550-compatible serial UART not present"); 3.55 3.56 /* Register with generic serial driver. */ 3.57 serial_register_uart(uart - ns16550_com, &ns16550_driver, uart);
4.1 --- a/xen/drivers/char/serial.c Fri Sep 12 10:41:51 2008 +0100 4.2 +++ b/xen/drivers/char/serial.c Fri Sep 12 11:43:47 2008 +0100 4.3 @@ -258,11 +258,7 @@ int serial_parse_handle(char *conf) 4.4 { 4.5 int handle; 4.6 4.7 - /* Silently fail if user has explicitly requested no serial I/O. */ 4.8 - if ( strcmp(conf, "none") == 0 ) 4.9 - return -1; 4.10 - 4.11 - if ( strncmp(conf, "com", 3) != 0 ) 4.12 + if ( strncmp(conf, "com", 3) ) 4.13 goto fail; 4.14 4.15 switch ( conf[3] ) 4.16 @@ -277,6 +273,9 @@ int serial_parse_handle(char *conf) 4.17 goto fail; 4.18 } 4.19 4.20 + if ( !com[handle].driver ) 4.21 + goto fail; 4.22 + 4.23 if ( conf[4] == 'H' ) 4.24 handle |= SERHND_HI; 4.25 else if ( conf[4] == 'L' ) 4.26 @@ -287,7 +286,6 @@ int serial_parse_handle(char *conf) 4.27 return handle; 4.28 4.29 fail: 4.30 - printk("ERROR: bad serial-interface specification '%s'\n", conf); 4.31 return -1; 4.32 } 4.33