linux-mips
[Top] [All Lists]

Re: unable to handle kernel paging request

To: "Maciej W. Rozycki" <macro@linux-mips.org>
Subject: Re: unable to handle kernel paging request
From: Florian Lohoff <flo@rfc822.org>
Date: Mon, 1 Nov 2004 22:50:55 +0100
Cc: Dennis Grevenstein <dennis@pcde.inka.de>, linux-mips@linux-mips.org
In-reply-to: <Pine.LNX.4.58L.0410312354350.22630@blysk.ds.pg.gda.pl>
Organization: rfc822 - pure communication
Original-recipient: rfc822;linux-mips@linux-mips.org
References: <20041031184233.GA11120@aton.pcde.inka.de> <Pine.GSO.4.10.10410311947570.9753-100000@helios.et.put.poznan.pl> <20041031191631.GB11681@aton.pcde.inka.de> <20041031192653.GG2094@lug-owl.de> <20041031195550.GA12397@aton.pcde.inka.de> <20041031201335.GH2094@lug-owl.de> <20041031223612.GA15091@aton.pcde.inka.de> <Pine.LNX.4.58L.0410312354350.22630@blysk.ds.pg.gda.pl>
Sender: linux-mips-bounce@linux-mips.org
User-agent: Mutt/1.5.4i
On Sun, Oct 31, 2004 at 11:59:31PM +0000, Maciej W. Rozycki wrote:
> On Sun, 31 Oct 2004, Dennis Grevenstein wrote:
> 
> >         struct tty_struct *tty = up->port.info->tty;    /* XXX info==NULL? 
> > */
> 
>  It looks up->port.info is null for some reason (and unhandled as noted 
> in the comment).

I had the same problem and fixed it like this - It fixes some other
break/sysrq based problems ...

Index: drivers/serial/ip22zilog.c
===================================================================
RCS file: /home/flo/linux-mips-cvs/linux/drivers/serial/ip22zilog.c,v
retrieving revision 1.15
diff -u -r1.15 ip22zilog.c
--- drivers/serial/ip22zilog.c  28 Sep 2004 19:22:07 -0000      1.15
+++ drivers/serial/ip22zilog.c  3 Oct 2004 19:26:06 -0000
@@ -47,8 +47,6 @@
 
 #include "ip22zilog.h"
 
-void ip22_do_break(void);
-
 /*
  * On IP22 we need to delay after register accesses but we do not need to
  * flush writes.
@@ -256,17 +254,15 @@
                                   struct zilog_channel *channel,
                                   struct pt_regs *regs)
 {
-       struct tty_struct *tty = up->port.info->tty;    /* XXX info==NULL? */
+       struct tty_struct *tty = NULL;
+
+       if (up->port.info != NULL &&            /* Unopened serial console */
+           up->port.info->tty != NULL)         /* Keyboard || mouse */
+               tty = up->port.info->tty;
 
        while (1) {
                unsigned char ch, r1;
 
-               if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
-                       tty->flip.work.func((void *)tty);
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                               return;         /* XXX Ignores SysRq when we 
need it most. Fix. */
-               }
-
                r1 = read_zsreg(channel, R1);
                if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) {
                        writeb(ERR_RES, &channel->control);
@@ -288,24 +284,8 @@
 
                ch &= up->parity_mask;
 
-               if (ZS_IS_CONS(up) && (r1 & BRK_ABRT)) {
-                       /* Wait for BREAK to deassert to avoid potentially
-                        * confusing the PROM.
-                        */
-                       while (1) {
-                               ch = readb(&channel->control);
-                               ZSDELAY();
-                               if (!(ch & BRK_ABRT))
-                                       break;
-                       }
-                       ip22_do_break();
-                       return;
-               }
-
-               /* A real serial line, record the character and status.  */
-               *tty->flip.char_buf_ptr = ch;
-               *tty->flip.flag_buf_ptr = TTY_NORMAL;
                up->port.icount.rx++;
+
                if (r1 & (BRK_ABRT | PAR_ERR | Rx_OVR | CRC_ERR)) {
                        if (r1 & BRK_ABRT) {
                                r1 &= ~(PAR_ERR | CRC_ERR);
@@ -319,6 +299,25 @@
                                up->port.icount.frame++;
                        if (r1 & Rx_OVR)
                                up->port.icount.overrun++;
+               }
+
+               if (uart_handle_sysrq_char(&up->port, ch, regs))
+                       goto next_char;
+
+               if (!tty)
+                       goto next_char;
+
+               if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
+                       tty->flip.work.func((void *)tty);
+                       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+                               goto push_tty;          /* XXX We drop 
characters here - Either read or die */
+               }
+
+               /* A real serial line, record the character and status.  */
+               *tty->flip.char_buf_ptr = ch;
+               *tty->flip.flag_buf_ptr = TTY_NORMAL;
+
+               if (r1 & (BRK_ABRT | PAR_ERR | Rx_OVR | CRC_ERR)) {
                        r1 &= up->port.read_status_mask;
                        if (r1 & BRK_ABRT)
                                *tty->flip.flag_buf_ptr = TTY_BREAK;
@@ -327,8 +326,6 @@
                        else if (r1 & CRC_ERR)
                                *tty->flip.flag_buf_ptr = TTY_FRAME;
                }
-               if (uart_handle_sysrq_char(&up->port, ch, regs))
-                       goto next_char;
 
                if (up->port.ignore_status_mask == 0xff ||
                    (r1 & up->port.ignore_status_mask) == 0) {
@@ -350,7 +347,9 @@
                        break;
        }
 
-       tty_flip_buffer_push(tty);
+push_tty:
+       if (tty)
+               tty_flip_buffer_push(tty);
 }
 
 static void ip22zilog_status_handle(struct uart_ip22zilog_port *up,

-- 
Florian Lohoff                  flo@rfc822.org             +49-171-2280134
                        Heisenberg may have been here.

Attachment: pgpj5Vunxstph.pgp
Description: PGP signature

<Prev in Thread] Current Thread [Next in Thread>