Messages in this thread Patch in this message | | | From | Steven Cole <> | Subject | Re: Someting's busted with serial in 2.6.11 latest | Date | Thu, 10 Mar 2005 16:45:19 -0700 |
| |
On Thursday 10 March 2005 03:59 pm, Russell King wrote: > On Thu, Mar 10, 2005 at 03:40:11PM -0700, Steven Cole wrote: > > I'll test current bk tonight, but I don't see any recent fix to > > drivers/serial/8250.c when browsing linux.bkbits.net/linux-2.6. > > Ok, so Stephen's bug is already fixed. After testing the latest bk, if > you find your bug isn't resolved, please try to isolate the change by > applying this patch. If this doesn't resolve it, then your change of > behaviour hasn't been caused by changes to 8250.c, but must be down to > some other part of the kernel. > > ===== linux-2.6-rmk/drivers/serial/8250.c 1.97 vs 1.95 ===== > --- 1.97/drivers/serial/8250.c 2005-03-08 10:04:55 +00:00 > +++ 1.95/drivers/serial/8250.c 2005-02-28 16:05:18 +00:00 > @@ -642,7 +642,6 @@ > static void autoconfig_16550a(struct uart_8250_port *up) > { > unsigned char status1, status2; > - unsigned int iersave; > > up->port.type = PORT_16550A; > up->capabilities |= UART_CAP_FIFO; > @@ -729,7 +728,6 @@ > serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); > status2 = serial_in(up, UART_IIR) >> 5; > serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); > - serial_outp(up, UART_LCR, 0); > > DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2); > > @@ -738,40 +736,6 @@ > up->capabilities |= UART_CAP_AFE | UART_CAP_SLEEP; > return; > } > - > - /* > - * Try writing and reading the UART_IER_UUE bit (b6). > - * If it works, this is probably one of the Xscale platform's > - * internal UARTs. > - * We're going to explicitly set the UUE bit to 0 before > - * trying to write and read a 1 just to make sure it's not > - * already a 1 and maybe locked there before we even start start. > - */ > - iersave = serial_in(up, UART_IER); > - serial_outp(up, UART_IER, iersave & ~UART_IER_UUE); > - if (!(serial_in(up, UART_IER) & UART_IER_UUE)) { > - /* > - * OK it's in a known zero state, try writing and reading > - * without disturbing the current state of the other bits. > - */ > - serial_outp(up, UART_IER, iersave | UART_IER_UUE); > - if (serial_in(up, UART_IER) & UART_IER_UUE) { > - /* > - * It's an Xscale. > - * We'll leave the UART_IER_UUE bit set to 1 (enabled). > - */ > - DEBUG_AUTOCONF("Xscale "); > - up->port.type = PORT_XSCALE; > - return; > - } > - } else { > - /* > - * If we got here we couldn't force the IER_UUE bit to 0. > - * Log it and continue. > - */ > - DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 "); > - } > - serial_outp(up, UART_IER, iersave); > } > > /* > > I am currently doing a bk pull from linux.bkbits.net/linux-2.6, and can test the above patch if dialup via a serial modem breaks again, but I think I already know the answer.
I first noticed this _after_ the last one-line change to drivers/serial/8250.c. Last night, after establishing that 2.6.11-bk1 was the earliest kernel to have the problem, and reverting the Xscale patch fixed it, I tried with last night's bk-current. It also failed as previously described, and worked with the Xscale patch reverted.
Here is a snippet from dmesg from my current kernel (with Xscale reverted) working on dialup.via serial modem.
[ 43.034336] serio: i8042 AUX port at 0x60,0x64 irq 12 [ 43.034520] serio: i8042 KBD port at 0x60,0x64 irq 1 [ 43.034616] Serial: 8250/16550 driver $Revision: 1.90 $ 8 ports, IRQ sharing disabled [ 43.034924] ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A [ 43.038087] pnp: Device 00:01.00 activated. [ 43.038329] ttyS1 at I/O 0x2f8 (irq = 10) is a 16550A
For completeness, here is the patch I applied with patch -p1 -R:
Steven diff -Nru a/drivers/serial/8250.c b/drivers/serial/8250.c --- a/drivers/serial/8250.c 2005-02-28 08:05:18 -08:00 +++ b/drivers/serial/8250.c 2005-01-24 08:00:57 -08:00 @@ -642,6 +642,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) { unsigned char status1, status2; + unsigned int iersave; up->port.type = PORT_16550A; up->capabilities |= UART_CAP_FIFO; @@ -736,6 +737,40 @@ up->capabilities |= UART_CAP_AFE | UART_CAP_SLEEP; return; } + + /* + * Try writing and reading the UART_IER_UUE bit (b6). + * If it works, this is probably one of the Xscale platform's + * internal UARTs. + * We're going to explicitly set the UUE bit to 0 before + * trying to write and read a 1 just to make sure it's not + * already a 1 and maybe locked there before we even start start. + */ + iersave = serial_in(up, UART_IER); + serial_outp(up, UART_IER, iersave & ~UART_IER_UUE); + if (!(serial_in(up, UART_IER) & UART_IER_UUE)) { + /* + * OK it's in a known zero state, try writing and reading + * without disturbing the current state of the other bits. + */ + serial_outp(up, UART_IER, iersave | UART_IER_UUE); + if (serial_in(up, UART_IER) & UART_IER_UUE) { + /* + * It's an Xscale. + * We'll leave the UART_IER_UUE bit set to 1 (enabled). + */ + DEBUG_AUTOCONF("Xscale "); + up->port.type = PORT_XSCALE; + return; + } + } else { + /* + * If we got here we couldn't force the IER_UUE bit to 0. + * Log it and continue. + */ + DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 "); + } + serial_outp(up, UART_IER, iersave); } /* | |