[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-wlan-devel
Subject:    [lwlan-devel] [PATCH] Fixing rare hang on "cardctl eject"
From:       Pavel Roskin <proski () gnu ! org>
Date:       2003-03-27 2:33:40
[Download RAW message or body]

Hello!

linux-wlan-ng 0.2.0 sometimes hangs if I run "cardctl eject" while the
interface is running.  This is quite hard to reproduce, but it's quite
annoying when it happens.  The simplest way for me to reproduce the
problem was to run this command for some time (5 minutes is usually
enough):

while :; do cardctl insert; sleep 2; wlanctl-ng wlan0 lnxreq_ifstate \
ifstate=enable; sleep 2; cardctl eject; done

The problem has been traced to hfa384x_docmd_wait() when it's called from
hfa384x_cmd_initialize().  The hang happens in random places inside
hfa384x_docmd_wait().  It is also known that adding any printk() to the
beginning of hfa384x_interrupt() prevents hanging.

The driver is run on a uni-processor machine with kernel 2.4.21-pre5-ac3
and kernel pcmcia.  SMP is enabled in the kernel (for the purpose of
testing my code).  The card is ZoomAir 4106 and has AP firmware version
0.3.7 flashed.

I believe that we have two problems here.  One is non-standard and
possibly incorrect use of spinlocks in hfa384x_docmd_wait().  If you check
Linux sources, you'll see that spin_is_locked() is almost exclusively used
in the debugging code and very old drivers like wavelan_cs.  Also
spin_lock() should only be used if the spinlocks are never used in
interrupt handlers (see Documentation/spinlocks.txt in the kernel), which
is probably not the case in linux-wlan-ng.

The second problem is that the driver is resetting the card without
disabling its interrupts.  While fixing spinlocks could be sufficient (and
the right thing to do), I don't think that any interrupts during the reset
would be of any use.

Following patch disables interrupts during firmware reset.

================================
--- src/prism2/driver/hfa384x.c
+++ src/prism2/driver/hfa384x.c
@@ -1254,6 +1254,10 @@ int hfa384x_cmd_initialize(hfa384x_t *hw
 	cmd.parm1 = 0;
 	cmd.parm2 = 0;

+	/* we don't want to be interrupted during the reset */
+	hfa384x_setreg(hw, 0, HFA384x_INTEN);
+	hfa384x_setreg(hw, 0xffff, HFA384x_EVACK);
+
 	result = hfa384x_docmd_wait(hw, &cmd);
 	if ( result == 0 ) {
 		for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) {
================================

P.S. The above script has been running for almost an hour with the patched
driver without hangs as I'm writing this.

-- 
Regards,
Pavel Roskin
_______________________________________________
Linux-wlan-devel mailing list
Linux-wlan-devel@lists.linux-wlan.com
http://lists.linux-wlan.com/mailman/listinfo/linux-wlan-devel
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic