From d54bf49a84d29dc3e6a32db65a8c95278b742a4d Mon Sep 17 00:00:00 2001 From: Javier Achirica Date: Mon, 19 Apr 2004 04:58:55 -0400 Subject: [PATCH] [PATCH] airo: Fix suspend support --- drivers/net/wireless/airo.c | 124 ++++++++++++++++++++---------------- 1 file changed, 68 insertions(+), 56 deletions(-) diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 5545a9ad7736..6a677a8c7b95 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -1071,7 +1071,7 @@ struct airo_info; 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 @@ static int readBSSListRid(struct airo_info *ai, int first, 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 @@ static int readSsidRid(struct airo_info*ai, SsidRid *ssidr) { } 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 @@ static int writeSsidRid(struct airo_info*ai, SsidRid *pssidr) { 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 @@ static int readAPListRid(struct airo_info*ai, APListRid *aplr) { 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 @@ static void airo_read_stats(struct airo_info *ai) { 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 @@ static struct net_device *init_wifidev(struct airo_info *ai, 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 @@ int reset_mpi_card( struct net_device *dev ) { 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 @@ struct net_device *_init_airo_card( unsigned short irq, int port, 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 @@ struct net_device *_init_airo_card( unsigned short irq, int port, } 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 reset_airo_card( struct net_device *dev ) 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 @@ badrx: } } -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 @@ static u16 setup_card(struct airo_info *ai, u8 *mac) /* 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 @@ static u16 setup_card(struct airo_info *ai, u8 *mac) 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 @@ static u16 setup_card(struct airo_info *ai, u8 *mac) 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 @@ static u16 setup_card(struct airo_info *ai, u8 *mac) 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 @@ static u16 setup_card(struct airo_info *ai, u8 *mac) 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 @@ static u16 setup_card(struct airo_info *ai, u8 *mac) 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 @@ static int proc_status_open( struct inode *inode, struct file *file ) { } 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 @@ static void proc_SSID_on_close( struct inode *inode, struct file *file ) { 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 @@ static void proc_APList_on_close( struct inode *inode, struct file *file ) { } } disable_MAC(ai, 1); - writeAPListRid(ai, &APList_rid); + writeAPListRid(ai, &APList_rid, 1); enable_MAC(ai, &rsp, 1); } @@ -4931,7 +4939,7 @@ static int get_wep_key(struct airo_info *ai, u16 index) { 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 @@ static int get_wep_key(struct airo_info *ai, u16 index) { } return wkr.klen; } - readWepKeyRid(ai, &wkr, 0); + readWepKeyRid(ai, &wkr, 0, 1); } while(lastindex != wkr.kindex); return -1; } @@ -5049,7 +5057,7 @@ static int proc_wepkey_open( struct inode *inode, struct file *file ) { 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 @@ static int proc_wepkey_open( struct inode *inode, struct file *file ) { 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 @@ static int airo_pci_suspend(struct pci_dev *pdev, u32 state) 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 @@ static int airo_pci_suspend(struct pci_dev *pdev, u32 state) ai->power = state; cmd.cmd=HOSTSLEEP; issuecommand(ai, &cmd, &rsp); - up(&ai->sem); return 0; } @@ -5372,8 +5380,8 @@ static int airo_pci_resume(struct pci_dev *pdev) 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 @@ static int airo_pci_resume(struct pci_dev *pdev) } 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 @@ static int airo_pci_resume(struct pci_dev *pdev) } 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 @@ static int airo_set_essid(struct net_device *dev, 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 @@ static int airo_set_wap(struct net_device *dev, 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 @@ static int airo_set_rate(struct net_device *dev, 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 @@ static int airo_set_encode(struct net_device *dev, 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 @@ static int airo_get_encode(struct net_device *dev, 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 @@ static int airo_set_txpow(struct net_device *dev, 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 @@ static int airo_get_range(struct net_device *dev, 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 @@ static int airo_config_commit(struct net_device *dev, 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 readrids(struct net_device *dev, aironet_ioctl *comp) { 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 @@ int flashrestart(struct airo_info *ai,struct net_device *dev){ 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++ ) { -- 2.39.5