From: Tomasz Wroblewski <tomasz.wroblewski@citrix.com>
To: xen-devel@lists.xensource.com
Subject: [PATCH] PCI uart: fix boot hang, and second S3 resume inactive timer list corruption
Date: Mon, 26 Aug 2013 11:17:24 +0200 [thread overview]
Message-ID: <521B1D24.1060903@citrix.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 1 bytes --]
[-- Attachment #2: pci-uart-fixes --]
[-- Type: text/plain, Size: 3485 bytes --]
Couple PCI uart resume/boot fixes
- fix occasional xen boot hang whilst using PCI uart. Dom0 kernel disables ioport responses
during PCI system initialisation, causing xen hang if __ns16550_poll() routine happens to
be scheduled during that time. Detect and exit. Amended ns16550_ioport_invalid function
to only check IER register, which contains three reservered (always 0) bits, therefore
it's sufficient for this test.
- fix second s3 resume failures due to inactive timer list corruption. init_timer cannot be safely
called multiple times on same timer since it does memset(0) on the structure, erasing the
auxiliary member used by linked list code, breaking the inactive timer list in common/timer.c.
Moved resume_timer initialisation to ns16550_init_postirq, so it's only done once.
Signed-off-by: Tomasz Wroblewski <tomasz.wroblewski@citrix.com>
diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
index 6082c85..3ef096e 100644
--- a/xen/drivers/char/ns16550.c
+++ b/xen/drivers/char/ns16550.c
@@ -59,6 +59,8 @@ static struct ns16550 {
u8 bar_idx;
} ns16550_com[2] = { { 0 } };
+static void ns16550_delayed_resume(void *data);
+
static char ns_read_reg(struct ns16550 *uart, int reg)
{
if ( uart->remapped_io_base == NULL )
@@ -73,6 +75,11 @@ static void ns_write_reg(struct ns16550 *uart, int reg, char c)
writeb(c, uart->remapped_io_base + reg);
}
+static int ns16550_ioport_invalid(struct ns16550 *uart)
+{
+ return (((unsigned char)ns_read_reg(uart, UART_IER)) == 0xff);
+}
+
static void ns16550_interrupt(
int irq, void *dev_id, struct cpu_user_regs *regs)
{
@@ -103,11 +110,16 @@ static void __ns16550_poll(struct cpu_user_regs *regs)
return; /* Interrupts work - no more polling */
while ( ns_read_reg(uart, UART_LSR) & UART_LSR_DR )
+ {
serial_rx_interrupt(port, regs);
+ if ( ns16550_ioport_invalid(uart) )
+ goto out;
+ }
if ( ns_read_reg(uart, UART_LSR) & UART_LSR_THRE )
serial_tx_interrupt(port, regs);
+out:
set_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
}
@@ -256,6 +268,7 @@ static void __init ns16550_init_postirq(struct serial_port *port)
serial_async_transmit(port);
init_timer(&uart->timer, ns16550_poll, port, 0);
+ init_timer(&uart->resume_timer, ns16550_delayed_resume, port, 0);
/* Calculate time to fill RX FIFO and/or empty TX FIFO for polling. */
bits = uart->data_bits + uart->stop_bits + !!uart->parity;
@@ -305,15 +318,6 @@ static void _ns16550_resume(struct serial_port *port)
ns16550_setup_postirq(port->uart);
}
-static int ns16550_ioport_invalid(struct ns16550 *uart)
-{
- return ((((unsigned char)ns_read_reg(uart, UART_LSR)) == 0xff) &&
- (((unsigned char)ns_read_reg(uart, UART_MCR)) == 0xff) &&
- (((unsigned char)ns_read_reg(uart, UART_IER)) == 0xff) &&
- (((unsigned char)ns_read_reg(uart, UART_IIR)) == 0xff) &&
- (((unsigned char)ns_read_reg(uart, UART_LCR)) == 0xff));
-}
-
static int delayed_resume_tries;
static void ns16550_delayed_resume(void *data)
{
@@ -346,7 +350,6 @@ static void ns16550_resume(struct serial_port *port)
if ( ns16550_ioport_invalid(uart) )
{
delayed_resume_tries = RESUME_RETRIES;
- init_timer(&uart->resume_timer, ns16550_delayed_resume, port, 0);
set_timer(&uart->resume_timer, NOW() + RESUME_DELAY);
}
else
[-- Attachment #3: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
next reply other threads:[~2013-08-26 9:17 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-08-26 9:17 Tomasz Wroblewski [this message]
2013-08-26 11:17 ` [PATCH] PCI uart: fix boot hang, and second S3 resume inactive timer list corruption Jan Beulich
2013-08-26 11:39 ` Tomasz Wroblewski
2013-08-26 12:54 ` Jan Beulich
2013-08-26 13:25 ` Tomasz Wroblewski
2013-08-26 13:52 ` Jan Beulich
2013-08-26 15:09 ` Tomasz Wroblewski
2013-08-26 15:26 ` Jan Beulich
2013-08-26 16:12 ` Tomasz Wroblewski
2013-08-27 6:55 ` Jan Beulich
2013-08-27 8:52 ` Tomasz Wroblewski
2013-08-27 9:01 ` Jan Beulich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=521B1D24.1060903@citrix.com \
--to=tomasz.wroblewski@citrix.com \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.