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>
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