diff options
author | bde <bde@FreeBSD.org> | 1996-06-17 14:23:39 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1996-06-17 14:23:39 +0000 |
commit | 4e855e93224c277db07beb8ef156deb30365af0d (patch) | |
tree | d76bb727bfd3aebec09287c660f46ab22eb4c7c0 /sys/dev | |
parent | 6303ba66f8bb0cfed03198008c8728a9c919e969 (diff) | |
download | FreeBSD-src-4e855e93224c277db07beb8ef156deb30365af0d.zip FreeBSD-src-4e855e93224c277db07beb8ef156deb30365af0d.tar.gz |
Added support for TIOCDCDTIMESTAMP (enable/get timestamp of last DCD rise).
Original version by John Hay.
Simplified timestamp code by reading the time exactly when necessary.
This may slow down the interrupt handler with extra calls to microtime(),
but only in bad configurations - the input fifo should normally be
disabled if timestamps on input are being used, since otherwise the
timestamp won't be precisely associated with any particular input event.
The interrupt handler remains slowed down by one test and branch for
each input (and now DCD change) event - avoiding this is not practical
yet.
The simplifications also fixed:
- timestamps for input sometimes being clobbered by output and modem
status interrupts.
- valid timestamps not being available unless the port is configured with
vector siointrts. siointrts no longer exists.
- compiler warnings about siointr* in some configurations.
Simplified timestamp and probe code by depending on recent changes in
microtime() and DELAY() to preserve the interrupt enable flag.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/sio/sio.c | 51 |
1 files changed, 15 insertions, 36 deletions
diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c index aab233e..c7173db 100644 --- a/sys/dev/sio/sio.c +++ b/sys/dev/sio/sio.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)com.c 7.5 (Berkeley) 5/16/91 - * $Id: sio.c,v 1.141 1996/04/23 18:36:56 nate Exp $ + * $Id: sio.c,v 1.142 1996/05/02 09:34:40 phk Exp $ */ #include "opt_comconsole.h" @@ -68,7 +68,6 @@ #include <machine/clock.h> -#include <i386/isa/icu.h> /* XXX just to get at `imen' */ #include <i386/isa/isa.h> #include <i386/isa/isa_device.h> #include <i386/isa/sioreg.h> @@ -236,7 +235,9 @@ struct com_s { struct termios lt_out; bool_t do_timestamp; + bool_t do_dcd_timestamp; struct timeval timestamp; + struct timeval dcd_timestamp; u_long bytes_in; /* statistics */ u_long bytes_out; @@ -272,8 +273,7 @@ struct com_s { * by `config', not here. */ -/* Interrupt handling entry points. */ -inthand2_t siointrts; +/* Interrupt handling entry point. */ void siopoll __P((void)); /* Device switch entry points. */ @@ -309,8 +309,6 @@ static char driver_name[] = "sio"; static struct com_s *p_com_addr[NSIO]; #define com_addr(unit) (p_com_addr[unit]) -static struct timeval intr_timestamp; - struct isa_driver siodriver = { sioprobe, sioattach, driver_name }; @@ -600,14 +598,6 @@ sioprobe(dev) /* EXTRA DELAY? */ /* - * XXX DELAY() reenables CPU interrupts. This is a problem for - * shared interrupts after the first device using one has been - * successfully probed - config_isadev() has enabled the interrupt - * in the ICU. - */ - outb(IO_ICU1 + 1, 0xff); - - /* * Initialize the speed and the word size and wait long enough to * drain the maximum of 16 bytes of junk in device output queues. * The speed is undefined after a master reset and must be set @@ -706,7 +696,6 @@ sioprobe(dev) failures[8] = isa_irq_pending(idev) ? 1 : 0; failures[9] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND; - outb(IO_ICU1 + 1, imen); /* XXX */ enable_intr(); result = IO_COMSIZE; @@ -1358,24 +1347,6 @@ siodtrwakeup(chan) wakeup(&com->dtr_wait); } -/* Interrupt routine for timekeeping purposes */ -void -siointrts(unit) - int unit; -{ - /* - * XXX microtime() reenables CPU interrupts. We can't afford to - * be interrupted and don't want to slow down microtime(), so lock - * out interrupts in another way. - */ - outb(IO_ICU1 + 1, 0xff); - microtime(&intr_timestamp); - disable_intr(); - outb(IO_ICU1 + 1, imen); - - siointr(unit); -} - void siointr(unit) int unit; @@ -1418,9 +1389,6 @@ siointr1(com) u_char *ioptr; u_char recv_data; - if (com->do_timestamp) - /* XXX a little bloat here... */ - com->timestamp = intr_timestamp; while (TRUE) { line_status = inb(com->line_status_port); @@ -1467,6 +1435,8 @@ siointr1(com) if (ioptr >= com->ibufend) CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW); else { + if (com->do_timestamp) + microtime(&com->timestamp); ++com_events; schedsofttty(); #if 0 /* for testing input latency vs efficiency */ @@ -1494,6 +1464,11 @@ cont: /* modem status change? (always check before doing output) */ modem_status = inb(com->modem_status_port); if (modem_status != com->last_modem_status) { + if (com->do_dcd_timestamp + && !(com->last_modem_status & MSR_DCD) + && modem_status & MSR_DCD) + microtime(&com->dcd_timestamp); + /* * Schedule high level to handle DCD changes. Note * that we don't use the delta bits anywhere. Some @@ -1733,6 +1708,10 @@ sioioctl(dev, cmd, data, flag, p) com->do_timestamp = TRUE; *(struct timeval *)data = com->timestamp; break; + case TIOCDCDTIMESTAMP: + com->do_dcd_timestamp = TRUE; + *(struct timeval *)data = com->dcd_timestamp; + break; default: splx(s); return (ENOTTY); |