summaryrefslogtreecommitdiffstats
path: root/sys/dev/sio
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>2003-09-27 11:13:59 +0000
committerbde <bde@FreeBSD.org>2003-09-27 11:13:59 +0000
commitc21d189c3f13ce3c60be9f7e4b2d8fc554970d12 (patch)
treeb1fcaf29ac0faa4e9abd6768c23e4c26a6b79368 /sys/dev/sio
parent6d69006c55a01bc62f55b1d4623fc13457564a16 (diff)
downloadFreeBSD-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.c51
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;
OpenPOWER on IntegriCloud