|
|
f96e0b |
From 38f3f1c0902e344a92a7a8994cd25c13b544b7e9 Mon Sep 17 00:00:00 2001
|
|
|
f96e0b |
From: Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>
|
|
|
f96e0b |
Date: Sat, 27 Apr 2013 22:47:57 +0200
|
|
|
f96e0b |
Subject: [PATCH 368/482] * grub-core/term/ns8250.c: Systematically
|
|
|
f96e0b |
probe ports by writing to SR before using them.
|
|
|
f96e0b |
|
|
|
f96e0b |
---
|
|
|
f96e0b |
ChangeLog | 5 +++++
|
|
|
f96e0b |
grub-core/term/ns8250.c | 46 +++++++++++++++++++++++++++++++++++++++++++---
|
|
|
f96e0b |
2 files changed, 48 insertions(+), 3 deletions(-)
|
|
|
f96e0b |
|
|
|
f96e0b |
diff --git a/ChangeLog b/ChangeLog
|
|
|
f96e0b |
index 83cdafc..43b2906 100644
|
|
|
f96e0b |
--- a/ChangeLog
|
|
|
f96e0b |
+++ b/ChangeLog
|
|
|
f96e0b |
@@ -1,3 +1,8 @@
|
|
|
f96e0b |
+2013-04-27 Vladimir Serbinenko <phcoder@gmail.com>
|
|
|
f96e0b |
+
|
|
|
f96e0b |
+ * grub-core/term/ns8250.c: Systematically probe ports by writing
|
|
|
f96e0b |
+ to SR before using them.
|
|
|
f96e0b |
+
|
|
|
f96e0b |
2013-04-27 Paulo Flabiano Smorigo <pfsmorigo@br.ibm.com>
|
|
|
f96e0b |
|
|
|
f96e0b |
* util/ieee1275/ofpath.c (of_path_of_scsi): Fix path output for sas
|
|
|
f96e0b |
diff --git a/grub-core/term/ns8250.c b/grub-core/term/ns8250.c
|
|
|
f96e0b |
index e6947f5..2064e0d 100644
|
|
|
f96e0b |
--- a/grub-core/term/ns8250.c
|
|
|
f96e0b |
+++ b/grub-core/term/ns8250.c
|
|
|
f96e0b |
@@ -36,6 +36,8 @@ static const grub_port_t serial_hw_io_addr[] = GRUB_MACHINE_SERIAL_PORTS;
|
|
|
f96e0b |
#define GRUB_SERIAL_PORT_NUM (ARRAY_SIZE(serial_hw_io_addr))
|
|
|
f96e0b |
#endif
|
|
|
f96e0b |
|
|
|
f96e0b |
+static int dead_ports = 0;
|
|
|
f96e0b |
+
|
|
|
f96e0b |
/* Convert speed to divisor. */
|
|
|
f96e0b |
static unsigned short
|
|
|
f96e0b |
serial_get_divisor (const struct grub_serial_port *port __attribute__ ((unused)),
|
|
|
f96e0b |
@@ -83,6 +85,8 @@ do_real_config (struct grub_serial_port *port)
|
|
|
f96e0b |
{
|
|
|
f96e0b |
int divisor;
|
|
|
f96e0b |
unsigned char status = 0;
|
|
|
f96e0b |
+ grub_uint64_t endtime;
|
|
|
f96e0b |
+
|
|
|
f96e0b |
const unsigned char parities[] = {
|
|
|
f96e0b |
[GRUB_SERIAL_PARITY_NONE] = UART_NO_PARITY,
|
|
|
f96e0b |
[GRUB_SERIAL_PARITY_ODD] = UART_ODD_PARITY,
|
|
|
f96e0b |
@@ -132,8 +136,16 @@ do_real_config (struct grub_serial_port *port)
|
|
|
f96e0b |
#endif
|
|
|
f96e0b |
|
|
|
f96e0b |
/* Drain the input buffer. */
|
|
|
f96e0b |
+ endtime = grub_get_time_ms () + 1000;
|
|
|
f96e0b |
while (grub_inb (port->port + UART_LSR) & UART_DATA_READY)
|
|
|
f96e0b |
- grub_inb (port->port + UART_RX);
|
|
|
f96e0b |
+ {
|
|
|
f96e0b |
+ grub_inb (port->port + UART_RX);
|
|
|
f96e0b |
+ if (grub_get_time_ms () > endtime)
|
|
|
f96e0b |
+ {
|
|
|
f96e0b |
+ port->broken = 1;
|
|
|
f96e0b |
+ break;
|
|
|
f96e0b |
+ }
|
|
|
f96e0b |
+ }
|
|
|
f96e0b |
|
|
|
f96e0b |
port->configured = 1;
|
|
|
f96e0b |
}
|
|
|
f96e0b |
@@ -239,6 +251,20 @@ grub_ns8250_init (void)
|
|
|
f96e0b |
if (serial_hw_io_addr[i])
|
|
|
f96e0b |
{
|
|
|
f96e0b |
grub_err_t err;
|
|
|
f96e0b |
+
|
|
|
f96e0b |
+ grub_outb (0x5a, serial_hw_io_addr[i] + UART_SR);
|
|
|
f96e0b |
+ if (grub_inb (serial_hw_io_addr[i] + UART_SR) != 0x5a)
|
|
|
f96e0b |
+ {
|
|
|
f96e0b |
+ dead_ports |= (1 << i);
|
|
|
f96e0b |
+ continue;
|
|
|
f96e0b |
+ }
|
|
|
f96e0b |
+ grub_outb (0xa5, serial_hw_io_addr[i] + UART_SR);
|
|
|
f96e0b |
+ if (grub_inb (serial_hw_io_addr[i] + UART_SR) != 0xa5)
|
|
|
f96e0b |
+ {
|
|
|
f96e0b |
+ dead_ports |= (1 << i);
|
|
|
f96e0b |
+ continue;
|
|
|
f96e0b |
+ }
|
|
|
f96e0b |
+
|
|
|
f96e0b |
grub_snprintf (com_names[i], sizeof (com_names[i]), "com%d", i);
|
|
|
f96e0b |
com_ports[i].name = com_names[i];
|
|
|
f96e0b |
com_ports[i].driver = &grub_ns8250_driver;
|
|
|
f96e0b |
@@ -255,7 +281,8 @@ grub_ns8250_init (void)
|
|
|
f96e0b |
grub_port_t
|
|
|
f96e0b |
grub_ns8250_hw_get_port (const unsigned int unit)
|
|
|
f96e0b |
{
|
|
|
f96e0b |
- if (unit < GRUB_SERIAL_PORT_NUM)
|
|
|
f96e0b |
+ if (unit < GRUB_SERIAL_PORT_NUM
|
|
|
f96e0b |
+ && !(dead_ports & (1 << unit)))
|
|
|
f96e0b |
return serial_hw_io_addr[unit];
|
|
|
f96e0b |
else
|
|
|
f96e0b |
return 0;
|
|
|
f96e0b |
@@ -268,7 +295,20 @@ grub_serial_ns8250_add_port (grub_port_t port)
|
|
|
f96e0b |
unsigned i;
|
|
|
f96e0b |
for (i = 0; i < GRUB_SERIAL_PORT_NUM; i++)
|
|
|
f96e0b |
if (com_ports[i].port == port)
|
|
|
f96e0b |
- return com_names[i];
|
|
|
f96e0b |
+ {
|
|
|
f96e0b |
+ if (dead_ports & (1 << i))
|
|
|
f96e0b |
+ return NULL;
|
|
|
f96e0b |
+ return com_names[i];
|
|
|
f96e0b |
+ }
|
|
|
f96e0b |
+
|
|
|
f96e0b |
+ grub_outb (0x5a, port + UART_SR);
|
|
|
f96e0b |
+ if (grub_inb (port + UART_SR) != 0x5a)
|
|
|
f96e0b |
+ return NULL;
|
|
|
f96e0b |
+
|
|
|
f96e0b |
+ grub_outb (0xa5, port + UART_SR);
|
|
|
f96e0b |
+ if (grub_inb (port + UART_SR) != 0xa5)
|
|
|
f96e0b |
+ return NULL;
|
|
|
f96e0b |
+
|
|
|
f96e0b |
p = grub_malloc (sizeof (*p));
|
|
|
f96e0b |
if (!p)
|
|
|
f96e0b |
return NULL;
|
|
|
f96e0b |
--
|
|
|
f96e0b |
1.8.2.1
|
|
|
f96e0b |
|