[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 2/7] serial: Fix COM1 assumption if pci_uart_config did not find the PCI serial card.
On Mon, Mar 10, 2014 at 09:35:16AM +0000, Jan Beulich wrote: > >>> On 07.03.14 at 20:01, Konrad Rzeszutek Wilk <konrad@xxxxxxxxxx> wrote: > > The io_base by default is set to be 0x3f8 for COM1 and 0x2f8 for COM2 > > in __setup_xen. Then we call 'ns16550_init' which copies those in > > the appropiate uart, which then calls 'ns16550_parse_port_config' > > to deal with parameter parsing. If the 'pci' or 'amt' parameter > > has been specified we further call 'pci_uart_config code' which > > scans the PCI bus. If it does not find any relevant devices > > it will overwrite io_base with 0x3f8 regardless whether this is > > COM1 or COM2. The overwrite is a way to set it back to the > > failsafe defaults - except for COM2 of course. > > > > This in theory (as I don't have a machine with two COM ports > > readily available) means that if the user specified 'com2=9600,8n1,pci' > > and the device did not have an PCI serial card, instead of using 0x2f8 > > for the io_base it ends up using 0x3f8 - and we don't get the > > output on COM2. > > > > Fix it by saving the original io_base before starting the > > scan of the PCI bus. If we don't find an serial PCI device then > > assign the original io_base value back. > > While reviewing patch 1 I was specifically thinking of why you didn't > do this at once. But then I realized that this is done only in the AMT > case, and was assuming that you, when originally adding AMT > support, specifically did it that way knowing that if anything it could > only sit on port 0x3f8. If that wasn't the original intention, the > change is fine, but the description should be updated to say that > this only affects the AMT case. > > > --- a/xen/drivers/char/ns16550.c > > +++ b/xen/drivers/char/ns16550.c > > @@ -612,10 +612,11 @@ static int __init > > pci_uart_config (struct ns16550 *uart, int skip_amt, int bar_idx) > > { > > uint32_t bar, bar_64 = 0, len, len_64; > > - u64 size, mask; > > + u64 size, mask, orig_base; > > unsigned int b, d, f, nextf, i; > > u16 vendor, device; > > > > + orig_base = uart->io_base; > > uart->io_base = 0; > > /* NB. Start at bus 1 to avoid AMT: a plug-in card cannot be on bus 0. > > */ > > for ( b = skip_amt ? 1 : 0; b < 0x100; b++ ) > > @@ -747,7 +748,8 @@ pci_uart_config (struct ns16550 *uart, int skip_amt, > > int bar_idx) > > if ( !skip_amt ) > > return -1; > > > > - uart->io_base = 0x3f8; > > + if ( !uart->io_base ) > > + uart->io_base = orig_base; > > I don't think io_base can be zero when getting here. And even if it > could, what would be there would be bogus/wrong. Hence I think > you will want to unconditionally restore the original value. It can (with the "serial: Skip over PCIe device which have no quirks (fix AMT regression)." patch. If an user specified 'com1=115200,8n1,amt' on a machine without AMT but with the old-fashioned COM1, this would still work. The scan of the PCI bus would naturally fail, so the io_base would be zero (as we just had set it to zero at the start of the loop). But as you mentioned - if we are done with the loop and hadn't found anything - we might as well uncondionally set it to the original value. I was being a bit conservative here. > > > uart->irq = 0; > > I further wonder whether that's not really suffering from the same > issue: Shouldn't you save/restore this too? Or rather, looking at the > flow, simply delete the line, leaving the old value in place? Yes. <nods> Let me do it per you suggestion and just do this: From 5519bf9cfcaf6ec99af146825ae53f7f53deb37c Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> Date: Fri, 7 Mar 2014 10:45:04 -0500 Subject: [PATCH] serial: Fix COM1 assumption if pci_uart_config did not find the PCI serial card. The io_base by default is set to be 0x3f8 for COM1 and 0x2f8 for COM2 in __setup_xen. Then we call 'ns16550_init' which copies those in the appropiate uart, which then calls 'ns16550_parse_port_config' to deal with parameter parsing. If the 'pci' or 'amt' parameter has been specified we further call 'pci_uart_config code' which scans the PCI bus. If it does not find any relevant devices it will overwrite io_base with 0x3f8 regardless whether this is COM1 or COM2. The overwrite is a way to set it back to the failsafe defaults - except for COM2 of course. This in theory (as I don't have a machine with two COM ports readily available) means that if the user specified 'com2=9600,8n1,pci' and the device did not have an PCI serial card, instead of using 0x2f8 for the io_base it ends up using 0x3f8 - and we don't get the output on COM2. Fix it by saving the original io_base before starting the scan of the PCI bus. If we don't find an serial PCI device then assign the original io_base value back. Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> [v1: Also remove the irq overwrite] --- xen/drivers/char/ns16550.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c index 2fded08..b440e01 100644 --- a/xen/drivers/char/ns16550.c +++ b/xen/drivers/char/ns16550.c @@ -612,10 +612,11 @@ static int __init pci_uart_config (struct ns16550 *uart, int skip_amt, int bar_idx) { uint32_t bar, bar_64 = 0, len, len_64; - u64 size, mask; + u64 size, mask, orig_base; unsigned int b, d, f, nextf, i; u16 vendor, device; + orig_base = uart->io_base; uart->io_base = 0; /* NB. Start at bus 1 to avoid AMT: a plug-in card cannot be on bus 0. */ for ( b = skip_amt ? 1 : 0; b < 0x100; b++ ) @@ -747,8 +748,8 @@ pci_uart_config (struct ns16550 *uart, int skip_amt, int bar_idx) if ( !skip_amt ) return -1; - uart->io_base = 0x3f8; - uart->irq = 0; + /* No PCI or PCIe found, fallback to the defaults. */ + uart->io_base = orig_base; uart->clock_hz = UART_CLOCK_HZ; return 0; -- 1.7.7.6 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |