[PATCH] Fix BREAK handling in sunsab serial driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Handling of a BREAK on a serial line is currently broken in the sunsab serial
driver. Due to this defect, it is not possible to break to the firmware prompt
or trigger a Magic SysRq on these machines (which would be quite useful for
debugging kernel problems on headless machines).

This problem is caused by the fact that the count of characters to be processed
might be 0 when a BREAK interrupt is triggered. The code in the driver contains
a loop that processes the pending characters - with count set to 0 no processing
takes place at all. Unfortunately, the call of uart_handle_break() is contained
inside this loop and therefore skipped completely.

This patch moves the check for BREAK status in front of the loop and executes it
only when count == 0, i.e. when it would not be done inside the loop.

With this patch, Magic SysRq works again. However, there seems to be another
problem that causes an Oops when a register dump is requested by SysRq. This
is caused when perf_event_print_debug() is called from sysrq_handle_showregs()
in drivers/tty/sysrq.c. This patch provides no solution for this problem; my
workaround was to eliminate the call to perf_event_print_debug() in
sysrq_handle_showregs(). This problem was observed on a SunBlade 2000 with an
UltraSPARC III Cu CPU and might be specific to this CPU model (the UltraSPARC III
is the first CPU to support perf_event.).

The patch was originally developed against a 3.13 backport kernel from Debian.
Both the patch against 3.13 and a recent 3.16-rc6 are included below. Please note
that I could only test the 3.13 version as I do not have access to the affected
machine anymore.

PATCH 1 - KERNEL VERSION 3.13 #####################################################

diff -Naupr linux-source-3.13-orig/drivers/tty/serial/sunsab.c linux-source-3.13-patched/drivers/tty/serial/sunsab.c
--- linux-source-3.13-orig/drivers/tty/serial/sunsab.c  2014-04-14 15:48:24.000000000 +0200
+++ linux-source-3.13-patched/drivers/tty/serial/sunsab.c       2014-07-27 14:29:58.000000000 +0200
@@ -157,6 +157,14 @@ receive_chars(struct uart_sunsab_port *u
            (up->port.line == up->port.cons->index))
                saw_console_brk = 1;
 
+       if(count == 0) {
+               if(unlikely(stat->sreg.isr1 & SAB82532_ISR1_BRK)) {
+                       stat->sreg.isr0 &= ~(SAB82532_ISR0_PERR |
+                                            SAB82532_ISR0_FERR);
+                       uart_handle_break(&up->port);
+               }
+       }
+
        for (i = 0; i < count; i++) {
                unsigned char ch = buf[i], flag;

PATCH 2 - KERNEL VERSION 3.16 #####################################################

diff -Naupr linux-3.16-rc6-orig/drivers/tty/serial/sunsab.c linux-3.16-rc6-patched/drivers/tty/serial/sunsab.c
--- linux-3.16-rc6-orig/drivers/tty/serial/sunsab.c     2014-07-27 11:50:32.000000000 +0200
+++ linux-3.16-rc6-patched/drivers/tty/serial/sunsab.c  2014-07-27 14:28:12.000000000 +0200
@@ -157,6 +157,14 @@ receive_chars(struct uart_sunsab_port *u
            (up->port.line == up->port.cons->index))
                saw_console_brk = 1;
 
+       if(count == 0) {
+               if(unlikely(stat->sreg.isr1 & SAB82532_ISR1_BRK)) {
+                       stat->sreg.isr0 &= ~(SAB82532_ISR0_PERR |
+                                            SAB82532_ISR0_FERR);
+                       uart_handle_break(&up->port);
+               }
+       }
+
        for (i = 0; i < count; i++) {
                unsigned char ch = buf[i], flag;
 
Regards,
Alexander Schulze
--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Kernel Development]     [DCCP]     [Linux ARM Development]     [Linux]     [Photo]     [Yosemite Help]     [Linux ARM Kernel]     [Linux SCSI]     [Linux x86_64]     [Linux Hams]

  Powered by Linux