Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
[pandora-kernel.git] / drivers / net / wireless / spectrum_cs.c
index f7b77ce..bcc7038 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Driver for 802.11b cards using RAM-loadable Symbol firmware, such as
- * Symbol Wireless Networker LA4100, CompactFlash cards by Socket
+ * Symbol Wireless Networker LA4137, CompactFlash cards by Socket
  * Communications and Intel PRO/Wireless 2011B.
  *
  * The driver implements Symbol firmware download.  The rest is handled
@@ -21,7 +21,6 @@
 #define DRIVER_NAME "spectrum_cs"
 #define PFX DRIVER_NAME ": "
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -35,8 +34,6 @@
 
 #include "orinoco.h"
 
-static unsigned char *primsym;
-static unsigned char *secsym;
 static const char primary_fw_name[] = "symbol_sp24t_prim_fw";
 static const char secondary_fw_name[] = "symbol_sp24t_sec_fw";
 
@@ -120,8 +117,8 @@ static void spectrum_cs_release(struct pcmcia_device *link);
  * Each block has the following structure.
  */
 struct dblock {
-       __le32 _addr;           /* adapter address where to write the block */
-       __le16 _len;            /* length of the data only, in bytes */
+       __le32 addr;            /* adapter address where to write the block */
+       __le16 len;             /* length of the data only, in bytes */
        char data[0];           /* data to be written */
 } __attribute__ ((packed));
 
@@ -131,9 +128,9 @@ struct dblock {
  * items with matching ID should be written.
  */
 struct pdr {
-       __le32 _id;             /* record ID */
-       __le32 _addr;           /* adapter address where to write the data */
-       __le32 _len;            /* expected length of the data, in bytes */
+       __le32 id;              /* record ID */
+       __le32 addr;            /* adapter address where to write the data */
+       __le32 len;             /* expected length of the data, in bytes */
        char next[0];           /* next PDR starts here */
 } __attribute__ ((packed));
 
@@ -144,8 +141,8 @@ struct pdr {
  * be plugged into the secondary firmware.
  */
 struct pdi {
-       __le16 _len;            /* length of ID and data, in words */
-       __le16 _id;             /* record ID */
+       __le16 len;             /* length of ID and data, in words */
+       __le16 id;              /* record ID */
        char data[0];           /* plug data */
 } __attribute__ ((packed));
 
@@ -154,44 +151,44 @@ struct pdi {
 static inline u32
 dblock_addr(const struct dblock *blk)
 {
-       return le32_to_cpu(blk->_addr);
+       return le32_to_cpu(blk->addr);
 }
 
 static inline u32
 dblock_len(const struct dblock *blk)
 {
-       return le16_to_cpu(blk->_len);
+       return le16_to_cpu(blk->len);
 }
 
 static inline u32
 pdr_id(const struct pdr *pdr)
 {
-       return le32_to_cpu(pdr->_id);
+       return le32_to_cpu(pdr->id);
 }
 
 static inline u32
 pdr_addr(const struct pdr *pdr)
 {
-       return le32_to_cpu(pdr->_addr);
+       return le32_to_cpu(pdr->addr);
 }
 
 static inline u32
 pdr_len(const struct pdr *pdr)
 {
-       return le32_to_cpu(pdr->_len);
+       return le32_to_cpu(pdr->len);
 }
 
 static inline u32
 pdi_id(const struct pdi *pdi)
 {
-       return le16_to_cpu(pdi->_id);
+       return le16_to_cpu(pdi->id);
 }
 
 /* Return length of the data only, in bytes */
 static inline u32
 pdi_len(const struct pdi *pdi)
 {
-       return 2 * (le16_to_cpu(pdi->_len) - 1);
+       return 2 * (le16_to_cpu(pdi->len) - 1);
 }
 
 
@@ -245,7 +242,7 @@ spectrum_reset(struct pcmcia_device *link, int idle)
        u_int save_cor;
 
        /* Doing it if hardware is gone is guaranteed crash */
-       if (pcmcia_dev_present(link))
+       if (!pcmcia_dev_present(link))
                return -ENODEV;
 
        /* Save original COR value */
@@ -343,8 +340,7 @@ spectrum_plug_pdi(hermes_t *hw, struct pdr *first_pdr, struct pdi *pdi)
 
        /* do the actual plugging */
        spectrum_aux_setaddr(hw, pdr_addr(pdr));
-       hermes_write_words(hw, HERMES_AUXDATA, pdi->data,
-                          pdi_len(pdi) / 2);
+       hermes_write_bytes(hw, HERMES_AUXDATA, pdi->data, pdi_len(pdi));
 
        return 0;
 }
@@ -424,8 +420,8 @@ spectrum_load_blocks(hermes_t *hw, const struct dblock *first_block)
 
        while (dblock_addr(blk) != BLOCK_END) {
                spectrum_aux_setaddr(hw, blkaddr);
-               hermes_write_words(hw, HERMES_AUXDATA, blk->data,
-                                  blklen / 2);
+               hermes_write_bytes(hw, HERMES_AUXDATA, blk->data,
+                                  blklen);
 
                blk = (struct dblock *) &blk->data[blklen];
                blkaddr = dblock_addr(blk);
@@ -442,7 +438,7 @@ spectrum_load_blocks(hermes_t *hw, const struct dblock *first_block)
  */
 static int
 spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link,
-                 const unsigned char *image)
+                 const unsigned char *image, int secondary)
 {
        int ret;
        const unsigned char *ptr;
@@ -457,7 +453,7 @@ spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link,
        first_block = (const struct dblock *) ptr;
 
        /* Read the PDA */
-       if (image != primsym) {
+       if (secondary) {
                ret = spectrum_read_pda(hw, pda, sizeof(pda));
                if (ret)
                        return ret;
@@ -474,7 +470,7 @@ spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link,
                return ret;
 
        /* Write the PDA to the adapter */
-       if (image != primsym) {
+       if (secondary) {
                ret = spectrum_apply_pda(hw, first_block, pda);
                if (ret)
                        return ret;
@@ -489,7 +485,7 @@ spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link,
        ret = hermes_init(hw);
 
        /* hermes_reset() should return 0 with the secondary firmware */
-       if (image != primsym && ret != 0)
+       if (secondary && ret != 0)
                return -ENODEV;
 
        /* And this should work with any firmware */
@@ -511,33 +507,30 @@ spectrum_dl_firmware(hermes_t *hw, struct pcmcia_device *link)
        const struct firmware *fw_entry;
 
        if (request_firmware(&fw_entry, primary_fw_name,
-                            &handle_to_dev(link)) == 0) {
-               primsym = fw_entry->data;
-       } else {
+                            &handle_to_dev(link)) != 0) {
                printk(KERN_ERR PFX "Cannot find firmware: %s\n",
                       primary_fw_name);
                return -ENOENT;
        }
 
-       if (request_firmware(&fw_entry, secondary_fw_name,
-                            &handle_to_dev(link)) == 0) {
-               secsym = fw_entry->data;
-       } else {
-               printk(KERN_ERR PFX "Cannot find firmware: %s\n",
-                      secondary_fw_name);
-               return -ENOENT;
-       }
-
        /* Load primary firmware */
-       ret = spectrum_dl_image(hw, link, primsym);
+       ret = spectrum_dl_image(hw, link, fw_entry->data, 0);
+       release_firmware(fw_entry);
        if (ret) {
                printk(KERN_ERR PFX "Primary firmware download failed\n");
                return ret;
        }
 
-       /* Load secondary firmware */
-       ret = spectrum_dl_image(hw, link, secsym);
+       if (request_firmware(&fw_entry, secondary_fw_name,
+                            &handle_to_dev(link)) != 0) {
+               printk(KERN_ERR PFX "Cannot find firmware: %s\n",
+                      secondary_fw_name);
+               return -ENOENT;
+       }
 
+       /* Load secondary firmware */
+       ret = spectrum_dl_image(hw, link, fw_entry->data, 1);
+       release_firmware(fw_entry);
        if (ret) {
                printk(KERN_ERR PFX "Secondary firmware download failed\n");
        }
@@ -626,14 +619,11 @@ static void spectrum_cs_detach(struct pcmcia_device *link)
 {
        struct net_device *dev = link->priv;
 
+       if (link->dev_node)
+               unregister_netdev(dev);
+
        spectrum_cs_release(link);
 
-       DEBUG(0, PFX "detach: link=%p link->dev_node=%p\n", link, link->dev_node);
-       if (link->dev_node) {
-               DEBUG(0, PFX "About to unregister net device %p\n",
-                     dev);
-               unregister_netdev(dev);
-       }
        free_orinocodev(dev);
 }                              /* spectrum_cs_detach */
 
@@ -653,13 +643,10 @@ spectrum_cs_config(struct pcmcia_device *link)
        int last_fn, last_ret;
        u_char buf[64];
        config_info_t conf;
-       cisinfo_t info;
        tuple_t tuple;
        cisparse_t parse;
        void __iomem *mem;
 
-       CS_CHECK(ValidateCIS, pcmcia_validate_cis(link, &info));
-
        /*
         * This reads the card's CONFIG tuple to find its
         * configuration registers.
@@ -709,12 +696,6 @@ spectrum_cs_config(struct pcmcia_device *link)
                        goto next_entry;
                link->conf.ConfigIndex = cfg->index;
 
-               /* Does this card need audio output? */
-               if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
-                       link->conf.Attributes |= CONF_ENABLE_SPKR;
-                       link->conf.Status = CCSR_AUDIO_ENA;
-               }
-
                /* Use power settings for Vcc and Vpp if present */
                /* Note that the CIS values need to be rescaled */
                if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
@@ -835,19 +816,10 @@ spectrum_cs_config(struct pcmcia_device *link)
                                     net_device has been registered */
 
        /* Finally, report what we've done */
-       printk(KERN_DEBUG "%s: index 0x%02x: ",
-              dev->name, link->conf.ConfigIndex);
-       if (link->conf.Vpp)
-               printk(", Vpp %d.%d", link->conf.Vpp / 10,
-                      link->conf.Vpp % 10);
-       printk(", irq %d", link->irq.AssignedIRQ);
-       if (link->io.NumPorts1)
-               printk(", io 0x%04x-0x%04x", link->io.BasePort1,
-                      link->io.BasePort1 + link->io.NumPorts1 - 1);
-       if (link->io.NumPorts2)
-               printk(" & 0x%04x-0x%04x", link->io.BasePort2,
-                      link->io.BasePort2 + link->io.NumPorts2 - 1);
-       printk("\n");
+       printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
+              "0x%04x-0x%04x\n", dev->name, dev->class_dev.dev->bus_id,
+              link->irq.AssignedIRQ, link->io.BasePort1,
+              link->io.BasePort1 + link->io.NumPorts1 - 1);
 
        return 0;
 
@@ -888,11 +860,10 @@ spectrum_cs_suspend(struct pcmcia_device *link)
 {
        struct net_device *dev = link->priv;
        struct orinoco_private *priv = netdev_priv(dev);
-       unsigned long flags;
        int err = 0;
 
        /* Mark the device as stopped, to block IO until later */
-       spin_lock_irqsave(&priv->lock, flags);
+       spin_lock(&priv->lock);
 
        err = __orinoco_down(dev);
        if (err)
@@ -902,9 +873,9 @@ spectrum_cs_suspend(struct pcmcia_device *link)
        netif_device_detach(dev);
        priv->hw_unavailable++;
 
-       spin_unlock_irqrestore(&priv->lock, flags);
+       spin_unlock(&priv->lock);
 
-       return 0;
+       return err;
 }
 
 static int
@@ -932,7 +903,7 @@ static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
        " David Gibson <hermes@gibson.dropbear.id.au>, et al)";
 
 static struct pcmcia_device_id spectrum_cs_ids[] = {
-       PCMCIA_DEVICE_MANF_CARD(0x026c, 0x0001), /* Symbol Spectrum24 LA4100 */
+       PCMCIA_DEVICE_MANF_CARD(0x026c, 0x0001), /* Symbol Spectrum24 LA4137 */
        PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0001), /* Socket Communications CF */
        PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless LAN PC Card", 0x816cc815, 0x6fbf459a), /* 2011B, not 2011 */
        PCMCIA_DEVICE_NULL,