Subject: port-hp300/18735: Hardware flow control problem in dcm driver
To: None <gnats-bugs@gnats.netbsd.org>
From: None <swp@alumni.rice.edu>
List: netbsd-bugs
Date: 10/19/2002 23:48:46
>Number:         18735
>Category:       port-hp300
>Synopsis:       CTS flow control broken on dcm modem port
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    port-hp300-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Oct 19 22:50:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Steve Peurifoy
>Release:        NetBSD 1.5.2
>Organization:
>Environment:
System: NetBSD loop.home 1.5.2 NetBSD 1.5.2 (loop) #1: Sat Oct 19 22:08:48 MDT 2002 root@loop.home:/usr/obj/sys/arch/hp300/compile/loop hp300


>Description:
	The modem port (port 0) of a dcm mux card will not stop transmitting
	data when crtscts is enabled and the receiving device negates CTS.
>How-To-Repeat:
	Connecting the port to a modem using RTS/CTS flow control and
	attempting an upload of any significant size results in a
	dropped connection in my setup.  Strategically placed kernel
	debug printf()'s confirm that the interrupt service routine
	dcmmint() is being called when CTS changes state but TS_TTSTOP
	is never set.
>Fix:
	The dcmmint() function checks tp->t_flags to find out if
	RTS/CTS flow control is enabled.  This appears to be some
	sort of holdover from 4.3 given where else it appears in
	the tree but I'm only guessing.  In any case, the relevant
	bit is never set in this variable.  Note that tp->t_flags
	also shows up in several debug printf()'s in the dcm driver.
	They aren't doing any harm so I've ignored them in the
	following patch.  With this change, my uploads are much more
	reliable.

Index: dcm.c
===================================================================
RCS file: /cvs/src/sys/arch/hp300/dev/dcm.c,v
retrieving revision 1.1.1.2
diff -c -r1.1.1.2 dcm.c
*** dcm.c	1998/11/11 13:55:11	1.1.1.2
--- dcm.c	2002/10/19 07:22:32
***************
*** 917,923 ****
  	delta = mcnd ^ sc->sc_mcndlast[port];
  	sc->sc_mcndlast[port] = mcnd;
  	if ((delta & MI_CTS) && (tp->t_state & TS_ISOPEN) &&
! 	    (tp->t_flags & CCTS_OFLOW)) {
  		if (mcnd & MI_CTS) {
  			tp->t_state &= ~TS_TTSTOP;
  			ttstart(tp);
--- 917,923 ----
  	delta = mcnd ^ sc->sc_mcndlast[port];
  	sc->sc_mcndlast[port] = mcnd;
  	if ((delta & MI_CTS) && (tp->t_state & TS_ISOPEN) &&
! 	    (tp->t_cflag & CCTS_OFLOW)) {
  		if (mcnd & MI_CTS) {
  			tp->t_state &= ~TS_TTSTOP;
  			ttstart(tp);


>Release-Note:
>Audit-Trail:
>Unformatted: