[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.