--- linux-2.6.5-rc3/drivers/net/wireless/airo.c	2004-03-30 05:25:33.000000000 +0200
+++ linux/drivers/net/wireless/airo.c	2004-03-15 18:51:06.000000000 +0100
@@ -1071,7 +1071,7 @@
 static int get_dec_u16( char *buffer, int *start, int limit );
 static void OUT4500( struct airo_info *, u16 register, u16 value );
 static unsigned short IN4500( struct airo_info *, u16 register );
-static u16 setup_card(struct airo_info*, u8 *mac);
+static u16 setup_card(struct airo_info*, u8 *mac, int lock);
 static int enable_MAC( struct airo_info *ai, Resp *rsp, int lock );
 static void disable_MAC(struct airo_info *ai, int lock);
 static void enable_interrupts(struct airo_info*);
@@ -1709,9 +1709,9 @@
 	return rc;
 }
 
-static int readWepKeyRid(struct airo_info*ai, WepKeyRid *wkr, int temp) {
+static int readWepKeyRid(struct airo_info*ai, WepKeyRid *wkr, int temp, int lock) {
 	int rc = PC4500_readrid(ai, temp ? RID_WEP_TEMP : RID_WEP_PERM,
-				wkr, sizeof(*wkr), 1);
+				wkr, sizeof(*wkr), lock);
 
 	wkr->len = le16_to_cpu(wkr->len);
 	wkr->kindex = le16_to_cpu(wkr->kindex);
@@ -1748,7 +1748,7 @@
 	}
 	return rc;
 }
-static int writeSsidRid(struct airo_info*ai, SsidRid *pssidr) {
+static int writeSsidRid(struct airo_info*ai, SsidRid *pssidr, int lock) {
 	int rc;
 	int i;
 	SsidRid ssidr = *pssidr;
@@ -1757,7 +1757,7 @@
 	for(i = 0; i < 3; i++) {
 		ssidr.ssids[i].len = cpu_to_le16(ssidr.ssids[i].len);
 	}
-	rc = PC4500_writerid(ai, RID_SSID, &ssidr, sizeof(ssidr), 1);
+	rc = PC4500_writerid(ai, RID_SSID, &ssidr, sizeof(ssidr), lock);
 	return rc;
 }
 static int readConfigRid(struct airo_info*ai, int lock) {
@@ -1850,14 +1850,14 @@
 	aplr->len = le16_to_cpu(aplr->len);
 	return rc;
 }
-static int writeAPListRid(struct airo_info*ai, APListRid *aplr) {
+static int writeAPListRid(struct airo_info*ai, APListRid *aplr, int lock) {
 	int rc;
 	aplr->len = cpu_to_le16(aplr->len);
-	rc = PC4500_writerid(ai, RID_APLIST, aplr, sizeof(*aplr), 1);
+	rc = PC4500_writerid(ai, RID_APLIST, aplr, sizeof(*aplr), lock);
 	return rc;
 }
-static int readCapabilityRid(struct airo_info*ai, CapabilityRid *capr) {
-	int rc = PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr), 1);
+static int readCapabilityRid(struct airo_info*ai, CapabilityRid *capr, int lock) {
+	int rc = PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr), lock);
 	u16 *s;
 
 	capr->len = le16_to_cpu(capr->len);
@@ -2213,6 +2213,10 @@
 	u32 *vals = stats_rid.vals;
 
 	clear_bit(JOB_STATS, &ai->flags);
+	if (ai->power) {
+		up(&ai->sem);
+		return;
+	}
 	readStatsRid(ai, &stats_rid, RID_STATS, 0);
 	up(&ai->sem);
 
@@ -2649,10 +2653,10 @@
 	return dev;
 }
 
-int reset_mpi_card( struct net_device *dev ) {
+int reset_mpi_card( struct net_device *dev , int lock) {
 	struct airo_info *ai = dev->priv;
 
-	if (down_interruptible(&ai->sem))
+	if (lock && down_interruptible(&ai->sem))
 		return -1;
 	waitbusy (ai);
 	OUT4500(ai,COMMAND,CMD_SOFTRESET);
@@ -2661,7 +2665,8 @@
 	waitbusy (ai);
 	set_current_state (TASK_UNINTERRUPTIBLE);
 	schedule_timeout (HZ/5);
-	up(&ai->sem);
+	if (lock)
+		up(&ai->sem);
 	return 0;
 }
 
@@ -2728,7 +2733,7 @@
 	dev->base_addr = port;
 
 	if (test_bit(FLAG_MPI,&ai->flags))
-		reset_mpi_card (dev);
+		reset_mpi_card (dev, 1);
 
 	rc = request_irq( dev->irq, airo_interrupt, SA_SHIRQ, dev->name, dev );
 	if (rc) {
@@ -2751,7 +2756,7 @@
 	}
 
 	if (probe) {
-		if ( setup_card( ai, dev->dev_addr ) != SUCCESS ) {
+		if ( setup_card( ai, dev->dev_addr, 1 ) != SUCCESS ) {
 			printk( KERN_ERR "airo: MAC could not be enabled\n" );
 			rc = -EIO;
 			goto err_out_map;
@@ -2830,10 +2835,10 @@
 	int i;
 	struct airo_info *ai = dev->priv;
 
-	if (reset_mpi_card (dev))
+	if (reset_mpi_card (dev, 1))
 		return -1;
 
-	if ( setup_card(ai, dev->dev_addr ) != SUCCESS ) {
+	if ( setup_card(ai, dev->dev_addr, 1 ) != SUCCESS ) {
 		printk( KERN_ERR "airo: MAC could not be enabled\n" );
 		return -1;
 	}
@@ -3473,7 +3478,7 @@
 	}
 }
 
-static u16 setup_card(struct airo_info *ai, u8 *mac)
+static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
 {
 	Cmd cmd;
 	Resp rsp;
@@ -3493,10 +3498,11 @@
 	/* The NOP is the first step in getting the card going */
 	cmd.cmd = NOP;
 	cmd.parm0 = cmd.parm1 = cmd.parm2 = 0;
-	if (down_interruptible(&ai->sem))
+	if (lock && down_interruptible(&ai->sem))
 		return ERROR;
 	if ( issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
-		up(&ai->sem);
+		if (lock)
+			up(&ai->sem);
 		return ERROR;
 	}
 	disable_MAC( ai, 0);
@@ -3505,7 +3511,8 @@
 	if (!test_bit(FLAG_MPI,&ai->flags)) {
 		cmd.cmd = CMD_ENABLEAUX;
 		if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
-			up(&ai->sem);
+			if (lock)
+				up(&ai->sem);
 			printk(KERN_ERR "airo: Error checking for AUX port\n");
 			return ERROR;
 		}
@@ -3517,7 +3524,8 @@
 			printk(KERN_DEBUG "airo: Doing AUX bap_reads\n");
 		}
 	}
-	up(&ai->sem);
+	if (lock)
+		up(&ai->sem);
 	if (ai->config.len == 0) {
 		tdsRssiRid rssi_rid;
 		CapabilityRid cap_rid;
@@ -3531,10 +3539,10 @@
 			ai->SSID = NULL;
 		}
 		// general configuration (read/modify/write)
-		status = readConfigRid(ai, 1);
+		status = readConfigRid(ai, lock);
 		if ( status != SUCCESS ) return ERROR;
 
-		status = readCapabilityRid(ai, &cap_rid);
+		status = readCapabilityRid(ai, &cap_rid, lock);
 		if ( status != SUCCESS ) return ERROR;
 
 		if (test_bit(FLAG_MPI, &ai->flags) &&
@@ -3543,7 +3551,7 @@
 		    strcmp (cap_rid.prodVer, "5b00.08"))
 			printk(KERN_ERR "airo: Firmware version %s is not supported. Use it at your own risk!\n", cap_rid.prodVer);
 
-		status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),1);
+		status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),lock);
 		if ( status == SUCCESS ) {
 			if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL)
 				memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512);
@@ -3610,29 +3618,29 @@
 		mySsid.len = sizeof(mySsid);
 	}
 
-	status = writeConfigRid(ai, 1);
+	status = writeConfigRid(ai, lock);
 	if ( status != SUCCESS ) return ERROR;
 
 	/* Set up the SSID list */
 	if ( ssids[0] ) {
-		status = writeSsidRid(ai, &mySsid);
+		status = writeSsidRid(ai, &mySsid, lock);
 		if ( status != SUCCESS ) return ERROR;
 	}
 
-	status = enable_MAC(ai, &rsp, 1);
+	status = enable_MAC(ai, &rsp, lock);
 	if ( status != SUCCESS || (rsp.status & 0xFF00) != 0) {
 		printk( KERN_ERR "airo: Bad MAC enable reason = %x, rid = %x, offset = %d\n", rsp.rsp0, rsp.rsp1, rsp.rsp2 );
 		return ERROR;
 	}
 
 	/* Grab the initial wep key, we gotta save it for auto_wep */
-	rc = readWepKeyRid(ai, &wkr, 1);
+	rc = readWepKeyRid(ai, &wkr, 1, lock);
 	if (rc == SUCCESS) do {
 		lastindex = wkr.kindex;
 		if (wkr.kindex == 0xffff) {
 			ai->defindex = wkr.mac[0];
 		}
-		rc = readWepKeyRid(ai, &wkr, 0);
+		rc = readWepKeyRid(ai, &wkr, 0, lock);
 	} while(lastindex != wkr.kindex);
 
 	if (auto_wep) {
@@ -4417,7 +4425,7 @@
 	}
 
 	readStatusRid(apriv, &status_rid, 1);
-	readCapabilityRid(apriv, &cap_rid);
+	readCapabilityRid(apriv, &cap_rid, 1);
 
         i = sprintf(data->rbuffer, "Status: %s%s%s%s%s%s%s%s%s\n",
                     status_rid.mode & 1 ? "CFG ": "",
@@ -4865,7 +4873,7 @@
 	if (i)
 		SSID_rid.len = sizeof(SSID_rid);
 	disable_MAC(ai, 1);
-	writeSsidRid(ai, &SSID_rid);
+	writeSsidRid(ai, &SSID_rid, 1);
 	enable_MAC(ai, &rsp, 1);
 }
 
@@ -4906,7 +4914,7 @@
 		}
 	}
 	disable_MAC(ai, 1);
-	writeAPListRid(ai, &APList_rid);
+	writeAPListRid(ai, &APList_rid, 1);
 	enable_MAC(ai, &rsp, 1);
 }
 
@@ -4931,7 +4939,7 @@
 	int rc;
 	u16 lastindex;
 
-	rc = readWepKeyRid(ai, &wkr, 1);
+	rc = readWepKeyRid(ai, &wkr, 1, 1);
 	if (rc == SUCCESS) do {
 		lastindex = wkr.kindex;
 		if (wkr.kindex == index) {
@@ -4940,7 +4948,7 @@
 			}
 			return wkr.klen;
 		}
-		readWepKeyRid(ai, &wkr, 0);
+		readWepKeyRid(ai, &wkr, 0, 1);
 	} while(lastindex != wkr.kindex);
 	return -1;
 }
@@ -5049,7 +5057,7 @@
 
 	ptr = data->rbuffer;
 	strcpy(ptr, "No wep keys\n");
-	rc = readWepKeyRid(ai, &wkr, 1);
+	rc = readWepKeyRid(ai, &wkr, 1, 1);
 	if (rc == SUCCESS) do {
 		lastindex = wkr.kindex;
 		if (wkr.kindex == 0xffff) {
@@ -5059,7 +5067,7 @@
 			j += sprintf(ptr+j, "Key %d set with length = %d\n",
 				     (int)wkr.kindex, (int)wkr.klen);
 		}
-		readWepKeyRid(ai, &wkr, 0);
+		readWepKeyRid(ai, &wkr, 0, 1);
 	} while((lastindex != wkr.kindex) && (j < 180-30));
 
 	data->readlen = strlen( data->rbuffer );
@@ -5349,6 +5357,7 @@
 	readAPListRid(ai, ai->APList);
 	readSsidRid(ai, ai->SSID);
 	memset(&cmd, 0, sizeof(cmd));
+	/* the lock will be released at the end of the resume callback */
 	if (down_interruptible(&ai->sem))
 		return -EAGAIN;
 	disable_MAC(ai, 0);
@@ -5356,7 +5365,6 @@
 	ai->power = state;
 	cmd.cmd=HOSTSLEEP;
 	issuecommand(ai, &cmd, &rsp);
-	up(&ai->sem);
 	return 0;
 }
 
@@ -5372,8 +5380,8 @@
 	if (!ai->power)
 		return 0;
 
-	if (ai->power > 2) {
-		err = reset_mpi_card(dev);
+	if (ai->power > 1) {
+		err = reset_mpi_card(dev, 0);
 		if (err) {
 			printk(KERN_ERR "%s: Error %d resetting on %s()\n",
 			       dev->name, err, __FUNCTION__);
@@ -5381,7 +5389,7 @@
 		}
 		schedule_timeout (HZ/2);
 		mpi_init_descriptors(ai);
-		setup_card(ai, dev->dev_addr);
+		setup_card(ai, dev->dev_addr, 0);
 		clear_bit(FLAG_RADIO_OFF, &ai->flags);
 		clear_bit(FLAG_RADIO_DOWN, &ai->flags);
 		clear_bit(FLAG_PENDING_XMIT, &ai->flags);
@@ -5392,24 +5400,25 @@
 	}
 
 	set_bit (FLAG_COMMIT, &ai->flags);
-	disable_MAC(ai, 1);
+	disable_MAC(ai, 0);
         schedule_timeout (HZ/5);
 	if (ai->SSID) {
-		writeSsidRid(ai, ai->SSID);
+		writeSsidRid(ai, ai->SSID, 0);
 		kfree(ai->SSID);
 		ai->SSID = NULL;
 	}
 	if (ai->APList) {
-		writeAPListRid(ai, ai->APList);
+		writeAPListRid(ai, ai->APList, 0);
 		kfree(ai->APList);
 		ai->APList = NULL;
 	}
-	writeConfigRid(ai, 1);
-	enable_MAC(ai, &rsp, 1);
+	writeConfigRid(ai, 0);
+	enable_MAC(ai, &rsp, 0);
 	ai->power = 0;
 	netif_device_attach(dev);
 	netif_wake_queue(dev);
 	enable_interrupts(ai);
+	up(&ai->sem);
 	return 0;
 }
 #endif
@@ -5597,7 +5606,7 @@
 	SSID_rid.len = sizeof(SSID_rid);
 	/* Write it to the card */
 	disable_MAC(local, 1);
-	writeSsidRid(local, &SSID_rid);
+	writeSsidRid(local, &SSID_rid, 1);
 	enable_MAC(local, &rsp, 1);
 
 	return 0;
@@ -5661,7 +5670,7 @@
 		APList_rid.len = sizeof(APList_rid);
 		memcpy(APList_rid.ap[0], awrq->sa_data, ETH_ALEN);
 		disable_MAC(local, 1);
-		writeAPListRid(local, &APList_rid);
+		writeAPListRid(local, &APList_rid, 1);
 		enable_MAC(local, &rsp, 1);
 	}
 	return 0;
@@ -5745,7 +5754,7 @@
 	int	i;
 
 	/* First : get a valid bit rate value */
-	readCapabilityRid(local, &cap_rid);
+	readCapabilityRid(local, &cap_rid, 1);
 
 	/* Which type of value ? */
 	if((vwrq->value < 8) && (vwrq->value >= 0)) {
@@ -6015,7 +6024,7 @@
 	CapabilityRid cap_rid;		/* Card capability info */
 
 	/* Is WEP supported ? */
-	readCapabilityRid(local, &cap_rid);
+	readCapabilityRid(local, &cap_rid, 1);
 	/* Older firmware doesn't support this...
 	if(!(cap_rid.softCap & 2)) {
 		return -EOPNOTSUPP;
@@ -6103,7 +6112,7 @@
 	CapabilityRid cap_rid;		/* Card capability info */
 
 	/* Is it supported ? */
-	readCapabilityRid(local, &cap_rid);
+	readCapabilityRid(local, &cap_rid, 1);
 	if(!(cap_rid.softCap & 2)) {
 		return -EOPNOTSUPP;
 	}
@@ -6151,7 +6160,7 @@
 	int i;
 	int rc = -EINVAL;
 
-	readCapabilityRid(local, &cap_rid);
+	readCapabilityRid(local, &cap_rid, 1);
 
 	if (vwrq->disabled) {
 		set_bit (FLAG_RADIO_OFF | FLAG_COMMIT, &local->flags);
@@ -6275,7 +6284,7 @@
 	int		i;
 	int		k;
 
-	readCapabilityRid(local, &cap_rid);
+	readCapabilityRid(local, &cap_rid, 1);
 
 	dwrq->length = sizeof(struct iw_range);
 	memset(range, 0, sizeof(*range));
@@ -6774,8 +6783,8 @@
 		readSsidRid(local, &SSID_rid);
 		reset_airo_card(dev);
 		disable_MAC(local, 1);
-		writeSsidRid(local, &SSID_rid);
-		writeAPListRid(local, &APList_rid);
+		writeSsidRid(local, &SSID_rid, 1);
+		writeAPListRid(local, &APList_rid, 1);
 	}
 	if (down_interruptible(&local->sem))
 		return -ERESTARTSYS;
@@ -7097,7 +7106,10 @@
 
 static int writerids(struct net_device *dev, aironet_ioctl *comp) {
 	struct airo_info *ai = dev->priv;
-	int  ridcode, enabled;
+	int  ridcode;
+#ifdef MICSUPPORT
+        int  enabled;
+#endif
 	Resp      rsp;
 	static int (* writer)(struct airo_info *, u16 rid, const void *, int, int);
 	unsigned char *iobuf;
@@ -7425,7 +7437,7 @@
 	set_current_state (TASK_UNINTERRUPTIBLE);
 	schedule_timeout (HZ);          /* Added 12/7/00 */
 	clear_bit (FLAG_FLASHING, &ai->flags);
-	status = setup_card(ai, dev->dev_addr);
+	status = setup_card(ai, dev->dev_addr, 1);
 
 	if (!test_bit(FLAG_MPI,&ai->flags))
 		for( i = 0; i < MAX_FIDS; i++ ) {
