Hello,

For the last few days I have been trying to fix the problems with serial console on the machines with sunsab serial controller (I can reproduce them myself on my Ultra 5, another person reported similar issues on an Ultra 10). When booting a 2.6 kernel using serial console, some junk gets occasionally printed on it (see [0] and [1] for thescreenshots). Machine
also eventually hangs. After poking around a bit and comparing sunsab.c driver with the working sunzilog.c driver, I came up with the patch against 2.6.11 (attached), which takes care of the hang, but does not eliminate garbage on the console. I am pretty sure by now that this is a result of improper handling of the mode changes, as I see numerous calls to sunsab_set_mctrl() and sunsab_set_termios() right before and/or during the appearance of spurious symbols. As it is a little bit over my head, I hope someone more knowledgeable can give me a clue on how to debug this further.


[0] http://www.wooyd.org/misc/sunsab.1.png
[1] http://www.wooyd.org/misc/sunsab.2.png

Best regards,

Jurij Smakov                                        [EMAIL PROTECTED]
Key: http://www.wooyd.org/pgpkey/                   KeyID: C99E03CC
diff -aur a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
--- a/drivers/serial/sunsab.c   2005-03-02 02:38:07.000000000 -0500
+++ b/drivers/serial/sunsab.c   2005-03-09 19:44:51.000000000 -0500
@@ -295,20 +295,22 @@
 static void check_status(struct uart_sunsab_port *up,
                         union sab82532_irq_status *stat)
 {
-       if (stat->sreg.isr0 & SAB82532_ISR0_CDSC)
-               uart_handle_dcd_change(&up->port,
+       if (test_bit(SAB82532_MODEM_STATUS, &up->irqflags)) {
+               if (stat->sreg.isr0 & SAB82532_ISR0_CDSC)
+                       uart_handle_dcd_change(&up->port,
                                       !(readb(&up->regs->r.vstr) & 
SAB82532_VSTR_CD));
 
-       if (stat->sreg.isr1 & SAB82532_ISR1_CSC)
-               uart_handle_cts_change(&up->port,
+               if (stat->sreg.isr1 & SAB82532_ISR1_CSC)
+                       uart_handle_cts_change(&up->port,
                                       (readb(&up->regs->r.star) & 
SAB82532_STAR_CTS));
 
-       if ((readb(&up->regs->r.pvr) & up->pvr_dsr_bit) ^ up->dsr) {
-               up->dsr = (readb(&up->regs->r.pvr) & up->pvr_dsr_bit) ? 0 : 1;
-               up->port.icount.dsr++;
-       }
+               if ((readb(&up->regs->r.pvr) & up->pvr_dsr_bit) ^ up->dsr) {
+                       up->dsr = (readb(&up->regs->r.pvr) & up->pvr_dsr_bit) ? 
0 : 1;
+                       up->port.icount.dsr++;
+               }
 
-       wake_up_interruptible(&up->port.info->delta_msr_wait);
+               wake_up_interruptible(&up->port.info->delta_msr_wait);
+       }
 }
 
 static irqreturn_t sunsab_interrupt(int irq, void *dev_id, struct pt_regs 
*regs)
@@ -788,6 +790,11 @@
 
        spin_lock_irqsave(&up->port.lock, flags);
        sunsab_convert_to_sab(up, termios->c_cflag, termios->c_iflag, baud);
+        if (UART_ENABLE_MS(&up->port, termios->c_cflag))
+                set_bit(SAB82532_MODEM_STATUS, &up->irqflags);
+        else
+                clear_bit(SAB82532_MODEM_STATUS, &up->irqflags);
+       uart_update_timeout(port, termios->c_cflag, baud);
        spin_unlock_irqrestore(&up->port.lock, flags);
 }
 
diff -aur a/drivers/serial/sunsab.h b/drivers/serial/sunsab.h
--- a/drivers/serial/sunsab.h   2005-03-02 02:38:33.000000000 -0500
+++ b/drivers/serial/sunsab.h   2005-03-09 19:44:51.000000000 -0500
@@ -126,6 +126,7 @@
 /* irqflags bits */
 #define SAB82532_ALLS                  0x00000001
 #define SAB82532_XPR                   0x00000002
+#define SAB82532_MODEM_STATUS          0x00000004
 
 /* RFIFO Status Byte */
 #define SAB82532_RSTAT_PE              0x80

Reply via email to