summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2006-03-05 10:45:09 +0100
committerDominik Brodowski <linux@dominikbrodowski.net>2006-03-31 17:15:57 +0200
commitfd238232cd0ff4840ae6946bb338502154096d88 (patch)
treed20e8f5871f7cff9d0867a84f6ba088fbffcbe28 /drivers/net/wireless
parenta78f4dd331a4f6a396eb5849656a4a72a70a56d7 (diff)
[PATCH] pcmcia: embed dev_link_t into struct pcmcia_device
Embed dev_link_t into struct pcmcia_device(), as they basically address the same entity. The actual contents of dev_link_t will be cleaned up step by step. This patch includes a bugfix from and signed-off-by Andrew Morton. Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/airo_cs.c33
-rw-r--r--drivers/net/wireless/atmel_cs.c33
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c20
-rw-r--r--drivers/net/wireless/netwave_cs.c19
-rw-r--r--drivers/net/wireless/orinoco_cs.c22
-rw-r--r--drivers/net/wireless/ray_cs.c98
-rw-r--r--drivers/net/wireless/spectrum_cs.c21
-rw-r--r--drivers/net/wireless/wavelan_cs.c46
-rw-r--r--drivers/net/wireless/wl3501.h1
-rw-r--r--drivers/net/wireless/wl3501_cs.c61
10 files changed, 108 insertions, 246 deletions
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index 2216c04a02a..836c71ff776 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -143,22 +143,14 @@ typedef struct local_info_t {
static int airo_attach(struct pcmcia_device *p_dev)
{
- dev_link_t *link;
local_info_t *local;
DEBUG(0, "airo_attach()\n");
- /* Initialize the dev_link_t structure */
- link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
- if (!link) {
- printk(KERN_ERR "airo_cs: no memory for new device\n");
- return -ENOMEM;
- }
-
/* Interrupt setup */
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
- link->irq.Handler = NULL;
+ p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+ p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ p_dev->irq.Handler = NULL;
/*
General socket configuration defaults can go here. In this
@@ -167,23 +159,19 @@ static int airo_attach(struct pcmcia_device *p_dev)
and attributes of IO windows) are fixed by the nature of the
device, and can be hard-wired here.
*/
- link->conf.Attributes = 0;
- link->conf.IntType = INT_MEMORY_AND_IO;
+ p_dev->conf.Attributes = 0;
+ p_dev->conf.IntType = INT_MEMORY_AND_IO;
/* Allocate space for private device-specific data */
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local) {
printk(KERN_ERR "airo_cs: no memory for new device\n");
- kfree (link);
return -ENOMEM;
}
- link->priv = local;
-
- link->handle = p_dev;
- p_dev->instance = link;
+ p_dev->priv = local;
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- airo_config(link);
+ p_dev->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ airo_config(p_dev);
return 0;
} /* airo_attach */
@@ -212,7 +200,6 @@ static void airo_detach(struct pcmcia_device *p_dev)
((local_info_t*)link->priv)->eth_dev = NULL;
kfree(link->priv);
- kfree(link);
} /* airo_detach */
/*======================================================================
@@ -378,11 +365,11 @@ static void airo_config(dev_link_t *link)
/*
At this point, the dev_node_t structure(s) need to be
- initialized and arranged in a linked list at link->dev.
+ initialized and arranged in a linked list at link->dev_node.
*/
strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
dev->node.major = dev->node.minor = 0;
- link->dev = &dev->node;
+ link->dev_node = &dev->node;
/* Finally, report what we've done */
printk(KERN_INFO "%s: index 0x%02x: ",
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 53fdaa22226..522bbed47a0 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -154,22 +154,14 @@ typedef struct local_info_t {
static int atmel_attach(struct pcmcia_device *p_dev)
{
- dev_link_t *link;
local_info_t *local;
DEBUG(0, "atmel_attach()\n");
- /* Initialize the dev_link_t structure */
- link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
- if (!link) {
- printk(KERN_ERR "atmel_cs: no memory for new device\n");
- return -ENOMEM;
- }
-
/* Interrupt setup */
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
- link->irq.Handler = NULL;
+ p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+ p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ p_dev->irq.Handler = NULL;
/*
General socket configuration defaults can go here. In this
@@ -178,23 +170,19 @@ static int atmel_attach(struct pcmcia_device *p_dev)
and attributes of IO windows) are fixed by the nature of the
device, and can be hard-wired here.
*/
- link->conf.Attributes = 0;
- link->conf.IntType = INT_MEMORY_AND_IO;
+ p_dev->conf.Attributes = 0;
+ p_dev->conf.IntType = INT_MEMORY_AND_IO;
/* Allocate space for private device-specific data */
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local) {
printk(KERN_ERR "atmel_cs: no memory for new device\n");
- kfree (link);
return -ENOMEM;
}
- link->priv = local;
-
- link->handle = p_dev;
- p_dev->instance = link;
+ p_dev->priv = local;
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- atmel_config(link);
+ p_dev->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ atmel_config(p_dev);
return 0;
} /* atmel_attach */
@@ -218,7 +206,6 @@ static void atmel_detach(struct pcmcia_device *p_dev)
atmel_release(link);
kfree(link->priv);
- kfree(link);
}
/*======================================================================
@@ -387,11 +374,11 @@ static void atmel_config(dev_link_t *link)
/*
At this point, the dev_node_t structure(s) need to be
- initialized and arranged in a linked list at link->dev.
+ initialized and arranged in a linked list at link->dev_node.
*/
strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
dev->node.major = dev->node.minor = 0;
- link->dev = &dev->node;
+ link->dev_node = &dev->node;
link->state &= ~DEV_CONFIG_PENDING;
return;
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 69024bfb5bb..e3095a88745 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -503,22 +503,11 @@ static struct prism2_helper_functions prism2_pccard_funcs =
* initialize dev_link structure, but do not configure the card yet */
static int prism2_attach(struct pcmcia_device *p_dev)
{
- dev_link_t *link;
-
- link = kmalloc(sizeof(dev_link_t), GFP_KERNEL);
- if (link == NULL)
- return -ENOMEM;
-
- memset(link, 0, sizeof(dev_link_t));
-
PDEBUG(DEBUG_HW, "%s: setting Vcc=33 (constant)\n", dev_info);
- link->conf.IntType = INT_MEMORY_AND_IO;
-
- link->handle = p_dev;
- p_dev->instance = link;
+ p_dev->conf.IntType = INT_MEMORY_AND_IO;
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- if (prism2_config(link))
+ p_dev->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ if (prism2_config(p_dev))
PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n");
return 0;
@@ -546,7 +535,6 @@ static void prism2_detach(struct pcmcia_device *p_dev)
prism2_free_local_data(dev);
kfree(hw_priv);
}
- kfree(link);
}
@@ -713,7 +701,7 @@ static int prism2_config(dev_link_t *link)
local->hw_priv = hw_priv;
hw_priv->link = link;
strcpy(hw_priv->node.dev_name, dev->name);
- link->dev = &hw_priv->node;
+ link->dev_node = &hw_priv->node;
/*
* Allocate an interrupt line. Note that this does not assign a
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index 23d6b3376e6..68dfe68ffec 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -268,7 +268,7 @@ struct site_survey {
};
typedef struct netwave_private {
- dev_link_t link;
+ struct pcmcia_device *p_dev;
spinlock_t spinlock; /* Serialize access to the hardware (SMP) */
dev_node_t node;
u_char __iomem *ramBase;
@@ -378,9 +378,9 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
*/
static int netwave_attach(struct pcmcia_device *p_dev)
{
- dev_link_t *link;
struct net_device *dev;
netwave_private *priv;
+ dev_link_t *link = dev_to_instance(p_dev);
DEBUG(0, "netwave_attach()\n");
@@ -389,7 +389,7 @@ static int netwave_attach(struct pcmcia_device *p_dev)
if (!dev)
return -ENOMEM;
priv = netdev_priv(dev);
- link = &priv->link;
+ priv->p_dev = p_dev;
link->priv = dev;
/* The io structure describes IO port mapping */
@@ -429,9 +429,6 @@ static int netwave_attach(struct pcmcia_device *p_dev)
dev->stop = &netwave_close;
link->irq.Instance = dev;
- link->handle = p_dev;
- p_dev->instance = link;
-
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
netwave_pcmcia_config( link);
@@ -456,7 +453,7 @@ static void netwave_detach(struct pcmcia_device *p_dev)
if (link->state & DEV_CONFIG)
netwave_release(link);
- if (link->dev)
+ if (link->dev_node)
unregister_netdev(dev);
free_netdev(dev);
@@ -830,7 +827,7 @@ static void netwave_pcmcia_config(dev_link_t *link) {
}
strcpy(priv->node.dev_name, dev->name);
- link->dev = &priv->node;
+ link->dev_node = &priv->node;
link->state &= ~DEV_CONFIG_PENDING;
/* Reset card before reading physical address */
@@ -1103,7 +1100,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id, struct pt_regs *regs
u_char __iomem *ramBase;
struct net_device *dev = (struct net_device *)dev_id;
struct netwave_private *priv = netdev_priv(dev);
- dev_link_t *link = &priv->link;
+ dev_link_t *link = priv->p_dev;
int i;
if (!netif_device_present(dev))
@@ -1357,7 +1354,7 @@ static int netwave_rx(struct net_device *dev)
static int netwave_open(struct net_device *dev) {
netwave_private *priv = netdev_priv(dev);
- dev_link_t *link = &priv->link;
+ dev_link_t *link = priv->p_dev;
DEBUG(1, "netwave_open: starting.\n");
@@ -1374,7 +1371,7 @@ static int netwave_open(struct net_device *dev) {
static int netwave_close(struct net_device *dev) {
netwave_private *priv = netdev_priv(dev);
- dev_link_t *link = &priv->link;
+ dev_link_t *link = priv->p_dev;
DEBUG(1, "netwave_close: finishing.\n");
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index 75981d88a1e..f10d97bc45f 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -49,7 +49,7 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket
/* PCMCIA specific device information (goes in the card field of
* struct orinoco_private */
struct orinoco_pccard {
- dev_link_t link;
+ struct pcmcia_device *p_dev;
dev_node_t node;
/* Used to handle hard reset */
@@ -75,7 +75,7 @@ static int
orinoco_cs_hard_reset(struct orinoco_private *priv)
{
struct orinoco_pccard *card = priv->card;
- dev_link_t *link = &card->link;
+ dev_link_t *link = card->p_dev;
int err;
/* We need atomic ops here, because we're not holding the lock */
@@ -109,7 +109,7 @@ orinoco_cs_attach(struct pcmcia_device *p_dev)
struct net_device *dev;
struct orinoco_private *priv;
struct orinoco_pccard *card;
- dev_link_t *link;
+ dev_link_t *link = dev_to_instance(p_dev);
dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset);
if (! dev)
@@ -118,7 +118,7 @@ orinoco_cs_attach(struct pcmcia_device *p_dev)
card = priv->card;
/* Link both structures together */
- link = &card->link;
+ card->p_dev = p_dev;
link->priv = dev;
/* Interrupt setup */
@@ -135,12 +135,6 @@ orinoco_cs_attach(struct pcmcia_device *p_dev)
link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY_AND_IO;
- /* Register with Card Services */
- link->next = NULL;
-
- link->handle = p_dev;
- p_dev->instance = link;
-
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
orinoco_cs_config(link);
@@ -161,8 +155,8 @@ static void orinoco_cs_detach(struct pcmcia_device *p_dev)
if (link->state & DEV_CONFIG)
orinoco_cs_release(link);
- DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev);
- if (link->dev) {
+ 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);
@@ -364,9 +358,9 @@ orinoco_cs_config(dev_link_t *link)
}
/* At this point, the dev_node_t structure(s) needs to be
- * initialized and arranged in a linked list at link->dev. */
+ * initialized and arranged in a linked list at link->dev_node. */
strcpy(card->node.dev_name, dev->name);
- link->dev = &card->node; /* link->dev being non-NULL is also
+ link->dev_node = &card->node; /* link->dev_node being non-NULL is also
used to indicate that the
net_device has been registered */
link->state &= ~DEV_CONFIG_PENDING;
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 7d95587d09d..60297460deb 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -190,12 +190,6 @@ static int bc;
static char *phy_addr = NULL;
-/* A linked list of "instances" of the ray device. Each actual
- PCMCIA card corresponds to one device instance, and is described
- by one dev_link_t structure (defined in ds.h).
-*/
-static dev_link_t *dev_list = NULL;
-
/* A dev_link_t structure has fields for most things that are needed
to keep track of a socket, but there will usually be some device
specific information that also needs to be kept track of. The
@@ -204,6 +198,9 @@ static dev_link_t *dev_list = NULL;
*/
static unsigned int ray_mem_speed = 500;
+/* WARNING: THIS DRIVER IS NOT CAPABLE OF HANDLING MULTIPLE DEVICES! */
+static struct pcmcia_device *this_device = NULL;
+
MODULE_AUTHOR("Corey Thomas <corey@world.std.com>");
MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver");
MODULE_LICENSE("GPL");
@@ -308,53 +305,44 @@ static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.
=============================================================================*/
static int ray_attach(struct pcmcia_device *p_dev)
{
- dev_link_t *link;
ray_dev_t *local;
struct net_device *dev;
-
- DEBUG(1, "ray_attach()\n");
-
- /* Initialize the dev_link_t structure */
- link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
- if (!link)
- return -ENOMEM;
+ DEBUG(1, "ray_attach()\n");
/* Allocate space for private device-specific data */
dev = alloc_etherdev(sizeof(ray_dev_t));
-
if (!dev)
goto fail_alloc_dev;
local = dev->priv;
-
- memset(link, 0, sizeof(struct dev_link_t));
+ local->finder = p_dev;
/* The io structure describes IO port mapping. None used here */
- link->io.NumPorts1 = 0;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.IOAddrLines = 5;
+ p_dev->io.NumPorts1 = 0;
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ p_dev->io.IOAddrLines = 5;
/* Interrupt setup. For PCMCIA, driver takes what's given */
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
- link->irq.Handler = &ray_interrupt;
+ p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+ p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ p_dev->irq.Handler = &ray_interrupt;
/* General socket configuration */
- link->conf.Attributes = CONF_ENABLE_IRQ;
- link->conf.IntType = INT_MEMORY_AND_IO;
- link->conf.ConfigIndex = 1;
- link->conf.Present = PRESENT_OPTION;
+ p_dev->conf.Attributes = CONF_ENABLE_IRQ;
+ p_dev->conf.IntType = INT_MEMORY_AND_IO;
+ p_dev->conf.ConfigIndex = 1;
+ p_dev->conf.Present = PRESENT_OPTION;
- link->priv = dev;
- link->irq.Instance = dev;
+ p_dev->priv = dev;
+ p_dev->irq.Instance = dev;
- local->finder = link;
+ local->finder = p_dev;
local->card_status = CARD_INSERTED;
local->authentication_state = UNAUTHENTICATED;
local->num_multi = 0;
- DEBUG(2,"ray_attach link = %p, dev = %p, local = %p, intr = %p\n",
- link,dev,local,&ray_interrupt);
+ DEBUG(2,"ray_attach p_dev = %p, dev = %p, local = %p, intr = %p\n",
+ p_dev,dev,local,&ray_interrupt);
/* Raylink entries in the device structure */
dev->hard_start_xmit = &ray_dev_start_xmit;
@@ -378,16 +366,13 @@ static int ray_attach(struct pcmcia_device *p_dev)
init_timer(&local->timer);
- link->handle = p_dev;
- p_dev->instance = link;
-
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- ray_config(link);
+ p_dev->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ this_device = p_dev;
+ ray_config(p_dev);
return 0;
fail_alloc_dev:
- kfree(link);
return -ENOMEM;
} /* ray_attach */
/*=============================================================================
@@ -399,18 +384,12 @@ fail_alloc_dev:
static void ray_detach(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
- dev_link_t **linkp;
struct net_device *dev;
ray_dev_t *local;
DEBUG(1, "ray_detach(0x%p)\n", link);
-
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link) break;
- if (*linkp == NULL)
- return;
+ this_device = NULL;
dev = link->priv;
if (link->state & DEV_CONFIG) {
@@ -420,13 +399,10 @@ static void ray_detach(struct pcmcia_device *p_dev)
del_timer(&local->timer);
}
- /* Unlink device structure, free pieces */
- *linkp = link->next;
if (link->priv) {
- if (link->dev) unregister_netdev(dev);
+ if (link->dev_node) unregister_netdev(dev);
free_netdev(dev);
}
- kfree(link);
DEBUG(2,"ray_cs ray_detach ending\n");
} /* ray_detach */
/*=============================================================================
@@ -537,7 +513,7 @@ static void ray_config(dev_link_t *link)
}
strcpy(local->node.dev_name, dev->name);
- link->dev = &local->node;
+ link->dev_node = &local->node;
link->state &= ~DEV_CONFIG_PENDING;
printk(KERN_INFO "%s: RayLink, irq %d, hw_addr ",
@@ -1640,18 +1616,14 @@ static const struct iw_handler_def ray_handler_def =
/*===========================================================================*/
static int ray_open(struct net_device *dev)
{
- dev_link_t *link;
ray_dev_t *local = (ray_dev_t *)dev->priv;
+ dev_link_t *link;
+ link = local->finder;
DEBUG(1, "ray_open('%s')\n", dev->name);
- for (link = dev_list; link; link = link->next)
- if (link->priv == dev) break;
- if (!DEV_OK(link)) {
- return -ENODEV;
- }
-
- if (link->open == 0) local->num_multi = 0;
+ if (link->open == 0)
+ local->num_multi = 0;
link->open++;
/* If the card is not started, time to start it ! - Jean II */
@@ -1678,15 +1650,12 @@ static int ray_open(struct net_device *dev)
/*===========================================================================*/
static int ray_dev_close(struct net_device *dev)
{
+ ray_dev_t *local = (ray_dev_t *)dev->priv;
dev_link_t *link;
+ link = local->finder;
DEBUG(1, "ray_dev_close('%s')\n", dev->name);
- for (link = dev_list; link; link = link->next)
- if (link->priv == dev) break;
- if (link == NULL)
- return -ENODEV;
-
link->open--;
netif_stop_queue(dev);
@@ -2679,7 +2648,7 @@ static int ray_cs_proc_read(char *buf, char **start, off_t offset, int len)
struct freq_hop_element *pfh;
UCHAR c[33];
- link = dev_list;
+ link = this_device;
if (!link)
return 0;
dev = (struct net_device *)link->priv;
@@ -2923,7 +2892,6 @@ static void __exit exit_ray_cs(void)
#endif
pcmcia_unregister_driver(&ray_driver);
- BUG_ON(dev_list != NULL);
} /* exit_ray_cs */
module_init(init_ray_cs);
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index 7a4a80b01f9..be36679c8c9 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -63,7 +63,7 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket
/* PCMCIA specific device information (goes in the card field of
* struct orinoco_private */
struct orinoco_pccard {
- dev_link_t link;
+ struct pcmcia_device *p_dev;
dev_node_t node;
};
@@ -554,12 +554,12 @@ static int
spectrum_cs_hard_reset(struct orinoco_private *priv)
{
struct orinoco_pccard *card = priv->card;
- dev_link_t *link = &card->link;
+ dev_link_t *link = card->p_dev;
int err;
if (!hermes_present(&priv->hw)) {
/* The firmware needs to be reloaded */
- if (spectrum_dl_firmware(&priv->hw, &card->link) != 0) {
+ if (spectrum_dl_firmware(&priv->hw, link) != 0) {
printk(KERN_ERR PFX "Firmware download failed\n");
err = -ENODEV;
}
@@ -589,7 +589,7 @@ spectrum_cs_attach(struct pcmcia_device *p_dev)
struct net_device *dev;
struct orinoco_private *priv;
struct orinoco_pccard *card;
- dev_link_t *link;
+ dev_link_t *link = dev_to_instance(p_dev);
dev = alloc_orinocodev(sizeof(*card), spectrum_cs_hard_reset);
if (! dev)
@@ -598,7 +598,7 @@ spectrum_cs_attach(struct pcmcia_device *p_dev)
card = priv->card;
/* Link both structures together */
- link = &card->link;
+ card->p_dev = p_dev;
link->priv = dev;
/* Interrupt setup */
@@ -615,9 +615,6 @@ spectrum_cs_attach(struct pcmcia_device *p_dev)
link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY_AND_IO;
- link->handle = p_dev;
- p_dev->instance = link;
-
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
spectrum_cs_config(link);
@@ -638,8 +635,8 @@ static void spectrum_cs_detach(struct pcmcia_device *p_dev)
if (link->state & DEV_CONFIG)
spectrum_cs_release(link);
- DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev);
- if (link->dev) {
+ 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);
@@ -842,9 +839,9 @@ spectrum_cs_config(dev_link_t *link)
}
/* At this point, the dev_node_t structure(s) needs to be
- * initialized and arranged in a linked list at link->dev. */
+ * initialized and arranged in a linked list at link->dev_node. */
strcpy(card->node.dev_name, dev->name);
- link->dev = &card->node; /* link->dev being non-NULL is also
+ link->dev_node = &card->node; /* link->dev_node being non-NULL is also
used to indicate that the
net_device has been registered */
link->state &= ~DEV_CONFIG_PENDING;
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index daa17dc3432..baa1011e70e 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -4081,7 +4081,7 @@ wv_pcmcia_config(dev_link_t * link)
}
strcpy(((net_local *) netdev_priv(dev))->node.dev_name, dev->name);
- link->dev = &((net_local *) netdev_priv(dev))->node;
+ link->dev_node = &((net_local *) netdev_priv(dev))->node;
#ifdef DEBUG_CONFIG_TRACE
printk(KERN_DEBUG "<-wv_pcmcia_config()\n");
@@ -4583,7 +4583,6 @@ wavelan_close(struct net_device * dev)
static int
wavelan_attach(struct pcmcia_device *p_dev)
{
- dev_link_t * link; /* Info for cardmgr */
struct net_device * dev; /* Interface generic data */
net_local * lp; /* Interface specific data */
@@ -4591,34 +4590,26 @@ wavelan_attach(struct pcmcia_device *p_dev)
printk(KERN_DEBUG "-> wavelan_attach()\n");
#endif
- /* Initialize the dev_link_t structure */
- link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
- if (!link) return -ENOMEM;
-
/* The io structure describes IO port mapping */
- link->io.NumPorts1 = 8;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.IOAddrLines = 3;
+ p_dev->io.NumPorts1 = 8;
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ p_dev->io.IOAddrLines = 3;
/* Interrupt setup */
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
- link->irq.Handler = wavelan_interrupt;
+ p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+ p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ p_dev->irq.Handler = wavelan_interrupt;
/* General socket configuration */
- link->conf.Attributes = CONF_ENABLE_IRQ;
- link->conf.IntType = INT_MEMORY_AND_IO;
-
- /* Chain drivers */
- link->next = NULL;
+ p_dev->conf.Attributes = CONF_ENABLE_IRQ;
+ p_dev->conf.IntType = INT_MEMORY_AND_IO;
/* Allocate the generic data structure */
dev = alloc_etherdev(sizeof(net_local));
- if (!dev) {
- kfree(link);
+ if (!dev)
return -ENOMEM;
- }
- link->priv = link->irq.Instance = dev;
+
+ p_dev->priv = p_dev->irq.Instance = dev;
lp = netdev_priv(dev);
@@ -4635,7 +4626,6 @@ wavelan_attach(struct pcmcia_device *p_dev)
spin_lock_init(&lp->spinlock);
/* back links */
- lp->link = link;
lp->dev = dev;
/* wavelan NET3 callbacks */
@@ -4661,11 +4651,8 @@ wavelan_attach(struct pcmcia_device *p_dev)
/* Other specific data */
dev->mtu = WAVELAN_MTU;
- link->handle = p_dev;
- p_dev->instance = link;
-
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- if(wv_pcmcia_config(link) &&
+ p_dev->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ if(wv_pcmcia_config(p_dev) &&
wv_hw_config(dev))
wv_init_info(dev);
else
@@ -4713,14 +4700,13 @@ wavelan_detach(struct pcmcia_device *p_dev)
/* Remove ourselves from the kernel list of ethernet devices */
/* Warning : can't be called from interrupt, timer or wavelan_close() */
- if (link->dev)
+ if (link->dev_node)
unregister_netdev(dev);
- link->dev = NULL;
+ link->dev_node = NULL;
((net_local *)netdev_priv(dev))->link = NULL;
((net_local *)netdev_priv(dev))->dev = NULL;
free_netdev(dev);
}
- kfree(link);
#ifdef DEBUG_CALLBACK_TRACE
printk(KERN_DEBUG "<- wavelan_detach()\n");
diff --git a/drivers/net/wireless/wl3501.h b/drivers/net/wireless/wl3501.h
index 4303c50c2ab..65ceb088f70 100644
--- a/drivers/net/wireless/wl3501.h
+++ b/drivers/net/wireless/wl3501.h
@@ -611,5 +611,6 @@ struct wl3501_card {
struct iw_spy_data spy_data;
struct iw_public_data wireless_data;
struct dev_node_t node;
+ struct pcmcia_device *p_dev;
};
#endif
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 393b5cb7a52..4b054f54e9d 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -226,17 +226,6 @@ static void iw_copy_mgmt_info_element(struct iw_mgmt_info_element *to,
iw_set_mgmt_info_element(from->id, to, from->data, from->len);
}
-/*
- * A linked list of "instances" of the wl24 device. Each actual PCMCIA card
- * corresponds to one device instance, and is described by one dev_link_t
- * structure (defined in ds.h).
- *
- * You may not want to use a linked list for this -- for example, the memory
- * card driver uses an array of dev_link_t pointers, where minor device numbers
- * are used to derive the corresponding array index.
- */
-static dev_link_t *wl3501_dev_list;
-
static inline void wl3501_switch_page(struct wl3501_card *this, u8 page)
{
wl3501_outb(page, this->base_addr + WL3501_NIC_BSS);
@@ -1282,14 +1271,9 @@ static int wl3501_close(struct net_device *dev)
int rc = -ENODEV;
unsigned long flags;
dev_link_t *link;
+ link = this->p_dev;
spin_lock_irqsave(&this->lock, flags);
- /* Check if the device is in wl3501_dev_list */
- for (link = wl3501_dev_list; link; link = link->next)
- if (link->priv == dev)
- break;
- if (!link)
- goto out;
link->open--;
/* Stop wl3501_hard_start_xmit() from now on */
@@ -1301,7 +1285,6 @@ static int wl3501_close(struct net_device *dev)
rc = 0;
printk(KERN_INFO "%s: WL3501 closed\n", dev->name);
-out:
spin_unlock_irqrestore(&this->lock, flags);
return rc;
}
@@ -1401,12 +1384,9 @@ static int wl3501_open(struct net_device *dev)
struct wl3501_card *this = dev->priv;
unsigned long flags;
dev_link_t *link;
+ link = this->p_dev;
spin_lock_irqsave(&this->lock, flags);
- /* Check if the device is in wl3501_dev_list */
- for (link = wl3501_dev_list; link; link = link->next)
- if (link->priv == dev)
- break;
if (!DEV_OK(link))
goto out;
netif_device_attach(dev);
@@ -1500,16 +1480,8 @@ static struct ethtool_ops ops = {
static void wl3501_detach(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
- dev_link_t **linkp;
struct net_device *dev = link->priv;
- /* Locate device structure */
- for (linkp = &wl3501_dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link)
- break;
- if (!*linkp)
- goto out;
-
/* If the device is currently configured and active, we won't actually
* delete it yet. Instead, it is marked so that when the release()
* function is called, that will trigger a proper detach(). */
@@ -1522,13 +1494,9 @@ static void wl3501_detach(struct pcmcia_device *p_dev)
wl3501_release(link);
}
- /* Unlink device structure, free pieces */
- *linkp = link->next;
-
if (link->priv)
free_netdev(link->priv);
- kfree(link);
-out:
+
return;
}
@@ -1955,14 +1923,9 @@ static const struct iw_handler_def wl3501_handler_def = {
*/
static int wl3501_attach(struct pcmcia_device *p_dev)
{
- dev_link_t *link;
struct net_device *dev;
struct wl3501_card *this;
-
- /* Initialize the dev_link_t structure */
- link = kzalloc(sizeof(*link), GFP_KERNEL);
- if (!link)
- return -ENOMEM;
+ dev_link_t *link = dev_to_instance(p_dev);
/* The io structure describes IO port mapping */
link->io.NumPorts1 = 16;
@@ -1991,22 +1954,18 @@ static int wl3501_attach(struct pcmcia_device *p_dev)
dev->get_stats = wl3501_get_stats;
this = dev->priv;
this->wireless_data.spy_data = &this->spy_data;
+ this->p_dev = p_dev;
dev->wireless_data = &this->wireless_data;
dev->wireless_handlers = (struct iw_handler_def *)&wl3501_handler_def;
SET_ETHTOOL_OPS(dev, &ops);
netif_stop_queue(dev);
link->priv = link->irq.Instance = dev;
- link->handle = p_dev;
- p_dev->instance = link;
-
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- wl3501_config(link);
+ wl3501_config(p_dev);
return 0;
out_link:
- kfree(link);
- link = NULL;
return -ENOMEM;
}
@@ -2087,9 +2046,9 @@ static void wl3501_config(dev_link_t *link)
this = dev->priv;
/*
* At this point, the dev_node_t structure(s) should be initialized and
- * arranged in a linked list at link->dev.
+ * arranged in a linked list at link->dev_node.
*/
- link->dev = &this->node;
+ link->dev_node = &this->node;
link->state &= ~DEV_CONFIG_PENDING;
this->base_addr = dev->base_addr;
@@ -2148,7 +2107,7 @@ static void wl3501_release(dev_link_t *link)
struct net_device *dev = link->priv;
/* Unlink the device chain */
- if (link->dev)
+ if (link->dev_node)
unregister_netdev(dev);
pcmcia_disable_device(link->handle);
@@ -2206,9 +2165,7 @@ static int __init wl3501_init_module(void)
static void __exit wl3501_exit_module(void)
{
- dprintk(0, ": unloading");
pcmcia_unregister_driver(&wl3501_driver);
- BUG_ON(wl3501_dev_list != NULL);
}
module_init(wl3501_init_module);