Re: unable to handle kernel paging request

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

 



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@xxxxxxxxxx             +49-171-2280134
                        Heisenberg may have been here.

Attachment: pgpO24joxCtMg.pgp
Description: PGP signature


[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux