]> git.hungrycats.org Git - linux/commitdiff
[PATCH] airo: Fix suspend support
authorJavier Achirica <achirica@telefonica.net>
Mon, 19 Apr 2004 08:58:55 +0000 (04:58 -0400)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Mon, 19 Apr 2004 08:58:55 +0000 (04:58 -0400)
drivers/net/wireless/airo.c

index 5545a9ad7736d38f4e36f00cdef3bc6ef2877da8..6a677a8c7b952041e62fcf9a3888880454d2bff6 100644 (file)
@@ -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++ ) {