aboutsummaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/pcmcia/3c574_cs.c124
-rw-r--r--drivers/net/pcmcia/3c589_cs.c136
-rw-r--r--drivers/net/pcmcia/axnet_cs.c128
-rw-r--r--drivers/net/pcmcia/com20020_cs.c142
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c128
-rw-r--r--drivers/net/pcmcia/ibmtr_cs.c152
-rw-r--r--drivers/net/pcmcia/nmclan_cs.c134
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c129
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c195
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c158
-rw-r--r--drivers/net/wireless/airo_cs.c161
-rw-r--r--drivers/net/wireless/atmel_cs.c156
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c156
-rw-r--r--drivers/net/wireless/netwave_cs.c184
-rw-r--r--drivers/net/wireless/orinoco_cs.c208
-rw-r--r--drivers/net/wireless/ray_cs.c154
-rw-r--r--drivers/net/wireless/spectrum_cs.c175
-rw-r--r--drivers/net/wireless/wavelan_cs.c183
-rw-r--r--drivers/net/wireless/wavelan_cs.p.h11
-rw-r--r--drivers/net/wireless/wl3501_cs.c133
20 files changed, 940 insertions, 2007 deletions
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index 71fd41122c9..48774efeec7 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -227,8 +227,6 @@ static char mii_preamble_required = 0;
static void tc574_config(dev_link_t *link);
static void tc574_release(dev_link_t *link);
-static int tc574_event(event_t event, int priority,
- event_callback_args_t *args);
static void mdio_sync(kio_addr_t ioaddr, int bits);
static int mdio_read(kio_addr_t ioaddr, int phy_id, int location);
@@ -250,12 +248,7 @@ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static struct ethtool_ops netdev_ethtool_ops;
static void set_rx_mode(struct net_device *dev);
-static dev_info_t dev_info = "3c574_cs";
-
-static dev_link_t *tc574_attach(void);
-static void tc574_detach(dev_link_t *);
-
-static dev_link_t *dev_list;
+static void tc574_detach(struct pcmcia_device *p_dev);
/*
tc574_attach() creates an "instance" of the driver, allocating
@@ -263,20 +256,18 @@ static dev_link_t *dev_list;
with Card Services.
*/
-static dev_link_t *tc574_attach(void)
+static int tc574_attach(struct pcmcia_device *p_dev)
{
struct el3_private *lp;
- client_reg_t client_reg;
dev_link_t *link;
struct net_device *dev;
- int ret;
DEBUG(0, "3c574_attach()\n");
/* Create the PC card device object. */
dev = alloc_etherdev(sizeof(struct el3_private));
if (!dev)
- return NULL;
+ return -ENOMEM;
lp = netdev_priv(dev);
link = &lp->link;
link->priv = dev;
@@ -307,20 +298,13 @@ static dev_link_t *tc574_attach(void)
dev->watchdog_timeo = TX_TIMEOUT;
#endif
- /* Register with Card Services */
- link->next = dev_list;
- dev_list = link;
- client_reg.dev_info = &dev_info;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
- ret = pcmcia_register_client(&link->handle, &client_reg);
- if (ret != 0) {
- cs_error(link->handle, RegisterClient, ret);
- tc574_detach(link);
- return NULL;
- }
+ link->handle = p_dev;
+ p_dev->instance = link;
- return link;
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ tc574_config(link);
+
+ return 0;
} /* tc574_attach */
/*
@@ -332,30 +316,19 @@ static dev_link_t *tc574_attach(void)
*/
-static void tc574_detach(dev_link_t *link)
+static void tc574_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
- dev_link_t **linkp;
DEBUG(0, "3c574_detach(0x%p)\n", link);
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link) break;
- if (*linkp == NULL)
- return;
-
if (link->dev)
unregister_netdev(dev);
if (link->state & DEV_CONFIG)
tc574_release(link);
- if (link->handle)
- pcmcia_deregister_client(link->handle);
-
- /* Unlink device structure, free bits */
- *linkp = link->next;
free_netdev(dev);
} /* tc574_detach */
@@ -547,56 +520,37 @@ static void tc574_release(dev_link_t *link)
link->state &= ~DEV_CONFIG;
}
-/*
- The card status event handler. Mostly, this schedules other
- stuff to run after an event is received. A CARD_REMOVAL event
- also sets some flags to discourage the net drivers from trying
- to talk to the card any more.
-*/
-
-static int tc574_event(event_t event, int priority,
- event_callback_args_t *args)
+static int tc574_suspend(struct pcmcia_device *p_dev)
{
- dev_link_t *link = args->client_data;
+ dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
- DEBUG(1, "3c574_event(0x%06x)\n", event);
-
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG)
+ link->state |= DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ if (link->open)
netif_device_detach(dev);
- break;
- case CS_EVENT_CARD_INSERTION:
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- tc574_config(link);
- break;
- case CS_EVENT_PM_SUSPEND:
- link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
- if (link->state & DEV_CONFIG) {
- if (link->open)
- netif_device_detach(dev);
- pcmcia_release_configuration(link->handle);
- }
- break;
- case CS_EVENT_PM_RESUME:
- link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
- if (link->state & DEV_CONFIG) {
- pcmcia_request_configuration(link->handle, &link->conf);
- if (link->open) {
- tc574_reset(dev);
- netif_device_attach(dev);
- }
+ pcmcia_release_configuration(link->handle);
+ }
+
+ return 0;
+}
+
+static int tc574_resume(struct pcmcia_device *p_dev)
+{
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
+
+ link->state &= ~DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ pcmcia_request_configuration(link->handle, &link->conf);
+ if (link->open) {
+ tc574_reset(dev);
+ netif_device_attach(dev);
}
- break;
}
+
return 0;
-} /* tc574_event */
+}
static void dump_status(struct net_device *dev)
{
@@ -1292,10 +1246,11 @@ static struct pcmcia_driver tc574_driver = {
.drv = {
.name = "3c574_cs",
},
- .attach = tc574_attach,
- .event = tc574_event,
- .detach = tc574_detach,
+ .probe = tc574_attach,
+ .remove = tc574_detach,
.id_table = tc574_ids,
+ .suspend = tc574_suspend,
+ .resume = tc574_resume,
};
static int __init init_tc574(void)
@@ -1306,7 +1261,6 @@ static int __init init_tc574(void)
static void __exit exit_tc574(void)
{
pcmcia_unregister_driver(&tc574_driver);
- BUG_ON(dev_list != NULL);
}
module_init(init_tc574);
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index d83fdd8c194..1c3c9c666f7 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -143,8 +143,6 @@ DRV_NAME ".c " DRV_VERSION " 2001/10/13 00:08:50 (David Hinds)";
static void tc589_config(dev_link_t *link);
static void tc589_release(dev_link_t *link);
-static int tc589_event(event_t event, int priority,
- event_callback_args_t *args);
static u16 read_eeprom(kio_addr_t ioaddr, int index);
static void tc589_reset(struct net_device *dev);
@@ -161,12 +159,7 @@ static void el3_tx_timeout(struct net_device *dev);
static void set_multicast_list(struct net_device *dev);
static struct ethtool_ops netdev_ethtool_ops;
-static dev_info_t dev_info = "3c589_cs";
-
-static dev_link_t *tc589_attach(void);
-static void tc589_detach(dev_link_t *);
-
-static dev_link_t *dev_list;
+static void tc589_detach(struct pcmcia_device *p_dev);
/*======================================================================
@@ -176,20 +169,18 @@ static dev_link_t *dev_list;
======================================================================*/
-static dev_link_t *tc589_attach(void)
+static int tc589_attach(struct pcmcia_device *p_dev)
{
struct el3_private *lp;
- client_reg_t client_reg;
dev_link_t *link;
struct net_device *dev;
- int ret;
DEBUG(0, "3c589_attach()\n");
-
+
/* Create new ethernet device */
dev = alloc_etherdev(sizeof(struct el3_private));
if (!dev)
- return NULL;
+ return -ENOMEM;
lp = netdev_priv(dev);
link = &lp->link;
link->priv = dev;
@@ -206,7 +197,7 @@ static dev_link_t *tc589_attach(void)
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1;
link->conf.Present = PRESENT_OPTION;
-
+
/* The EL3-specific entries in the device structure. */
SET_MODULE_OWNER(dev);
dev->hard_start_xmit = &el3_start_xmit;
@@ -221,20 +212,13 @@ static dev_link_t *tc589_attach(void)
#endif
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
- /* Register with Card Services */
- link->next = dev_list;
- dev_list = link;
- client_reg.dev_info = &dev_info;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
- ret = pcmcia_register_client(&link->handle, &client_reg);
- if (ret != 0) {
- cs_error(link->handle, RegisterClient, ret);
- tc589_detach(link);
- return NULL;
- }
-
- return link;
+ link->handle = p_dev;
+ p_dev->instance = link;
+
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ tc589_config(link);
+
+ return 0;
} /* tc589_attach */
/*======================================================================
@@ -246,30 +230,19 @@ static dev_link_t *tc589_attach(void)
======================================================================*/
-static void tc589_detach(dev_link_t *link)
+static void tc589_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
- dev_link_t **linkp;
-
+
DEBUG(0, "3c589_detach(0x%p)\n", link);
-
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link) break;
- if (*linkp == NULL)
- return;
if (link->dev)
unregister_netdev(dev);
if (link->state & DEV_CONFIG)
tc589_release(link);
-
- if (link->handle)
- pcmcia_deregister_client(link->handle);
-
- /* Unlink device structure, free bits */
- *linkp = link->next;
+
free_netdev(dev);
} /* tc589_detach */
@@ -421,58 +394,37 @@ static void tc589_release(dev_link_t *link)
link->state &= ~DEV_CONFIG;
}
-/*======================================================================
-
- The card status event handler. Mostly, this schedules other
- stuff to run after an event is received. A CARD_REMOVAL event
- also sets some flags to discourage the net drivers from trying
- to talk to the card any more.
-
-======================================================================*/
-
-static int tc589_event(event_t event, int priority,
- event_callback_args_t *args)
+static int tc589_suspend(struct pcmcia_device *p_dev)
{
- dev_link_t *link = args->client_data;
- struct net_device *dev = link->priv;
-
- DEBUG(1, "3c589_event(0x%06x)\n", event);
-
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG)
- netif_device_detach(dev);
- break;
- case CS_EVENT_CARD_INSERTION:
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- tc589_config(link);
- break;
- case CS_EVENT_PM_SUSPEND:
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
+
link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
- if (link->open)
- netif_device_detach(dev);
- pcmcia_release_configuration(link->handle);
+ if (link->open)
+ netif_device_detach(dev);
+ pcmcia_release_configuration(link->handle);
}
- break;
- case CS_EVENT_PM_RESUME:
+
+ return 0;
+}
+
+static int tc589_resume(struct pcmcia_device *p_dev)
+{
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
+
link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
- pcmcia_request_configuration(link->handle, &link->conf);
- if (link->open) {
- tc589_reset(dev);
- netif_device_attach(dev);
- }
+ pcmcia_request_configuration(link->handle, &link->conf);
+ if (link->open) {
+ tc589_reset(dev);
+ netif_device_attach(dev);
+ }
}
- break;
- }
- return 0;
-} /* tc589_event */
+
+ return 0;
+}
/*====================================================================*/
@@ -1067,10 +1019,11 @@ static struct pcmcia_driver tc589_driver = {
.drv = {
.name = "3c589_cs",
},
- .attach = tc589_attach,
- .event = tc589_event,
- .detach = tc589_detach,
+ .probe = tc589_attach,
+ .remove = tc589_detach,
.id_table = tc589_ids,
+ .suspend = tc589_suspend,
+ .resume = tc589_resume,
};
static int __init init_tc589(void)
@@ -1081,7 +1034,6 @@ static int __init init_tc589(void)
static void __exit exit_tc589(void)
{
pcmcia_unregister_driver(&tc589_driver);
- BUG_ON(dev_list != NULL);
}
module_init(init_tc589);
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 8bb4e85689e..01ddfc8cce3 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -87,8 +87,6 @@ static char *version =
static void axnet_config(dev_link_t *link);
static void axnet_release(dev_link_t *link);
-static int axnet_event(event_t event, int priority,
- event_callback_args_t *args);
static int axnet_open(struct net_device *dev);
static int axnet_close(struct net_device *dev);
static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -107,11 +105,7 @@ static void block_input(struct net_device *dev, int count,
static void block_output(struct net_device *dev, int count,
const u_char *buf, const int start_page);
-static dev_link_t *axnet_attach(void);
-static void axnet_detach(dev_link_t *);
-
-static dev_info_t dev_info = "axnet_cs";
-static dev_link_t *dev_list;
+static void axnet_detach(struct pcmcia_device *p_dev);
static void axdev_setup(struct net_device *dev);
static void AX88190_init(struct net_device *dev, int startp);
@@ -147,13 +141,11 @@ static inline axnet_dev_t *PRIV(struct net_device *dev)
======================================================================*/
-static dev_link_t *axnet_attach(void)
+static int axnet_attach(struct pcmcia_device *p_dev)
{
axnet_dev_t *info;
dev_link_t *link;
struct net_device *dev;
- client_reg_t client_reg;
- int ret;
DEBUG(0, "axnet_attach()\n");
@@ -161,7 +153,7 @@ static dev_link_t *axnet_attach(void)
"eth%d", axdev_setup);
if (!dev)
- return NULL;
+ return -ENOMEM;
info = PRIV(dev);
link = &info->link;
@@ -176,20 +168,13 @@ static dev_link_t *axnet_attach(void)
dev->do_ioctl = &axnet_ioctl;
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
- /* Register with Card Services */
- link->next = dev_list;
- dev_list = link;
- client_reg.dev_info = &dev_info;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
- ret = pcmcia_register_client(&link->handle, &client_reg);
- if (ret != CS_SUCCESS) {
- cs_error(link->handle, RegisterClient, ret);
- axnet_detach(link);
- return NULL;
- }
+ link->handle = p_dev;
+ p_dev->instance = link;
- return link;
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ axnet_config(link);
+
+ return 0;
} /* axnet_attach */
/*======================================================================
@@ -201,30 +186,19 @@ static dev_link_t *axnet_attach(void)
======================================================================*/
-static void axnet_detach(dev_link_t *link)
+static void axnet_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
- dev_link_t **linkp;
DEBUG(0, "axnet_detach(0x%p)\n", link);
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link) break;
- if (*linkp == NULL)
- return;
-
if (link->dev)
unregister_netdev(dev);
if (link->state & DEV_CONFIG)
axnet_release(link);
- if (link->handle)
- pcmcia_deregister_client(link->handle);
-
- /* Unlink device structure, free bits */
- *linkp = link->next;
free_netdev(dev);
} /* axnet_detach */
@@ -490,59 +464,39 @@ static void axnet_release(dev_link_t *link)
link->state &= ~DEV_CONFIG;
}
-/*======================================================================
-
- The card status event handler. Mostly, this schedules other
- stuff to run after an event is received. A CARD_REMOVAL event
- also sets some flags to discourage the net drivers from trying
- to talk to the card any more.
-
-======================================================================*/
-
-static int axnet_event(event_t event, int priority,
- event_callback_args_t *args)
+static int axnet_suspend(struct pcmcia_device *p_dev)
{
- dev_link_t *link = args->client_data;
- struct net_device *dev = link->priv;
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
- DEBUG(2, "axnet_event(0x%06x)\n", event);
-
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG)
- netif_device_detach(dev);
- break;
- case CS_EVENT_CARD_INSERTION:
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- axnet_config(link);
- break;
- case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
- if (link->open)
- netif_device_detach(dev);
- pcmcia_release_configuration(link->handle);
+ if (link->open)
+ netif_device_detach(dev);
+ pcmcia_release_configuration(link->handle);
}
- break;
- case CS_EVENT_PM_RESUME:
+
+ return 0;
+}
+
+static int axnet_resume(struct pcmcia_device *p_dev)
+{
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
+
link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
- pcmcia_request_configuration(link->handle, &link->conf);
- if (link->open) {
- axnet_reset_8390(dev);
- AX88190_init(dev, 1);
- netif_device_attach(dev);
- }
+ pcmcia_request_configuration(link->handle, &link->conf);
+ if (link->open) {
+ axnet_reset_8390(dev);
+ AX88190_init(dev, 1);
+ netif_device_attach(dev);
+ }
}
- break;
- }
- return 0;
-} /* axnet_event */
+
+ return 0;
+}
+
/*======================================================================
@@ -616,7 +570,7 @@ static int axnet_open(struct net_device *dev)
link->open++;
- request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, dev_info, dev);
+ request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, "axnet_cs", dev);
info->link_status = 0x00;
init_timer(&info->watchdog);
@@ -877,10 +831,11 @@ static struct pcmcia_driver axnet_cs_driver = {
.drv = {
.name = "axnet_cs",
},
- .attach = axnet_attach,
- .event = axnet_event,
- .detach = axnet_detach,
+ .probe = axnet_attach,
+ .remove = axnet_detach,
.id_table = axnet_ids,
+ .suspend = axnet_suspend,
+ .resume = axnet_resume,
};
static int __init init_axnet_cs(void)
@@ -891,7 +846,6 @@ static int __init init_axnet_cs(void)
static void __exit exit_axnet_cs(void)
{
pcmcia_unregister_driver(&axnet_cs_driver);
- BUG_ON(dev_list != NULL);
}
module_init(init_axnet_cs);
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c
index b9355d9498a..2827a48ea37 100644
--- a/drivers/net/pcmcia/com20020_cs.c
+++ b/drivers/net/pcmcia/com20020_cs.c
@@ -120,15 +120,8 @@ MODULE_LICENSE("GPL");
static void com20020_config(dev_link_t *link);
static void com20020_release(dev_link_t *link);
-static int com20020_event(event_t event, int priority,
- event_callback_args_t *args);
-static dev_info_t dev_info = "com20020_cs";
-
-static dev_link_t *com20020_attach(void);
-static void com20020_detach(dev_link_t *);
-
-static dev_link_t *dev_list;
+static void com20020_detach(struct pcmcia_device *p_dev);
/*====================================================================*/
@@ -145,21 +138,19 @@ typedef struct com20020_dev_t {
======================================================================*/
-static dev_link_t *com20020_attach(void)
+static int com20020_attach(struct pcmcia_device *p_dev)
{
- client_reg_t client_reg;
dev_link_t *link;
com20020_dev_t *info;
struct net_device *dev;
- int ret;
struct arcnet_local *lp;
-
+
DEBUG(0, "com20020_attach()\n");
/* Create new network device */
link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
if (!link)
- return NULL;
+ return -ENOMEM;
info = kmalloc(sizeof(struct com20020_dev_t), GFP_KERNEL);
if (!info)
@@ -191,30 +182,19 @@ static dev_link_t *com20020_attach(void)
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.Present = PRESENT_OPTION;
-
link->irq.Instance = info->dev = dev;
link->priv = info;
- /* Register with Card Services */
- link->next = dev_list;
- dev_list = link;
- client_reg.dev_info = &dev_info;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
- ret = pcmcia_register_client(&link->handle, &client_reg);
- if (ret != 0) {
- cs_error(link->handle, RegisterClient, ret);
- com20020_detach(link);
- return NULL;
- }
+ link->state |= DEV_PRESENT;
+ com20020_config(link);
- return link;
+ return 0;
fail_alloc_dev:
kfree(info);
fail_alloc_info:
kfree(link);
- return NULL;
+ return -ENOMEM;
} /* com20020_attach */
/*======================================================================
@@ -226,29 +206,21 @@ fail_alloc_info:
======================================================================*/
-static void com20020_detach(dev_link_t *link)
+static void com20020_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
struct com20020_dev_t *info = link->priv;
- dev_link_t **linkp;
- struct net_device *dev;
-
+ struct net_device *dev = info->dev;
+
DEBUG(1,"detach...\n");
DEBUG(0, "com20020_detach(0x%p)\n", link);
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link) break;
- if (*linkp == NULL)
- return;
-
- dev = info->dev;
-
if (link->dev) {
DEBUG(1,"unregister...\n");
unregister_netdev(dev);
-
+
/*
* this is necessary because we register our IRQ separately
* from card services.
@@ -260,12 +232,8 @@ static void com20020_detach(dev_link_t *link)
if (link->state & DEV_CONFIG)
com20020_release(link);
- if (link->handle)
- pcmcia_deregister_client(link->handle);
-
/* Unlink device structure, free bits */
DEBUG(1,"unlinking...\n");
- *linkp = link->next;
if (link->priv)
{
dev = info->dev;
@@ -421,61 +389,41 @@ static void com20020_release(dev_link_t *link)
link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);
}
-/*======================================================================
+static int com20020_suspend(struct pcmcia_device *p_dev)
+{
+ dev_link_t *link = dev_to_instance(p_dev);
+ com20020_dev_t *info = link->priv;
+ struct net_device *dev = info->dev;
- The card status event handler. Mostly, this schedules other
- stuff to run after an event is received. A CARD_REMOVAL event
- also sets some flags to discourage the net drivers from trying
- to talk to the card any more.
+ link->state |= DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ if (link->open) {
+ netif_device_detach(dev);
+ }
+ pcmcia_release_configuration(link->handle);
+ }
-======================================================================*/
+ return 0;
+}
-static int com20020_event(event_t event, int priority,
- event_callback_args_t *args)
+static int com20020_resume(struct pcmcia_device *p_dev)
{
- dev_link_t *link = args->client_data;
- com20020_dev_t *info = link->priv;
- struct net_device *dev = info->dev;
+ dev_link_t *link = dev_to_instance(p_dev);
+ com20020_dev_t *info = link->priv;
+ struct net_device *dev = info->dev;
- DEBUG(1, "com20020_event(0x%06x)\n", event);
-
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG)
- netif_device_detach(dev);
- break;
- case CS_EVENT_CARD_INSERTION:
- link->state |= DEV_PRESENT;
- com20020_config(link);
- break;
- case CS_EVENT_PM_SUSPEND:
- link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
- if (link->state & DEV_CONFIG) {
- if (link->open) {
- netif_device_detach(dev);
- }
- pcmcia_release_configuration(link->handle);
- }
- break;
- case CS_EVENT_PM_RESUME:
- link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
+ link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
- pcmcia_request_configuration(link->handle, &link->conf);
- if (link->open) {
- int ioaddr = dev->base_addr;
- struct arcnet_local *lp = dev->priv;
- ARCRESET;
- }
+ pcmcia_request_configuration(link->handle, &link->conf);
+ if (link->open) {
+ int ioaddr = dev->base_addr;
+ struct arcnet_local *lp = dev->priv;
+ ARCRESET;
+ }
}
- break;
- }
- return 0;
-} /* com20020_event */
+
+ return 0;
+}
static struct pcmcia_device_id com20020_ids[] = {
PCMCIA_DEVICE_PROD_ID12("Contemporary Control Systems, Inc.", "PCM20 Arcnet Adapter", 0x59991666, 0x95dfffaf),
@@ -488,10 +436,11 @@ static struct pcmcia_driver com20020_cs_driver = {
.drv = {
.name = "com20020_cs",
},
- .attach = com20020_attach,
- .event = com20020_event,
- .detach = com20020_detach,
+ .probe = com20020_attach,
+ .remove = com20020_detach,
.id_table = com20020_ids,
+ .suspend = com20020_suspend,
+ .resume = com20020_resume,
};
static int __init init_com20020_cs(void)
@@ -502,7 +451,6 @@ static int __init init_com20020_cs(void)
static void __exit exit_com20020_cs(void)
{
pcmcia_unregister_driver(&com20020_cs_driver);
- BUG_ON(dev_list != NULL);
}
module_init(init_com20020_cs);
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 356f5090922..28fe2fb4d6c 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -88,10 +88,7 @@ static void fmvj18x_config(dev_link_t *link);
static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id);
static int fmvj18x_setup_mfc(dev_link_t *link);
static void fmvj18x_release(dev_link_t *link);
-static int fmvj18x_event(event_t event, int priority,
- event_callback_args_t *args);
-static dev_link_t *fmvj18x_attach(void);
-static void fmvj18x_detach(dev_link_t *);
+static void fmvj18x_detach(struct pcmcia_device *p_dev);
/*
LAN controller(MBH86960A) specific routines
@@ -108,9 +105,6 @@ static void set_rx_mode(struct net_device *dev);
static void fjn_tx_timeout(struct net_device *dev);
static struct ethtool_ops netdev_ethtool_ops;
-static dev_info_t dev_info = "fmvj18x_cs";
-static dev_link_t *dev_list;
-
/*
card type
*/
@@ -234,20 +228,18 @@ typedef struct local_info_t {
#define BANK_1U 0x24 /* bank 1 (CONFIG_1) */
#define BANK_2U 0x28 /* bank 2 (CONFIG_1) */
-static dev_link_t *fmvj18x_attach(void)
+static int fmvj18x_attach(struct pcmcia_device *p_dev)
{
local_info_t *lp;
dev_link_t *link;
struct net_device *dev;
- client_reg_t client_reg;
- int ret;
-
+
DEBUG(0, "fmvj18x_attach()\n");
/* Make up a FMVJ18x specific data structure */
dev = alloc_etherdev(sizeof(local_info_t));
if (!dev)
- return NULL;
+ return -ENOMEM;
lp = netdev_priv(dev);
link = &lp->link;
link->priv = dev;
@@ -262,7 +254,7 @@ static dev_link_t *fmvj18x_attach(void)
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->irq.Handler = &fjn_interrupt;
link->irq.Instance = dev;
-
+
/* General socket configuration */
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Vcc = 50;
@@ -281,37 +273,24 @@ static dev_link_t *fmvj18x_attach(void)
dev->watchdog_timeo = TX_TIMEOUT;
#endif
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
-
- /* Register with Card Services */
- link->next = dev_list;
- dev_list = link;
- client_reg.dev_info = &dev_info;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
- ret = pcmcia_register_client(&link->handle, &client_reg);
- if (ret != 0) {
- cs_error(link->handle, RegisterClient, ret);
- fmvj18x_detach(link);
- return NULL;
- }
- return link;
+ link->handle = p_dev;
+ p_dev->instance = link;
+
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ fmvj18x_config(link);
+
+ return 0;
} /* fmvj18x_attach */
/*====================================================================*/
-static void fmvj18x_detach(dev_link_t *link)
+static void fmvj18x_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
- dev_link_t **linkp;
-
+
DEBUG(0, "fmvj18x_detach(0x%p)\n", link);
-
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link) break;
- if (*linkp == NULL)
- return;
if (link->dev)
unregister_netdev(dev);
@@ -319,12 +298,6 @@ static void fmvj18x_detach(dev_link_t *link)
if (link->state & DEV_CONFIG)
fmvj18x_release(link);
- /* Break the link with Card Services */
- if (link->handle)
- pcmcia_deregister_client(link->handle);
-
- /* Unlink device structure, free pieces */
- *linkp = link->next;
free_netdev(dev);
} /* fmvj18x_detach */
@@ -713,51 +686,40 @@ static void fmvj18x_release(dev_link_t *link)
link->state &= ~DEV_CONFIG;
}
-/*====================================================================*/
-
-static int fmvj18x_event(event_t event, int priority,
- event_callback_args_t *args)
+static int fmvj18x_suspend(struct pcmcia_device *p_dev)
{
- dev_link_t *link = args->client_data;
- struct net_device *dev = link->priv;
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
- DEBUG(1, "fmvj18x_event(0x%06x)\n", event);
-
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG)
- netif_device_detach(dev);
- break;
- case CS_EVENT_CARD_INSERTION:
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- fmvj18x_config(link);
- break;
- case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
- if (link->open)
- netif_device_detach(dev);
- pcmcia_release_configuration(link->handle);
+ if (link->open)
+ netif_device_detach(dev);
+ pcmcia_release_configuration(link->handle);
}
- break;
- case CS_EVENT_PM_RESUME:
+
+
+ return 0;
+}
+
+static int fmvj18x_resume(struct pcmcia_device *p_dev)
+{
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
+
link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
- pcmcia_request_configuration(link->handle, &link->conf);
- if (link->open) {
- fjn_reset(dev);
- netif_device_attach(dev);
- }
+ pcmcia_request_configuration(link->handle, &link->conf);
+ if (link->open) {
+ fjn_reset(dev);
+ netif_device_attach(dev);
+ }
}
- break;
- }
- return 0;
-} /* fmvj18x_event */
+
+ return 0;
+}
+
+/*====================================================================*/
static struct pcmcia_device_id fmvj18x_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x0004, 0x0004),
@@ -789,10 +751,11 @@ static struct pcmcia_driver fmvj18x_cs_driver = {
.drv = {
.name = "fmvj18x_cs",
},
- .attach = fmvj18x_attach,
- .event = fmvj18x_event,
- .detach = fmvj18x_detach,
+ .probe = fmvj18x_attach,
+ .remove = fmvj18x_detach,
.id_table = fmvj18x_ids,
+ .suspend = fmvj18x_suspend,
+ .resume = fmvj18x_resume,
};
static int __init init_fmvj18x_cs(void)
@@ -803,7 +766,6 @@ static int __init init_fmvj18x_cs(void)
static void __exit exit_fmvj18x_cs(void)
{
pcmcia_unregister_driver(&fmvj18x_cs_driver);
- BUG_ON(dev_list != NULL);
}
module_init(init_fmvj18x_cs);
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
index b6c140eb979..b9c7e39576f 100644
--- a/drivers/net/pcmcia/ibmtr_cs.c
+++ b/drivers/net/pcmcia/ibmtr_cs.c
@@ -108,15 +108,7 @@ MODULE_LICENSE("GPL");
static void ibmtr_config(dev_link_t *link);
static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase);
static void ibmtr_release(dev_link_t *link);
-static int ibmtr_event(event_t event, int priority,
- event_callback_args_t *args);
-
-static dev_info_t dev_info = "ibmtr_cs";
-
-static dev_link_t *ibmtr_attach(void);
-static void ibmtr_detach(dev_link_t *);
-
-static dev_link_t *dev_list;
+static void ibmtr_detach(struct pcmcia_device *p_dev);
/*====================================================================*/
@@ -146,25 +138,23 @@ static struct ethtool_ops netdev_ethtool_ops = {
======================================================================*/
-static dev_link_t *ibmtr_attach(void)
+static int ibmtr_attach(struct pcmcia_device *p_dev)
{
ibmtr_dev_t *info;
dev_link_t *link;
struct net_device *dev;
- client_reg_t client_reg;
- int ret;
DEBUG(0, "ibmtr_attach()\n");
/* Create new token-ring device */
info = kmalloc(sizeof(*info), GFP_KERNEL);
- if (!info) return NULL;
+ if (!info) return -ENOMEM;
memset(info,0,sizeof(*info));
dev = alloc_trdev(sizeof(struct tok_info));
- if (!dev) {
- kfree(info);
- return NULL;
- }
+ if (!dev) {
+ kfree(info);
+ return -ENOMEM;
+ }
link = &info->link;
link->priv = info;
@@ -185,25 +175,13 @@ static dev_link_t *ibmtr_attach(void)
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
- /* Register with Card Services */
- link->next = dev_list;
- dev_list = link;
- client_reg.dev_info = &dev_info;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
- ret = pcmcia_register_client(&link->handle, &client_reg);
- if (ret != 0) {
- cs_error(link->handle, RegisterClient, ret);
- goto out_detach;
- }
+ link->handle = p_dev;
+ p_dev->instance = link;
-out:
- return link;
+ link->state |= DEV_PRESENT;
+ ibmtr_config(link);
-out_detach:
- ibmtr_detach(link);
- link = NULL;
- goto out;
+ return 0;
} /* ibmtr_attach */
/*======================================================================
@@ -215,22 +193,14 @@ out_detach:
======================================================================*/
-static void ibmtr_detach(dev_link_t *link)
+static void ibmtr_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
struct ibmtr_dev_t *info = link->priv;
- dev_link_t **linkp;
- struct net_device *dev;
+ struct net_device *dev = info->dev;
DEBUG(0, "ibmtr_detach(0x%p)\n", link);
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link) break;
- if (*linkp == NULL)
- return;
-
- dev = info->dev;
-
if (link->dev)
unregister_netdev(dev);
@@ -241,13 +211,8 @@ static void ibmtr_detach(dev_link_t *link)
if (link->state & DEV_CONFIG)
ibmtr_release(link);
- if (link->handle)
- pcmcia_deregister_client(link->handle);
-
- /* Unlink device structure, free bits */
- *linkp = link->next;
free_netdev(dev);
- kfree(info);
+ kfree(info);
} /* ibmtr_detach */
/*======================================================================
@@ -401,63 +366,40 @@ static void ibmtr_release(dev_link_t *link)
link->state &= ~DEV_CONFIG;
}
-/*======================================================================
+static int ibmtr_suspend(struct pcmcia_device *p_dev)
+{
+ dev_link_t *link = dev_to_instance(p_dev);
+ ibmtr_dev_t *info = link->priv;
+ struct net_device *dev = info->dev;
- The card status event handler. Mostly, this schedules other
- stuff to run after an event is received. A CARD_REMOVAL event
- also sets some flags to discourage the net drivers from trying
- to talk to the card any more.
+ link->state |= DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ if (link->open)
+ netif_device_detach(dev);
+ pcmcia_release_configuration(link->handle);
+ }
-======================================================================*/
+ return 0;
+}
-static int ibmtr_event(event_t event, int priority,
- event_callback_args_t *args)
+static int ibmtr_resume(struct pcmcia_device *p_dev)
{
- dev_link_t *link = args->client_data;
- ibmtr_dev_t *info = link->priv;
- struct net_device *dev = info->dev;
+ dev_link_t *link = dev_to_instance(p_dev);
+ ibmtr_dev_t *info = link->priv;
+ struct net_device *dev = info->dev;
- DEBUG(1, "ibmtr_event(0x%06x)\n", event);
-
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- /* set flag to bypass normal interrupt code */
- struct tok_info *priv = netdev_priv(dev);
- priv->sram_phys |= 1;
- netif_device_detach(dev);
- }
- break;
- case CS_EVENT_CARD_INSERTION:
- link->state |= DEV_PRESENT;
- ibmtr_config(link);
- break;
- case CS_EVENT_PM_SUSPEND:
- link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
+ link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
- if (link->open)
- netif_device_detach(dev);
- pcmcia_release_configuration(link->handle);
+ pcmcia_request_configuration(link->handle, &link->conf);
+ if (link->open) {
+ ibmtr_probe(dev); /* really? */
+ netif_device_attach(dev);
+ }
}
- break;
- case CS_EVENT_PM_RESUME:
- link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
- if (link->state & DEV_CONFIG) {
- pcmcia_request_configuration(link->handle, &link->conf);
- if (link->open) {
- ibmtr_probe(dev); /* really? */
- netif_device_attach(dev);
- }
- }
- break;
- }
- return 0;
-} /* ibmtr_event */
+
+ return 0;
+}
+
/*====================================================================*/
@@ -514,10 +456,11 @@ static struct pcmcia_driver ibmtr_cs_driver = {
.drv = {
.name = "ibmtr_cs",
},
- .attach = ibmtr_attach,
- .event = ibmtr_event,
- .detach = ibmtr_detach,
+ .probe = ibmtr_attach,
+ .remove = ibmtr_detach,
.id_table = ibmtr_ids,
+ .suspend = ibmtr_suspend,
+ .resume = ibmtr_resume,
};
static int __init init_ibmtr_cs(void)
@@ -528,7 +471,6 @@ static int __init init_ibmtr_cs(void)
static void __exit exit_ibmtr_cs(void)
{
pcmcia_unregister_driver(&ibmtr_cs_driver);
- BUG_ON(dev_list != NULL);
}
module_init(init_ibmtr_cs);
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 980d7e5d66c..4a232254a49 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -388,9 +388,6 @@ static char *version =
DRV_NAME " " DRV_VERSION " (Roger C. Pao)";
#endif
-static dev_info_t dev_info="nmclan_cs";
-static dev_link_t *dev_list;
-
static char *if_names[]={
"Auto", "10baseT", "BNC",
};
@@ -422,8 +419,6 @@ Function Prototypes
static void nmclan_config(dev_link_t *link);
static void nmclan_release(dev_link_t *link);
-static int nmclan_event(event_t event, int priority,
- event_callback_args_t *args);
static void nmclan_reset(struct net_device *dev);
static int mace_config(struct net_device *dev, struct ifmap *map);
@@ -439,8 +434,7 @@ static void set_multicast_list(struct net_device *dev);
static struct ethtool_ops netdev_ethtool_ops;
-static dev_link_t *nmclan_attach(void);
-static void nmclan_detach(dev_link_t *);
+static void nmclan_detach(struct pcmcia_device *p_dev);
/* ----------------------------------------------------------------------------
nmclan_attach
@@ -449,13 +443,11 @@ nmclan_attach
Services.
---------------------------------------------------------------------------- */
-static dev_link_t *nmclan_attach(void)
+static int nmclan_attach(struct pcmcia_device *p_dev)
{
mace_private *lp;
dev_link_t *link;
struct net_device *dev;
- client_reg_t client_reg;
- int ret;
DEBUG(0, "nmclan_attach()\n");
DEBUG(1, "%s\n", rcsid);
@@ -463,7 +455,7 @@ static dev_link_t *nmclan_attach(void)
/* Create new ethernet device */
dev = alloc_etherdev(sizeof(mace_private));
if (!dev)
- return NULL;
+ return -ENOMEM;
lp = netdev_priv(dev);
link = &lp->link;
link->priv = dev;
@@ -497,20 +489,13 @@ static dev_link_t *nmclan_attach(void)
dev->watchdog_timeo = TX_TIMEOUT;
#endif
- /* Register with Card Services */
- link->next = dev_list;
- dev_list = link;
- client_reg.dev_info = &dev_info;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
- ret = pcmcia_register_client(&link->handle, &client_reg);
- if (ret != 0) {
- cs_error(link->handle, RegisterClient, ret);
- nmclan_detach(link);
- return NULL;
- }
+ link->handle = p_dev;
+ p_dev->instance = link;
+
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ nmclan_config(link);
- return link;
+ return 0;
} /* nmclan_attach */
/* ----------------------------------------------------------------------------
@@ -521,30 +506,19 @@ nmclan_detach
when the device is released.
---------------------------------------------------------------------------- */
-static void nmclan_detach(dev_link_t *link)
+static void nmclan_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
- dev_link_t **linkp;
DEBUG(0, "nmclan_detach(0x%p)\n", link);
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link) break;
- if (*linkp == NULL)
- return;
-
if (link->dev)
unregister_netdev(dev);
if (link->state & DEV_CONFIG)
nmclan_release(link);
- if (link->handle)
- pcmcia_deregister_client(link->handle);
-
- /* Unlink device structure, free bits */
- *linkp = link->next;
free_netdev(dev);
} /* nmclan_detach */
@@ -801,59 +775,39 @@ static void nmclan_release(dev_link_t *link)
link->state &= ~DEV_CONFIG;
}
-/* ----------------------------------------------------------------------------
-nmclan_event
- The card status event handler. Mostly, this schedules other
- stuff to run after an event is received. A CARD_REMOVAL event
- also sets some flags to discourage the net drivers from trying
- to talk to the card any more.
----------------------------------------------------------------------------- */
-static int nmclan_event(event_t event, int priority,
- event_callback_args_t *args)
+static int nmclan_suspend(struct pcmcia_device *p_dev)
{
- dev_link_t *link = args->client_data;
- struct net_device *dev = link->priv;
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
+
+ link->state |= DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ if (link->open)
+ netif_device_detach(dev);
+ pcmcia_release_configuration(link->handle);
+ }
- DEBUG(1, "nmclan_event(0x%06x)\n", event);
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG)
- netif_device_detach(dev);
- break;
- case CS_EVENT_CARD_INSERTION:
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- nmclan_config(link);
- break;
- case CS_EVENT_PM_SUSPEND:
- link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
- if (link->state & DEV_CONFIG) {
- if (link->open)
- netif_device_detach(dev);
- pcmcia_release_configuration(link->handle);
- }
- break;
- case CS_EVENT_PM_RESUME:
- link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
- if (link->state & DEV_CONFIG) {
- pcmcia_request_configuration(link->handle, &link->conf);
- if (link->open) {
- nmclan_reset(dev);
- netif_device_attach(dev);
+ return 0;
+}
+
+static int nmclan_resume(struct pcmcia_device *p_dev)
+{
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
+
+ link->state &= ~DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ pcmcia_request_configuration(link->handle, &link->conf);
+ if (link->open) {
+ nmclan_reset(dev);
+ netif_device_attach(dev);
+ }
}
- }
- break;
- case CS_EVENT_RESET_REQUEST:
- return 1;
- break;
- }
- return 0;
-} /* nmclan_event */
+
+ return 0;
+}
+
/* ----------------------------------------------------------------------------
nmclan_reset
@@ -1681,10 +1635,11 @@ static struct pcmcia_driver nmclan_cs_driver = {
.drv = {
.name = "nmclan_cs",
},
- .attach = nmclan_attach,
- .event = nmclan_event,
- .detach = nmclan_detach,
+ .probe = nmclan_attach,
+ .remove = nmclan_detach,
.id_table = nmclan_ids,
+ .suspend = nmclan_suspend,
+ .resume = nmclan_resume,
};
static int __init init_nmclan_cs(void)
@@ -1695,7 +1650,6 @@ static int __init init_nmclan_cs(void)
static void __exit exit_nmclan_cs(void)
{
pcmcia_unregister_driver(&nmclan_cs_driver);
- BUG_ON(dev_list != NULL);
}
module_init(init_nmclan_cs);
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 818c185d643..d85b758f3ef 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -105,8 +105,6 @@ module_param_array(hw_addr, int, NULL, 0);
static void mii_phy_probe(struct net_device *dev);
static void pcnet_config(dev_link_t *link);
static void pcnet_release(dev_link_t *link);
-static int pcnet_event(event_t event, int priority,
- event_callback_args_t *args);
static int pcnet_open(struct net_device *dev);
static int pcnet_close(struct net_device *dev);
static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -120,11 +118,9 @@ static int setup_shmem_window(dev_link_t *link, int start_pg,
static int setup_dma_config(dev_link_t *link, int start_pg,
int stop_pg);
-static dev_link_t *pcnet_attach(void);
-static void pcnet_detach(dev_link_t *);
+static void pcnet_detach(struct pcmcia_device *p_dev);
static dev_info_t dev_info = "pcnet_cs";
-static dev_link_t *dev_list;
/*====================================================================*/
@@ -244,19 +240,17 @@ static inline pcnet_dev_t *PRIV(struct net_device *dev)
======================================================================*/
-static dev_link_t *pcnet_attach(void)
+static int pcnet_probe(struct pcmcia_device *p_dev)
{
pcnet_dev_t *info;
dev_link_t *link;
struct net_device *dev;
- client_reg_t client_reg;
- int ret;
DEBUG(0, "pcnet_attach()\n");
/* Create new ethernet device */
dev = __alloc_ei_netdev(sizeof(pcnet_dev_t));
- if (!dev) return NULL;
+ if (!dev) return -ENOMEM;
info = PRIV(dev);
link = &info->link;
link->priv = dev;
@@ -271,20 +265,13 @@ static dev_link_t *pcnet_attach(void)
dev->stop = &pcnet_close;
dev->set_config = &set_config;
- /* Register with Card Services */
- link->next = dev_list;
- dev_list = link;
- client_reg.dev_info = &dev_info;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
- ret = pcmcia_register_client(&link->handle, &client_reg);
- if (ret != CS_SUCCESS) {
- cs_error(link->handle, RegisterClient, ret);
- pcnet_detach(link);
- return NULL;
- }
+ link->handle = p_dev;
+ p_dev->instance = link;
- return link;
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ pcnet_config(link);
+
+ return 0;
} /* pcnet_attach */
/*======================================================================
@@ -296,31 +283,20 @@ static dev_link_t *pcnet_attach(void)
======================================================================*/
-static void pcnet_detach(dev_link_t *link)
+static void pcnet_detach(struct pcmcia_device *p_dev)
{
- struct net_device *dev = link->priv;
- dev_link_t **linkp;
-
- DEBUG(0, "pcnet_detach(0x%p)\n", link);
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link) break;
- if (*linkp == NULL)
- return;
+ DEBUG(0, "pcnet_detach(0x%p)\n", link);
- if (link->dev)
- unregister_netdev(dev);
+ if (link->dev)
+ unregister_netdev(dev);
- if (link->state & DEV_CONFIG)
- pcnet_release(link);
-
- if (link->handle)
- pcmcia_deregister_client(link->handle);
+ if (link->state & DEV_CONFIG)
+ pcnet_release(link);
- /* Unlink device structure, free bits */
- *linkp = link->next;
- free_netdev(dev);
+ free_netdev(dev);
} /* pcnet_detach */
/*======================================================================
@@ -780,50 +756,39 @@ static void pcnet_release(dev_link_t *link)
======================================================================*/
-static int pcnet_event(event_t event, int priority,
- event_callback_args_t *args)
+static int pcnet_suspend(struct pcmcia_device *p_dev)
{
- dev_link_t *link = args->client_data;
- struct net_device *dev = link->priv;
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
- DEBUG(2, "pcnet_event(0x%06x)\n", event);
-
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG)
- netif_device_detach(dev);
- break;
- case CS_EVENT_CARD_INSERTION:
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- pcnet_config(link);
- break;
- case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
- if (link->open)
- netif_device_detach(dev);
- pcmcia_release_configuration(link->handle);
+ if (link->open)
+ netif_device_detach(dev);
+ pcmcia_release_configuration(link->handle);
}
- break;
- case CS_EVENT_PM_RESUME:
+
+ return 0;
+}
+
+static int pcnet_resume(struct pcmcia_device *p_dev)
+{
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
+
link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
- pcmcia_request_configuration(link->handle, &link->conf);
- if (link->open) {
- pcnet_reset_8390(dev);
- NS8390_init(dev, 1);
- netif_device_attach(dev);
- }
+ pcmcia_request_configuration(link->handle, &link->conf);
+ if (link->open) {
+ pcnet_reset_8390(dev);
+ NS8390_init(dev, 1);
+ netif_device_attach(dev);
+ }
}
- break;
- }
- return 0;
-} /* pcnet_event */
+
+ return 0;
+}
+
/*======================================================================
@@ -1844,11 +1809,12 @@ static struct pcmcia_driver pcnet_driver = {
.drv = {
.name = "pcnet_cs",
},
- .attach = pcnet_attach,
- .event = pcnet_event,
- .detach = pcnet_detach,
+ .probe = pcnet_probe,
+ .remove = pcnet_detach,
.owner = THIS_MODULE,
.id_table = pcnet_ids,
+ .suspend = pcnet_suspend,
+ .resume = pcnet_resume,
};
static int __init init_pcnet_cs(void)
@@ -1860,7 +1826,6 @@ static void __exit exit_pcnet_cs(void)
{
DEBUG(0, "pcnet_cs: unloading\n");
pcmcia_unregister_driver(&pcnet_driver);
- BUG_ON(dev_list != NULL);
}
module_init(init_pcnet_cs);
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index c7cca842e5e..0122415dfee 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -102,10 +102,6 @@ static const char *version =
currently have room for another Tx packet. */
#define MEMORY_WAIT_TIME 8
-static dev_info_t dev_info = "smc91c92_cs";
-
-static dev_link_t *dev_list;
-
struct smc_private {
dev_link_t link;
spinlock_t lock;
@@ -281,12 +277,9 @@ enum RxCfg { RxAllMulti = 0x0004, RxPromisc = 0x0002,
/*====================================================================*/
-static dev_link_t *smc91c92_attach(void);
-static void smc91c92_detach(dev_link_t *);
+static void smc91c92_detach(struct pcmcia_device *p_dev);
static void smc91c92_config(dev_link_t *link);
static void smc91c92_release(dev_link_t *link);
-static int smc91c92_event(event_t event, int priority,
- event_callback_args_t *args);
static int smc_open(struct net_device *dev);
static int smc_close(struct net_device *dev);
@@ -315,20 +308,18 @@ static struct ethtool_ops ethtool_ops;
======================================================================*/
-static dev_link_t *smc91c92_attach(void)
+static int smc91c92_attach(struct pcmcia_device *p_dev)
{
- client_reg_t client_reg;
struct smc_private *smc;
dev_link_t *link;
struct net_device *dev;
- int ret;
DEBUG(0, "smc91c92_attach()\n");
/* Create new ethernet device */
dev = alloc_etherdev(sizeof(struct smc_private));
if (!dev)
- return NULL;
+ return -ENOMEM;
smc = netdev_priv(dev);
link = &smc->link;
link->priv = dev;
@@ -366,20 +357,13 @@ static dev_link_t *smc91c92_attach(void)
smc->mii_if.phy_id_mask = 0x1f;
smc->mii_if.reg_num_mask = 0x1f;
- /* Register with Card Services */
- link->next = dev_list;
- dev_list = link;
- client_reg.dev_info = &dev_info;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
- ret = pcmcia_register_client(&link->handle, &client_reg);
- if (ret != 0) {
- cs_error(link->handle, RegisterClient, ret);
- smc91c92_detach(link);
- return NULL;
- }
+ link->handle = p_dev;
+ p_dev->instance = link;
+
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ smc91c92_config(link);
- return link;
+ return 0;
} /* smc91c92_attach */
/*======================================================================
@@ -391,30 +375,19 @@ static dev_link_t *smc91c92_attach(void)
======================================================================*/
-static void smc91c92_detach(dev_link_t *link)
+static void smc91c92_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
- dev_link_t **linkp;
DEBUG(0, "smc91c92_detach(0x%p)\n", link);
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link) break;
- if (*linkp == NULL)
- return;
-
if (link->dev)
unregister_netdev(dev);
if (link->state & DEV_CONFIG)
smc91c92_release(link);
- if (link->handle)
- pcmcia_deregister_client(link->handle);
-
- /* Unlink device structure, free bits */
- *linkp = link->next;
free_netdev(dev);
} /* smc91c92_detach */
@@ -895,6 +868,62 @@ free_cfg_mem:
return rc;
}
+static int smc91c92_suspend(struct pcmcia_device *p_dev)
+{
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
+
+ link->state |= DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ if (link->open)
+ netif_device_detach(dev);
+ pcmcia_release_configuration(link->handle);
+ }
+
+ return 0;
+}
+
+static int smc91c92_resume(struct pcmcia_device *p_dev)
+{
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
+ struct smc_private *smc = netdev_priv(dev);
+ int i;
+
+ link->state &= ~DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ if ((smc->manfid == MANFID_MEGAHERTZ) &&
+ (smc->cardid == PRODID_MEGAHERTZ_EM3288))
+ mhz_3288_power(link);
+ pcmcia_request_configuration(link->handle, &link->conf);
+ if (smc->manfid == MANFID_MOTOROLA)
+ mot_config(link);
+ if ((smc->manfid == MANFID_OSITECH) &&
+ (smc->cardid != PRODID_OSITECH_SEVEN)) {
+ /* Power up the card and enable interrupts */
+ set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
+ set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
+ }
+ if (((smc->manfid == MANFID_OSITECH) &&
+ (smc->cardid == PRODID_OSITECH_SEVEN)) ||
+ ((smc->manfid == MANFID_PSION) &&
+ (smc->cardid == PRODID_PSION_NET100))) {
+ /* Download the Seven of Diamonds firmware */
+ for (i = 0; i < sizeof(__Xilinx7OD); i++) {
+ outb(__Xilinx7OD[i], link->io.BasePort1+2);
+ udelay(50);
+ }
+ }
+ if (link->open) {
+ smc_reset(dev);
+ netif_device_attach(dev);
+ }
+ }
+
+ return 0;
+}
+
+
/*======================================================================
This verifies that the chip is some SMC91cXX variant, and returns
@@ -935,14 +964,12 @@ static int check_sig(dev_link_t *link)
}
if (width) {
- event_callback_args_t args;
printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n");
- args.client_data = link;
- smc91c92_event(CS_EVENT_RESET_PHYSICAL, 0, &args);
+ smc91c92_suspend(link->handle);
pcmcia_release_io(link->handle, &link->io);
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
pcmcia_request_io(link->handle, &link->io);
- smc91c92_event(CS_EVENT_CARD_RESET, 0, &args);
+ smc91c92_resume(link->handle);
return check_sig(link);
}
return -ENODEV;
@@ -1172,82 +1199,6 @@ static void smc91c92_release(dev_link_t *link)
/*======================================================================
- The card status event handler. Mostly, this schedules other
- stuff to run after an event is received. A CARD_REMOVAL event
- also sets some flags to discourage the net drivers from trying
- to talk to the card any more.
-
-======================================================================*/
-
-static int smc91c92_event(event_t event, int priority,
- event_callback_args_t *args)
-{
- dev_link_t *link = args->client_data;
- struct net_device *dev = link->priv;
- struct smc_private *smc = netdev_priv(dev);
- int i;
-
- DEBUG(1, "smc91c92_event(0x%06x)\n", event);
-
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG)
- netif_device_detach(dev);
- break;
- case CS_EVENT_CARD_INSERTION:
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- smc91c92_config(link);
- break;
- case CS_EVENT_PM_SUSPEND:
- link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
- if (link->state & DEV_CONFIG) {
- if (link->open)
- netif_device_detach(dev);
- pcmcia_release_configuration(link->handle);
- }
- break;
- case CS_EVENT_PM_RESUME:
- link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
- if (link->state & DEV_CONFIG) {
- if ((smc->manfid == MANFID_MEGAHERTZ) &&
- (smc->cardid == PRODID_MEGAHERTZ_EM3288))
- mhz_3288_power(link);
- pcmcia_request_configuration(link->handle, &link->conf);
- if (smc->manfid == MANFID_MOTOROLA)
- mot_config(link);
- if ((smc->manfid == MANFID_OSITECH) &&
- (smc->cardid != PRODID_OSITECH_SEVEN)) {
- /* Power up the card and enable interrupts */
- set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
- set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
- }
- if (((smc->manfid == MANFID_OSITECH) &&
- (smc->cardid == PRODID_OSITECH_SEVEN)) ||
- ((smc->manfid == MANFID_PSION) &&
- (smc->cardid == PRODID_PSION_NET100))) {
- /* Download the Seven of Diamonds firmware */
- for (i = 0; i < sizeof(__Xilinx7OD); i++) {
- outb(__Xilinx7OD[i], link->io.BasePort1+2);
- udelay(50);
- }
- }
- if (link->open) {
- smc_reset(dev);
- netif_device_attach(dev);
- }
- }
- break;
- }
- return 0;
-} /* smc91c92_event */
-
-/*======================================================================
-
MII interface support for SMC91cXX based cards
======================================================================*/
@@ -2360,10 +2311,11 @@ static struct pcmcia_driver smc91c92_cs_driver = {
.drv = {
.name = "smc91c92_cs",
},
- .attach = smc91c92_attach,
- .event = smc91c92_event,
- .detach = smc91c92_detach,
+ .probe = smc91c92_attach,
+ .remove = smc91c92_detach,
.id_table = smc91c92_ids,
+ .suspend = smc91c92_suspend,
+ .resume = smc91c92_resume,
};
static int __init init_smc91c92_cs(void)
@@ -2374,7 +2326,6 @@ static int __init init_smc91c92_cs(void)
static void __exit exit_smc91c92_cs(void)
{
pcmcia_unregister_driver(&smc91c92_cs_driver);
- BUG_ON(dev_list != NULL);
}
module_init(init_smc91c92_cs);
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index ce143f08638..049c34b3706 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -292,8 +292,6 @@ static void mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg,
static int has_ce2_string(dev_link_t * link);
static void xirc2ps_config(dev_link_t * link);
static void xirc2ps_release(dev_link_t * link);
-static int xirc2ps_event(event_t event, int priority,
- event_callback_args_t * args);
/****************
* The attach() and detach() entry points are used to create and destroy
@@ -301,8 +299,7 @@ static int xirc2ps_event(event_t event, int priority,
* needed to manage one actual PCMCIA card.
*/
-static dev_link_t *xirc2ps_attach(void);
-static void xirc2ps_detach(dev_link_t *);
+static void xirc2ps_detach(struct pcmcia_device *p_dev);
/****************
* You'll also need to prototype all the functions that will actually
@@ -313,14 +310,6 @@ static void xirc2ps_detach(dev_link_t *);
static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-/*
- * The dev_info variable is the "key" that is used to match up this
- * device driver with appropriate cards, through the card configuration
- * database.
- */
-
-static dev_info_t dev_info = "xirc2ps_cs";
-
/****************
* A linked list of "instances" of the device. Each actual
* PCMCIA card corresponds to one device instance, and is described
@@ -331,15 +320,7 @@ static dev_info_t dev_info = "xirc2ps_cs";
* device numbers are used to derive the corresponding array index.
*/
-static dev_link_t *dev_list;
-
/****************
- * 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
- * 'priv' pointer in a dev_link_t structure can be used to point to
- * a device-specific private data structure, like this.
- *
* A driver needs to provide a dev_node_t structure for each device
* on a card. In some cases, there is only one device per card (for
* example, ethernet cards, modems). In other cases, there may be
@@ -571,21 +552,19 @@ mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg, unsigned data, int len)
* card insertion event.
*/
-static dev_link_t *
-xirc2ps_attach(void)
+static int
+xirc2ps_attach(struct pcmcia_device *p_dev)
{
- client_reg_t client_reg;
dev_link_t *link;
struct net_device *dev;
local_info_t *local;
- int err;
DEBUG(0, "attach()\n");
/* Allocate the device structure */
dev = alloc_etherdev(sizeof(local_info_t));
if (!dev)
- return NULL;
+ return -ENOMEM;
local = netdev_priv(dev);
link = &local->link;
link->priv = dev;
@@ -614,19 +593,13 @@ xirc2ps_attach(void)
dev->watchdog_timeo = TX_TIMEOUT;
#endif
- /* Register with Card Services */
- link->next = dev_list;
- dev_list = link;
- client_reg.dev_info = &dev_info;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
- if ((err = pcmcia_register_client(&link->handle, &client_reg))) {
- cs_error(link->handle, RegisterClient, err);
- xirc2ps_detach(link);
- return NULL;
- }
+ link->handle = p_dev;
+ p_dev->instance = link;
+
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ xirc2ps_config(link);
- return link;
+ return 0;
} /* xirc2ps_attach */
/****************
@@ -637,40 +610,19 @@ xirc2ps_attach(void)
*/
static void
-xirc2ps_detach(dev_link_t * link)
+xirc2ps_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
- dev_link_t **linkp;
DEBUG(0, "detach(0x%p)\n", link);
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link)
- break;
- if (!*linkp) {
- DEBUG(0, "detach(0x%p): dev_link lost\n", link);
- return;
- }
-
if (link->dev)
unregister_netdev(dev);
- /*
- * 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().
- */
if (link->state & DEV_CONFIG)
xirc2ps_release(link);
- /* Break the link with Card Services */
- if (link->handle)
- pcmcia_deregister_client(link->handle);
-
- /* Unlink device structure, free it */
- *linkp = link->next;
free_netdev(dev);
} /* xirc2ps_detach */
@@ -1157,67 +1109,41 @@ xirc2ps_release(dev_link_t *link)
/*====================================================================*/
-/****************
- * The card status event handler. Mostly, this schedules other
- * stuff to run after an event is received. A CARD_REMOVAL event
- * also sets some flags to discourage the net drivers from trying
- * to talk to the card any more.
- *
- * When a CARD_REMOVAL event is received, we immediately set a flag
- * to block future accesses to this device. All the functions that
- * actually access the device should check this flag to make sure
- * the card is still present.
- */
-static int
-xirc2ps_event(event_t event, int priority,
- event_callback_args_t * args)
+static int xirc2ps_suspend(struct pcmcia_device *p_dev)
{
- dev_link_t *link = args->client_data;
- struct net_device *dev = link->priv;
-
- DEBUG(0, "event(%d)\n", (int)event);
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
- switch (event) {
- case CS_EVENT_REGISTRATION_COMPLETE:
- DEBUG(0, "registration complete\n");
- break;
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG)
- netif_device_detach(dev);
- break;
- case CS_EVENT_CARD_INSERTION:
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- xirc2ps_config(link);
- break;
- case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
- if (link->open) {
- netif_device_detach(dev);
- do_powerdown(dev);
- }
- pcmcia_release_configuration(link->handle);
+ if (link->open) {
+ netif_device_detach(dev);
+ do_powerdown(dev);
+ }
+ pcmcia_release_configuration(link->handle);
}
- break;
- case CS_EVENT_PM_RESUME:
+
+ return 0;
+}
+
+static int xirc2ps_resume(struct pcmcia_device *p_dev)
+{
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
+
link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
- pcmcia_request_configuration(link->handle, &link->conf);
- if (link->open) {
- do_reset(dev,1);
- netif_device_attach(dev);
- }
+ pcmcia_request_configuration(link->handle, &link->conf);
+ if (link->open) {
+ do_reset(dev,1);
+ netif_device_attach(dev);
+ }
}
- break;
- }
- return 0;
-} /* xirc2ps_event */
+
+ return 0;
+}
+
/*====================================================================*/
@@ -2009,10 +1935,11 @@ static struct pcmcia_driver xirc2ps_cs_driver = {
.drv = {
.name = "xirc2ps_cs",
},
- .attach = xirc2ps_attach,
- .event = xirc2ps_event,
- .detach = xirc2ps_detach,
+ .probe = xirc2ps_attach,
+ .remove = xirc2ps_detach,
.id_table = xirc2ps_ids,
+ .suspend = xirc2ps_suspend,
+ .resume = xirc2ps_resume,
};
static int __init
@@ -2025,7 +1952,6 @@ static void __exit
exit_xirc2ps_cs(void)
{
pcmcia_unregister_driver(&xirc2ps_cs_driver);
- BUG_ON(dev_list != NULL);
}
module_init(init_xirc2ps_cs);
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index e328547599d..a496460ce22 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -82,8 +82,6 @@ MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
static void airo_config(dev_link_t *link);
static void airo_release(dev_link_t *link);
-static int airo_event(event_t event, int priority,
- event_callback_args_t *args);
/*
The attach() and detach() entry points are used to create and destroy
@@ -91,8 +89,7 @@ static int airo_event(event_t event, int priority,
needed to manage one actual PCMCIA card.
*/
-static dev_link_t *airo_attach(void);
-static void airo_detach(dev_link_t *);
+static void airo_detach(struct pcmcia_device *p_dev);
/*
You'll also need to prototype all the functions that will actually
@@ -102,14 +99,6 @@ static void airo_detach(dev_link_t *);
*/
/*
- The dev_info variable is the "key" that is used to match up this
- device driver with appropriate cards, through the card configuration
- database.
-*/
-
-static dev_info_t dev_info = "airo_cs";
-
-/*
A linked list of "instances" of the aironet device. Each actual
PCMCIA card corresponds to one device instance, and is described
by one dev_link_t structure (defined in ds.h).
@@ -119,15 +108,7 @@ static dev_info_t dev_info = "airo_cs";
device numbers are used to derive the corresponding array index.
*/
-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
- 'priv' pointer in a dev_link_t structure can be used to point to
- a device-specific private data structure, like this.
-
A driver needs to provide a dev_node_t structure for each device
on a card. In some cases, there is only one device per card (for
example, ethernet cards, modems). In other cases, there may be
@@ -160,20 +141,18 @@ typedef struct local_info_t {
======================================================================*/
-static dev_link_t *airo_attach(void)
+static int airo_attach(struct pcmcia_device *p_dev)
{
- client_reg_t client_reg;
dev_link_t *link;
local_info_t *local;
- int ret;
-
+
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 NULL;
+ return -ENOMEM;
}
/* Interrupt setup */
@@ -197,24 +176,17 @@ static dev_link_t *airo_attach(void)
if (!local) {
printk(KERN_ERR "airo_cs: no memory for new device\n");
kfree (link);
- return NULL;
+ return -ENOMEM;
}
link->priv = local;
-
- /* Register with Card Services */
- link->next = dev_list;
- dev_list = link;
- client_reg.dev_info = &dev_info;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
- ret = pcmcia_register_client(&link->handle, &client_reg);
- if (ret != 0) {
- cs_error(link->handle, RegisterClient, ret);
- airo_detach(link);
- return NULL;
- }
-
- return link;
+
+ link->handle = p_dev;
+ p_dev->instance = link;
+
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ airo_config(link);
+
+ return 0;
} /* airo_attach */
/*======================================================================
@@ -226,37 +198,22 @@ static dev_link_t *airo_attach(void)
======================================================================*/
-static void airo_detach(dev_link_t *link)
+static void airo_detach(struct pcmcia_device *p_dev)
{
- dev_link_t **linkp;
-
+ dev_link_t *link = dev_to_instance(p_dev);
+
DEBUG(0, "airo_detach(0x%p)\n", link);
-
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link) break;
- if (*linkp == NULL)
- return;
-
+
if (link->state & DEV_CONFIG)
airo_release(link);
-
+
if ( ((local_info_t*)link->priv)->eth_dev ) {
stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 );
}
- ((local_info_t*)link->priv)->eth_dev = NULL;
-
- /* Break the link with Card Services */
- if (link->handle)
- pcmcia_deregister_client(link->handle);
-
-
-
- /* Unlink device structure, free pieces */
- *linkp = link->next;
+ ((local_info_t*)link->priv)->eth_dev = NULL;
+
kfree(link->priv);
kfree(link);
-
} /* airo_detach */
/*======================================================================
@@ -492,60 +449,34 @@ static void airo_release(dev_link_t *link)
link->state &= ~DEV_CONFIG;
}
-/*======================================================================
-
- The card status event handler. Mostly, this schedules other
- stuff to run after an event is received.
+static int airo_suspend(struct pcmcia_device *p_dev)
+{
+ dev_link_t *link = dev_to_instance(p_dev);
+ local_info_t *local = link->priv;
- When a CARD_REMOVAL event is received, we immediately set a
- private flag to block future accesses to this device. All the
- functions that actually access the device should check this flag
- to make sure the card is still present.
-
- ======================================================================*/
+ link->state |= DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ netif_device_detach(local->eth_dev);
+ pcmcia_release_configuration(link->handle);
+ }
+
+ return 0;
+}
-static int airo_event(event_t event, int priority,
- event_callback_args_t *args)
+static int airo_resume(struct pcmcia_device *p_dev)
{
- dev_link_t *link = args->client_data;
+ dev_link_t *link = dev_to_instance(p_dev);
local_info_t *local = link->priv;
-
- DEBUG(1, "airo_event(0x%06x)\n", event);
-
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- netif_device_detach(local->eth_dev);
- airo_release(link);
- }
- break;
- case CS_EVENT_CARD_INSERTION:
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- airo_config(link);
- break;
- case CS_EVENT_PM_SUSPEND:
- link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
- if (link->state & DEV_CONFIG) {
- netif_device_detach(local->eth_dev);
- pcmcia_release_configuration(link->handle);
- }
- break;
- case CS_EVENT_PM_RESUME:
- link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
- if (link->state & DEV_CONFIG) {
- pcmcia_request_configuration(link->handle, &link->conf);
- reset_airo_card(local->eth_dev);
- netif_device_attach(local->eth_dev);
- }
- break;
+
+ link->state &= ~DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ pcmcia_request_configuration(link->handle, &link->conf);
+ reset_airo_card(local->eth_dev);
+ netif_device_attach(local->eth_dev);
}
+
return 0;
-} /* airo_event */
+}
static struct pcmcia_device_id airo_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x015f, 0x000a),
@@ -561,10 +492,11 @@ static struct pcmcia_driver airo_driver = {
.drv = {
.name = "airo_cs",
},
- .attach = airo_attach,
- .event = airo_event,
- .detach = airo_detach,
+ .probe = airo_attach,
+ .remove = airo_detach,
.id_table = airo_ids,
+ .suspend = airo_suspend,
+ .resume = airo_resume,
};
static int airo_cs_init(void)
@@ -575,7 +507,6 @@ static int airo_cs_init(void)
static void airo_cs_cleanup(void)
{
pcmcia_unregister_driver(&airo_driver);
- BUG_ON(dev_list != NULL);
}
/*
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 17d1fd90f83..d6f4a5a3e55 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -93,8 +93,6 @@ MODULE_SUPPORTED_DEVICE("Atmel at76c50x PCMCIA cards");
static void atmel_config(dev_link_t *link);
static void atmel_release(dev_link_t *link);
-static int atmel_event(event_t event, int priority,
- event_callback_args_t *args);
/*
The attach() and detach() entry points are used to create and destroy
@@ -102,8 +100,7 @@ static int atmel_event(event_t event, int priority,
needed to manage one actual PCMCIA card.
*/
-static dev_link_t *atmel_attach(void);
-static void atmel_detach(dev_link_t *);
+static void atmel_detach(struct pcmcia_device *p_dev);
/*
You'll also need to prototype all the functions that will actually
@@ -113,14 +110,6 @@ static void atmel_detach(dev_link_t *);
*/
/*
- The dev_info variable is the "key" that is used to match up this
- device driver with appropriate cards, through the card configuration
- database.
-*/
-
-static dev_info_t dev_info = "atmel_cs";
-
-/*
A linked list of "instances" of the atmelnet device. Each actual
PCMCIA card corresponds to one device instance, and is described
by one dev_link_t structure (defined in ds.h).
@@ -130,15 +119,7 @@ static dev_info_t dev_info = "atmel_cs";
device numbers are used to derive the corresponding array index.
*/
-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
- 'priv' pointer in a dev_link_t structure can be used to point to
- a device-specific private data structure, like this.
-
A driver needs to provide a dev_node_t structure for each device
on a card. In some cases, there is only one device per card (for
example, ethernet cards, modems). In other cases, there may be
@@ -171,27 +152,25 @@ typedef struct local_info_t {
======================================================================*/
-static dev_link_t *atmel_attach(void)
+static int atmel_attach(struct pcmcia_device *p_dev)
{
- client_reg_t client_reg;
dev_link_t *link;
local_info_t *local;
- int ret;
-
+
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 NULL;
+ return -ENOMEM;
}
-
+
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->irq.Handler = NULL;
-
+
/*
General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost
@@ -202,30 +181,23 @@ static dev_link_t *atmel_attach(void)
link->conf.Attributes = 0;
link->conf.Vcc = 50;
link->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 NULL;
+ return -ENOMEM;
}
link->priv = local;
-
- /* Register with Card Services */
- link->next = dev_list;
- dev_list = link;
- client_reg.dev_info = &dev_info;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
- ret = pcmcia_register_client(&link->handle, &client_reg);
- if (ret != 0) {
- cs_error(link->handle, RegisterClient, ret);
- atmel_detach(link);
- return NULL;
- }
-
- return link;
+
+ link->handle = p_dev;
+ p_dev->instance = link;
+
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ atmel_config(link);
+
+ return 0;
} /* atmel_attach */
/*======================================================================
@@ -237,27 +209,15 @@ static dev_link_t *atmel_attach(void)
======================================================================*/
-static void atmel_detach(dev_link_t *link)
+static void atmel_detach(struct pcmcia_device *p_dev)
{
- dev_link_t **linkp;
-
+ dev_link_t *link = dev_to_instance(p_dev);
+
DEBUG(0, "atmel_detach(0x%p)\n", link);
-
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link) break;
- if (*linkp == NULL)
- return;
if (link->state & DEV_CONFIG)
atmel_release(link);
-
- /* Break the link with Card Services */
- if (link->handle)
- pcmcia_deregister_client(link->handle);
- /* Unlink device structure, free pieces */
- *linkp = link->next;
kfree(link->priv);
kfree(link);
}
@@ -477,60 +437,34 @@ static void atmel_release(dev_link_t *link)
link->state &= ~DEV_CONFIG;
}
-/*======================================================================
-
- The card status event handler. Mostly, this schedules other
- stuff to run after an event is received.
+static int atmel_suspend(struct pcmcia_device *dev)
+{
+ dev_link_t *link = dev_to_instance(dev);
+ local_info_t *local = link->priv;
- When a CARD_REMOVAL event is received, we immediately set a
- private flag to block future accesses to this device. All the
- functions that actually access the device should check this flag
- to make sure the card is still present.
-
- ======================================================================*/
+ link->state |= DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ netif_device_detach(local->eth_dev);
+ pcmcia_release_configuration(link->handle);
+ }
+
+ return 0;
+}
-static int atmel_event(event_t event, int priority,
- event_callback_args_t *args)
+static int atmel_resume(struct pcmcia_device *dev)
{
- dev_link_t *link = args->client_data;
+ dev_link_t *link = dev_to_instance(dev);
local_info_t *local = link->priv;
-
- DEBUG(1, "atmel_event(0x%06x)\n", event);
-
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- netif_device_detach(local->eth_dev);
- atmel_release(link);
- }
- break;
- case CS_EVENT_CARD_INSERTION:
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- atmel_config(link);
- break;
- case CS_EVENT_PM_SUSPEND:
- link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
- if (link->state & DEV_CONFIG) {
- netif_device_detach(local->eth_dev);
- pcmcia_release_configuration(link->handle);
- }
- break;
- case CS_EVENT_PM_RESUME:
- link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
- if (link->state & DEV_CONFIG) {
- pcmcia_request_configuration(link->handle, &link->conf);
- atmel_open(local->eth_dev);
- netif_device_attach(local->eth_dev);
- }
- break;
+
+ link->state &= ~DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ pcmcia_request_configuration(link->handle, &link->conf);
+ atmel_open(local->eth_dev);
+ netif_device_attach(local->eth_dev);
}
+
return 0;
-} /* atmel_event */
+}
/*====================================================================*/
/* We use the driver_info field to store the correct firmware type for a card. */
@@ -581,10 +515,11 @@ static struct pcmcia_driver atmel_driver = {
.drv = {
.name = "atmel_cs",
},
- .attach = atmel_attach,
- .event = atmel_event,
- .detach = atmel_detach,
+ .probe = atmel_attach,
+ .remove = atmel_detach,
.id_table = atmel_ids,
+ .suspend = atmel_suspend,
+ .resume = atmel_resume,
};
static int atmel_cs_init(void)
@@ -595,7 +530,6 @@ static int atmel_cs_init(void)
static void atmel_cs_cleanup(void)
{
pcmcia_unregister_driver(&atmel_driver);
- BUG_ON(dev_list != NULL);
}
/*
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 2643976a667..8bc0b528548 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -25,7 +25,6 @@
static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)";
static dev_info_t dev_info = "hostap_cs";
-static dev_link_t *dev_list = NULL;
MODULE_AUTHOR("Jouni Malinen");
MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN "
@@ -203,10 +202,9 @@ static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len)
-static void prism2_detach(dev_link_t *link);
+static void prism2_detach(struct pcmcia_device *p_dev);
static void prism2_release(u_long arg);
-static int prism2_event(event_t event, int priority,
- event_callback_args_t *args);
+static int prism2_config(dev_link_t *link);
static int prism2_pccard_card_present(local_info_t *local)
@@ -503,15 +501,13 @@ static struct prism2_helper_functions prism2_pccard_funcs =
/* allocate local data and register with CardServices
* initialize dev_link structure, but do not configure the card yet */
-static dev_link_t *prism2_attach(void)
+static int prism2_attach(struct pcmcia_device *p_dev)
{
dev_link_t *link;
- client_reg_t client_reg;
- int ret;
link = kmalloc(sizeof(dev_link_t), GFP_KERNEL);
if (link == NULL)
- return NULL;
+ return -ENOMEM;
memset(link, 0, sizeof(dev_link_t));
@@ -519,50 +515,27 @@ static dev_link_t *prism2_attach(void)
link->conf.Vcc = 33;
link->conf.IntType = INT_MEMORY_AND_IO;
- /* register with CardServices */
- link->next = dev_list;
- dev_list = link;
- client_reg.dev_info = &dev_info;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
- ret = pcmcia_register_client(&link->handle, &client_reg);
- if (ret != CS_SUCCESS) {
- cs_error(link->handle, RegisterClient, ret);
- prism2_detach(link);
- return NULL;
- }
- return link;
+ link->handle = p_dev;
+ p_dev->instance = link;
+
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ if (prism2_config(link))
+ PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n");
+
+ return 0;
}
-static void prism2_detach(dev_link_t *link)
+static void prism2_detach(struct pcmcia_device *p_dev)
{
- dev_link_t **linkp;
+ dev_link_t *link = dev_to_instance(p_dev);
PDEBUG(DEBUG_FLOW, "prism2_detach\n");
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link)
- break;
- if (*linkp == NULL) {
- printk(KERN_WARNING "%s: Attempt to detach non-existing "
- "PCMCIA client\n", dev_info);
- return;
- }
-
if (link->state & DEV_CONFIG) {
prism2_release((u_long)link);
}
- if (link->handle) {
- int res = pcmcia_deregister_client(link->handle);
- if (res) {
- printk("CardService(DeregisterClient) => %d\n", res);
- cs_error(link->handle, DeregisterClient, res);
- }
- }
-
- *linkp = link->next;
/* release net devices */
if (link->priv) {
struct hostap_cs_priv *hw_priv;
@@ -846,84 +819,58 @@ static void prism2_release(u_long arg)
PDEBUG(DEBUG_FLOW, "release - done\n");
}
-
-static int prism2_event(event_t event, int priority,
- event_callback_args_t *args)
+static int hostap_cs_suspend(struct pcmcia_device *p_dev)
{
- dev_link_t *link = args->client_data;
+ dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = (struct net_device *) link->priv;
int dev_open = 0;
+ PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info);
+
+ link->state |= DEV_SUSPEND;
+
if (link->state & DEV_CONFIG) {
struct hostap_interface *iface = netdev_priv(dev);
if (iface && iface->local)
dev_open = iface->local->num_dev_open > 0;
- }
-
- switch (event) {
- case CS_EVENT_CARD_INSERTION:
- PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_INSERTION\n", dev_info);
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- if (prism2_config(link)) {
- PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n");
- }
- break;
-
- case CS_EVENT_CARD_REMOVAL:
- PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_REMOVAL\n", dev_info);
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
+ if (dev_open) {
netif_stop_queue(dev);
netif_device_detach(dev);
- prism2_release((u_long) link);
}
- break;
+ prism2_suspend(dev);
+ pcmcia_release_configuration(link->handle);
+ }
- case CS_EVENT_PM_SUSPEND:
- PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info);
- link->state |= DEV_SUSPEND;
- /* fall through */
-
- case CS_EVENT_RESET_PHYSICAL:
- PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_RESET_PHYSICAL\n", dev_info);
- if (link->state & DEV_CONFIG) {
- if (dev_open) {
- netif_stop_queue(dev);
- netif_device_detach(dev);
- }
- prism2_suspend(dev);
- pcmcia_release_configuration(link->handle);
- }
- break;
+ return 0;
+}
- case CS_EVENT_PM_RESUME:
- PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info);
- link->state &= ~DEV_SUSPEND;
- /* fall through */
-
- case CS_EVENT_CARD_RESET:
- PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_RESET\n", dev_info);
- if (link->state & DEV_CONFIG) {
- pcmcia_request_configuration(link->handle,
- &link->conf);
- prism2_hw_shutdown(dev, 1);
- prism2_hw_config(dev, dev_open ? 0 : 1);
- if (dev_open) {
- netif_device_attach(dev);
- netif_start_queue(dev);
- }
- }
- break;
+static int hostap_cs_resume(struct pcmcia_device *p_dev)
+{
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = (struct net_device *) link->priv;
+ int dev_open = 0;
- default:
- PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n",
- dev_info, event);
- break;
+ PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info);
+
+ link->state &= ~DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ struct hostap_interface *iface = netdev_priv(dev);
+ if (iface && iface->local)
+ dev_open = iface->local->num_dev_open > 0;
+
+ pcmcia_request_configuration(link->handle, &link->conf);
+
+ prism2_hw_shutdown(dev, 1);
+ prism2_hw_config(dev, dev_open ? 0 : 1);
+ if (dev_open) {
+ netif_device_attach(dev);
+ netif_start_queue(dev);
+ }
}
+
return 0;
}
-
static struct pcmcia_device_id hostap_cs_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100),
PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300),
@@ -982,11 +929,12 @@ static struct pcmcia_driver hostap_driver = {
.drv = {
.name = "hostap_cs",
},
- .attach = prism2_attach,
- .detach = prism2_detach,
+ .probe = prism2_attach,
+ .remove = prism2_detach,
.owner = THIS_MODULE,
- .event = prism2_event,
.id_table = hostap_cs_ids,
+ .suspend = hostap_cs_suspend,
+ .resume = hostap_cs_resume,
};
static int __init init_prism2_pccard(void)
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index 92793b958e3..bf6271ee387 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -166,8 +166,6 @@ static char *version =
#define DEBUG(n, args...)
#endif
-static dev_info_t dev_info = "netwave_cs";
-
/*====================================================================*/
/* Parameters that can be set with 'insmod' */
@@ -195,12 +193,9 @@ module_param(mem_speed, int, 0);
/* PCMCIA (Card Services) related functions */
static void netwave_release(dev_link_t *link); /* Card removal */
-static int netwave_event(event_t event, int priority,
- event_callback_args_t *args);
static void netwave_pcmcia_config(dev_link_t *arg); /* Runs after card
insertion */
-static dev_link_t *netwave_attach(void); /* Create instance */
-static void netwave_detach(dev_link_t *); /* Destroy instance */
+static void netwave_detach(struct pcmcia_device *p_dev); /* Destroy instance */
/* Hardware configuration */
static void netwave_doreset(kio_addr_t iobase, u_char __iomem *ramBase);
@@ -228,17 +223,6 @@ static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev);
static void set_multicast_list(struct net_device *dev);
/*
- A linked list of "instances" of the skeleton 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 *dev_list;
-
-/*
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
@@ -394,20 +378,18 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
* configure the card at this point -- we wait until we receive a
* card insertion event.
*/
-static dev_link_t *netwave_attach(void)
+static int netwave_attach(struct pcmcia_device *p_dev)
{
- client_reg_t client_reg;
dev_link_t *link;
struct net_device *dev;
netwave_private *priv;
- int ret;
-
+
DEBUG(0, "netwave_attach()\n");
-
+
/* Initialize the dev_link_t structure */
dev = alloc_etherdev(sizeof(netwave_private));
if (!dev)
- return NULL;
+ return -ENOMEM;
priv = netdev_priv(dev);
link = &priv->link;
link->priv = dev;
@@ -449,21 +431,14 @@ static dev_link_t *netwave_attach(void)
dev->open = &netwave_open;
dev->stop = &netwave_close;
link->irq.Instance = dev;
-
- /* Register with Card Services */
- link->next = dev_list;
- dev_list = link;
- client_reg.dev_info = &dev_info;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
- ret = pcmcia_register_client(&link->handle, &client_reg);
- if (ret != 0) {
- cs_error(link->handle, RegisterClient, ret);
- netwave_detach(link);
- return NULL;
- }
- return link;
+ link->handle = p_dev;
+ p_dev->instance = link;
+
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ netwave_pcmcia_config( link);
+
+ return 0;
} /* netwave_attach */
/*
@@ -474,42 +449,20 @@ static dev_link_t *netwave_attach(void)
* structures are freed. Otherwise, the structures will be freed
* when the device is released.
*/
-static void netwave_detach(dev_link_t *link)
+static void netwave_detach(struct pcmcia_device *p_dev)
{
- struct net_device *dev = link->priv;
- dev_link_t **linkp;
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
- DEBUG(0, "netwave_detach(0x%p)\n", link);
-
- /*
- 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().
- */
- if (link->state & DEV_CONFIG)
- netwave_release(link);
-
- /* Break the link with Card Services */
- if (link->handle)
- pcmcia_deregister_client(link->handle);
-
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link) break;
- if (*linkp == NULL)
- {
- DEBUG(1, "netwave_cs: detach fail, '%s' not in list\n",
- link->dev->dev_name);
- return;
- }
-
- /* Unlink device structure, free pieces */
- *linkp = link->next;
- if (link->dev)
- unregister_netdev(dev);
- free_netdev(dev);
-
+ DEBUG(0, "netwave_detach(0x%p)\n", link);
+
+ if (link->state & DEV_CONFIG)
+ netwave_release(link);
+
+ if (link->dev)
+ unregister_netdev(dev);
+
+ free_netdev(dev);
} /* netwave_detach */
/*
@@ -935,69 +888,38 @@ static void netwave_release(dev_link_t *link)
link->state &= ~DEV_CONFIG;
}
-/*
- * Function netwave_event (event, priority, args)
- *
- * The card status event handler. Mostly, this schedules other
- * stuff to run after an event is received. A CARD_REMOVAL event
- * also sets some flags to discourage the net drivers from trying
- * to talk to the card any more.
- *
- * When a CARD_REMOVAL event is received, we immediately set a flag
- * to block future accesses to this device. All the functions that
- * actually access the device should check this flag to make sure
- * the card is still present.
- *
- */
-static int netwave_event(event_t event, int priority,
- event_callback_args_t *args)
+static int netwave_suspend(struct pcmcia_device *p_dev)
{
- dev_link_t *link = args->client_data;
- struct net_device *dev = link->priv;
-
- DEBUG(1, "netwave_event(0x%06x)\n", event);
-
- switch (event) {
- case CS_EVENT_REGISTRATION_COMPLETE:
- DEBUG(0, "netwave_cs: registration complete\n");
- break;
-
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- netif_device_detach(dev);
- netwave_release(link);
- }
- break;
- case CS_EVENT_CARD_INSERTION:
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- netwave_pcmcia_config( link);
- break;
- case CS_EVENT_PM_SUSPEND:
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
+
link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
- if (link->open)
- netif_device_detach(dev);
- pcmcia_release_configuration(link->handle);
+ if (link->open)
+ netif_device_detach(dev);
+ pcmcia_release_configuration(link->handle);
}
- break;
- case CS_EVENT_PM_RESUME:
+
+ return 0;
+}
+
+static int netwave_resume(struct pcmcia_device *p_dev)
+{
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
+
link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
- pcmcia_request_configuration(link->handle, &link->conf);
- if (link->open) {
- netwave_reset(dev);
- netif_device_attach(dev);
- }
+ pcmcia_request_configuration(link->handle, &link->conf);
+ if (link->open) {
+ netwave_reset(dev);
+ netif_device_attach(dev);
+ }
}
- break;
- }
- return 0;
-} /* netwave_event */
+
+ return 0;
+}
+
/*
* Function netwave_doreset (ioBase, ramBase)
@@ -1491,10 +1413,11 @@ static struct pcmcia_driver netwave_driver = {
.drv = {
.name = "netwave_cs",
},
- .attach = netwave_attach,
- .event = netwave_event,
- .detach = netwave_detach,
+ .probe = netwave_attach,
+ .remove = netwave_detach,
.id_table = netwave_ids,
+ .suspend = netwave_suspend,
+ .resume = netwave_resume,
};
static int __init init_netwave_cs(void)
@@ -1505,7 +1428,6 @@ static int __init init_netwave_cs(void)
static void __exit exit_netwave_cs(void)
{
pcmcia_unregister_driver(&netwave_driver);
- BUG_ON(dev_list != NULL);
}
module_init(init_netwave_cs);
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index dc1128a0097..b664708481c 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -43,17 +43,6 @@ module_param(ignore_cis_vcc, int, 0);
MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");
/********************************************************************/
-/* Magic constants */
-/********************************************************************/
-
-/*
- * The dev_info variable is the "key" that is used to match up this
- * device driver with appropriate cards, through the card
- * configuration database.
- */
-static dev_info_t dev_info = DRIVER_NAME;
-
-/********************************************************************/
/* Data structures */
/********************************************************************/
@@ -69,19 +58,14 @@ struct orinoco_pccard {
unsigned long hard_reset_in_progress;
};
-/*
- * A linked list of "instances" of the 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 */
/********************************************************************/
/* Function prototypes */
/********************************************************************/
+static void orinoco_cs_config(dev_link_t *link);
static void orinoco_cs_release(dev_link_t *link);
-static void orinoco_cs_detach(dev_link_t *link);
+static void orinoco_cs_detach(struct pcmcia_device *p_dev);
/********************************************************************/
/* Device methods */
@@ -119,19 +103,17 @@ orinoco_cs_hard_reset(struct orinoco_private *priv)
* The dev_link structure is initialized, but we don't actually
* configure the card at this point -- we wait until we receive a card
* insertion event. */
-static dev_link_t *
-orinoco_cs_attach(void)
+static int
+orinoco_cs_attach(struct pcmcia_device *p_dev)
{
struct net_device *dev;
struct orinoco_private *priv;
struct orinoco_pccard *card;
dev_link_t *link;
- client_reg_t client_reg;
- int ret;
dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset);
if (! dev)
- return NULL;
+ return -ENOMEM;
priv = netdev_priv(dev);
card = priv->card;
@@ -154,22 +136,15 @@ orinoco_cs_attach(void)
link->conf.IntType = INT_MEMORY_AND_IO;
/* Register with Card Services */
- /* FIXME: need a lock? */
- link->next = dev_list;
- dev_list = link;
-
- client_reg.dev_info = &dev_info;
- client_reg.Version = 0x0210; /* FIXME: what does this mean? */
- client_reg.event_callback_args.client_data = link;
-
- ret = pcmcia_register_client(&link->handle, &client_reg);
- if (ret != CS_SUCCESS) {
- cs_error(link->handle, RegisterClient, ret);
- orinoco_cs_detach(link);
- return NULL;
- }
+ link->next = NULL;
+
+ link->handle = p_dev;
+ p_dev->instance = link;
+
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ orinoco_cs_config(link);
- return link;
+ return 0;
} /* orinoco_cs_attach */
/*
@@ -178,27 +153,14 @@ orinoco_cs_attach(void)
* are freed. Otherwise, the structures will be freed when the device
* is released.
*/
-static void orinoco_cs_detach(dev_link_t *link)
+static void orinoco_cs_detach(struct pcmcia_device *p_dev)
{
- dev_link_t **linkp;
+ dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link)
- break;
-
- BUG_ON(*linkp == NULL);
-
if (link->state & DEV_CONFIG)
orinoco_cs_release(link);
- /* Break the link with Card Services */
- if (link->handle)
- pcmcia_deregister_client(link->handle);
-
- /* Unlink device structure, and free it */
- *linkp = link->next;
DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev);
if (link->dev) {
DEBUG(0, PFX "About to unregister net device %p\n",
@@ -465,106 +427,82 @@ orinoco_cs_release(dev_link_t *link)
ioport_unmap(priv->hw.iobase);
} /* orinoco_cs_release */
-/*
- * The card status event handler. Mostly, this schedules other stuff
- * to run after an event is received.
- */
-static int
-orinoco_cs_event(event_t event, int priority,
- event_callback_args_t * args)
+static int orinoco_cs_suspend(struct pcmcia_device *p_dev)
{
- dev_link_t *link = args->client_data;
+ dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
struct orinoco_private *priv = netdev_priv(dev);
struct orinoco_pccard *card = priv->card;
int err = 0;
unsigned long flags;
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- unsigned long flags;
-
+ link->state |= DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ /* This is probably racy, but I can't think of
+ a better way, short of rewriting the PCMCIA
+ layer to not suck :-( */
+ if (! test_bit(0, &card->hard_reset_in_progress)) {
spin_lock_irqsave(&priv->lock, flags);
+
+ err = __orinoco_down(dev);
+ if (err)
+ printk(KERN_WARNING "%s: Error %d downing interface\n",
+ dev->name, err);
+
netif_device_detach(dev);
priv->hw_unavailable++;
+
spin_unlock_irqrestore(&priv->lock, flags);
}
- break;
- case CS_EVENT_CARD_INSERTION:
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- orinoco_cs_config(link);
- break;
+ pcmcia_release_configuration(link->handle);
+ }
- case CS_EVENT_PM_SUSPEND:
- link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
- /* Mark the device as stopped, to block IO until later */
- if (link->state & DEV_CONFIG) {
- /* This is probably racy, but I can't think of
- a better way, short of rewriting the PCMCIA
- layer to not suck :-( */
- if (! test_bit(0, &card->hard_reset_in_progress)) {
- spin_lock_irqsave(&priv->lock, flags);
-
- err = __orinoco_down(dev);
- if (err)
- printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
- dev->name,
- event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL",
- err);
-
- netif_device_detach(dev);
- priv->hw_unavailable++;
-
- spin_unlock_irqrestore(&priv->lock, flags);
+ return 0;
+}
+
+static int orinoco_cs_resume(struct pcmcia_device *p_dev)
+{
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct orinoco_pccard *card = priv->card;
+ int err = 0;
+ unsigned long flags;
+
+ link->state &= ~DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ /* FIXME: should we double check that this is
+ * the same card as we had before */
+ pcmcia_request_configuration(link->handle, &link->conf);
+
+ if (! test_bit(0, &card->hard_reset_in_progress)) {
+ err = orinoco_reinit_firmware(dev);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
+ dev->name, err);
+ return -EIO;
}
- pcmcia_release_configuration(link->handle);
- }
- break;
+ spin_lock_irqsave(&priv->lock, flags);
+
+ netif_device_attach(dev);
+ priv->hw_unavailable--;
- case CS_EVENT_PM_RESUME:
- link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
- if (link->state & DEV_CONFIG) {
- /* FIXME: should we double check that this is
- * the same card as we had before */
- pcmcia_request_configuration(link->handle, &link->conf);
-
- if (! test_bit(0, &card->hard_reset_in_progress)) {
- err = orinoco_reinit_firmware(dev);
- if (err) {
- printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
+ if (priv->open && ! priv->hw_unavailable) {
+ err = __orinoco_up(dev);
+ if (err)
+ printk(KERN_ERR "%s: Error %d restarting card\n",
dev->name, err);
- break;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- netif_device_attach(dev);
- priv->hw_unavailable--;
-
- if (priv->open && ! priv->hw_unavailable) {
- err = __orinoco_up(dev);
- if (err)
- printk(KERN_ERR "%s: Error %d restarting card\n",
- dev->name, err);
-
- }
-
- spin_unlock_irqrestore(&priv->lock, flags);
}
+
+ spin_unlock_irqrestore(&priv->lock, flags);
}
- break;
}
- return err;
-} /* orinoco_cs_event */
+ return 0;
+}
+
/********************************************************************/
/* Module initialization */
@@ -665,10 +603,11 @@ static struct pcmcia_driver orinoco_driver = {
.drv = {
.name = DRIVER_NAME,
},
- .attach = orinoco_cs_attach,
- .detach = orinoco_cs_detach,
- .event = orinoco_cs_event,
+ .probe = orinoco_cs_attach,
+ .remove = orinoco_cs_detach,
.id_table = orinoco_cs_ids,
+ .suspend = orinoco_cs_suspend,
+ .resume = orinoco_cs_resume,
};
static int __init
@@ -683,7 +622,6 @@ static void __exit
exit_orinoco_cs(void)
{
pcmcia_unregister_driver(&orinoco_driver);
- BUG_ON(dev_list != NULL);
}
module_init(init_orinoco_cs);
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 70fd6fd8feb..319180ca7e7 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -92,9 +92,7 @@ module_param(pc_debug, int, 0);
/** Prototypes based on PCMCIA skeleton driver *******************************/
static void ray_config(dev_link_t *link);
static void ray_release(dev_link_t *link);
-static int ray_event(event_t event, int priority, event_callback_args_t *args);
-static dev_link_t *ray_attach(void);
-static void ray_detach(dev_link_t *);
+static void ray_detach(struct pcmcia_device *p_dev);
/***** Prototypes indicated by device structure ******************************/
static int ray_dev_close(struct net_device *dev);
@@ -192,12 +190,6 @@ static int bc;
static char *phy_addr = NULL;
-/* The dev_info variable is the "key" that is used to match up this
- device driver with appropriate cards, through the card configuration
- database.
-*/
-static dev_info_t dev_info = "ray_cs";
-
/* 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).
@@ -314,12 +306,10 @@ 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.
=============================================================================*/
-static dev_link_t *ray_attach(void)
+static int ray_attach(struct pcmcia_device *p_dev)
{
- client_reg_t client_reg;
dev_link_t *link;
ray_dev_t *local;
- int ret;
struct net_device *dev;
DEBUG(1, "ray_attach()\n");
@@ -328,7 +318,7 @@ static dev_link_t *ray_attach(void)
link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
if (!link)
- return NULL;
+ return -ENOMEM;
/* Allocate space for private device-specific data */
dev = alloc_etherdev(sizeof(ray_dev_t));
@@ -387,30 +377,19 @@ static dev_link_t *ray_attach(void)
dev->stop = &ray_dev_close;
netif_stop_queue(dev);
- /* Register with Card Services */
- link->next = dev_list;
- dev_list = link;
- client_reg.dev_info = &dev_info;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
+ init_timer(&local->timer);
- DEBUG(2,"ray_cs ray_attach calling pcmcia_register_client(...)\n");
+ link->handle = p_dev;
+ p_dev->instance = link;
- init_timer(&local->timer);
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ ray_config(link);
- ret = pcmcia_register_client(&link->handle, &client_reg);
- if (ret != 0) {
- printk("ray_cs ray_attach RegisterClient unhappy - detaching\n");
- cs_error(link->handle, RegisterClient, ret);
- ray_detach(link);
- return NULL;
- }
- DEBUG(2,"ray_cs ray_attach ending\n");
- return link;
+ return 0;
fail_alloc_dev:
kfree(link);
- return NULL;
+ return -ENOMEM;
} /* ray_attach */
/*=============================================================================
This deletes a driver "instance". The device is de-registered
@@ -418,9 +397,12 @@ fail_alloc_dev:
structures are freed. Otherwise, the structures will be freed
when the device is released.
=============================================================================*/
-static void ray_detach(dev_link_t *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);
@@ -430,22 +412,18 @@ static void ray_detach(dev_link_t *link)
if (*linkp == NULL)
return;
- /* 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().
- */
- if (link->state & DEV_CONFIG)
- ray_release(link);
+ dev = link->priv;
+
+ if (link->state & DEV_CONFIG) {
+ ray_release(link);
+
+ local = (ray_dev_t *)dev->priv;
+ del_timer(&local->timer);
+ }
- /* Break the link with Card Services */
- if (link->handle)
- pcmcia_deregister_client(link->handle);
-
/* Unlink device structure, free pieces */
*linkp = link->next;
if (link->priv) {
- struct net_device *dev = link->priv;
if (link->dev) unregister_netdev(dev);
free_netdev(dev);
}
@@ -891,65 +869,40 @@ static void ray_release(dev_link_t *link)
DEBUG(2,"ray_release ending\n");
}
-/*=============================================================================
- The card status event handler. Mostly, this schedules other
- stuff to run after an event is received. A CARD_REMOVAL event
- also sets some flags to discourage the net drivers from trying
- to talk to the card any more.
-
- When a CARD_REMOVAL event is received, we immediately set a flag
- to block future accesses to this device. All the functions that
- actually access the device should check this flag to make sure
- the card is still present.
-=============================================================================*/
-static int ray_event(event_t event, int priority,
- event_callback_args_t *args)
+static int ray_suspend(struct pcmcia_device *p_dev)
{
- dev_link_t *link = args->client_data;
- struct net_device *dev = link->priv;
- ray_dev_t *local = (ray_dev_t *)dev->priv;
- DEBUG(1, "ray_event(0x%06x)\n", event);
-
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- netif_device_detach(dev);
- if (link->state & DEV_CONFIG) {
- ray_release(link);
- del_timer(&local->timer);
- }
- break;
- case CS_EVENT_CARD_INSERTION:
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- ray_config(link);
- break;
- case CS_EVENT_PM_SUSPEND:
- link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
+
+ link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
- if (link->open)
- netif_device_detach(dev);
+ if (link->open)
+ netif_device_detach(dev);
- pcmcia_release_configuration(link->handle);
+ pcmcia_release_configuration(link->handle);
}
- break;
- case CS_EVENT_PM_RESUME:
- link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
+
+
+ return 0;
+}
+
+static int ray_resume(struct pcmcia_device *p_dev)
+{
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
+
+ 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);
- }
+ pcmcia_request_configuration(link->handle, &link->conf);
+ if (link->open) {
+ ray_reset(dev);
+ netif_device_attach(dev);
+ }
}
- break;
- }
- return 0;
- DEBUG(2,"ray_event ending\n");
-} /* ray_event */
+
+ return 0;
+}
+
/*===========================================================================*/
int ray_dev_init(struct net_device *dev)
{
@@ -2945,10 +2898,11 @@ static struct pcmcia_driver ray_driver = {
.drv = {
.name = "ray_cs",
},
- .attach = ray_attach,
- .event = ray_event,
- .detach = ray_detach,
+ .probe = ray_attach,
+ .remove = ray_detach,
.id_table = ray_ids,
+ .suspend = ray_suspend,
+ .resume = ray_resume,
};
static int __init init_ray_cs(void)
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index b1bbc8e8e91..fee4be1ce81 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -57,17 +57,6 @@ module_param(ignore_cis_vcc, int, 0);
MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");
/********************************************************************/
-/* Magic constants */
-/********************************************************************/
-
-/*
- * The dev_info variable is the "key" that is used to match up this
- * device driver with appropriate cards, through the card
- * configuration database.
- */
-static dev_info_t dev_info = DRIVER_NAME;
-
-/********************************************************************/
/* Data structures */
/********************************************************************/
@@ -78,19 +67,12 @@ struct orinoco_pccard {
dev_node_t node;
};
-/*
- * A linked list of "instances" of the 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 */
-
/********************************************************************/
/* Function prototypes */
/********************************************************************/
+static void spectrum_cs_config(dev_link_t *link);
static void spectrum_cs_release(dev_link_t *link);
-static void spectrum_cs_detach(dev_link_t *link);
/********************************************************************/
/* Firmware downloader */
@@ -601,19 +583,17 @@ spectrum_cs_hard_reset(struct orinoco_private *priv)
* The dev_link structure is initialized, but we don't actually
* configure the card at this point -- we wait until we receive a card
* insertion event. */
-static dev_link_t *
-spectrum_cs_attach(void)
+static int
+spectrum_cs_attach(struct pcmcia_device *p_dev)
{
struct net_device *dev;
struct orinoco_private *priv;
struct orinoco_pccard *card;
dev_link_t *link;
- client_reg_t client_reg;
- int ret;
dev = alloc_orinocodev(sizeof(*card), spectrum_cs_hard_reset);
if (! dev)
- return NULL;
+ return -ENOMEM;
priv = netdev_priv(dev);
card = priv->card;
@@ -635,23 +615,13 @@ spectrum_cs_attach(void)
link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY_AND_IO;
- /* Register with Card Services */
- /* FIXME: need a lock? */
- link->next = dev_list;
- dev_list = link;
+ link->handle = p_dev;
+ p_dev->instance = link;
- client_reg.dev_info = &dev_info;
- client_reg.Version = 0x0210; /* FIXME: what does this mean? */
- client_reg.event_callback_args.client_data = link;
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ spectrum_cs_config(link);
- ret = pcmcia_register_client(&link->handle, &client_reg);
- if (ret != CS_SUCCESS) {
- cs_error(link->handle, RegisterClient, ret);
- spectrum_cs_detach(link);
- return NULL;
- }
-
- return link;
+ return 0;
} /* spectrum_cs_attach */
/*
@@ -660,27 +630,14 @@ spectrum_cs_attach(void)
* are freed. Otherwise, the structures will be freed when the device
* is released.
*/
-static void spectrum_cs_detach(dev_link_t *link)
+static void spectrum_cs_detach(struct pcmcia_device *p_dev)
{
- dev_link_t **linkp;
+ dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link)
- break;
-
- BUG_ON(*linkp == NULL);
-
if (link->state & DEV_CONFIG)
spectrum_cs_release(link);
- /* Break the link with Card Services */
- if (link->handle)
- pcmcia_deregister_client(link->handle);
-
- /* Unlink device structure, and free it */
- *linkp = link->next;
DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev);
if (link->dev) {
DEBUG(0, PFX "About to unregister net device %p\n",
@@ -948,82 +905,56 @@ spectrum_cs_release(dev_link_t *link)
ioport_unmap(priv->hw.iobase);
} /* spectrum_cs_release */
-/*
- * The card status event handler. Mostly, this schedules other stuff
- * to run after an event is received.
- */
+
static int
-spectrum_cs_event(event_t event, int priority,
- event_callback_args_t * args)
+spectrum_cs_suspend(struct pcmcia_device *p_dev)
{
- dev_link_t *link = args->client_data;
+ dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
struct orinoco_private *priv = netdev_priv(dev);
- int err = 0;
unsigned long flags;
+ int err = 0;
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- unsigned long flags;
+ link->state |= DEV_SUSPEND;
+ /* Mark the device as stopped, to block IO until later */
+ if (link->state & DEV_CONFIG) {
+ spin_lock_irqsave(&priv->lock, flags);
- spin_lock_irqsave(&priv->lock, flags);
- netif_device_detach(dev);
- priv->hw_unavailable++;
- spin_unlock_irqrestore(&priv->lock, flags);
- }
- break;
+ err = __orinoco_down(dev);
+ if (err)
+ printk(KERN_WARNING "%s: Error %d downing interface\n",
+ dev->name, err);
- case CS_EVENT_CARD_INSERTION:
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- spectrum_cs_config(link);
- break;
+ netif_device_detach(dev);
+ priv->hw_unavailable++;
- case CS_EVENT_PM_SUSPEND:
- link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
- /* Mark the device as stopped, to block IO until later */
- if (link->state & DEV_CONFIG) {
- /* This is probably racy, but I can't think of
- a better way, short of rewriting the PCMCIA
- layer to not suck :-( */
- spin_lock_irqsave(&priv->lock, flags);
-
- err = __orinoco_down(dev);
- if (err)
- printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
- dev->name,
- event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL",
- err);
-
- netif_device_detach(dev);
- priv->hw_unavailable++;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- pcmcia_release_configuration(link->handle);
- }
- break;
+ spin_unlock_irqrestore(&priv->lock, flags);
- case CS_EVENT_PM_RESUME:
- link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
- if (link->state & DEV_CONFIG) {
- /* FIXME: should we double check that this is
- * the same card as we had before */
- pcmcia_request_configuration(link->handle, &link->conf);
- netif_device_attach(dev);
- priv->hw_unavailable--;
- schedule_work(&priv->reset_work);
- }
- break;
+ pcmcia_release_configuration(link->handle);
+ }
+
+ return 0;
+}
+
+static int
+spectrum_cs_resume(struct pcmcia_device *p_dev)
+{
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
+ struct orinoco_private *priv = netdev_priv(dev);
+
+ link->state &= ~DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ /* FIXME: should we double check that this is
+ * the same card as we had before */
+ pcmcia_request_configuration(link->handle, &link->conf);
+ netif_device_attach(dev);
+ priv->hw_unavailable--;
+ schedule_work(&priv->reset_work);
}
+ return 0;
+}
- return err;
-} /* spectrum_cs_event */
/********************************************************************/
/* Module initialization */
@@ -1048,9 +979,10 @@ static struct pcmcia_driver orinoco_driver = {
.drv = {
.name = DRIVER_NAME,
},
- .attach = spectrum_cs_attach,
- .detach = spectrum_cs_detach,
- .event = spectrum_cs_event,
+ .probe = spectrum_cs_attach,
+ .remove = spectrum_cs_detach,
+ .suspend = spectrum_cs_suspend,
+ .resume = spectrum_cs_resume,
.id_table = spectrum_cs_ids,
};
@@ -1066,7 +998,6 @@ static void __exit
exit_spectrum_cs(void)
{
pcmcia_unregister_driver(&orinoco_driver);
- BUG_ON(dev_list != NULL);
}
module_init(init_spectrum_cs);
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index c822cad3333..7e2039f52c4 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -4594,14 +4594,12 @@ wavelan_close(struct net_device * dev)
* configure the card at this point -- we wait until we receive a
* card insertion event.
*/
-static dev_link_t *
-wavelan_attach(void)
+static int
+wavelan_attach(struct pcmcia_device *p_dev)
{
- client_reg_t client_reg; /* Register with cardmgr */
dev_link_t * link; /* Info for cardmgr */
struct net_device * dev; /* Interface generic data */
net_local * lp; /* Interface specific data */
- int ret;
#ifdef DEBUG_CALLBACK_TRACE
printk(KERN_DEBUG "-> wavelan_attach()\n");
@@ -4609,7 +4607,7 @@ wavelan_attach(void)
/* Initialize the dev_link_t structure */
link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
- if (!link) return NULL;
+ if (!link) return -ENOMEM;
/* The io structure describes IO port mapping */
link->io.NumPorts1 = 8;
@@ -4627,14 +4625,13 @@ wavelan_attach(void)
link->conf.IntType = INT_MEMORY_AND_IO;
/* Chain drivers */
- link->next = dev_list;
- dev_list = link;
+ link->next = NULL;
/* Allocate the generic data structure */
dev = alloc_etherdev(sizeof(net_local));
if (!dev) {
kfree(link);
- return NULL;
+ return -ENOMEM;
}
link->priv = link->irq.Instance = dev;
@@ -4679,28 +4676,21 @@ wavelan_attach(void)
/* Other specific data */
dev->mtu = WAVELAN_MTU;
- /* Register with Card Services */
- client_reg.dev_info = &dev_info;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
+ link->handle = p_dev;
+ p_dev->instance = link;
-#ifdef DEBUG_CONFIG_INFO
- printk(KERN_DEBUG "wavelan_attach(): almost done, calling pcmcia_register_client\n");
-#endif
-
- ret = pcmcia_register_client(&link->handle, &client_reg);
- if(ret != 0)
- {
- cs_error(link->handle, RegisterClient, ret);
- wavelan_detach(link);
- return NULL;
- }
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ if(wv_pcmcia_config(link) &&
+ wv_hw_config(dev))
+ wv_init_info(dev);
+ else
+ dev->irq = 0;
#ifdef DEBUG_CALLBACK_TRACE
printk(KERN_DEBUG "<- wavelan_attach()\n");
#endif
- return link;
+ return 0;
}
/*------------------------------------------------------------------*/
@@ -4711,8 +4701,10 @@ wavelan_attach(void)
* is released.
*/
static void
-wavelan_detach(dev_link_t * link)
+wavelan_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
+
#ifdef DEBUG_CALLBACK_TRACE
printk(KERN_DEBUG "-> wavelan_detach(0x%p)\n", link);
#endif
@@ -4729,31 +4721,6 @@ wavelan_detach(dev_link_t * link)
wv_pcmcia_release(link);
}
- /* Break the link with Card Services */
- if(link->handle)
- pcmcia_deregister_client(link->handle);
-
- /* Remove the interface data from the linked list */
- if(dev_list == link)
- dev_list = link->next;
- else
- {
- dev_link_t * prev = dev_list;
-
- while((prev != (dev_link_t *) NULL) && (prev->next != link))
- prev = prev->next;
-
- if(prev == (dev_link_t *) NULL)
- {
-#ifdef DEBUG_CONFIG_ERRORS
- printk(KERN_WARNING "wavelan_detach : Attempting to remove a nonexistent device.\n");
-#endif
- return;
- }
-
- prev->next = link->next;
- }
-
/* Free pieces */
if(link->priv)
{
@@ -4775,65 +4742,11 @@ wavelan_detach(dev_link_t * link)
#endif
}
-/*------------------------------------------------------------------*/
-/*
- * The card status event handler. Mostly, this schedules other stuff
- * to run after an event is received. A CARD_REMOVAL event also sets
- * some flags to discourage the net drivers from trying to talk to the
- * card any more.
- */
-static int
-wavelan_event(event_t event, /* The event received */
- int priority,
- event_callback_args_t * args)
+static int wavelan_suspend(struct pcmcia_device *p_dev)
{
- dev_link_t * link = (dev_link_t *) args->client_data;
- struct net_device * dev = (struct net_device *) link->priv;
-
-#ifdef DEBUG_CALLBACK_TRACE
- printk(KERN_DEBUG "->wavelan_event(): %s\n",
- ((event == CS_EVENT_REGISTRATION_COMPLETE)?"registration complete" :
- ((event == CS_EVENT_CARD_REMOVAL) ? "card removal" :
- ((event == CS_EVENT_CARD_INSERTION) ? "card insertion" :
- ((event == CS_EVENT_PM_SUSPEND) ? "pm suspend" :
- ((event == CS_EVENT_RESET_PHYSICAL) ? "physical reset" :
- ((event == CS_EVENT_PM_RESUME) ? "pm resume" :
- ((event == CS_EVENT_CARD_RESET) ? "card reset" :
- "unknown"))))))));
-#endif
-
- switch(event)
- {
- case CS_EVENT_REGISTRATION_COMPLETE:
-#ifdef DEBUG_CONFIG_INFO
- printk(KERN_DEBUG "wavelan_cs: registration complete\n");
-#endif
- break;
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device * dev = (struct net_device *) link->priv;
- case CS_EVENT_CARD_REMOVAL:
- /* Oups ! The card is no more there */
- link->state &= ~DEV_PRESENT;
- if(link->state & DEV_CONFIG)
- {
- /* Accept no more transmissions */
- netif_device_detach(dev);
-
- /* Release the card */
- wv_pcmcia_release(link);
- }
- break;
-
- case CS_EVENT_CARD_INSERTION:
- /* Reset and configure the card */
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- if(wv_pcmcia_config(link) &&
- wv_hw_config(dev))
- wv_init_info(dev);
- else
- dev->irq = 0;
- break;
-
- case CS_EVENT_PM_SUSPEND:
/* NB: wavelan_close will be called, but too late, so we are
* obliged to close nicely the wavelan here. David, could you
* close the device before suspending them ? And, by the way,
@@ -4848,38 +4761,37 @@ wavelan_event(event_t event, /* The event received */
/* The card is now suspended */
link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
+
if(link->state & DEV_CONFIG)
- {
- if(link->open)
- netif_device_detach(dev);
- pcmcia_release_configuration(link->handle);
- }
- break;
+ {
+ if(link->open)
+ netif_device_detach(dev);
+ pcmcia_release_configuration(link->handle);
+ }
+
+ return 0;
+}
+
+static int wavelan_resume(struct pcmcia_device *p_dev)
+{
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device * dev = (struct net_device *) link->priv;
- case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
if(link->state & DEV_CONFIG)
- {
- pcmcia_request_configuration(link->handle, &link->conf);
- if(link->open) /* If RESET -> True, If RESUME -> False ? */
- {
- wv_hw_reset(dev);
- netif_device_attach(dev);
- }
- }
- break;
- }
+ {
+ pcmcia_request_configuration(link->handle, &link->conf);
+ if(link->open) /* If RESET -> True, If RESUME -> False ? */
+ {
+ wv_hw_reset(dev);
+ netif_device_attach(dev);
+ }
+ }
-#ifdef DEBUG_CALLBACK_TRACE
- printk(KERN_DEBUG "<-wavelan_event()\n");
-#endif
- return 0;
+ return 0;
}
+
static struct pcmcia_device_id wavelan_ids[] = {
PCMCIA_DEVICE_PROD_ID12("AT&T","WaveLAN/PCMCIA", 0xe7c5affd, 0x1bc50975),
PCMCIA_DEVICE_PROD_ID12("Digital", "RoamAbout/DS", 0x9999ab35, 0x00d05e06),
@@ -4894,10 +4806,11 @@ static struct pcmcia_driver wavelan_driver = {
.drv = {
.name = "wavelan_cs",
},
- .attach = wavelan_attach,
- .event = wavelan_event,
- .detach = wavelan_detach,
+ .probe = wavelan_attach,
+ .remove = wavelan_detach,
.id_table = wavelan_ids,
+ .suspend = wavelan_suspend,
+ .resume = wavelan_resume,
};
static int __init
diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h
index 724a715089c..f2d59756815 100644
--- a/drivers/net/wireless/wavelan_cs.p.h
+++ b/drivers/net/wireless/wavelan_cs.p.h
@@ -754,20 +754,11 @@ static void
static int
wavelan_open(struct net_device *), /* Open the device */
wavelan_close(struct net_device *); /* Close the device */
-static dev_link_t *
- wavelan_attach(void); /* Create a new device */
static void
- wavelan_detach(dev_link_t *); /* Destroy a removed device */
-static int
- wavelan_event(event_t, /* Manage pcmcia events */
- int,
- event_callback_args_t *);
+ wavelan_detach(struct pcmcia_device *p_dev); /* Destroy a removed device */
/**************************** VARIABLES ****************************/
-static dev_info_t dev_info = "wavelan_cs";
-static dev_link_t *dev_list = NULL; /* Linked list of devices */
-
/*
* Parameters that can be set with 'insmod'
* The exact syntax is 'insmod wavelan_cs.o <var>=<value>'
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 978fdc60678..48e10b0c7e7 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -105,7 +105,6 @@ module_param(pc_debug, int, 0);
*/
static void wl3501_config(dev_link_t *link);
static void wl3501_release(dev_link_t *link);
-static int wl3501_event(event_t event, int pri, event_callback_args_t *args);
/*
* The dev_info variable is the "key" that is used to match up this
@@ -1498,9 +1497,11 @@ static struct ethtool_ops ops = {
* Services. If it has been released, all local data structures are freed.
* Otherwise, the structures will be freed when the device is released.
*/
-static void wl3501_detach(dev_link_t *link)
+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)
@@ -1514,16 +1515,12 @@ static void wl3501_detach(dev_link_t *link)
* function is called, that will trigger a proper detach(). */
if (link->state & DEV_CONFIG) {
-#ifdef PCMCIA_DEBUG
- printk(KERN_DEBUG "wl3501_cs: detach postponed, '%s' "
- "still locked\n", link->dev->dev_name);
-#endif
- goto out;
- }
+ while (link->open > 0)
+ wl3501_close(dev);
- /* Break the link with Card Services */
- if (link->handle)
- pcmcia_deregister_client(link->handle);
+ netif_device_detach(dev);
+ wl3501_release(link);
+ }
/* Unlink device structure, free pieces */
*linkp = link->next;
@@ -1956,18 +1953,16 @@ static const struct iw_handler_def wl3501_handler_def = {
* The dev_link structure is initialized, but we don't actually configure the
* card at this point -- we wait until we receive a card insertion event.
*/
-static dev_link_t *wl3501_attach(void)
+static int wl3501_attach(struct pcmcia_device *p_dev)
{
- client_reg_t client_reg;
dev_link_t *link;
struct net_device *dev;
struct wl3501_card *this;
- int ret;
/* Initialize the dev_link_t structure */
link = kzalloc(sizeof(*link), GFP_KERNEL);
if (!link)
- goto out;
+ return -ENOMEM;
/* The io structure describes IO port mapping */
link->io.NumPorts1 = 16;
@@ -2003,24 +1998,17 @@ static dev_link_t *wl3501_attach(void)
netif_stop_queue(dev);
link->priv = link->irq.Instance = dev;
- /* Register with Card Services */
- link->next = wl3501_dev_list;
- wl3501_dev_list = link;
- client_reg.dev_info = &wl3501_dev_info;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
- ret = pcmcia_register_client(&link->handle, &client_reg);
- if (ret) {
- cs_error(link->handle, RegisterClient, ret);
- wl3501_detach(link);
- link = NULL;
- }
-out:
- return link;
+ link->handle = p_dev;
+ p_dev->instance = link;
+
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ wl3501_config(link);
+
+ return 0;
out_link:
kfree(link);
link = NULL;
- goto out;
+ return -ENOMEM;
}
#define CS_CHECK(fn, ret) \
@@ -2173,67 +2161,41 @@ static void wl3501_release(dev_link_t *link)
link->state &= ~DEV_CONFIG;
}
-/**
- * wl3501_event - The card status event handler
- * @event - event
- * @pri - priority
- * @args - arguments for this event
- *
- * The card status event handler. Mostly, this schedules other stuff to run
- * after an event is received. A CARD_REMOVAL event also sets some flags to
- * discourage the net drivers from trying to talk to the card any more.
- *
- * When a CARD_REMOVAL event is received, we immediately set a flag to block
- * future accesses to this device. All the functions that actually access the
- * device should check this flag to make sure the card is still present.
- */
-static int wl3501_event(event_t event, int pri, event_callback_args_t *args)
+static int wl3501_suspend(struct pcmcia_device *p_dev)
{
- dev_link_t *link = args->client_data;
+ dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- while (link->open > 0)
- wl3501_close(dev);
+ link->state |= DEV_SUSPEND;
+
+ wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND);
+ if (link->state & DEV_CONFIG) {
+ if (link->open)
netif_device_detach(dev);
- wl3501_release(link);
- }
- break;
- case CS_EVENT_CARD_INSERTION:
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- wl3501_config(link);
- break;
- case CS_EVENT_PM_SUSPEND:
- link->state |= DEV_SUSPEND;
- wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND);
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
- if (link->state & DEV_CONFIG) {
- if (link->open)
- netif_device_detach(dev);
- pcmcia_release_configuration(link->handle);
- }
- break;
- case CS_EVENT_PM_RESUME:
- link->state &= ~DEV_SUSPEND;
- wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
- if (link->state & DEV_CONFIG) {
- pcmcia_request_configuration(link->handle, &link->conf);
- if (link->open) {
- wl3501_reset(dev);
- netif_device_attach(dev);
- }
+ pcmcia_release_configuration(link->handle);
+ }
+
+ return 0;
+}
+
+static int wl3501_resume(struct pcmcia_device *p_dev)
+{
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
+
+ wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
+ if (link->state & DEV_CONFIG) {
+ pcmcia_request_configuration(link->handle, &link->conf);
+ if (link->open) {
+ wl3501_reset(dev);
+ netif_device_attach(dev);
}
- break;
}
+
return 0;
}
+
static struct pcmcia_device_id wl3501_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0001),
PCMCIA_DEVICE_NULL
@@ -2245,10 +2207,11 @@ static struct pcmcia_driver wl3501_driver = {
.drv = {
.name = "wl3501_cs",
},
- .attach = wl3501_attach,
- .event = wl3501_event,
- .detach = wl3501_detach,
+ .probe = wl3501_attach,
+ .remove = wl3501_detach,
.id_table = wl3501_ids,
+ .suspend = wl3501_suspend,
+ .resume = wl3501_resume,
};
static int __init wl3501_init_module(void)