Subject: port-hp300/18849: open of dcm modem port sometimes hangs
To: None <gnats-bugs@gnats.netbsd.org>
From: None <swp@alumni.rice.edu>
List: netbsd-bugs
Date: 10/29/2002 01:39:01
>Number: 18849
>Category: port-hp300
>Synopsis: open of dcm modem port sometimes hangs
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: port-hp300-maintainer
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Oct 29 00:40:00 PST 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) #2: Fri Oct 25 23:49:35 MDT 2002 root@loop.home:/usr/obj/sys/arch/hp300/compile/loop hp300
>Description:
Occasionally a blocking open of dcm port 0 will hang in ttyopen()
waiting for carrier detect to be asserted when it's already
present.
>How-To-Repeat:
I've encountered this at random times wth a couple of different
modems.
>Fix:
The problem is that dcmmint() will return before updating the
value of sc->sc_mcndlast if the device is not open. If carrier
detect drops after the device is closed, sc->sc_mcndlast will
no longer correctly represent the "previous" state of the
signals when the next transition of carrier detect occurs.
A subsequent blocking open will wait forever for an event
which has in fact taken place.
Index: dcm.c
===================================================================
RCS file: /cvs/src/sys/arch/hp300/dev/dcm.c,v
retrieving revision 1.2
diff -c -r1.2 dcm.c
*** dcm.c 2002/10/21 08:36:57 1.2
--- dcm.c 2002/10/26 05:46:09
***************
*** 908,917 ****
struct tty *tp;
struct dcmdevice *dcm = sc->sc_dcm;
- tp = sc->sc_tty[port];
- if (tp == NULL || (tp->t_state & TS_ISOPEN) == 0)
- return;
-
#ifdef DEBUG
if (dcmdebug & DDB_MODEM)
printf("%s port %d: dcmmint: mcnd %x mcndlast %x\n",
--- 908,913 ----
***************
*** 919,924 ****
--- 915,924 ----
#endif
delta = mcnd ^ sc->sc_mcndlast[port];
sc->sc_mcndlast[port] = mcnd;
+ tp = sc->sc_tty[port];
+ if (tp == NULL || (tp->t_state & TS_ISOPEN) == 0)
+ return;
+
if ((delta & MI_CTS) && (tp->t_state & TS_ISOPEN) &&
(tp->t_cflag & CCTS_OFLOW)) {
if (mcnd & MI_CTS) {
>Release-Note:
>Audit-Trail:
>Unformatted: