Messages in this thread Patch in this message |  | | From | Peter Fox <> | Subject | Bug in serial line hangup code ? | Date | Sun, 5 May 1996 13:45:11 GMT |
| |
I've continued my line monitoring program, and found the following problem:
My program opens the line, and ignores HUP. info.count is 1.
ppp (for example) opens the line, does its stuff etc, info.count is 2.
ppp enables hangup, and on hangup closes the port. The serial driver sets info.count to 0 on hangup, even though my program still has the port open. As my program watches info.count to determine if another process has the line is open, this is a bit of a problem.
Here are my patches to fix this, (and also add data transfer counters to the async_struct, and allow ioctls on a line that has received a hangup).
The fix involves doing not alot in the serial driver on hangup, but wait for the port to be closed. If the process doesn't catch HUP, then it will close the port just like before.
How about including this lot before 2.0 ?
Peter.
---------------------------- diff -P -r -u -X diffexcl linux.1.3.97/drivers/char/serial.c linux.1.3.97.pf/drivers/char/serial.c --- linux.1.3.97/drivers/char/serial.c Tue Apr 30 21:55:44 1996 +++ linux.1.3.97.pf/drivers/char/serial.c Sun May 5 13:39:34 1996 @@ -396,6 +396,7 @@ do { ch = serial_inp(info, UART_RX); + info->rx_char_count++; if (*status & info->ignore_status_mask) { if (++ignored > 100) break; @@ -433,6 +434,7 @@ if (info->x_char) { serial_outp(info, UART_TX, info->x_char); + info->tx_char_count++; info->x_char = 0; if (intr_done) *intr_done = 0; @@ -448,6 +450,7 @@ count = info->xmit_fifo_size; do { serial_out(info, UART_TX, info->xmit_buf[info->xmit_tail++]); + info->tx_char_count++; info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); if (--info->xmit_cnt <= 0) break; @@ -1002,6 +1005,11 @@ (void) serial_inp(info, UART_MSR); /* + * Initialise the byte counters + */ + info->rx_char_count = 0; + info->tx_char_count = 0; + /* * Now, initialize the UART */ serial_outp(info, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */ @@ -1903,6 +1911,7 @@ if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) && (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT) && + (cmd != TIOCMGET) && (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { if (tty->flags & (1 << TTY_IO_ERROR)) return -EIO; @@ -2110,12 +2119,14 @@ save_flags(flags); cli(); +#ifdef NOTACHANCE if (tty_hung_up_p(filp)) { DBG_CNT("before DEC-hung"); MOD_DEC_USE_COUNT; restore_flags(flags); return; } +#endif #ifdef SERIAL_DEBUG_OPEN printk("rs_close ttys%d, count = %d\n", info->line, info->count); @@ -2217,11 +2228,13 @@ return; rs_flush_buffer(tty); +#ifdef NOTACHANCE /* Close will do all this (when last process closes the line) */ shutdown(info); info->event = 0; info->count = 0; - info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE); info->tty = 0; +#endif + info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE); wake_up_interruptible(&info->open_wait); } diff -P -r -u -X diffexcl linux.1.3.97/drivers/char/tty_io.c linux.1.3.97.pf/drivers/char/tty_io.c --- linux.1.3.97/drivers/char/tty_io.c Sat Apr 27 00:02:00 1996 +++ linux.1.3.97.pf/drivers/char/tty_io.c Tue Apr 30 21:58:25 1996 @@ -358,7 +358,8 @@ hung_up_tty_write, NULL, /* hung_up_tty_readdir */ hung_up_tty_select, - hung_up_tty_ioctl, + tty_ioctl, /* Why shouldn't we do IOCTLs on hung up tty ? */ + /* hung_up_tty_ioctl, */ NULL, /* hung_up_tty_mmap */ NULL, /* hung_up_tty_open */ tty_release, /* hung_up_tty_release */ diff -P -r -u -X diffexcl linux.1.3.97/include/linux/serial.h linux.1.3.97.pf/include/linux/serial.h --- linux.1.3.97/include/linux/serial.h Thu Mar 21 08:05:06 1996 +++ linux.1.3.97.pf/include/linux/serial.h Tue Apr 30 22:02:20 1996 @@ -170,6 +170,8 @@ struct async_icount icount; /* kernel counters for the 4 input interrupts */ struct async_struct *next_port; /* For the linked list */ struct async_struct *prev_port; + unsigned long rx_char_count; /* Total no of chars received */ + unsigned long tx_char_count; /* Total no of chars transmitted */ }; #define SERIAL_MAGIC 0x5301
|  |