Subject: Re: kern/37462: use of com at pcmcia hangs system
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Takehiko NOZAKI <th-nozaki@netwrk.co.jp>
List: netbsd-bugs
Date: 12/31/2007 10:20:03
The following reply was made to PR kern/37462; it has been noted by GNATS.

From: Takehiko NOZAKI <th-nozaki@netwrk.co.jp>
To: gnats-bugs@NetBSD.org
Cc: apb@cequrux.com
Subject: Re: kern/37462: use of com at pcmcia hangs system
Date: Mon, 31 Dec 2007 19:13:26 +0900

 hi,
 
 > When I attempt to use a GSM UMTS modem, the system hangs so hard that I
 > can't even enter ddb.  The modem is a PCMCIA card that attaches as com
 > at pcmcia.
 
 my ThinkPad s30 + NetIndex AX530IN pcmcia modem card have same problem too.
  
 > I first noticed the problem using pppd, but I can replicate the problem
 > using cu.  I get the same problem with the jmcneill-pm branch as with a
 > kernel from HEAD.
 > 
 > This used to work a few months ago.
 
 this problem introduced by merging vmlocking branch:
     src/sys/dev/ic/com.c r1.262 -> r1.263
     http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/dev/ic/com.c.diff?r1=1.262&r2=1.263
 it uses mutex_spin_enter(9) instead of simple_lock(9).
 but this change is not good for tsleep(9) in src/sys/dev/pci/pccbb.c line 1370.
 (mutex_spin_enter -> tsleep -> mi_switch -> cpu_switchto -> hangup)
 
 i don't know how to solve this problem, but here is a workaround.
 apply following patch and recompile your kernel.
 
 Index: com.c
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/ic/com.c,v
 retrieving revision 1.268
 diff -u -r1.268 com.c
 --- com.c	14 Dec 2007 03:36:54 -0000	1.268
 +++ com.c	30 Dec 2007 18:49:46 -0000
 @@ -724,7 +724,9 @@
  		if (!sc->enabled)
  			panic("com_shutdown: not enabled?");
  #endif
 +		mutex_spin_exit(&sc->sc_lock);
  		(*sc->disable)(sc);
 +		mutex_spin_enter(&sc->sc_lock);
  		sc->enabled = 0;
  	}
  	mutex_spin_exit(&sc->sc_lock);
 @@ -772,13 +774,14 @@
  		mutex_spin_enter(&sc->sc_lock);
  
  		if (sc->enable) {
 +			mutex_spin_exit(&sc->sc_lock);
  			if ((*sc->enable)(sc)) {
 -				mutex_spin_exit(&sc->sc_lock);
  				splx(s);
  				printf("%s: device enable failed\n",
  				       sc->sc_dev.dv_xname);
  				return (EIO);
  			}
 +			mutex_spin_enter(&sc->sc_lock);
  			sc->enabled = 1;
  			com_config(sc);
  		}
 
 this make ppp work again as far as my environment.
 ...but i don't know this is ok for multi-processor, other bus/architecture.
 
 very truly yours.
 --
 Takehiko NOZAKI <tnozaki@netbsd.org>