Patch "media: rc: sir_ir: detect presence of port" has been added to the 4.14-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
media: rc: sir_ir: detect presence of port
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
media-rc-sir_ir-detect-presence-of-port.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
30b4e122d71cbec2944a5f8b558b88936ee42f10Mon Sep 17 00:00:00 2001
From: Sean Young <[email protected]>
Date: Wed, 8 Nov 2017 16:19:45 -0500
Subject: media: rc: sir_ir: detect presence of port
From: Sean Young <[email protected]>
commit 30b4e122d71cbec2944a5f8b558b88936ee42f10 upstream.
Without this test, sir_ir clumsy claims resources for a device which does not exist.
The 0-day kernel test robot reports the following errors (in a loop):
sir_ir sir_ir.0: Trapped in interrupt genirq: Flags mismatch irq 4. 00000000 (ttyS0) vs. 00000000 (sir_ir)
When sir_ir is loaded with the default io and irq, the following happens:
- sir_ir claims irq 4
- user space opens /dev/ttyS0
- in serial8250_do_startup(), some setup is done for ttyS0, which causes irq 4 to fire (in THRE test)
- sir_ir does not realise it was not for it, and spins until the "trapped in interrupt"
- now serial driver calls setup_irq() and fails and we get the "Flags mismatch" error.
There is no port present at 0x3e8 so simply check for the presence of a port, as suggested by Linus.
--- drivers/media/rc/sir_ir.c | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-)
drivers/media/rc/sir_ir.c +36 -4
@@ -57,7 +57,7 @@ static void add_read_queue(int flag, unsstatic irqreturn_t sir_interrupt (int irq,void *dev_id);static void send_space (unsigned long len);static void send_pulse (unsigned long len); -static void init_hardware (void ); +static int init_hardware (void );static void drop_hardware (void );/* Initialisation */
@@ -263,11 +263,36 @@ static void send_pulse(unsigned long len } } -static void init_hardware (void ) +static int init_hardware (void ) { +u8 scratch, scratch2, scratch3;unsigned long flags;spin_lock_irqsave (&hardware_lock, flags); + +/* +* This is a simple port existence test, borrowed from the autoconfig +* function in drivers/tty/serial/8250/8250_port.c +*/ + scratch =sinp (UART_IER ); +soutp (UART_IER ,0 ); +#ifdef __i386__ +outb (0xff ,0x080 ); +#endif + scratch2 =sinp (UART_IER ) &0x0f ; +soutp (UART_IER ,0x0f ); +#ifdef __i386__ +outb (0x00 ,0x080 ); +#endif + scratch3 =sinp (UART_IER ) &0x0f ; +soutp (UART_IER , scratch); +if (scratch2 !=0 || scratch3 !=0x0f ) { +/* we fail, there's nothing here */ +spin_unlock_irqrestore (&hardware_lock, flags); +pr_err ("port existence test failed, cannot continue\n" ); +return -ENODEV ; + } +/* reset UART */ outb (0 , io +UART_MCR );outb (0 , io +UART_IER );
@@ -285,6 +310,8 @@ static void init_hardware(void)/* turn on UART */ outb (UART_MCR_DTR |UART_MCR_RTS |UART_MCR_OUT2 , io +UART_MCR );spin_unlock_irqrestore (&hardware_lock, flags); + +return 0 ; }static void drop_hardware (void )
@@ -334,14 +361,19 @@ static int sir_ir_probe(struct platform_pr_err ("IRQ %d already in use.\n" , irq);return retval; } + + retval =init_hardware (); +if (retval) { +del_timer_sync (&timerlist); +return retval; + } +pr_info ("I/O port 0x%.4x, IRQ %d.\n" , io, irq); retval =devm_rc_register_device (&sir_ir_dev->dev, rcdev);if (retval <0 )return retval; -init_hardware (); -return 0 ; }
Patches currently in stable-queue which might be from [email protected] are
queue-4.14/media-rc-partial-revert-of-media-rc-per-protocol-repeat-period.patch queue-4.14/media-rc-sir_ir-detect-presence-of-port.patch queue-4.14/media-dvb-i2c-transfers-over-usb-cannot-be-done-from-stack.patch