+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
#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>
if (port->configured)
return;
+ port->broken = 0;
+
divisor = serial_get_divisor (port->config.speed);
/* Turn off the interrupt. */
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);
}