All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] PCI serial card support
@ 2008-11-04  0:38 donald.d.dugger
  2008-11-04 15:39 ` Robert Millan
  2009-07-21  8:11 ` tony.gugo
  0 siblings, 2 replies; 29+ messages in thread
From: donald.d.dugger @ 2008-11-04  0:38 UTC (permalink / raw)
  To: grub-devel

The problem with using a PCI serial card for the console is that many
PCI cards use a different crystal than the IBM PC standard.  This means
that serial drivers wind up computing the wrong divisor when trying to
set the baud rate.  This patch solves this problem by adding the `--base'
parameter to the `serial' command.  The allows you to set the base baud
(typically the highest baud rate supported by the device) so that PCI
cards with non-standard crystal frequencies can be supported.  For example,
the option I use with my PCI serial card is:

	serial --port=0xe880 --speed=115200 --base=921600

Signed-off-by: Don Dugger <donald.d.dugger@intel.com>

diffstat /isis/homeb/intel/patch.d/pci_serial-grub-1103.patch 
 ChangeLog                     |    8 +++++
 include/grub/i386/pc/serial.h |    3 ++
 term/i386/pc/serial.c         |   60 ++++++++++++++++--------------------------
 3 files changed, 35 insertions(+), 36 deletions(-)

----- cut here for pci_serial-grub-1103.patch -----
Index: include/grub/i386/pc/serial.h
===================================================================
--- include/grub/i386/pc/serial.h	(revision 1892)
+++ include/grub/i386/pc/serial.h	(working copy)
@@ -40,6 +40,9 @@
 #define UART_DATA_READY		0x01
 #define UART_EMPTY_TRANSMITTER	0x20
 
+/* Default base baud */
+#define UART_BASE_BAUD		115200
+
 /* The type of parity.  */
 #define UART_NO_PARITY		0x00
 #define UART_ODD_PARITY		0x08
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 1892)
+++ ChangeLog	(working copy)
@@ -1,3 +1,11 @@
+2008-11-03  Don Dugger <donald.d.dugger@intel.com>
+
+	* term/i386/pc/serial.c: add `--base' parameter to serial command,
+	allows user to specify base baud for those UARTs that don't follow
+	the PC standard.
+	* include/grub/i386/pc/serial.h: define default base baud value
+	of 115200 (default for PCs).
+
 2008-11-03  Bean  <bean123ch@gmail.com>
 
 	* kern/elf.c (grub_elf32_load): Revert to previous code.
Index: term/i386/pc/serial.c
===================================================================
--- term/i386/pc/serial.c	(revision 1892)
+++ term/i386/pc/serial.c	(working copy)
@@ -48,6 +48,7 @@
   {"word",   'w', 0, "Set the serial port word length", 0, ARG_TYPE_INT},
   {"parity", 'r', 0, "Set the serial port parity",      0, ARG_TYPE_STRING},
   {"stop",   't', 0, "Set the serial port stop bits",   0, ARG_TYPE_INT},
+  {"base",   'b', 0, "Set the serial port base baud",   0, ARG_TYPE_INT},
   {0, 0, 0, 0, 0, 0}
 };
 
@@ -55,7 +56,8 @@
 struct serial_port
 {
   unsigned short port;
-  unsigned short divisor;
+  unsigned int   speed;
+  unsigned int   base;
   unsigned short word_len;
   unsigned int   parity;
   unsigned short stop_bits;
@@ -210,35 +212,9 @@
 
 /* Convert speed to divisor.  */
 static unsigned short
-serial_get_divisor (unsigned int speed)
+serial_get_divisor (unsigned int speed, unsigned int base)
 {
-  unsigned int i;
-
-  /* The structure for speed vs. divisor.  */
-  struct divisor
-  {
-    unsigned int speed;
-    unsigned short div;
-  };
-
-  /* The table which lists common configurations.  */
-  /* 1843200 / (speed * 16)  */
-  static struct divisor divisor_tab[] =
-    {
-      { 2400,   0x0030 },
-      { 4800,   0x0018 },
-      { 9600,   0x000C },
-      { 19200,  0x0006 },
-      { 38400,  0x0003 },
-      { 57600,  0x0002 },
-      { 115200, 0x0001 }
-    };
-
-  /* Set the baud rate.  */
-  for (i = 0; i < sizeof (divisor_tab) / sizeof (divisor_tab[0]); i++)
-    if (divisor_tab[i].speed == speed)
-      return divisor_tab[i].div;
-  return 0;
+  return ((base << 4) + (speed << 3)) / (speed << 4);
 }
 
 /* The serial version of checkkey.  */
@@ -277,6 +253,7 @@
 serial_hw_init (void)
 {
   unsigned char status = 0;
+  unsigned short divisor;
 
   /* Turn off the interrupt.  */
   grub_outb (0, serial_settings.port + UART_IER);
@@ -285,8 +262,9 @@
   grub_outb (UART_DLAB, serial_settings.port + UART_LCR);
 
   /* Set the baud rate.  */
-  grub_outb (serial_settings.divisor & 0xFF, serial_settings.port + UART_DLL);
-  grub_outb (serial_settings.divisor >> 8, serial_settings.port + UART_DLH);
+  divisor = serial_get_divisor(serial_settings.speed, serial_settings.base);
+  grub_outb (divisor & 0xFF, serial_settings.port + UART_DLL);
+  grub_outb (divisor >> 8, serial_settings.port + UART_DLH);
 
   /* Set the line status.  */
   status |= (serial_settings.parity
@@ -511,11 +489,9 @@
   
   if (state[2].set)
     {
-      unsigned long speed;
 
-      speed = grub_strtoul (state[2].arg, 0, 0);
-      serial_settings.divisor = serial_get_divisor ((unsigned int) speed);
-      if (serial_settings.divisor == 0)
+      serial_settings.speed = (unsigned int )grub_strtoul (state[2].arg, 0, 0);
+      if (serial_settings.speed == 0)
 	{
 	  serial_settings = backup_settings;
 	  return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad speed");
@@ -567,6 +543,17 @@
 	}
     }
 
+  if (state[6].set)
+    {
+
+      serial_settings.base = grub_strtoul (state[6].arg, 0, 0);
+      if (serial_settings.base == 0)
+	{
+	  serial_settings = backup_settings;
+	  return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad base baud");
+	}
+    }
+
   /* Initialize with new settings.  */
   hwiniterr = serial_hw_init ();
   
@@ -606,7 +593,8 @@
                          "serial [OPTIONS...]", "Configure serial port.", options);
   /* Set default settings.  */
   serial_settings.port      = serial_hw_get_port (0);
-  serial_settings.divisor   = serial_get_divisor (9600);
+  serial_settings.speed     = 9600;
+  serial_settings.base      = UART_BASE_BAUD;
   serial_settings.word_len  = UART_8BITS_WORD;
   serial_settings.parity    = UART_NO_PARITY;
   serial_settings.stop_bits = UART_1_STOP_BIT;



^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2009-07-21  8:11 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-11-04  0:38 [PATCH] PCI serial card support donald.d.dugger
2008-11-04 15:39 ` Robert Millan
2008-11-04 18:24   ` Dugger, Donald D
2008-11-05  9:58     ` Robert Millan
2008-11-05 15:37       ` Dugger, Donald D
2008-11-06 15:02         ` Robert Millan
2008-11-06 15:28           ` Dugger, Donald D
2008-11-06 16:06             ` Robert Millan
2008-11-06 16:30               ` Dugger, Donald D
2008-11-06 17:00                 ` Dugger, Donald D
2008-11-07 16:07                   ` n0ano
2008-11-07 16:52                     ` Vesa Jääskeläinen
2008-11-08 11:25                       ` Robert Millan
2008-11-08 12:23                         ` Vesa Jääskeläinen
2008-11-08 12:45                           ` Robert Millan
2008-11-08 14:00                             ` Vesa Jääskeläinen
2008-11-09  1:58                             ` n0ano
2008-11-09 21:57                               ` Robert Millan
2008-11-09 22:13                                 ` Vesa Jääskeläinen
2008-11-09 22:14                                 ` n0ano
2008-11-12 18:58                                 ` n0ano
2008-11-13 18:05                                   ` Vesa Jääskeläinen
2008-11-13 20:13                                     ` n0ano
2008-11-14 19:24                                     ` n0ano
2008-11-22  2:53                                       ` Neo Jia
2008-11-22  7:18                                         ` Vesa Jääskeläinen
2008-11-04 18:26   ` Vesa Jääskeläinen
2008-11-04 18:38     ` Dugger, Donald D
2009-07-21  8:11 ` tony.gugo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.