[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Allow arch-specific defaults to be specified for ns16550



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 64f26eed8d473a96beab96162c230f1300539d7c
# Parent  9b77ba29108d9e0ad4fcae90d9df51888d8d1244

Allow arch-specific defaults to be specified for ns16550
uart configuration. Based on a patch from Hollis Blanchard
at IBM.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r 9b77ba29108d -r 64f26eed8d47 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Thu Jul 14 08:00:55 2005
+++ b/xen/arch/x86/setup.c      Thu Jul 14 09:05:22 2005
@@ -247,6 +247,11 @@
     unsigned long initial_images_start, initial_images_end;
     struct e820entry e820_raw[E820MAX];
     int i, e820_raw_nr = 0, bytes = 0;
+    struct ns16550_defaults ns16550 = {
+        .data_bits = 8,
+        .parity    = 'n',
+        .stop_bits = 1
+    };
 
     /* Parse the command-line options. */
     if ( (mbi->flags & MBI_CMDLINE) && (mbi->cmdline != 0) )
@@ -259,7 +264,12 @@
     smp_prepare_boot_cpu();
 
     /* We initialise the serial devices very early so we can get debugging. */
-    ns16550_init();
+    ns16550.io_base = 0x3f8;
+    ns16550.irq     = 4;
+    ns16550_init(0, &ns16550);
+    ns16550.io_base = 0x2f8;
+    ns16550.irq     = 3;
+    ns16550_init(1, &ns16550);
     serial_init_preirq();
 
     init_console();
diff -r 9b77ba29108d -r 64f26eed8d47 xen/include/xen/serial.h
--- a/xen/include/xen/serial.h  Thu Jul 14 08:00:55 2005
+++ b/xen/include/xen/serial.h  Thu Jul 14 09:05:22 2005
@@ -113,7 +113,15 @@
 /*
  * Initialisers for individual uart drivers.
  */
-void ns16550_init(void);
+struct ns16550_defaults {
+    int baud;      /* default baud rate; 0 == pre-configured */
+    int data_bits; /* default data bits (5, 6, 7 or 8) */
+    int parity;    /* default parity (n, o, e, m or s) */
+    int stop_bits; /* default stop bits (1 or 2) */
+    int irq;       /* default irq */
+    unsigned long io_base; /* default io_base address */
+};
+void ns16550_init(int index, struct ns16550_defaults *defaults);
 
 #endif /* __XEN_SERIAL_H__ */
 
diff -r 9b77ba29108d -r 64f26eed8d47 xen/drivers/char/ns16550.c
--- a/xen/drivers/char/ns16550.c        Thu Jul 14 08:00:55 2005
+++ b/xen/drivers/char/ns16550.c        Thu Jul 14 09:05:22 2005
@@ -16,7 +16,7 @@
 #include <asm/io.h>
 
 /* Config serial port with a string <baud>,DPS,<io-base>,<irq>. */
-char opt_com1[30] = "", opt_com2[30] = "";
+static char opt_com1[30] = "", opt_com2[30] = "";
 string_param("com1", opt_com1);
 string_param("com2", opt_com2);
 
@@ -25,10 +25,7 @@
     unsigned long io_base;   /* I/O port or memory-mapped I/O address. */
     char *remapped_io_base;  /* Remapped virtual address of mmap I/O.  */ 
     struct irqaction irqaction;
-} ns16550_com[2] = {
-    { 0, 0, 0, 0, 4, 0x3f8 },
-    { 0, 0, 0, 0, 3, 0x2f8 }
-};
+} ns16550_com[2] = { { 0 } };
 
 /* Register offsets */
 #define RBR             0x00    /* receive buffer       */
@@ -157,9 +154,12 @@
     ns_write_reg(uart, IER, 0);
 
     /* Line control and baud-rate generator. */
-    ns_write_reg(uart, LCR, lcr | LCR_DLAB);
-    ns_write_reg(uart, DLL, 115200/uart->baud); /* baud lo */
-    ns_write_reg(uart, DLM, 0);                 /* baud hi */
+    if ( uart->baud != 0 )
+    {
+        ns_write_reg(uart, LCR, lcr | LCR_DLAB);
+        ns_write_reg(uart, DLL, 115200/uart->baud); /* baud lo */
+        ns_write_reg(uart, DLM, 0);                 /* baud hi */
+    }
     ns_write_reg(uart, LCR, lcr);               /* parity, data, stop */
 
     /* No flow ctrl: DTR and RTS are both wedged high to keep remote happy. */
@@ -177,6 +177,9 @@
 {
     struct ns16550 *uart = port->uart;
     int rc;
+
+    if ( uart->irq <= 0 )
+        return;
 
     serial_async_transmit(port);
 
@@ -213,6 +216,24 @@
     .getc         = ns16550_getc
 };
 
+static int parse_parity_char(int c)
+{
+    switch ( c )
+    {
+    case 'n':
+        return PARITY_NONE;
+    case 'o': 
+        return PARITY_ODD;
+    case 'e': 
+        return PARITY_EVEN;
+    case 'm': 
+        return PARITY_MARK;
+    case 's': 
+        return PARITY_SPACE;
+    }
+    return 0;
+}
+
 #define PARSE_ERR(_f, _a...)                 \
     do {                                     \
         printk( "ERROR: " _f "\n" , ## _a ); \
@@ -221,49 +242,24 @@
 
 static void ns16550_parse_port_config(struct ns16550 *uart, char *conf)
 {
-    if ( *conf == '\0' )
-        return;
-
-    uart->baud = simple_strtol(conf, &conf, 10);
-    if ( (uart->baud < 1200) || (uart->baud > 115200) )
-        PARSE_ERR("Baud rate %d outside supported range.", uart->baud);
+    int baud;
+
+    if ( (conf == NULL) || (*conf == '\0') )
+        goto config_parsed;
+
+    if ( (baud = simple_strtol(conf, &conf, 10)) != 0 )
+        uart->baud = baud;
 
     if ( *conf != ',' )
-        PARSE_ERR("Missing data/parity/stop specifiers.");
-
+        goto config_parsed;
     conf++;
 
     uart->data_bits = simple_strtol(conf, &conf, 10);
-    if ( (uart->data_bits < 5) || (uart->data_bits > 8) )
-        PARSE_ERR("%d data bits are unsupported.", uart->data_bits);
-
-    switch ( *conf )
-    {
-    case 'n':
-        uart->parity = PARITY_NONE;
-        break;
-    case 'o': 
-        uart->parity =  PARITY_ODD;
-        break;
-    case 'e': 
-        uart->parity =  PARITY_EVEN;
-        break;
-    case 'm': 
-        uart->parity =  PARITY_MARK;
-        break;
-    case 's': 
-        uart->parity =  PARITY_SPACE;
-        break;
-
-    default:
-        PARSE_ERR("Invalid parity specifier '%c'.", *conf);
-    }
-
+
+    uart->parity = parse_parity_char(*conf);
     conf++;
 
     uart->stop_bits = simple_strtol(conf, &conf, 10);
-    if ( (uart->stop_bits < 1) || (uart->stop_bits > 2) )
-        PARSE_ERR("%d stop bits are unsupported.", uart->stop_bits);
 
     if ( *conf == ',' )
     {
@@ -277,13 +273,39 @@
         }
     }
 
+ config_parsed:
+    /* Sanity checks. */
+    if ( (uart->baud != 0) && ((uart->baud < 1200) || (uart->baud > 115200)) )
+        PARSE_ERR("Baud rate %d outside supported range.", uart->baud);
+    if ( (uart->data_bits < 5) || (uart->data_bits > 8) )
+        PARSE_ERR("%d data bits are unsupported.", uart->data_bits);
+    if ( (uart->stop_bits < 1) || (uart->stop_bits > 2) )
+        PARSE_ERR("%d stop bits are unsupported.", uart->stop_bits);
+    if ( uart->io_base == 0 )
+        PARSE_ERR("I/O base address must be specified.");
+
+    /* Register with generic serial driver. */
     serial_register_uart(uart - ns16550_com, &ns16550_driver, uart);
 }
 
-void ns16550_init(void)
-{
-    ns16550_parse_port_config(&ns16550_com[0], opt_com1);
-    ns16550_parse_port_config(&ns16550_com[1], opt_com2);
+void ns16550_init(int index, struct ns16550_defaults *defaults)
+{
+    struct ns16550 *uart = &ns16550_com[index];
+
+    if ( (index < 0) || (index > 1) )
+        return;
+
+    if ( defaults != NULL )
+    {
+        uart->baud      = defaults->baud;
+        uart->data_bits = defaults->data_bits;
+        uart->parity    = parse_parity_char(defaults->parity);
+        uart->stop_bits = defaults->stop_bits;
+        uart->irq       = defaults->irq;
+        uart->io_base   = defaults->io_base;
+    }
+
+    ns16550_parse_port_config(uart, (index == 0) ? opt_com1 : opt_com2);
 }
 
 /*
diff -r 9b77ba29108d -r 64f26eed8d47 xen/arch/ia64/pcdp.c
--- a/xen/arch/ia64/pcdp.c      Thu Jul 14 08:00:55 2005
+++ b/xen/arch/ia64/pcdp.c      Thu Jul 14 09:05:22 2005
@@ -24,11 +24,11 @@
 setup_serial_console(struct pcdp_uart *uart)
 {
 #ifdef XEN
-       extern char opt_com1[1];
-       if (opt_com1[0]) return 0;
-       sprintf(&opt_com1[0], "%lu,%dn1,0x%lx,9",
-               uart->baud, uart->bits ? uart->bits : 8,
-               uart->addr.address);
+       extern struct ns16550_defaults ns16550_com1;
+       ns16550_com1.baud = uart->baud;
+       ns16550_com1.io_base = uart->addr.address;
+       if (uart->bits)
+               ns16550_com1.data_bits = uart->bits;
        return 0;
 #else
 #ifdef CONFIG_SERIAL_8250_CONSOLE
diff -r 9b77ba29108d -r 64f26eed8d47 xen/arch/ia64/xensetup.c
--- a/xen/arch/ia64/xensetup.c  Thu Jul 14 08:00:55 2005
+++ b/xen/arch/ia64/xensetup.c  Thu Jul 14 09:05:22 2005
@@ -131,6 +131,12 @@
     return;
 }
 
+struct ns16550_defaults ns16550_com1 = {
+    .data_bits = 8,
+    .parity    = 'n',
+    .stop_bits = 1
+};
+
 void start_kernel(void)
 {
     unsigned char *cmdline;
@@ -153,7 +159,7 @@
 
     /* We initialise the serial devices very early so we can get debugging. */
     if (running_on_sim) hpsim_serial_init();
-    else ns16550_init();
+    else ns16550_init(0, &ns16550_com1);
     serial_init_preirq();
 
     init_console();

_______________________________________________
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®.