1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-21 15:45:02 +00:00

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.
This commit is contained in:
Bruce Evans 2003-09-27 11:13:59 +00:00
parent 7872ac5542
commit 5da172697f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=120505

View File

@ -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;