git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git]
/
drivers
/
net
/
wireless
/
ray_cs.c
diff --git
a/drivers/net/wireless/ray_cs.c
b/drivers/net/wireless/ray_cs.c
index
879eb42
..
7880d8c
100644
(file)
--- a/
drivers/net/wireless/ray_cs.c
+++ b/
drivers/net/wireless/ray_cs.c
@@
-90,8
+90,8
@@
module_param(pc_debug, int, 0);
#define DEBUG(n, args...)
#endif
/** Prototypes based on PCMCIA skeleton driver *******************************/
#define DEBUG(n, args...)
#endif
/** Prototypes based on PCMCIA skeleton driver *******************************/
-static
int ray_config(struct pcmcia_device
*link);
-static void ray_release(
struct pcmcia_device
*link);
+static
void ray_config(dev_link_t
*link);
+static void ray_release(
dev_link_t
*link);
static void ray_detach(struct pcmcia_device *p_dev);
/***** Prototypes indicated by device structure ******************************/
static void ray_detach(struct pcmcia_device *p_dev);
/***** Prototypes indicated by device structure ******************************/
@@
-190,17
+190,20
@@
static int bc;
static char *phy_addr = NULL;
static char *phy_addr = NULL;
-/* A struct pcmcia_device structure has fields for most things that are needed
+/* 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
to keep track of a socket, but there will usually be some device
specific information that also needs to be kept track of. The
- 'priv' pointer in a
struct pcmcia_device
structure can be used to point to
+ 'priv' pointer in a
dev_link_t
structure can be used to point to
a device-specific private data structure, like this.
*/
static unsigned int ray_mem_speed = 500;
a device-specific private data structure, like this.
*/
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");
MODULE_AUTHOR("Corey Thomas <corey@world.std.com>");
MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver");
MODULE_LICENSE("GPL");
@@
-303,46
+306,56
@@
static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.
configure the card at this point -- we wait until we receive a
card insertion event.
=============================================================================*/
configure the card at this point -- we wait until we receive a
card insertion event.
=============================================================================*/
-static int ray_
probe
(struct pcmcia_device *p_dev)
+static int ray_
attach
(struct pcmcia_device *p_dev)
{
{
+ dev_link_t *link;
ray_dev_t *local;
struct net_device *dev;
ray_dev_t *local;
struct net_device *dev;
-
+
DEBUG(1, "ray_attach()\n");
DEBUG(1, "ray_attach()\n");
+ /* Initialize the dev_link_t structure */
+ link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+
+ if (!link)
+ return -ENOMEM;
+
/* Allocate space for private device-specific data */
dev = alloc_etherdev(sizeof(ray_dev_t));
/* Allocate space for private device-specific data */
dev = alloc_etherdev(sizeof(ray_dev_t));
+
if (!dev)
goto fail_alloc_dev;
local = dev->priv;
if (!dev)
goto fail_alloc_dev;
local = dev->priv;
- local->finder = p_dev;
+
+ memset(link, 0, sizeof(struct dev_link_t));
/* The io structure describes IO port mapping. None used here */
/* The io structure describes IO port mapping. None used here */
-
p_dev
->io.NumPorts1 = 0;
-
p_dev
->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-
p_dev
->io.IOAddrLines = 5;
+
link
->io.NumPorts1 = 0;
+
link
->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+
link
->io.IOAddrLines = 5;
/* Interrupt setup. For PCMCIA, driver takes what's given */
/* Interrupt setup. For PCMCIA, driver takes what's given */
-
p_dev
->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-
p_dev
->irq.IRQInfo1 = IRQ_LEVEL_ID;
-
p_dev
->irq.Handler = &ray_interrupt;
+
link
->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+
link
->irq.IRQInfo1 = IRQ_LEVEL_ID;
+
link
->irq.Handler = &ray_interrupt;
/* General socket configuration */
/* General socket configuration */
- 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;
-
- p_dev->priv = dev;
- p_dev->irq.Instance = dev;
+ link->conf.Attributes = CONF_ENABLE_IRQ;
+ link->conf.Vcc = 50;
+ link->conf.IntType = INT_MEMORY_AND_IO;
+ link->conf.ConfigIndex = 1;
+ link->conf.Present = PRESENT_OPTION;
+
+ link->priv = dev;
+ link->irq.Instance = dev;
- local->finder =
p_dev
;
+ local->finder =
link
;
local->card_status = CARD_INSERTED;
local->authentication_state = UNAUTHENTICATED;
local->num_multi = 0;
local->card_status = CARD_INSERTED;
local->authentication_state = UNAUTHENTICATED;
local->num_multi = 0;
- DEBUG(2,"ray_attach
p_dev
= %p, dev = %p, local = %p, intr = %p\n",
-
p_dev
,dev,local,&ray_interrupt);
+ DEBUG(2,"ray_attach
link
= %p, dev = %p, local = %p, intr = %p\n",
+
link
,dev,local,&ray_interrupt);
/* Raylink entries in the device structure */
dev->hard_start_xmit = &ray_dev_start_xmit;
/* Raylink entries in the device structure */
dev->hard_start_xmit = &ray_dev_start_xmit;
@@
-366,10
+379,16
@@
static int ray_probe(struct pcmcia_device *p_dev)
init_timer(&local->timer);
init_timer(&local->timer);
- this_device = p_dev;
- return ray_config(p_dev);
+ link->handle = p_dev;
+ p_dev->instance = link;
+
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ ray_config(link);
+
+ return 0;
fail_alloc_dev:
fail_alloc_dev:
+ kfree(link);
return -ENOMEM;
} /* ray_attach */
/*=============================================================================
return -ENOMEM;
} /* ray_attach */
/*=============================================================================
@@
-378,25
+397,37
@@
fail_alloc_dev:
structures are freed. Otherwise, the structures will be freed
when the device is released.
=============================================================================*/
structures are freed. Otherwise, the structures will be freed
when the device is released.
=============================================================================*/
-static void ray_detach(struct pcmcia_device *
link
)
+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);
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;
dev = link->priv;
- ray_release(link);
+ if (link->state & DEV_CONFIG) {
+ ray_release(link);
- local = (ray_dev_t *)dev->priv;
- del_timer(&local->timer);
+ local = (ray_dev_t *)dev->priv;
+ del_timer(&local->timer);
+ }
+ /* Unlink device structure, free pieces */
+ *linkp = link->next;
if (link->priv) {
if (link->priv) {
- if (link->dev
_node
) unregister_netdev(dev);
+ if (link->dev) unregister_netdev(dev);
free_netdev(dev);
}
free_netdev(dev);
}
+ kfree(link);
DEBUG(2,"ray_cs ray_detach ending\n");
} /* ray_detach */
/*=============================================================================
DEBUG(2,"ray_cs ray_detach ending\n");
} /* ray_detach */
/*=============================================================================
@@
-407,8
+438,9
@@
static void ray_detach(struct pcmcia_device *link)
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
#define MAX_TUPLE_SIZE 128
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
#define MAX_TUPLE_SIZE 128
-static
int ray_config(struct pcmcia_device
*link)
+static
void ray_config(dev_link_t
*link)
{
{
+ client_handle_t handle = link->handle;
tuple_t tuple;
cisparse_t parse;
int last_fn = 0, last_ret = 0;
tuple_t tuple;
cisparse_t parse;
int last_fn = 0, last_ret = 0;
@@
-423,45
+455,48
@@
static int ray_config(struct pcmcia_device *link)
/* This reads the card's CONFIG tuple to find its configuration regs */
tuple.DesiredTuple = CISTPL_CONFIG;
/* This reads the card's CONFIG tuple to find its configuration regs */
tuple.DesiredTuple = CISTPL_CONFIG;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(
link
, &tuple));
+ CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(
handle
, &tuple));
tuple.TupleData = buf;
tuple.TupleDataMax = MAX_TUPLE_SIZE;
tuple.TupleOffset = 0;
tuple.TupleData = buf;
tuple.TupleDataMax = MAX_TUPLE_SIZE;
tuple.TupleOffset = 0;
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(
link
, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(
link
, &tuple, &parse));
+ CS_CHECK(GetTupleData, pcmcia_get_tuple_data(
handle
, &tuple));
+ CS_CHECK(ParseTuple, pcmcia_parse_tuple(
handle
, &tuple, &parse));
link->conf.ConfigBase = parse.config.base;
link->conf.Present = parse.config.rmask[0];
/* Determine card type and firmware version */
buf[0] = buf[MAX_TUPLE_SIZE - 1] = 0;
tuple.DesiredTuple = CISTPL_VERS_1;
link->conf.ConfigBase = parse.config.base;
link->conf.Present = parse.config.rmask[0];
/* Determine card type and firmware version */
buf[0] = buf[MAX_TUPLE_SIZE - 1] = 0;
tuple.DesiredTuple = CISTPL_VERS_1;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(
link
, &tuple));
+ CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(
handle
, &tuple));
tuple.TupleData = buf;
tuple.TupleDataMax = MAX_TUPLE_SIZE;
tuple.TupleOffset = 2;
tuple.TupleData = buf;
tuple.TupleDataMax = MAX_TUPLE_SIZE;
tuple.TupleOffset = 2;
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(
link
, &tuple));
+ CS_CHECK(GetTupleData, pcmcia_get_tuple_data(
handle
, &tuple));
for (i=0; i<tuple.TupleDataLen - 4; i++)
if (buf[i] == 0) buf[i] = ' ';
printk(KERN_INFO "ray_cs Detected: %s\n",buf);
for (i=0; i<tuple.TupleDataLen - 4; i++)
if (buf[i] == 0) buf[i] = ' ';
printk(KERN_INFO "ray_cs Detected: %s\n",buf);
+ /* Configure card */
+ link->state |= DEV_CONFIG;
+
/* Now allocate an interrupt line. Note that this does not
actually assign a handler to the interrupt.
*/
/* Now allocate an interrupt line. Note that this does not
actually assign a handler to the interrupt.
*/
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+ CS_CHECK(RequestIRQ, pcmcia_request_irq(link
->handle
, &link->irq));
dev->irq = link->irq.AssignedIRQ;
/* This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping.
*/
dev->irq = link->irq.AssignedIRQ;
/* This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping.
*/
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link
->handle
, &link->conf));
/*** Set up 32k window for shared memory (transmit and control) ************/
req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
req.Base = 0;
req.Size = 0x8000;
req.AccessSpeed = ray_mem_speed;
/*** Set up 32k window for shared memory (transmit and control) ************/
req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
req.Base = 0;
req.Size = 0x8000;
req.AccessSpeed = ray_mem_speed;
- CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
+ CS_CHECK(RequestWindow, pcmcia_request_window(&link
->handle
, &req, &link->win));
mem.CardOffset = 0x0000; mem.Page = 0;
CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
local->sram = ioremap(req.Base,req.Size);
mem.CardOffset = 0x0000; mem.Page = 0;
CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
local->sram = ioremap(req.Base,req.Size);
@@
-471,7
+506,7
@@
static int ray_config(struct pcmcia_device *link)
req.Base = 0;
req.Size = 0x4000;
req.AccessSpeed = ray_mem_speed;
req.Base = 0;
req.Size = 0x4000;
req.AccessSpeed = ray_mem_speed;
- CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &local->rmem_handle));
+ CS_CHECK(RequestWindow, pcmcia_request_window(&link
->handle
, &req, &local->rmem_handle));
mem.CardOffset = 0x8000; mem.Page = 0;
CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->rmem_handle, &mem));
local->rmem = ioremap(req.Base,req.Size);
mem.CardOffset = 0x8000; mem.Page = 0;
CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->rmem_handle, &mem));
local->rmem = ioremap(req.Base,req.Size);
@@
-481,7
+516,7
@@
static int ray_config(struct pcmcia_device *link)
req.Base = 0;
req.Size = 0x1000;
req.AccessSpeed = ray_mem_speed;
req.Base = 0;
req.Size = 0x1000;
req.AccessSpeed = ray_mem_speed;
- CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &local->amem_handle));
+ CS_CHECK(RequestWindow, pcmcia_request_window(&link
->handle
, &req, &local->amem_handle));
mem.CardOffset = 0x0000; mem.Page = 0;
CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->amem_handle, &mem));
local->amem = ioremap(req.Base,req.Size);
mem.CardOffset = 0x0000; mem.Page = 0;
CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->amem_handle, &mem));
local->amem = ioremap(req.Base,req.Size);
@@
-491,32
+526,32
@@
static int ray_config(struct pcmcia_device *link)
DEBUG(3,"ray_config amem=%p\n",local->amem);
if (ray_init(dev) < 0) {
ray_release(link);
DEBUG(3,"ray_config amem=%p\n",local->amem);
if (ray_init(dev) < 0) {
ray_release(link);
- return
-ENODEV
;
+ return;
}
}
- SET_NETDEV_DEV(dev, &handle_to_dev(
link
));
+ SET_NETDEV_DEV(dev, &handle_to_dev(
handle
));
i = register_netdev(dev);
if (i != 0) {
printk("ray_config register_netdev() failed\n");
ray_release(link);
i = register_netdev(dev);
if (i != 0) {
printk("ray_config register_netdev() failed\n");
ray_release(link);
- return
i
;
+ return;
}
strcpy(local->node.dev_name, dev->name);
}
strcpy(local->node.dev_name, dev->name);
- link->dev
_node
= &local->node;
+ link->dev = &local->node;
+ link->state &= ~DEV_CONFIG_PENDING;
printk(KERN_INFO "%s: RayLink, irq %d, hw_addr ",
dev->name, dev->irq);
for (i = 0; i < 6; i++)
printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
printk(KERN_INFO "%s: RayLink, irq %d, hw_addr ",
dev->name, dev->irq);
for (i = 0; i < 6; i++)
printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
- return
0
;
+ return;
cs_failed:
cs_failed:
- cs_error(link, last_fn, last_ret);
+ cs_error(link
->handle
, last_fn, last_ret);
ray_release(link);
ray_release(link);
- return -ENODEV;
} /* ray_config */
static inline struct ccs __iomem *ccs_base(ray_dev_t *dev)
} /* ray_config */
static inline struct ccs __iomem *ccs_base(ray_dev_t *dev)
@@
-543,9
+578,9
@@
static int ray_init(struct net_device *dev)
UCHAR *p;
struct ccs __iomem *pccs;
ray_dev_t *local = (ray_dev_t *)dev->priv;
UCHAR *p;
struct ccs __iomem *pccs;
ray_dev_t *local = (ray_dev_t *)dev->priv;
-
struct pcmcia_device
*link = local->finder;
+
dev_link_t
*link = local->finder;
DEBUG(1, "ray_init(0x%p)\n", dev);
DEBUG(1, "ray_init(0x%p)\n", dev);
- if (!(
pcmcia_dev_present(link)
)) {
+ if (!(
link->state & DEV_PRESENT
)) {
DEBUG(0,"ray_init - device not present\n");
return -1;
}
DEBUG(0,"ray_init - device not present\n");
return -1;
}
@@
-605,10
+640,10
@@
static int dl_startup_params(struct net_device *dev)
int ccsindex;
ray_dev_t *local = (ray_dev_t *)dev->priv;
struct ccs __iomem *pccs;
int ccsindex;
ray_dev_t *local = (ray_dev_t *)dev->priv;
struct ccs __iomem *pccs;
-
struct pcmcia_device
*link = local->finder;
+
dev_link_t
*link = local->finder;
DEBUG(1,"dl_startup_params entered\n");
DEBUG(1,"dl_startup_params entered\n");
- if (!(
pcmcia_dev_present(link)
)) {
+ if (!(
link->state & DEV_PRESENT
)) {
DEBUG(2,"ray_cs dl_startup_params - device not present\n");
return -1;
}
DEBUG(2,"ray_cs dl_startup_params - device not present\n");
return -1;
}
@@
-712,9
+747,9
@@
static void verify_dl_startup(u_long data)
ray_dev_t *local = (ray_dev_t *)data;
struct ccs __iomem *pccs = ccs_base(local) + local->dl_param_ccs;
UCHAR status;
ray_dev_t *local = (ray_dev_t *)data;
struct ccs __iomem *pccs = ccs_base(local) + local->dl_param_ccs;
UCHAR status;
-
struct pcmcia_device
*link = local->finder;
+
dev_link_t
*link = local->finder;
- if (!(
pcmcia_dev_present(link)
)) {
+ if (!(
link->state & DEV_PRESENT
)) {
DEBUG(2,"ray_cs verify_dl_startup - device not present\n");
return;
}
DEBUG(2,"ray_cs verify_dl_startup - device not present\n");
return;
}
@@
-752,8
+787,8
@@
static void start_net(u_long data)
ray_dev_t *local = (ray_dev_t *)data;
struct ccs __iomem *pccs;
int ccsindex;
ray_dev_t *local = (ray_dev_t *)data;
struct ccs __iomem *pccs;
int ccsindex;
-
struct pcmcia_device
*link = local->finder;
- if (!(
pcmcia_dev_present(link)
)) {
+
dev_link_t
*link = local->finder;
+ if (!(
link->state & DEV_PRESENT
)) {
DEBUG(2,"ray_cs start_net - device not present\n");
return;
}
DEBUG(2,"ray_cs start_net - device not present\n");
return;
}
@@
-779,9
+814,9
@@
static void join_net(u_long data)
struct ccs __iomem *pccs;
int ccsindex;
struct ccs __iomem *pccs;
int ccsindex;
-
struct pcmcia_device
*link = local->finder;
+
dev_link_t
*link = local->finder;
- if (!(
pcmcia_dev_present(link)
)) {
+ if (!(
link->state & DEV_PRESENT
)) {
DEBUG(2,"ray_cs join_net - device not present\n");
return;
}
DEBUG(2,"ray_cs join_net - device not present\n");
return;
}
@@
-805,7
+840,7
@@
static void join_net(u_long data)
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
=============================================================================*/
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
=============================================================================*/
-static void ray_release(
struct pcmcia_device
*link)
+static void ray_release(
dev_link_t
*link)
{
struct net_device *dev = link->priv;
ray_dev_t *local = dev->priv;
{
struct net_device *dev = link->priv;
ray_dev_t *local = dev->priv;
@@
-814,38
+849,56
@@
static void ray_release(struct pcmcia_device *link)
DEBUG(1, "ray_release(0x%p)\n", link);
del_timer(&local->timer);
DEBUG(1, "ray_release(0x%p)\n", link);
del_timer(&local->timer);
+ link->state &= ~DEV_CONFIG;
iounmap(local->sram);
iounmap(local->rmem);
iounmap(local->amem);
/* Do bother checking to see if these succeed or not */
iounmap(local->sram);
iounmap(local->rmem);
iounmap(local->amem);
/* Do bother checking to see if these succeed or not */
+ i = pcmcia_release_window(link->win);
+ if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(link->win) ret = %x\n",i);
i = pcmcia_release_window(local->amem_handle);
if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i);
i = pcmcia_release_window(local->rmem_handle);
if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i);
i = pcmcia_release_window(local->amem_handle);
if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i);
i = pcmcia_release_window(local->rmem_handle);
if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i);
- pcmcia_disable_device(link);
+ i = pcmcia_release_configuration(link->handle);
+ if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseConfiguration ret = %x\n",i);
+ i = pcmcia_release_irq(link->handle, &link->irq);
+ if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseIRQ ret = %x\n",i);
DEBUG(2,"ray_release ending\n");
}
DEBUG(2,"ray_release ending\n");
}
-static int ray_suspend(struct pcmcia_device *
link
)
+static int ray_suspend(struct pcmcia_device *
p_dev
)
{
{
+ dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
struct net_device *dev = link->priv;
- if (link->open)
- netif_device_detach(dev);
+ link->state |= DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ if (link->open)
+ netif_device_detach(dev);
+
+ pcmcia_release_configuration(link->handle);
+ }
+
return 0;
}
return 0;
}
-static int ray_resume(struct pcmcia_device *
link
)
+static int ray_resume(struct pcmcia_device *
p_dev
)
{
{
+ dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
struct net_device *dev = link->priv;
- if (link->open) {
- ray_reset(dev);
- netif_device_attach(dev);
- }
+ link->state &= ~DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ pcmcia_request_configuration(link->handle, &link->conf);
+ if (link->open) {
+ ray_reset(dev);
+ netif_device_attach(dev);
+ }
+ }
return 0;
}
return 0;
}
@@
-857,10
+910,10
@@
int ray_dev_init(struct net_device *dev)
int i;
#endif /* RAY_IMMEDIATE_INIT */
ray_dev_t *local = dev->priv;
int i;
#endif /* RAY_IMMEDIATE_INIT */
ray_dev_t *local = dev->priv;
-
struct pcmcia_device
*link = local->finder;
+
dev_link_t
*link = local->finder;
DEBUG(1,"ray_dev_init(dev=%p)\n",dev);
DEBUG(1,"ray_dev_init(dev=%p)\n",dev);
- if (!(
pcmcia_dev_present(link)
)) {
+ if (!(
link->state & DEV_PRESENT
)) {
DEBUG(2,"ray_dev_init - device not present\n");
return -1;
}
DEBUG(2,"ray_dev_init - device not present\n");
return -1;
}
@@
-891,10
+944,10
@@
int ray_dev_init(struct net_device *dev)
static int ray_dev_config(struct net_device *dev, struct ifmap *map)
{
ray_dev_t *local = dev->priv;
static int ray_dev_config(struct net_device *dev, struct ifmap *map)
{
ray_dev_t *local = dev->priv;
-
struct pcmcia_device
*link = local->finder;
+
dev_link_t
*link = local->finder;
/* Dummy routine to satisfy device structure */
DEBUG(1,"ray_dev_config(dev=%p,ifmap=%p)\n",dev,map);
/* Dummy routine to satisfy device structure */
DEBUG(1,"ray_dev_config(dev=%p,ifmap=%p)\n",dev,map);
- if (!(
pcmcia_dev_present(link)
)) {
+ if (!(
link->state & DEV_PRESENT
)) {
DEBUG(2,"ray_dev_config - device not present\n");
return -1;
}
DEBUG(2,"ray_dev_config - device not present\n");
return -1;
}
@@
-905,10
+958,10
@@
static int ray_dev_config(struct net_device *dev, struct ifmap *map)
static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
ray_dev_t *local = dev->priv;
static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
ray_dev_t *local = dev->priv;
-
struct pcmcia_device
*link = local->finder;
+
dev_link_t
*link = local->finder;
short length = skb->len;
short length = skb->len;
- if (!(
pcmcia_dev_present(link)
)) {
+ if (!(
link->state & DEV_PRESENT
)) {
DEBUG(2,"ray_dev_start_xmit - device not present\n");
return -1;
}
DEBUG(2,"ray_dev_start_xmit - device not present\n");
return -1;
}
@@
-1517,7
+1570,7
@@
static int ray_commit(struct net_device *dev,
static iw_stats * ray_get_wireless_stats(struct net_device * dev)
{
ray_dev_t * local = (ray_dev_t *) dev->priv;
static iw_stats * ray_get_wireless_stats(struct net_device * dev)
{
ray_dev_t * local = (ray_dev_t *) dev->priv;
-
struct pcmcia_device
*link = local->finder;
+
dev_link_t
*link = local->finder;
struct status __iomem *p = local->sram + STATUS_BASE;
if(local == (ray_dev_t *) NULL)
struct status __iomem *p = local->sram + STATUS_BASE;
if(local == (ray_dev_t *) NULL)
@@
-1535,7
+1588,7
@@
static iw_stats * ray_get_wireless_stats(struct net_device * dev)
}
#endif /* WIRELESS_SPY */
}
#endif /* WIRELESS_SPY */
- if(
pcmcia_dev_present(link
)) {
+ if(
(link->state & DEV_PRESENT
)) {
local->wstats.qual.noise = readb(&p->rxnoise);
local->wstats.qual.updated |= 4;
}
local->wstats.qual.noise = readb(&p->rxnoise);
local->wstats.qual.updated |= 4;
}
@@
-1604,14
+1657,18
@@
static const struct iw_handler_def ray_handler_def =
/*===========================================================================*/
static int ray_open(struct net_device *dev)
{
/*===========================================================================*/
static int ray_open(struct net_device *dev)
{
+ dev_link_t *link;
ray_dev_t *local = (ray_dev_t *)dev->priv;
ray_dev_t *local = (ray_dev_t *)dev->priv;
- struct pcmcia_device *link;
- link = local->finder;
DEBUG(1, "ray_open('%s')\n", dev->name);
DEBUG(1, "ray_open('%s')\n", dev->name);
- if (link->open == 0)
- local->num_multi = 0;
+ 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;
link->open++;
/* If the card is not started, time to start it ! - Jean II */
link->open++;
/* If the card is not started, time to start it ! - Jean II */
@@
-1638,12
+1695,15
@@
static int ray_open(struct net_device *dev)
/*===========================================================================*/
static int ray_dev_close(struct net_device *dev)
{
/*===========================================================================*/
static int ray_dev_close(struct net_device *dev)
{
- ray_dev_t *local = (ray_dev_t *)dev->priv;
- struct pcmcia_device *link;
- link = local->finder;
+ dev_link_t *link;
DEBUG(1, "ray_dev_close('%s')\n", dev->name);
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);
link->open--;
netif_stop_queue(dev);
@@
-1665,9
+1725,9
@@
static void ray_reset(struct net_device *dev) {
static int interrupt_ecf(ray_dev_t *local, int ccs)
{
int i = 50;
static int interrupt_ecf(ray_dev_t *local, int ccs)
{
int i = 50;
-
struct pcmcia_device
*link = local->finder;
+
dev_link_t
*link = local->finder;
- if (!(
pcmcia_dev_present(link)
)) {
+ if (!(
link->state & DEV_PRESENT
)) {
DEBUG(2,"ray_cs interrupt_ecf - device not present\n");
return -1;
}
DEBUG(2,"ray_cs interrupt_ecf - device not present\n");
return -1;
}
@@
-1692,9
+1752,9
@@
static int get_free_tx_ccs(ray_dev_t *local)
{
int i;
struct ccs __iomem *pccs = ccs_base(local);
{
int i;
struct ccs __iomem *pccs = ccs_base(local);
-
struct pcmcia_device
*link = local->finder;
+
dev_link_t
*link = local->finder;
- if (!(
pcmcia_dev_present(link)
)) {
+ if (!(
link->state & DEV_PRESENT
)) {
DEBUG(2,"ray_cs get_free_tx_ccs - device not present\n");
return ECARDGONE;
}
DEBUG(2,"ray_cs get_free_tx_ccs - device not present\n");
return ECARDGONE;
}
@@
-1723,9
+1783,9
@@
static int get_free_ccs(ray_dev_t *local)
{
int i;
struct ccs __iomem *pccs = ccs_base(local);
{
int i;
struct ccs __iomem *pccs = ccs_base(local);
-
struct pcmcia_device
*link = local->finder;
+
dev_link_t
*link = local->finder;
- if (!(
pcmcia_dev_present(link)
)) {
+ if (!(
link->state & DEV_PRESENT
)) {
DEBUG(2,"ray_cs get_free_ccs - device not present\n");
return ECARDGONE;
}
DEBUG(2,"ray_cs get_free_ccs - device not present\n");
return ECARDGONE;
}
@@
-1798,9
+1858,9
@@
static int parse_addr(char *in_str, UCHAR *out)
static struct net_device_stats *ray_get_stats(struct net_device *dev)
{
ray_dev_t *local = (ray_dev_t *)dev->priv;
static struct net_device_stats *ray_get_stats(struct net_device *dev)
{
ray_dev_t *local = (ray_dev_t *)dev->priv;
-
struct pcmcia_device
*link = local->finder;
+
dev_link_t
*link = local->finder;
struct status __iomem *p = local->sram + STATUS_BASE;
struct status __iomem *p = local->sram + STATUS_BASE;
- if (!(
pcmcia_dev_present(link)
)) {
+ if (!(
link->state & DEV_PRESENT
)) {
DEBUG(2,"ray_cs net_device_stats - device not present\n");
return &local->stats;
}
DEBUG(2,"ray_cs net_device_stats - device not present\n");
return &local->stats;
}
@@
-1828,12
+1888,12
@@
static struct net_device_stats *ray_get_stats(struct net_device *dev)
static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len)
{
ray_dev_t *local = (ray_dev_t *)dev->priv;
static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len)
{
ray_dev_t *local = (ray_dev_t *)dev->priv;
-
struct pcmcia_device
*link = local->finder;
+
dev_link_t
*link = local->finder;
int ccsindex;
int i;
struct ccs __iomem *pccs;
int ccsindex;
int i;
struct ccs __iomem *pccs;
- if (!(
pcmcia_dev_present(link)
)) {
+ if (!(
link->state & DEV_PRESENT
)) {
DEBUG(2,"ray_update_parm - device not present\n");
return;
}
DEBUG(2,"ray_update_parm - device not present\n");
return;
}
@@
-1865,10
+1925,10
@@
static void ray_update_multi_list(struct net_device *dev, int all)
struct ccs __iomem *pccs;
int i = 0;
ray_dev_t *local = (ray_dev_t *)dev->priv;
struct ccs __iomem *pccs;
int i = 0;
ray_dev_t *local = (ray_dev_t *)dev->priv;
-
struct pcmcia_device
*link = local->finder;
+
dev_link_t
*link = local->finder;
void __iomem *p = local->sram + HOST_TO_ECF_BASE;
void __iomem *p = local->sram + HOST_TO_ECF_BASE;
- if (!(
pcmcia_dev_present(link)
)) {
+ if (!(
link->state & DEV_PRESENT
)) {
DEBUG(2,"ray_update_multi_list - device not present\n");
return;
}
DEBUG(2,"ray_update_multi_list - device not present\n");
return;
}
@@
-1945,7
+2005,7
@@
static void set_multicast_list(struct net_device *dev)
static irqreturn_t ray_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
struct net_device *dev = (struct net_device *)dev_id;
static irqreturn_t ray_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
struct net_device *dev = (struct net_device *)dev_id;
-
struct pcmcia_device
*link;
+
dev_link_t
*link;
ray_dev_t *local;
struct ccs __iomem *pccs;
struct rcs __iomem *prcs;
ray_dev_t *local;
struct ccs __iomem *pccs;
struct rcs __iomem *prcs;
@@
-1960,8
+2020,8
@@
static irqreturn_t ray_interrupt(int irq, void *dev_id, struct pt_regs * regs)
DEBUG(4,"ray_cs: interrupt for *dev=%p\n",dev);
local = (ray_dev_t *)dev->priv;
DEBUG(4,"ray_cs: interrupt for *dev=%p\n",dev);
local = (ray_dev_t *)dev->priv;
- link = (
struct pcmcia_device
*)local->finder;
- if (
!pcmcia_dev_present(link)
) {
+ link = (
dev_link_t
*)local->finder;
+ if (
! (link->state & DEV_PRESENT) || link->state & DEV_SUSPEND
) {
DEBUG(2,"ray_cs interrupt from device not present or suspended.\n");
return IRQ_NONE;
}
DEBUG(2,"ray_cs interrupt from device not present or suspended.\n");
return IRQ_NONE;
}
@@
-2480,9
+2540,9
@@
static void release_frag_chain(ray_dev_t *local, struct rcs __iomem * prcs)
/*===========================================================================*/
static void authenticate(ray_dev_t *local)
{
/*===========================================================================*/
static void authenticate(ray_dev_t *local)
{
-
struct pcmcia_device
*link = local->finder;
+
dev_link_t
*link = local->finder;
DEBUG(0,"ray_cs Starting authentication.\n");
DEBUG(0,"ray_cs Starting authentication.\n");
- if (!(
pcmcia_dev_present(link)
)) {
+ if (!(
link->state & DEV_PRESENT
)) {
DEBUG(2,"ray_cs authenticate - device not present\n");
return;
}
DEBUG(2,"ray_cs authenticate - device not present\n");
return;
}
@@
-2546,10
+2606,10
@@
static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
static void associate(ray_dev_t *local)
{
struct ccs __iomem *pccs;
static void associate(ray_dev_t *local)
{
struct ccs __iomem *pccs;
-
struct pcmcia_device
*link = local->finder;
+
dev_link_t
*link = local->finder;
struct net_device *dev = link->priv;
int ccsindex;
struct net_device *dev = link->priv;
int ccsindex;
- if (!(
pcmcia_dev_present(link)
)) {
+ if (!(
link->state & DEV_PRESENT
)) {
DEBUG(2,"ray_cs associate - device not present\n");
return;
}
DEBUG(2,"ray_cs associate - device not present\n");
return;
}
@@
-2629,14
+2689,14
@@
static int ray_cs_proc_read(char *buf, char **start, off_t offset, int len)
* eg ifconfig
*/
int i;
* eg ifconfig
*/
int i;
-
struct pcmcia_device
*link;
+
dev_link_t
*link;
struct net_device *dev;
ray_dev_t *local;
UCHAR *p;
struct freq_hop_element *pfh;
UCHAR c[33];
struct net_device *dev;
ray_dev_t *local;
UCHAR *p;
struct freq_hop_element *pfh;
UCHAR c[33];
- link =
this_device
;
+ link =
dev_list
;
if (!link)
return 0;
dev = (struct net_device *)link->priv;
if (!link)
return 0;
dev = (struct net_device *)link->priv;
@@
-2838,7
+2898,7
@@
static struct pcmcia_driver ray_driver = {
.drv = {
.name = "ray_cs",
},
.drv = {
.name = "ray_cs",
},
- .probe = ray_
probe
,
+ .probe = ray_
attach
,
.remove = ray_detach,
.id_table = ray_ids,
.suspend = ray_suspend,
.remove = ray_detach,
.id_table = ray_ids,
.suspend = ray_suspend,
@@
-2880,6
+2940,7
@@
static void __exit exit_ray_cs(void)
#endif
pcmcia_unregister_driver(&ray_driver);
#endif
pcmcia_unregister_driver(&ray_driver);
+ BUG_ON(dev_list != NULL);
} /* exit_ray_cs */
module_init(init_ray_cs);
} /* exit_ray_cs */
module_init(init_ray_cs);