diff options
author | bde <bde@FreeBSD.org> | 2003-09-27 11:13:59 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 2003-09-27 11:13:59 +0000 |
commit | c21d189c3f13ce3c60be9f7e4b2d8fc554970d12 (patch) | |
tree | b1fcaf29ac0faa4e9abd6768c23e4c26a6b79368 /sys/dev/sio | |
parent | 6d69006c55a01bc62f55b1d4623fc13457564a16 (diff) | |
download | FreeBSD-src-c21d189c3f13ce3c60be9f7e4b2d8fc554970d12.zip FreeBSD-src-c21d189c3f13ce3c60be9f7e4b2d8fc554970d12.tar.gz |
Cleaned up and fixed setting of speeds in comparam():
- Removed conversion of a zero input speed to the output speed. This
has been done better in ttioctl() since rev.1.108 of kern/tty.c
almost 5 years ago. comparam() did the conversion incompletely for
the case where the output speed is also zero. It had complications
to avoid using zero speeds, but would still have used a zero input
speed for setting watermarks if kern/tty.c had passed one.
- Never permit the input speed to be different from the output speed.
There was no validity check on the input speed for the case of a zero
output speed. Then we didn't change the physical speeds, but we used
the unvalidated input speed for setting watermarks and didn't return
an error, so ttioctl() stored the unvalidated input speed in the tty
struct where it could cause problems later.
- Removed complications that were to avoid using a divisor of 0. The
divisor is now always valid if the speed is accepted.
Diffstat (limited to 'sys/dev/sio')
-rw-r--r-- | sys/dev/sio/sio.c | 51 |
1 files changed, 20 insertions, 31 deletions
diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c index cfc87ed..e8f88a8 100644 --- a/sys/dev/sio/sio.c +++ b/sys/dev/sio/sio.c @@ -2217,24 +2217,16 @@ comparam(tp, t) if (com == NULL) return (ENODEV); - /* do historical conversions */ - if (t->c_ispeed == 0) - t->c_ispeed = t->c_ospeed; - /* check requested parameters */ - if (t->c_ospeed == 0) - divisor = 0; - else { - if (t->c_ispeed != t->c_ospeed) - return (EINVAL); - divisor = siodivisor(com->rclk, t->c_ispeed); - if (divisor == 0) - return (EINVAL); - } + if (t->c_ispeed != (t->c_ospeed != 0 ? t->c_ospeed : tp->t_ospeed)) + return (EINVAL); + divisor = siodivisor(com->rclk, t->c_ispeed); + if (divisor == 0) + return (EINVAL); /* parameters are OK, convert them to the com struct and the device */ s = spltty(); - if (divisor == 0) + if (t->c_ospeed == 0) (void)commctl(com, TIOCM_DTR, DMBIC); /* hang up line */ else (void)commctl(com, TIOCM_DTR, DMBIS); @@ -2261,7 +2253,7 @@ comparam(tp, t) if (cflag & CSTOPB) cfcr |= CFCR_STOPB; - if (com->hasfifo && divisor != 0) { + if (com->hasfifo) { /* * Use a fifo trigger level low enough so that the input * latency from the fifo is less than about 16 msec and @@ -2276,7 +2268,7 @@ comparam(tp, t) * without producing silo overflow errors. */ com->fifo_image = com->unit == siotsunit ? 0 - : t->c_ospeed <= 4800 + : t->c_ispeed <= 4800 ? FIFO_ENABLE : FIFO_ENABLE | FIFO_RX_MEDH; #ifdef COM_ESP /* @@ -2297,21 +2289,18 @@ comparam(tp, t) */ (void) siosetwater(com, t->c_ispeed); - if (divisor != 0) { - sio_setreg(com, com_cfcr, cfcr | CFCR_DLAB); - /* - * Only set the divisor registers if they would change, - * since on some 16550 incompatibles (UMC8669F), setting - * them while input is arriving them loses sync until - * data stops arriving. - */ - dlbl = divisor & 0xFF; - if (sio_getreg(com, com_dlbl) != dlbl) - sio_setreg(com, com_dlbl, dlbl); - dlbh = divisor >> 8; - if (sio_getreg(com, com_dlbh) != dlbh) - sio_setreg(com, com_dlbh, dlbh); - } + sio_setreg(com, com_cfcr, cfcr | CFCR_DLAB); + /* + * Only set the divisor registers if they would change, since on + * some 16550 incompatibles (UMC8669F), setting them while input + * is arriving loses sync until data stops arriving. + */ + dlbl = divisor & 0xFF; + if (sio_getreg(com, com_dlbl) != dlbl) + sio_setreg(com, com_dlbl, dlbl); + dlbh = divisor >> 8; + if (sio_getreg(com, com_dlbh) != dlbh) + sio_setreg(com, com_dlbh, dlbh); if (!(tp->t_state & TS_TTSTOP)) com->state |= CS_TTGO; |