Subject: kern/6547: com driver asserts DTR too late for KGDB or serial console
To: None <gnats-bugs@gnats.netbsd.org>
From: Andreas Gustafsson <gson@araneus.fi>
List: netbsd-bugs
Date: 12/08/1998 17:55:07
>Number:         6547
>Category:       kern
>Synopsis:       com driver asserts DTR too late for KGDB or serial console
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Dec  8 08:05:00 1998
>Last-Modified:
>Originator:     Andreas Gustafsson
>Organization:
Araneus Information Systems Oy
>Release:        1.3.2
>Environment:

System: NetBSD guava.araneus.fi 1.3.2 NetBSD 1.3.2 (GUAVA) #0: Mon Nov 30 09:08:39 EET 1998 gson@guava.araneus.fi:/z/src-1.3/sys/arch/i386/compile/GUAVA i386


>Description:

When using the "com" driver for remote debugging with KGDB or as a
serial console, the serial port is initialized early in the boot
process (at least on the i386 platform) and may be used long before
the driver attach() routine is called.  However, the DTR and RTS
signals will not be turned on until attach() time.  Depending on the
degree to which the device attached to the port ignores modem control
signals, the connection may or may not work during the intervening
time.


>How-To-Repeat:

Connect two NetBSD machines with a fully wired null modem cable, where
the DTR signal on one end side is connected to the CD signal on the
other end and vice versa.  On one machine, start gdb and set it up for
remote debugging through the serial line.  On the other, boot a
KGDB-enabled kernel with the -d option.

Then find that the setup deadlocks because on one machine GDB is
waiting for carrier to be asserted, while on the other machine the
KGDB stub is waiting for GDB to respond with DTR still low.

If kern/6502 has not been fixed on the system running GDB, the KGDB
stub may instead get into an infinite dialog with its own echo.

This particular instance of the bug can be worked around by setting
softcar on the machine running GDB, but that is just a workaround, not
a fix.  The softcar option should only be necessary with cables that
do not connect the CD signal at all; this problem specifically occurs
with cables that *are* wired correctly.

You can also observe the bug outside a KGDB context by hooking up an
RS232 analyzer to a line serving as a serial console and noting that
all boot messages up to those dealing with the console com port itself
are printed with DTR and RTS still low.

>Fix:

Apply the following patch.  I've also taken the opportunity
to clarify a comment to more accurately describe the purpose
of the cominit() function.

*** src/sys/dev/ic/com.c.pre-kgdb	Sun Dec  6 16:35:42 1998
--- src/sys/dev/ic/com.c	Tue Dec  8 17:36:54 1998
***************
*** 1781,1787 ****
  }
  
  /*
!  * Initialize UART to known state.
   */
  int
  cominit(iot, iobase, rate, frequency, cflag, iohp)
--- 1781,1787 ----
  }
  
  /*
!  * Initialize UART for use as console or KGDB line.
   */
  int
  cominit(iot, iobase, rate, frequency, cflag, iohp)
***************
*** 1803,1809 ****
  	bus_space_write_1(iot, ioh, com_dlbl, rate);
  	bus_space_write_1(iot, ioh, com_dlbh, rate >> 8);
  	bus_space_write_1(iot, ioh, com_lcr, cflag2lcr(cflag));
! 	bus_space_write_1(iot, ioh, com_mcr, 0);
  	bus_space_write_1(iot, ioh, com_fifo,
  	    FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_1);
  	bus_space_write_1(iot, ioh, com_ier, 0);
--- 1803,1809 ----
  	bus_space_write_1(iot, ioh, com_dlbl, rate);
  	bus_space_write_1(iot, ioh, com_dlbh, rate >> 8);
  	bus_space_write_1(iot, ioh, com_lcr, cflag2lcr(cflag));
! 	bus_space_write_1(iot, ioh, com_mcr, MCR_DTR | MCR_RTS);
  	bus_space_write_1(iot, ioh, com_fifo,
  	    FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_1);
  	bus_space_write_1(iot, ioh, com_ier, 0);
>Audit-Trail:
>Unformatted: