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