#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>
#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";
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 */
*/
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;
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;
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;
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 */
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");
}
{
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 */
cisparse_t parse;
void __iomem *mem;
- /*
- * This reads the card's CONFIG tuple to find its
- * configuration registers.
- */
- tuple.DesiredTuple = CISTPL_CONFIG;
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
-
/* Look up the current Vcc */
CS_CHECK(GetConfigurationInfo,
pcmcia_get_configuration_info(link, &conf));
* implementation-defined details.
*/
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ tuple.Attributes = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
/* Ok, we have the configuration, prepare to register the netdev */
dev->base_addr = link->io.BasePort1;
dev->irq = link->irq.AssignedIRQ;
- SET_MODULE_OWNER(dev);
card->node.major = card->node.minor = 0;
/* Reset card and download firmware */
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->dev.parent->bus_id,
+ link->irq.AssignedIRQ, link->io.BasePort1,
+ link->io.BasePort1 + link->io.NumPorts1 - 1);
return 0;
{
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)
netif_device_detach(dev);
priv->hw_unavailable++;
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock(&priv->lock);
- return 0;
+ return err;
}
static int