Subject: kern/3001: com ports don't work at 9600 baud
To: None <gnats-bugs@gnats.netbsd.org>
From: Andreas Gustafsson <gson@araneus.fi>
List: netbsd-bugs
Date: 12/07/1996 11:16:07
>Number:         3001
>Category:       kern
>Synopsis:       com ports don't work at 9600 baud
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Dec  7 01:20:01 1996
>Last-Modified:
>Originator:     Andreas Gustafsson
>Organization:
Araneus Information Systems Oy
>Release:        1.2
>Environment:
System: NetBSD guava.araneus.fi 1.2 NetBSD 1.2 (GUAVA) #4: Tue Dec 3 20:48:00 EET 1996 gson@guava.araneus.fi:/usr/src/sys/arch/i386/compile/GUAVA i386

>Description:

This PR describes the same bug as PR #2238, but contains an
alternative, less intrusive patch.

If a com port is set to a baud rate of 9600, the UART does not get
properly initialized and the port doesn't work.  If another speed is
set even temporarily, the initialization will take place, after which
the port does work even at 9600 baud.

The bug occurs because the UART com_dlbl and com_dblh registers are
only initialized when the baud rate changes to a value different from
the "current" one ("if (tp->t_ispeed != t->c_ispeed)").  When the
system boots, the UART is uninitialized, but tp->t_ispeed is
initialized to 9600.  Thus, any attempt to set the baud rate to 9600
will be ignored, because in this case the new value is identical to
the "current" one.

My proposed fix is to initialize tp->t_ispeed to a sentinel value
which is not a legal baud rate, to ensure that the first baud rate
set will always be considered different from the "current" one.

>How-To-Repeat:

Try to set up a serial terminal using the following line in /etc/ttys:

  tty00	"/usr/libexec/getty std.9600"	vt100	on  secure

reboot the system, and notice that the line is completely dead.

>Fix:

*** com.c.orig-1.2	Tue Dec  3 21:17:57 1996
--- com.c	Tue Dec  3 21:18:06 1996
***************
*** 553,559 ****
  		if (ISSET(sc->sc_swflags, COM_SW_MDMBUF))
  			SET(tp->t_cflag, MDMBUF);
  		tp->t_lflag = TTYDEF_LFLAG;
! 		tp->t_ispeed = tp->t_ospeed = comdefaultrate;
  
  		s = spltty();
  
--- 553,561 ----
  		if (ISSET(sc->sc_swflags, COM_SW_MDMBUF))
  			SET(tp->t_cflag, MDMBUF);
  		tp->t_lflag = TTYDEF_LFLAG;
! 
! 		/* No speed has ben set yet */
! 		tp->t_ispeed = tp->t_ospeed = -1;
  
  		s = spltty();
  
>Audit-Trail:
>Unformatted: