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.
pgpfAaDLmV4Wh.pgp
Description: PGP signature
|