linux/drivers/tty
Maciej W. Rozycki e5227c5109 serial: 8250: Mask out floating 16/32-bit bus bits
Make sure only actual 8 bits of the IIR register are used in determining
the port type in `autoconfig'.

The `serial_in' port accessor returns the `unsigned int' type, meaning
that with UPIO_AU, UPIO_MEM16, UPIO_MEM32, and UPIO_MEM32BE access types
more than 8 bits of data are returned, of which the high order bits will
often come from bus lines that are left floating in the data phase.  For
example with the MIPS Malta board's CBUS UART, where the registers are
aligned on 8-byte boundaries and which uses 32-bit accesses, data as
follows is returned:

YAMON> dump -32 0xbf000900 0x40

BF000900: 1F000942 1F000942 1F000900 1F000900  ...B...B........
BF000910: 1F000901 1F000901 1F000900 1F000900  ................
BF000920: 1F000900 1F000900 1F000960 1F000960  ...........`...`
BF000930: 1F000900 1F000900 1F0009FF 1F0009FF  ................

YAMON>

Evidently high-order 24 bits return values previously driven in the
address phase (the 3 highest order address bits used with the command
above are masked out in the simple virtual address mapping used here and
come out at zeros on the external bus), a common scenario with bus lines
left floating, due to bus capacitance.

Consequently when the value of IIR, mapped at 0x1f000910, is retrieved
in `autoconfig', it comes out at 0x1f0009c1 and when it is right-shifted
by 6 and then assigned to 8-bit `scratch' variable, the value calculated
is 0x27, not one of 0, 1, 2, 3 expected in port type determination.

Fix the issue then, by assigning the value returned from `serial_in' to
`scratch' first, which masks out 24 high-order bits retrieved, and only
then right-shift the resulting 8-bit data quantity, producing the value
of 3 in this case, as expected.  Fix the same issue in `serial_dl_read'.

The problem first appeared with Linux 2.6.9-rc3 which predates our repo
history, but the origin could be identified with the old MIPS/Linux repo
also at: <git://git.kernel.org/pub/scm/linux/kernel/git/ralf/linux.git>
as commit e0d2356c0777 ("Merge with Linux 2.6.9-rc3."), where code in
`serial_in' was updated with this case:

+	case UPIO_MEM32:
+		return readl(up->port.membase + offset);
+

which made it produce results outside the unsigned 8-bit range for the
first time, though obviously it is system dependent what actual values
appear in the high order bits retrieved and it may well have been zeros
in the relevant positions with the system the change originally was
intended for.  It is at that point that code in `autoconf' should have
been updated accordingly, but clearly it was overlooked.

Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org # v2.6.12+
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
Link: https://lore.kernel.org/r/alpine.DEB.2.21.2106260516220.37803@angie.orcam.me.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-07-21 12:52:14 +02:00
..
hvc TTY / Serial patches for 5.14-rc1 2021-07-05 14:08:24 -07:00
ipwireless ipwireless: remove unused ipw_tty::closing 2021-06-15 14:02:43 +02:00
serdev tty: serdev: core: Fix misspelled function name __serdev_device_driver_register() 2021-05-20 17:05:34 +02:00
serial serial: 8250: Mask out floating 16/32-bit bus bits 2021-07-21 12:52:14 +02:00
vt Merge 5.13-rc4 into tty-next 2021-05-31 09:44:28 +02:00
amiserial.c tty: make tty_operations::chars_in_buffer return uint 2021-05-13 18:29:11 +02:00
ehv_bytechan.c tty: make tty_operations::write_room return uint 2021-05-13 17:03:20 +02:00
goldfish.c tty: make tty_operations::chars_in_buffer return uint 2021-05-13 18:29:11 +02:00
Kconfig This pull request contains the following changes for UML: 2021-07-09 10:19:13 -07:00
Makefile tty: remove broken r3964 line discipline 2021-05-13 16:57:15 +02:00
mips_ejtag_fdc.c tty: make tty_operations::chars_in_buffer return uint 2021-05-13 18:29:11 +02:00
moxa.c tty: make tty_operations::chars_in_buffer return uint 2021-05-13 18:29:11 +02:00
moxa.h tty: fix spelling mistake 2020-06-27 16:21:20 +02:00
mxser.c mxser: introduce mxser_16550A_or_MUST helper 2021-06-18 13:10:03 +02:00
n_gsm.c tty: n_gsm: Fix function naming and provide missing param descriptions 2021-05-20 17:06:17 +02:00
n_hdlc.c tty: n_hdlc: Fix a little doc-rot in n_hdlc_tty_read() 2021-05-20 17:06:17 +02:00
n_null.c tty: make tty_ldisc_ops a param in tty_unregister_ldisc 2021-05-13 16:57:16 +02:00
n_tty.c tty: drop tty_ldisc_ops::refcount 2021-05-13 16:57:17 +02:00
nozomi.c tty: nozomi: Fix the error handling path of 'nozomi_card_init()' 2021-05-27 15:20:02 +02:00
pty.c tty: pty: correct function name pty_resize() 2021-05-20 16:33:06 +02:00
synclink_gt.c tty: make use of tty_get_{char,frame}_size 2021-06-15 14:03:27 +02:00
sysrq.c tty/sysrq: Fix issues of code indent should use tabs 2021-04-10 10:33:00 +02:00
tty_audit.c tty: audit: move some local functions out of tty.h 2021-04-15 10:24:58 +02:00
tty_baudrate.c tty: tty_baudrate: Fix coding style issues of block comments 2021-05-13 18:29:12 +02:00
tty_buffer.c tty: tty_buffer: Fix incorrectly documented function __tty_buffer_request_room() 2021-05-20 17:06:15 +02:00
tty_io.c tty: fix kernel-doc for {start,stop}_tty 2021-05-20 16:59:14 +02:00
tty_ioctl.c tty: make tty_get_{char,frame}_size available 2021-06-15 14:03:26 +02:00
tty_jobctrl.c tty: tty_jobctrl: Fix 2 incorrectly documented functions 2021-05-20 17:06:15 +02:00
tty_ldisc.c tty: tty_ldisc: fix doc warnings in tty_ldisc.c 2021-06-09 14:43:23 +02:00
tty_ldsem.c locking/lockdep: Remove unused @nested argument from lock_release() 2019-10-09 12:46:10 +02:00
tty_mutex.c tty: move some internal tty lock enums and functions out of tty.h 2021-04-15 10:26:58 +02:00
tty_port.c tty: tty_port: Fix coding style issues of block comments 2021-05-13 18:29:13 +02:00
tty.h tty: clean include/linux/tty.h up 2021-04-15 10:32:17 +02:00
ttynull.c tty: make tty_operations::write_room return uint 2021-05-13 17:03:20 +02:00
vcc.c TTY / Serial patches for 5.14-rc1 2021-07-05 14:08:24 -07:00