]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
* grub-core/term/ns8250.c (do_real_config): Set port->broken to 0.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 16 Oct 2010 15:29:12 +0000 (17:29 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 16 Oct 2010 15:29:12 +0000 (17:29 +0200)
(serial_hw_put): Wait based on real time rather than port reads. Don't
roken ports.
* include/grub/serial.h (grub_serial_port): New field broken.

ChangeLog
grub-core/term/ns8250.c
include/grub/serial.h

index 4b2a7a7051320d71bd3d17c9932ed9a2e11e2885..3f9c5a8cdbb1c6f17330a2577b79fafaaad23a10 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2010-10-16  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       * grub-core/term/ns8250.c (do_real_config): Set port->broken to 0.
+       (serial_hw_put): Wait based on real time rather than port reads. Don't
+       roken ports.
+       * include/grub/serial.h (grub_serial_port): New field broken.
+
 2010-10-16  Robert Millan  <rmh@gnu.org>
 
        * grub-core/kern/emu/misc.c
index 550ee6341a062c056ca8b5297385dcefa9c385ed..4be528df8c5a1767eb6176b0b02ca9eea20a7397 100644 (file)
@@ -23,6 +23,7 @@
 #include <grub/misc.h>
 #include <grub/cpu/io.h>
 #include <grub/mm.h>
+#include <grub/time.h>
 
 #ifdef GRUB_MACHINE_PCBIOS
 #include <grub/machine/memory.h>
@@ -90,6 +91,8 @@ do_real_config (struct grub_serial_port *port)
   if (port->configured)
     return;
 
+  port->broken = 0;
+
   divisor = serial_get_divisor (port->config.speed);
 
   /* Turn off the interrupt.  */
@@ -145,18 +148,30 @@ serial_hw_fetch (struct grub_serial_port *port)
 static void
 serial_hw_put (struct grub_serial_port *port, const int c)
 {
-  unsigned int timeout = 100000;
+  grub_uint64_t endtime;
 
   do_real_config (port);
 
+  if (port->broken > 5)
+    endtime = grub_get_time_ms ();
+  else if (port->broken > 1)
+    endtime = grub_get_time_ms () + 50;
+  else
+    endtime = grub_get_time_ms () + 200;
   /* Wait until the transmitter holding register is empty.  */
   while ((grub_inb (port->port + UART_LSR) & UART_EMPTY_TRANSMITTER) == 0)
     {
-      if (--timeout == 0)
-        /* There is something wrong. But what can I do?  */
-        return;
+      if (grub_get_time_ms () > endtime)
+       {
+         port->broken++;
+         /* There is something wrong. But what can I do?  */
+         return;
+       }
     }
 
+  if (port->broken)
+    port->broken--;
+
   grub_outb (c, port->port + UART_TX);
 }
 
index 652268b2e5f0d03622da7609f8ad100dd836ab29..9540bee64e1a23059eb3994ce42a101252db5152 100644 (file)
@@ -72,7 +72,11 @@ struct grub_serial_port
    */
   union
   {
-    grub_port_t port;
+    struct
+    {
+      grub_port_t port;
+      int broken;
+    };
     struct
     {
       grub_usb_device_t usbdev;