Subject: kern/30268: umodem (ucom) tty does not hanlde DCD correct
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Wolfgang Stukenbrock <wgstuken@s012.nagler-company.com>
List: netbsd-bugs
Date: 05/18/2005 08:46:00
>Number:         30268
>Category:       kern
>Synopsis:       umodem (ucom) tty does not hanlde DCD correct
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed May 18 08:46:00 +0000 2005
>Originator:     Wolfgang Stukenbrock
>Release:        NetBSD 2.0_2
>Organization:
	
>Environment:
	
	
System: NetBSD s012 2.0_RC5 NetBSD 2.0_RC5 (S012) #6: Tue Nov 30 11:38:39 CET 2004 wgstuken@s012:/export/netbsd-2.0rc4/src/sys/arch/i386/compile/S012 i386
Architecture: i386
Machine: i386
>Description:
	There are two tty lines for each physical tty. One dialin and one dialout device.
	The dialout device should open all the time, but the dialin-device should only open, if carrier is dedected
	on the DCD line.
	For usb-modems this does not work correctly - and it won't for any other usb-com device.
	The problem is located in sys/dev/usb/ucom.c. During parmeter setup of the modem, the code will always signal
	carrier to the upper tty-layer. For this reason, the an open on the dialin-device will always succee.
	To correct this problem the correct DCD-state needs to be signaled to the tty-layer. (see fix below)
	In order to continue to support usb-devices (other than umodem) that does not report any DCD information,
	it is also nessesary to set DCD for theese devices in the detection routine all the time.
	It looks to me, as if the work-around for non-DCD devices has been inserted at the wrong place.
>How-To-Repeat:
	Connect an usb-modem to the system, setup the modem to indicate no carrier on DCD and open /dev/ttyU0.
	It will succeed, but the open should hang ....
>Fix:
	see appended fix for ucom.c


***************
*** 791,797 ****
                            ISSET(sc->sc_msr, UMSR_DCD));
        } else {
                sc->sc_lsr = 0;
!               sc->sc_msr = 0;
        }
  }
  
--- 791,798 ----
                            ISSET(sc->sc_msr, UMSR_DCD));
        } else {
                sc->sc_lsr = 0;
! /* XXXX assume DCD is present, if we have no chance to check it ... */
!               sc->sc_msr = UMSR_DCD;
        }
  }
  
***************
*** 848,854 ****
         * explicit request.
         */
        DPRINTF(("ucomparam: l_modem\n"));
!       (void) (*tp->t_linesw->l_modem)(tp, 1 /* XXX carrier */ );
  
  #if 0
  XXX what if the hardware is not open
--- 849,855 ----
         * explicit request.
         */
        DPRINTF(("ucomparam: l_modem\n"));
!       (void) (*tp->t_linesw->l_modem)(tp, ISSET(sc->sc_msr, UMSR_DCD));
  
  #if 0
  XXX what if the hardware is not open

>Unformatted: