Unify the "detach" and REMOVAL_EVENT handlers to one "remove" function.
Old functionality is preserved, for the moment.
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
This file details changes in 2.6 which affect PCMCIA card driver authors:
+* Unify detach and REMOVAL event code (as of 2.6.16)
+ void (*remove) (struct pcmcia_device *dev);
+
* Move suspend, resume and reset out of event handler (as of 2.6.16)
int (*suspend) (struct pcmcia_device *dev);
int (*resume) (struct pcmcia_device *dev);
static dev_info_t dev_info = "bluecard_cs";
static dev_link_t *bluecard_attach(void);
-static void bluecard_detach(dev_link_t *);
+static void bluecard_detach(struct pcmcia_device *p_dev);
static dev_link_t *dev_list = NULL;
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
- bluecard_detach(link);
+ bluecard_detach(link->handle);
return NULL;
}
}
-static void bluecard_detach(dev_link_t *link)
+static void bluecard_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
bluecard_info_t *info = link->priv;
dev_link_t **linkp;
- int ret;
/* Locate device structure */
for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
if (link->state & DEV_CONFIG)
bluecard_release(link);
- if (link->handle) {
- ret = pcmcia_deregister_client(link->handle);
- if (ret != CS_SUCCESS)
- cs_error(link->handle, DeregisterClient, ret);
- }
-
/* Unlink device structure, free bits */
*linkp = link->next;
static int bluecard_event(event_t event, int priority, event_callback_args_t *args)
{
dev_link_t *link = args->client_data;
- bluecard_info_t *info = link->priv;
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- bluecard_close(info);
- bluecard_release(link);
- }
- break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
bluecard_config(link);
},
.attach = bluecard_attach,
.event = bluecard_event,
- .detach = bluecard_detach,
+ .remove = bluecard_detach,
.id_table = bluecard_ids,
.suspend = bluecard_suspend,
.resume = bluecard_resume,
static dev_info_t dev_info = "bt3c_cs";
static dev_link_t *bt3c_attach(void);
-static void bt3c_detach(dev_link_t *);
+static void bt3c_detach(struct pcmcia_device *p_dev);
static dev_link_t *dev_list = NULL;
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
- bt3c_detach(link);
+ bt3c_detach(link->handle);
return NULL;
}
}
-static void bt3c_detach(dev_link_t *link)
+static void bt3c_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
bt3c_info_t *info = link->priv;
dev_link_t **linkp;
- int ret;
/* Locate device structure */
for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
if (link->state & DEV_CONFIG)
bt3c_release(link);
- if (link->handle) {
- ret = pcmcia_deregister_client(link->handle);
- if (ret != CS_SUCCESS)
- cs_error(link->handle, DeregisterClient, ret);
- }
-
/* Unlink device structure, free bits */
*linkp = link->next;
static int bt3c_event(event_t event, int priority, event_callback_args_t *args)
{
dev_link_t *link = args->client_data;
- bt3c_info_t *info = link->priv;
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- bt3c_close(info);
- bt3c_release(link);
- }
- break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
bt3c_config(link);
},
.attach = bt3c_attach,
.event = bt3c_event,
- .detach = bt3c_detach,
+ .remove = bt3c_detach,
.id_table = bt3c_ids,
.suspend = bt3c_suspend,
.resume = bt3c_resume,
static dev_info_t dev_info = "btuart_cs";
static dev_link_t *btuart_attach(void);
-static void btuart_detach(dev_link_t *);
+static void btuart_detach(struct pcmcia_device *p_dev);
static dev_link_t *dev_list = NULL;
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
- btuart_detach(link);
+ btuart_detach(link->handle);
return NULL;
}
}
-static void btuart_detach(dev_link_t *link)
+static void btuart_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
btuart_info_t *info = link->priv;
dev_link_t **linkp;
- int ret;
/* Locate device structure */
for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
if (link->state & DEV_CONFIG)
btuart_release(link);
- if (link->handle) {
- ret = pcmcia_deregister_client(link->handle);
- if (ret != CS_SUCCESS)
- cs_error(link->handle, DeregisterClient, ret);
- }
-
/* Unlink device structure, free bits */
*linkp = link->next;
static int btuart_event(event_t event, int priority, event_callback_args_t *args)
{
dev_link_t *link = args->client_data;
- btuart_info_t *info = link->priv;
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- btuart_close(info);
- btuart_release(link);
- }
- break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
btuart_config(link);
},
.attach = btuart_attach,
.event = btuart_event,
- .detach = btuart_detach,
+ .remove = btuart_detach,
.id_table = btuart_ids,
.suspend = btuart_suspend,
.resume = btuart_resume,
static dev_info_t dev_info = "dtl1_cs";
static dev_link_t *dtl1_attach(void);
-static void dtl1_detach(dev_link_t *);
+static void dtl1_detach(struct pcmcia_device *p_dev);
static dev_link_t *dev_list = NULL;
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
- dtl1_detach(link);
+ dtl1_detach(link->handle);
return NULL;
}
}
-static void dtl1_detach(dev_link_t *link)
+static void dtl1_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
dtl1_info_t *info = link->priv;
dev_link_t **linkp;
- int ret;
/* Locate device structure */
for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
if (link->state & DEV_CONFIG)
dtl1_release(link);
- if (link->handle) {
- ret = pcmcia_deregister_client(link->handle);
- if (ret != CS_SUCCESS)
- cs_error(link->handle, DeregisterClient, ret);
- }
-
/* Unlink device structure, free bits */
*linkp = link->next;
static int dtl1_event(event_t event, int priority, event_callback_args_t *args)
{
dev_link_t *link = args->client_data;
- dtl1_info_t *info = link->priv;
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- dtl1_close(info);
- dtl1_release(link);
- }
- break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
dtl1_config(link);
},
.attach = dtl1_attach,
.event = dtl1_event,
- .detach = dtl1_detach,
+ .remove = dtl1_detach,
.id_table = dtl1_ids,
.suspend = dtl1_suspend,
.resume = dtl1_resume,
#define T_100MSEC msecs_to_jiffies(100)
#define T_500MSEC msecs_to_jiffies(500)
-static void cm4000_detach(dev_link_t *link);
+static void cm4000_detach(struct pcmcia_device *p_dev);
static void cm4000_release(dev_link_t *link);
static int major; /* major number we get from the kernel */
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
cm4000_config(link, devno);
break;
- case CS_EVENT_CARD_REMOVAL:
- DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n");
- link->state &= ~DEV_PRESENT;
- stop_monitor(dev);
- break;
default:
DEBUGP(5, dev, "unknown event %.2x\n", event);
break;
i = pcmcia_register_client(&link->handle, &client_reg);
if (i) {
cs_error(link->handle, RegisterClient, i);
- cm4000_detach(link);
+ cm4000_detach(link->handle);
return NULL;
}
return link;
}
-static void cm4000_detach_by_devno(int devno, dev_link_t * link)
+static void cm4000_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
struct cm4000_dev *dev = link->priv;
+ int devno;
- DEBUGP(3, dev, "-> detach_by_devno(devno=%d)\n", devno);
+ /* find device */
+ for (devno = 0; devno < CM4000_MAX_DEV; devno++)
+ if (dev_table[devno] == link)
+ break;
+ if (devno == CM4000_MAX_DEV)
+ return;
- if (link->state & DEV_CONFIG) {
- DEBUGP(5, dev, "device still configured (try to release it)\n");
- cm4000_release(link);
- }
+ link->state &= ~DEV_PRESENT;
+ stop_monitor(dev);
- if (link->handle) {
- pcmcia_deregister_client(link->handle);
- }
+ if (link->state & DEV_CONFIG)
+ cm4000_release(link);
dev_table[devno] = NULL;
- kfree(dev);
- return;
-}
-
-static void cm4000_detach(dev_link_t * link)
-{
- int i;
+ kfree(dev);
- /* find device */
- for (i = 0; i < CM4000_MAX_DEV; i++)
- if (dev_table[i] == link)
- break;
-
- if (i == CM4000_MAX_DEV)
- return;
-
- cm4000_detach_by_devno(i, link);
return;
}
.name = "cm4000_cs",
},
.attach = cm4000_attach,
- .detach = cm4000_detach,
+ .remove = cm4000_detach,
.suspend = cm4000_suspend,
.resume = cm4000_resume,
.event = cm4000_event,
static void __exit cmm_exit(void)
{
- int i;
-
printk(KERN_INFO MODULE_NAME ": unloading\n");
pcmcia_unregister_driver(&cm4000_driver);
- for (i = 0; i < CM4000_MAX_DEV; i++)
- if (dev_table[i])
- cm4000_detach_by_devno(i, dev_table[i]);
unregister_chrdev(major, DEVICE_NAME);
};
#define POLL_PERIOD msecs_to_jiffies(10)
static void reader_release(dev_link_t *link);
-static void reader_detach(dev_link_t *link);
+static void reader_detach(struct pcmcia_device *p_dev);
static int major;
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
reader_config(link, devno);
break;
- case CS_EVENT_CARD_REMOVAL:
- DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n");
- link->state &= ~DEV_PRESENT;
- break;
default:
DEBUGP(5, dev, "reader_event: unknown event %.2x\n",
i = pcmcia_register_client(&link->handle, &client_reg);
if (i) {
cs_error(link->handle, RegisterClient, i);
- reader_detach(link);
+ reader_detach(link->handle);
return NULL;
}
init_waitqueue_head(&dev->devq);
return link;
}
-static void reader_detach_by_devno(int devno, dev_link_t *link)
+static void reader_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
struct reader_dev *dev = link->priv;
-
- if (link->state & DEV_CONFIG) {
- DEBUGP(5, dev, "device still configured (try to release it)\n");
- reader_release(link);
- }
-
- pcmcia_deregister_client(link->handle);
- dev_table[devno] = NULL;
- DEBUGP(5, dev, "freeing dev=%p\n", dev);
- cm4040_stop_poll(dev);
- kfree(dev);
- return;
-}
-
-static void reader_detach(dev_link_t *link)
-{
- int i;
+ int devno;
/* find device */
- for (i = 0; i < CM_MAX_DEV; i++) {
- if (dev_table[i] == link)
+ for (devno = 0; devno < CM_MAX_DEV; devno++) {
+ if (dev_table[devno] == link)
break;
}
- if (i == CM_MAX_DEV)
+ if (devno == CM_MAX_DEV)
return;
- reader_detach_by_devno(i, link);
+ link->state &= ~DEV_PRESENT;
+
+ if (link->state & DEV_CONFIG)
+ reader_release(link);
+
+ dev_table[devno] = NULL;
+ kfree(dev);
+
return;
}
.name = "cm4040_cs",
},
.attach = reader_attach,
- .detach = reader_detach,
+ .remove = reader_detach,
.suspend = reader_suspend,
.resume = reader_resume,
.event = reader_event,
static void __exit cm4040_exit(void)
{
- int i;
-
printk(KERN_INFO MODULE_NAME ": unloading\n");
pcmcia_unregister_driver(&reader_driver);
- for (i = 0; i < CM_MAX_DEV; i++) {
- if (dev_table[i])
- reader_detach_by_devno(i, dev_table[i]);
- }
unregister_chrdev(major, DEVICE_NAME);
}
static int mgslpc_event(event_t event, int priority,
event_callback_args_t *args);
static dev_link_t *mgslpc_attach(void);
-static void mgslpc_detach(dev_link_t *);
+static void mgslpc_detach(struct pcmcia_device *p_dev);
static dev_info_t dev_info = "synclink_cs";
static dev_link_t *dev_list = NULL;
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
- mgslpc_detach(link);
+ mgslpc_detach(link->handle);
return NULL;
}
pcmcia_release_io(link->handle, &link->io);
if (link->irq.AssignedIRQ)
pcmcia_release_irq(link->handle, &link->irq);
- if (link->state & DEV_STALE_LINK)
- mgslpc_detach(link);
}
-static void mgslpc_detach(dev_link_t *link)
+static void mgslpc_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
dev_link_t **linkp;
if (debug_level >= DEBUG_LEVEL_INFO)
printk("mgslpc_detach(0x%p)\n", link);
-
+
/* find device */
for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
if (*linkp == link) break;
return;
if (link->state & DEV_CONFIG) {
- /* device is configured/active, mark it so when
- * release() is called a proper detach() occurs.
- */
- if (debug_level >= DEBUG_LEVEL_INFO)
- printk(KERN_DEBUG "synclinkpc: detach postponed, '%s' "
- "still locked\n", link->dev->dev_name);
- link->state |= DEV_STALE_LINK;
- return;
+ ((MGSLPC_INFO *)link->priv)->stop = 1;
+ mgslpc_release((u_long)link);
}
- /* Break the link with Card Services */
- if (link->handle)
- pcmcia_deregister_client(link->handle);
-
/* Unlink device structure, and free it */
*linkp = link->next;
mgslpc_remove_device((MGSLPC_INFO *)link->priv);
printk("mgslpc_event(0x%06x)\n", event);
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- ((MGSLPC_INFO *)link->priv)->stop = 1;
- mgslpc_release((u_long)link);
- }
- break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
mgslpc_config(link);
},
.attach = mgslpc_attach,
.event = mgslpc_event,
- .detach = mgslpc_detach,
+ .remove = mgslpc_detach,
.id_table = mgslpc_ids,
.suspend = mgslpc_suspend,
.resume = mgslpc_resume,
static dev_info_t dev_info = "ide-cs";
static dev_link_t *ide_attach(void);
-static void ide_detach(dev_link_t *);
+static void ide_detach(struct pcmcia_device *p_dev);
static dev_link_t *dev_list = NULL;
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
- ide_detach(link);
+ ide_detach(link->handle);
return NULL;
}
======================================================================*/
-static void ide_detach(dev_link_t *link)
+static void ide_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
dev_link_t **linkp;
- int ret;
DEBUG(0, "ide_detach(0x%p)\n", link);
if (link->state & DEV_CONFIG)
ide_release(link);
- if (link->handle) {
- ret = pcmcia_deregister_client(link->handle);
- if (ret != CS_SUCCESS)
- cs_error(link->handle, DeregisterClient, ret);
- }
-
/* Unlink, free device structure */
*linkp = link->next;
kfree(link->priv);
DEBUG(1, "ide_event(0x%06x)\n", event);
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG)
- ide_release(link);
- break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
ide_config(link);
},
.attach = ide_attach,
.event = ide_event,
- .detach = ide_detach,
+ .remove = ide_detach,
.id_table = ide_ids,
.suspend = ide_suspend,
.resume = ide_resume,
*/
static dev_link_t *avmcs_attach(void);
-static void avmcs_detach(dev_link_t *);
+static void avmcs_detach(struct pcmcia_device *p_dev);
/*
The dev_info variable is the "key" that is used to match up this
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != 0) {
cs_error(link->handle, RegisterClient, ret);
- avmcs_detach(link);
+ avmcs_detach(link->handle);
goto err;
}
return link;
======================================================================*/
-static void avmcs_detach(dev_link_t *link)
+static void avmcs_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
dev_link_t **linkp;
/* Locate device structure */
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) {
- link->state |= DEV_STALE_LINK;
- return;
- }
+ if (link->state & DEV_CONFIG)
+ avmcs_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);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
-
- if (link->state & DEV_STALE_LINK)
- avmcs_detach(link);
-
} /* avmcs_release */
static int avmcs_suspend(struct pcmcia_device *dev)
dev_link_t *link = args->client_data;
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG)
- avmcs_release(link);
- break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
avmcs_config(link);
},
.attach = avmcs_attach,
.event = avmcs_event,
- .detach = avmcs_detach,
+ .remove = avmcs_detach,
.id_table = avmcs_ids,
.suspend= avmcs_suspend,
.resume = avmcs_resume,
*/
static dev_link_t *avma1cs_attach(void);
-static void avma1cs_detach(dev_link_t *);
+static void avma1cs_detach(struct pcmcia_device *p_dev);
/*
The dev_info variable is the "key" that is used to match up this
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != 0) {
cs_error(link->handle, RegisterClient, ret);
- avma1cs_detach(link);
+ avma1cs_detach(link->handle);
return NULL;
}
======================================================================*/
-static void avma1cs_detach(dev_link_t *link)
+static void avma1cs_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
dev_link_t **linkp;
DEBUG(0, "avma1cs_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 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) {
-#ifdef PCMCIA_DEBUG
- printk(KERN_DEBUG "avma1_cs: detach postponed, '%s' "
- "still locked\n", link->dev->dev_name);
-#endif
- link->state |= DEV_STALE_LINK;
- return;
- }
+ if (link->state & DEV_CONFIG)
+ avma1cs_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);
-
} /* avma1cs_detach */
/*======================================================================
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
-
- if (link->state & DEV_STALE_LINK)
- avma1cs_detach(link);
} /* avma1cs_release */
static int avma1cs_suspend(struct pcmcia_device *dev)
DEBUG(1, "avma1cs_event(0x%06x)\n", event);
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- if (link->state & DEV_CONFIG)
- avma1cs_release(link);
- break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
avma1cs_config(link);
},
.attach = avma1cs_attach,
.event = avma1cs_event,
- .detach = avma1cs_detach,
+ .remove = avma1cs_detach,
.id_table = avma1cs_ids,
.suspend = avma1cs_suspend,
.resume = avma1cs_resume,
*/
static dev_link_t *elsa_cs_attach(void);
-static void elsa_cs_detach(dev_link_t *);
+static void elsa_cs_detach(struct pcmcia_device *p_dev);
/*
The dev_info variable is the "key" that is used to match up this
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
- elsa_cs_detach(link);
+ elsa_cs_detach(link->handle);
return NULL;
}
======================================================================*/
-static void elsa_cs_detach(dev_link_t *link)
+static void elsa_cs_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
dev_link_t **linkp;
local_info_t *info = link->priv;
- int ret;
DEBUG(0, "elsa_cs_detach(0x%p)\n", link);
if (*linkp == NULL)
return;
- if (link->state & DEV_CONFIG)
+ if (link->state & DEV_CONFIG) {
+ ((local_info_t*)link->priv)->busy = 1;
elsa_cs_release(link);
-
- /* Break the link with Card Services */
- if (link->handle) {
- ret = pcmcia_deregister_client(link->handle);
- if (ret != CS_SUCCESS)
- cs_error(link->handle, DeregisterClient, ret);
}
/* Unlink device structure and free it */
DEBUG(1, "elsa_cs_event(%d)\n", event);
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- ((local_info_t*)link->priv)->busy = 1;
- elsa_cs_release(link);
- }
- break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
elsa_cs_config(link);
},
.attach = elsa_cs_attach,
.event = elsa_cs_event,
- .detach = elsa_cs_detach,
+ .remove = elsa_cs_detach,
.id_table = elsa_ids,
.suspend = elsa_suspend,
.resume = elsa_resume,
*/
static dev_link_t *sedlbauer_attach(void);
-static void sedlbauer_detach(dev_link_t *);
+static void sedlbauer_detach(struct pcmcia_device *p_dev);
/*
You'll also need to prototype all the functions that will actually
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
- sedlbauer_detach(link);
+ sedlbauer_detach(link->handle);
return NULL;
}
======================================================================*/
-static void sedlbauer_detach(dev_link_t *link)
+static void sedlbauer_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
dev_link_t **linkp;
DEBUG(0, "sedlbauer_detach(0x%p)\n", 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) {
-#ifdef PCMCIA_DEBUG
- printk(KERN_DEBUG "sedlbauer_cs: detach postponed, '%s' "
- "still locked\n", link->dev->dev_name);
-#endif
- link->state |= DEV_STALE_LINK;
- return;
+ ((local_info_t *)link->priv)->stop = 1;
+ sedlbauer_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;
/* This points to the parent local_info_t struct */
if (link->irq.AssignedIRQ)
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
-
- if (link->state & DEV_STALE_LINK)
- sedlbauer_detach(link);
-
} /* sedlbauer_release */
static int sedlbauer_suspend(struct pcmcia_device *p_dev)
DEBUG(1, "sedlbauer_event(0x%06x)\n", event);
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- ((local_info_t *)link->priv)->stop = 1;
- sedlbauer_release(link);
- }
- break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
sedlbauer_config(link);
},
.attach = sedlbauer_attach,
.event = sedlbauer_event,
- .detach = sedlbauer_detach,
+ .remove = sedlbauer_detach,
.id_table = sedlbauer_ids,
.suspend = sedlbauer_suspend,
.resume = sedlbauer_resume,
*/
static dev_link_t *teles_attach(void);
-static void teles_detach(dev_link_t *);
+static void teles_detach(struct pcmcia_device *p_dev);
/*
The dev_info variable is the "key" that is used to match up this
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
- teles_detach(link);
+ teles_detach(link->handle);
return NULL;
}
======================================================================*/
-static void teles_detach(dev_link_t *link)
+static void teles_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
dev_link_t **linkp;
local_info_t *info = link->priv;
- int ret;
DEBUG(0, "teles_detach(0x%p)\n", link);
if (*linkp == NULL)
return;
- if (link->state & DEV_CONFIG)
+ if (link->state & DEV_CONFIG) {
+ info->busy = 1;
teles_cs_release(link);
-
- /* Break the link with Card Services */
- if (link->handle) {
- ret = pcmcia_deregister_client(link->handle);
- if (ret != CS_SUCCESS)
- cs_error(link->handle, DeregisterClient, ret);
}
/* Unlink device structure and free it */
DEBUG(1, "teles_cs_event(%d)\n", event);
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- ((local_info_t*)link->priv)->busy = 1;
- teles_cs_release(link);
- }
- break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
teles_cs_config(link);
},
.attach = teles_attach,
.event = teles_cs_event,
- .detach = teles_detach,
+ .remove = teles_detach,
.id_table = teles_ids,
.suspend = teles_suspend,
.resume = teles_resume,
DEBUG(1, "event=0x%06x", event);
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- DEBUG(2, "EVENT_CARD_REMOVAL");
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- struct pcmciamtd_dev *dev = link->priv;
- if(dev->mtd_info) {
- del_mtd_device(dev->mtd_info);
- info("mtd%d: Removed", dev->mtd_info->index);
- }
- pcmciamtd_release(link);
- }
- break;
case CS_EVENT_CARD_INSERTION:
DEBUG(2, "EVENT_CARD_INSERTION");
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
* when the device is released.
*/
-static void pcmciamtd_detach(dev_link_t *link)
+static void pcmciamtd_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
+
DEBUG(3, "link=0x%p", link);
if(link->state & DEV_CONFIG) {
- pcmciamtd_release(link);
- }
+ struct pcmciamtd_dev *dev = link->priv;
+ if(dev->mtd_info) {
+ del_mtd_device(dev->mtd_info);
+ info("mtd%d: Removed", dev->mtd_info->index);
+ }
- if (link->handle) {
- int ret;
- DEBUG(2, "Deregistering with card services");
- ret = pcmcia_deregister_client(link->handle);
- if (ret != CS_SUCCESS)
- cs_error(link->handle, DeregisterClient, ret);
+ pcmciamtd_release(link);
}
-
- link->state |= DEV_STALE_LINK;
}
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != 0) {
cs_error(link->handle, RegisterClient, ret);
- pcmciamtd_detach(link);
+ pcmciamtd_detach(link->handle);
return NULL;
}
DEBUG(2, "link = %p", link);
},
.attach = pcmciamtd_attach,
.event = pcmciamtd_event,
- .detach = pcmciamtd_detach,
+ .remove = pcmciamtd_detach,
.owner = THIS_MODULE,
.id_table = pcmciamtd_ids,
.suspend = pcmciamtd_suspend,
static dev_info_t dev_info = "3c574_cs";
static dev_link_t *tc574_attach(void);
-static void tc574_detach(dev_link_t *);
+static void tc574_detach(struct pcmcia_device *p_dev);
static dev_link_t *dev_list;
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != 0) {
cs_error(link->handle, RegisterClient, ret);
- tc574_detach(link);
+ tc574_detach(link->handle);
return NULL;
}
*/
-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;
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);
event_callback_args_t *args)
{
dev_link_t *link = args->client_data;
- 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)
- netif_device_detach(dev);
- break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
tc574_config(link);
},
.attach = tc574_attach,
.event = tc574_event,
- .detach = tc574_detach,
+ .remove = tc574_detach,
.id_table = tc574_ids,
.suspend = tc574_suspend,
.resume = tc574_resume,
static dev_info_t dev_info = "3c589_cs";
static dev_link_t *tc589_attach(void);
-static void tc589_detach(dev_link_t *);
+static void tc589_detach(struct pcmcia_device *p_dev);
static dev_link_t *dev_list;
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != 0) {
cs_error(link->handle, RegisterClient, ret);
- tc589_detach(link);
+ tc589_detach(link->handle);
return NULL;
}
======================================================================*/
-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;
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);
event_callback_args_t *args)
{
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);
},
.attach = tc589_attach,
.event = tc589_event,
- .detach = tc589_detach,
+ .remove = tc589_detach,
.id_table = tc589_ids,
.suspend = tc589_suspend,
.resume = tc589_resume,
const u_char *buf, const int start_page);
static dev_link_t *axnet_attach(void);
-static void axnet_detach(dev_link_t *);
+static void axnet_detach(struct pcmcia_device *p_dev);
static dev_info_t dev_info = "axnet_cs";
static dev_link_t *dev_list;
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
- axnet_detach(link);
+ axnet_detach(link->handle);
return NULL;
}
======================================================================*/
-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;
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);
event_callback_args_t *args)
{
dev_link_t *link = args->client_data;
- 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);
},
.attach = axnet_attach,
.event = axnet_event,
- .detach = axnet_detach,
+ .remove = axnet_detach,
.id_table = axnet_ids,
.suspend = axnet_suspend,
.resume = axnet_resume,
static dev_info_t dev_info = "com20020_cs";
static dev_link_t *com20020_attach(void);
-static void com20020_detach(dev_link_t *);
+static void com20020_detach(struct pcmcia_device *p_dev);
static dev_link_t *dev_list;
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != 0) {
cs_error(link->handle, RegisterClient, ret);
- com20020_detach(link);
+ com20020_detach(link->handle);
return NULL;
}
======================================================================*/
-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;
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;
event_callback_args_t *args)
{
dev_link_t *link = args->client_data;
- 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);
},
.attach = com20020_attach,
.event = com20020_event,
- .detach = com20020_detach,
+ .remove = com20020_detach,
.id_table = com20020_ids,
.suspend = com20020_suspend,
.resume = com20020_resume,
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
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != 0) {
cs_error(link->handle, RegisterClient, ret);
- fmvj18x_detach(link);
+ fmvj18x_detach(link->handle);
return NULL;
}
/*====================================================================*/
-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;
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);
event_callback_args_t *args)
{
dev_link_t *link = args->client_data;
- 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);
},
.attach = fmvj18x_attach,
.event = fmvj18x_event,
- .detach = fmvj18x_detach,
+ .remove = fmvj18x_detach,
.id_table = fmvj18x_ids,
.suspend = fmvj18x_suspend,
.resume = fmvj18x_resume,
static dev_info_t dev_info = "ibmtr_cs";
static dev_link_t *ibmtr_attach(void);
-static void ibmtr_detach(dev_link_t *);
+static void ibmtr_detach(struct pcmcia_device *p_dev);
static dev_link_t *dev_list;
return link;
out_detach:
- ibmtr_detach(link);
+ ibmtr_detach(link->handle);
link = NULL;
goto out;
} /* ibmtr_attach */
======================================================================*/
-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;
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);
event_callback_args_t *args)
{
dev_link_t *link = args->client_data;
- 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);
},
.attach = ibmtr_attach,
.event = ibmtr_event,
- .detach = ibmtr_detach,
+ .remove = ibmtr_detach,
.id_table = ibmtr_ids,
.suspend = ibmtr_suspend,
.resume = ibmtr_resume,
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
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != 0) {
cs_error(link->handle, RegisterClient, ret);
- nmclan_detach(link);
+ nmclan_detach(link->handle);
return NULL;
}
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;
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);
event_callback_args_t *args)
{
dev_link_t *link = args->client_data;
- struct net_device *dev = link->priv;
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);
},
.attach = nmclan_attach,
.event = nmclan_event,
- .detach = nmclan_detach,
+ .remove = nmclan_detach,
.id_table = nmclan_ids,
.suspend = nmclan_suspend,
.resume = nmclan_resume,
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;
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
- pcnet_detach(link);
+ pcnet_detach(link->handle);
return NULL;
}
======================================================================*/
-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;
+ dev_link_t **linkp;
- /* 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);
+ /* Locate device structure */
+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+ if (*linkp == link) break;
+ if (*linkp == NULL)
+ return;
- if (link->state & DEV_CONFIG)
- pcnet_release(link);
+ if (link->dev)
+ unregister_netdev(dev);
- 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);
+ /* Unlink device structure, free bits */
+ *linkp = link->next;
+ free_netdev(dev);
} /* pcnet_detach */
/*======================================================================
event_callback_args_t *args)
{
dev_link_t *link = args->client_data;
- 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);
},
.attach = pcnet_attach,
.event = pcnet_event,
- .detach = pcnet_detach,
+ .remove = pcnet_detach,
.owner = THIS_MODULE,
.id_table = pcnet_ids,
.suspend = pcnet_suspend,
/*====================================================================*/
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,
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != 0) {
cs_error(link->handle, RegisterClient, ret);
- smc91c92_detach(link);
+ smc91c92_detach(link->handle);
return NULL;
}
======================================================================*/
-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;
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);
event_callback_args_t *args)
{
dev_link_t *link = args->client_data;
- struct net_device *dev = link->priv;
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);
},
.attach = smc91c92_attach,
.event = smc91c92_event,
- .detach = smc91c92_detach,
+ .remove = smc91c92_detach,
.id_table = smc91c92_ids,
.suspend = smc91c92_suspend,
.resume = smc91c92_resume,
*/
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
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);
+ xirc2ps_detach(link->handle);
return NULL;
}
*/
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;
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);
event_callback_args_t * args)
{
dev_link_t *link = args->client_data;
- struct net_device *dev = link->priv;
DEBUG(0, "event(%d)\n", (int)event);
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);
},
.attach = xirc2ps_attach,
.event = xirc2ps_event,
- .detach = xirc2ps_detach,
+ .remove = xirc2ps_detach,
.id_table = xirc2ps_ids,
.suspend = xirc2ps_suspend,
.resume = xirc2ps_resume,
*/
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
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != 0) {
cs_error(link->handle, RegisterClient, ret);
- airo_detach(link);
+ airo_detach(link->handle);
return NULL;
}
======================================================================*/
-static void airo_detach(dev_link_t *link)
+static void airo_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
dev_link_t **linkp;
DEBUG(0, "airo_detach(0x%p)\n", 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);
-
-
-
+ ((local_info_t*)link->priv)->eth_dev = NULL;
+
/* Unlink device structure, free pieces */
*linkp = link->next;
kfree(link->priv);
event_callback_args_t *args)
{
dev_link_t *link = args->client_data;
- 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);
},
.attach = airo_attach,
.event = airo_event,
- .detach = airo_detach,
+ .remove = airo_detach,
.id_table = airo_ids,
.suspend = airo_suspend,
.resume = airo_resume,
*/
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
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != 0) {
cs_error(link->handle, RegisterClient, ret);
- atmel_detach(link);
+ atmel_detach(link->handle);
return NULL;
}
======================================================================*/
-static void atmel_detach(dev_link_t *link)
+static void atmel_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
dev_link_t **linkp;
DEBUG(0, "atmel_detach(0x%p)\n", link);
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);
event_callback_args_t *args)
{
dev_link_t *link = args->client_data;
- 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);
},
.attach = atmel_attach,
.event = atmel_event,
- .detach = atmel_detach,
+ .remove = atmel_detach,
.id_table = atmel_ids,
.suspend = atmel_suspend,
.resume = atmel_resume,
-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);
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
- prism2_detach(link);
+ prism2_detach(link->handle);
return NULL;
}
return link;
}
-static void prism2_detach(dev_link_t *link)
+static void prism2_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
dev_link_t **linkp;
PDEBUG(DEBUG_FLOW, "prism2_detach\n");
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) {
event_callback_args_t *args)
{
dev_link_t *link = args->client_data;
- struct net_device *dev = (struct net_device *) link->priv;
switch (event) {
case CS_EVENT_CARD_INSERTION:
}
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) {
- netif_stop_queue(dev);
- netif_device_detach(dev);
- prism2_release((u_long) link);
- }
- break;
-
default:
PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n",
dev_info, event);
.name = "hostap_cs",
},
.attach = prism2_attach,
- .detach = prism2_detach,
+ .remove = prism2_detach,
.owner = THIS_MODULE,
.event = prism2_event,
.id_table = hostap_cs_ids,
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);
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != 0) {
cs_error(link->handle, RegisterClient, ret);
- netwave_detach(link);
+ netwave_detach(link->handle);
return NULL;
}
* 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)
{
+ dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
dev_link_t **linkp;
*/
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;
event_callback_args_t *args)
{
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;
+ switch (event) {
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
netwave_pcmcia_config( link);
},
.attach = netwave_attach,
.event = netwave_event,
- .detach = netwave_detach,
+ .remove = netwave_detach,
.id_table = netwave_ids,
.suspend = netwave_suspend,
.resume = netwave_resume,
/********************************************************************/
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 */
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
- orinoco_cs_detach(link);
+ orinoco_cs_detach(link->handle);
return NULL;
}
* 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 *link = dev_to_instance(p_dev);
dev_link_t **linkp;
struct net_device *dev = link->priv;
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);
event_callback_args_t * args)
{
dev_link_t *link = args->client_data;
- struct net_device *dev = link->priv;
- struct orinoco_private *priv = netdev_priv(dev);
- int err = 0;
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
- 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;
}
- return err;
+ return 0;
} /* orinoco_cs_event */
/********************************************************************/
.name = DRIVER_NAME,
},
.attach = orinoco_cs_attach,
- .detach = orinoco_cs_detach,
+ .remove = orinoco_cs_detach,
.event = orinoco_cs_event,
.id_table = orinoco_cs_ids,
.suspend = orinoco_cs_suspend,
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);
if (ret != 0) {
printk("ray_cs ray_attach RegisterClient unhappy - detaching\n");
cs_error(link->handle, RegisterClient, ret);
- ray_detach(link);
+ ray_detach(link->handle);
return NULL;
}
DEBUG(2,"ray_cs ray_attach ending\n");
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);
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);
}
event_callback_args_t *args)
{
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);
},
.attach = ray_attach,
.event = ray_event,
- .detach = ray_detach,
+ .remove = ray_detach,
.id_table = ray_ids,
.suspend = ray_suspend,
.resume = ray_resume,
/********************************************************************/
static void spectrum_cs_release(dev_link_t *link);
-static void spectrum_cs_detach(dev_link_t *link);
+static void spectrum_cs_detach(struct pcmcia_device *p_dev);
/********************************************************************/
/* Firmware downloader */
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
- spectrum_cs_detach(link);
+ spectrum_cs_detach(link->handle);
return NULL;
}
* 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",
event_callback_args_t * args)
{
dev_link_t *link = args->client_data;
- struct net_device *dev = link->priv;
- struct orinoco_private *priv = netdev_priv(dev);
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
- 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;
spectrum_cs_config(link);
.name = DRIVER_NAME,
},
.attach = spectrum_cs_attach,
- .detach = spectrum_cs_detach,
+ .remove = spectrum_cs_detach,
.suspend = spectrum_cs_suspend,
.resume = spectrum_cs_resume,
.event = spectrum_cs_event,
if(ret != 0)
{
cs_error(link->handle, RegisterClient, ret);
- wavelan_detach(link);
+ wavelan_detach(link->handle);
return NULL;
}
* 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
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;
switch(event)
{
- case CS_EVENT_REGISTRATION_COMPLETE:
-#ifdef DEBUG_CONFIG_INFO
- printk(KERN_DEBUG "wavelan_cs: registration complete\n");
-#endif
- break;
-
- 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;
},
.attach = wavelan_attach,
.event = wavelan_event,
- .detach = wavelan_detach,
+ .remove = wavelan_detach,
.id_table = wavelan_ids,
.suspend = wavelan_suspend,
.resume = wavelan_resume,
static dev_link_t *
wavelan_attach(void); /* Create a new device */
static void
- wavelan_detach(dev_link_t *); /* Destroy a removed device */
+ wavelan_detach(struct pcmcia_device *p_dev); /* Destroy a removed device */
static int
wavelan_event(event_t, /* Manage pcmcia events */
int,
* 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)
* 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;
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret) {
cs_error(link->handle, RegisterClient, ret);
- wl3501_detach(link);
+ wl3501_detach(link->handle);
link = NULL;
}
out:
static int wl3501_event(event_t event, int pri, event_callback_args_t *args)
{
dev_link_t *link = args->client_data;
- 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);
- netif_device_detach(dev);
- wl3501_release(link);
- }
- break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
wl3501_config(link);
},
.attach = wl3501_attach,
.event = wl3501_event,
- .detach = wl3501_detach,
+ .remove = wl3501_detach,
.id_table = wl3501_ids,
.suspend = wl3501_suspend,
.resume = wl3501_resume,
} parport_info_t;
static dev_link_t *parport_attach(void);
-static void parport_detach(dev_link_t *);
+static void parport_detach(struct pcmcia_device *p_dev);
static void parport_config(dev_link_t *link);
static void parport_cs_release(dev_link_t *);
static int parport_event(event_t event, int priority,
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
- parport_detach(link);
+ parport_detach(link->handle);
return NULL;
}
======================================================================*/
-static void parport_detach(dev_link_t *link)
+static void parport_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
dev_link_t **linkp;
- int ret;
DEBUG(0, "parport_detach(0x%p)\n", link);
-
+
/* Locate device structure */
for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
if (*linkp == link) break;
if (link->state & DEV_CONFIG)
parport_cs_release(link);
-
- if (link->handle) {
- ret = pcmcia_deregister_client(link->handle);
- if (ret != CS_SUCCESS)
- cs_error(link->handle, DeregisterClient, ret);
- }
-
+
/* Unlink, free device structure */
*linkp = link->next;
kfree(link->priv);
-
} /* parport_detach */
/*======================================================================
DEBUG(1, "parport_event(0x%06x)\n", event);
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG)
- parport_cs_release(link);
- break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
parport_config(link);
},
.attach = parport_attach,
.event = parport_event,
- .detach = parport_detach,
+ .remove = parport_detach,
.id_table = parport_ids,
.suspend = parport_suspend,
.resume = parport_resume,
spinlock_t pcmcia_dev_list_lock;
-static int unbind_request(struct pcmcia_socket *s);
-
/*====================================================================*/
/* code which was in cs.c before */
unsigned int i;
u32 hash;
- if (!p_drv->attach || !p_drv->event || !p_drv->detach)
+ if (!p_drv->attach || !p_drv->event || !p_drv->remove)
printk(KERN_DEBUG "pcmcia: %s lacks a requisite callback "
"function\n", p_drv->drv.name);
{
struct pcmcia_device *p_dev;
struct pcmcia_driver *p_drv;
+ int i;
/* detach the "instance" */
p_dev = to_pcmcia_dev(dev);
p_drv = to_pcmcia_drv(dev->driver);
+ /* the likely, new path */
+ if (p_drv && p_drv->remove) {
+ p_drv->remove(p_dev);
+
+ /* check for proper unloading */
+ if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
+ printk(KERN_INFO "pcmcia: driver %s did not release config properly\n",
+ p_drv->drv.name);
+
+ for (i = 0; i < MAX_WIN; i++)
+ if (p_dev->state & CLIENT_WIN_REQ(i))
+ printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n",
+ p_drv->drv.name);
+
+ /* undo pcmcia_register_client */
+ p_dev->state = CLIENT_UNBOUND;
+ pcmcia_put_dev(p_dev);
+
+ /* references from pcmcia_probe_device */
+ pcmcia_put_dev(p_dev);
+ module_put(p_drv->owner);
+
+ return 0;
+ }
+
+ /* old path */
if (p_drv) {
if ((p_drv->detach) && (p_dev->instance)) {
+ printk(KERN_INFO "pcmcia: using deprecated detach mechanism. Fix the driver!\n");
+
p_drv->detach(p_dev->instance);
/* from pcmcia_probe_device */
put_device(&p_dev->dev);
}
+/*
+ * Removes a PCMCIA card from the device tree and socket list.
+ */
+static void pcmcia_card_remove(struct pcmcia_socket *s)
+{
+ struct pcmcia_device *p_dev;
+ unsigned long flags;
+
+ ds_dbg(2, "unbind_request(%d)\n", s->sock);
+
+ s->device_count = 0;
+
+ for (;;) {
+ /* unregister all pcmcia_devices registered with this socket*/
+ spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+ if (list_empty(&s->devices_list)) {
+ spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ return;
+ }
+ p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list);
+ list_del(&p_dev->socket_device_list);
+ p_dev->state |= CLIENT_STALE;
+ spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+
+ device_unregister(&p_dev->dev);
+ }
+
+ return;
+} /* unbind_request */
+
/*
* pcmcia_device_query -- determine information about a pcmcia device
case CS_EVENT_CARD_REMOVAL:
s->pcmcia_state.present = 0;
- send_event(skt, event, priority);
- unbind_request(skt);
+ send_event(skt, event, priority);
+ pcmcia_card_remove(skt);
handle_event(skt, event);
break;
EXPORT_SYMBOL(pcmcia_register_client);
-/* unbind _all_ devices attached to a given pcmcia_bus_socket. The
- * drivers have been called with EVENT_CARD_REMOVAL before.
- */
-static int unbind_request(struct pcmcia_socket *s)
-{
- struct pcmcia_device *p_dev;
- unsigned long flags;
-
- ds_dbg(2, "unbind_request(%d)\n", s->sock);
-
- s->device_count = 0;
-
- for (;;) {
- /* unregister all pcmcia_devices registered with this socket*/
- spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
- if (list_empty(&s->devices_list)) {
- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
- return 0;
- }
- p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list);
- list_del(&p_dev->socket_device_list);
- p_dev->state |= CLIENT_STALE;
- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
-
- device_unregister(&p_dev->dev);
- }
-
- return 0;
-} /* unbind_request */
-
int pcmcia_deregister_client(struct pcmcia_device *p_dev)
{
struct pcmcia_socket *s;
event_callback_args_t *args);
static dev_link_t *aha152x_attach(void);
-static void aha152x_detach(dev_link_t *);
+static void aha152x_detach(struct pcmcia_device *p_dev);
static dev_link_t *dev_list;
static dev_info_t dev_info = "aha152x_cs";
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != 0) {
cs_error(link->handle, RegisterClient, ret);
- aha152x_detach(link);
+ aha152x_detach(link->handle);
return NULL;
}
/*====================================================================*/
-static void aha152x_detach(dev_link_t *link)
+static void aha152x_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
dev_link_t **linkp;
DEBUG(0, "aha152x_detach(0x%p)\n", link);
if (link->state & DEV_CONFIG)
aha152x_release_cs(link);
- if (link->handle)
- pcmcia_deregister_client(link->handle);
-
/* Unlink device structure, free bits */
*linkp = link->next;
kfree(link->priv);
DEBUG(0, "aha152x_event(0x%06x)\n", event);
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG)
- aha152x_release_cs(link);
- break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
aha152x_config_cs(link);
},
.attach = aha152x_attach,
.event = aha152x_event,
- .detach = aha152x_detach,
+ .remove = aha152x_detach,
.id_table = aha152x_ids,
.suspend = aha152x_suspend,
.resume = aha152x_resume,
event_callback_args_t *args);
static dev_link_t *fdomain_attach(void);
-static void fdomain_detach(dev_link_t *);
+static void fdomain_detach(struct pcmcia_device *p_dev);
static dev_link_t *dev_list = NULL;
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != 0) {
cs_error(link->handle, RegisterClient, ret);
- fdomain_detach(link);
+ fdomain_detach(link->handle);
return NULL;
}
/*====================================================================*/
-static void fdomain_detach(dev_link_t *link)
+static void fdomain_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
dev_link_t **linkp;
DEBUG(0, "fdomain_detach(0x%p)\n", link);
if (link->state & DEV_CONFIG)
fdomain_release(link);
- if (link->handle)
- pcmcia_deregister_client(link->handle);
-
/* Unlink device structure, free bits */
*linkp = link->next;
kfree(link->priv);
DEBUG(1, "fdomain_event(0x%06x)\n", event);
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG)
- fdomain_release(link);
- break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
fdomain_config(link);
},
.attach = fdomain_attach,
.event = fdomain_event,
- .detach = fdomain_detach,
+ .remove = fdomain_detach,
.id_table = fdomain_ids,
.suspend = fdomain_suspend,
.resume = fdomain_resume,
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
- nsp_cs_detach(link);
+ nsp_cs_detach(link->handle);
return NULL;
}
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
-static void nsp_cs_detach(dev_link_t *link)
+static void nsp_cs_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
dev_link_t **linkp;
nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
return;
}
- if (link->state & DEV_CONFIG)
+ if (link->state & DEV_CONFIG) {
+ ((scsi_info_t *)link->priv)->stop = 1;
nsp_cs_release(link);
-
- /* Break the link with Card Services */
- if (link->handle) {
- pcmcia_deregister_client(link->handle);
}
/* Unlink device structure, free bits */
nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event);
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- nsp_dbg(NSP_DEBUG_INIT, "event: remove");
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- ((scsi_info_t *)link->priv)->stop = 1;
- nsp_cs_release(link);
- }
- break;
-
case CS_EVENT_CARD_INSERTION:
nsp_dbg(NSP_DEBUG_INIT, "event: insert");
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
},
.attach = nsp_cs_attach,
.event = nsp_cs_event,
- .detach = nsp_cs_detach,
+ .remove = nsp_cs_detach,
.id_table = nsp_cs_ids,
.suspend = nsp_cs_suspend,
.resume = nsp_cs_resume,
/* Card service functions */
static dev_link_t *nsp_cs_attach (void);
-static void nsp_cs_detach (dev_link_t *link);
+static void nsp_cs_detach (struct pcmcia_device *p_dev);
static void nsp_cs_release(dev_link_t *link);
static void nsp_cs_config (dev_link_t *link);
static int nsp_cs_event (event_t event, int priority, event_callback_args_t *args);
static int qlogic_event(event_t event, int priority, event_callback_args_t * args);
static dev_link_t *qlogic_attach(void);
-static void qlogic_detach(dev_link_t *);
+static void qlogic_detach(struct pcmcia_device *p_dev);
static dev_link_t *dev_list = NULL;
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != 0) {
cs_error(link->handle, RegisterClient, ret);
- qlogic_detach(link);
+ qlogic_detach(link->handle);
return NULL;
}
/*====================================================================*/
-static void qlogic_detach(dev_link_t * link)
+static void qlogic_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
dev_link_t **linkp;
DEBUG(0, "qlogic_detach(0x%p)\n", link);
if (link->state & DEV_CONFIG)
qlogic_release(link);
- if (link->handle)
- pcmcia_deregister_client(link->handle);
-
/* Unlink device structure, free bits */
*linkp = link->next;
kfree(link->priv);
DEBUG(1, "qlogic_event(0x%06x)\n", event);
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG)
- qlogic_release(link);
- break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
qlogic_config(link);
},
.attach = qlogic_attach,
.event = qlogic_event,
- .detach = qlogic_detach,
+ .remove = qlogic_detach,
.id_table = qlogic_ids,
.suspend = qlogic_suspend,
.resume = qlogic_resume,
DEBUG(1, "SYM53C500_event(0x%06x)\n", event);
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG)
- SYM53C500_release(link);
- break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
SYM53C500_config(link);
} /* SYM53C500_event */
static void
-SYM53C500_detach(dev_link_t *link)
+SYM53C500_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
dev_link_t **linkp;
DEBUG(0, "SYM53C500_detach(0x%p)\n", link);
if (link->state & DEV_CONFIG)
SYM53C500_release(link);
- if (link->handle)
- pcmcia_deregister_client(link->handle);
-
/* Unlink device structure, free bits. */
*linkp = link->next;
kfree(link->priv);
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != 0) {
cs_error(link->handle, RegisterClient, ret);
- SYM53C500_detach(link);
+ SYM53C500_detach(link->handle);
return NULL;
}
},
.attach = SYM53C500_attach,
.event = SYM53C500_event,
- .detach = SYM53C500_detach,
+ .remove = SYM53C500_detach,
.id_table = sym53c500_ids,
.suspend = sym53c500_suspend,
.resume = sym53c500_resume,
static dev_info_t dev_info = "serial_cs";
static dev_link_t *serial_attach(void);
-static void serial_detach(dev_link_t *);
+static void serial_detach(struct pcmcia_device *p_dev);
static dev_link_t *dev_list = NULL;
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
- serial_detach(link);
+ serial_detach(link->handle);
return NULL;
}
======================================================================*/
-static void serial_detach(dev_link_t * link)
+static void serial_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
struct serial_info *info = link->priv;
dev_link_t **linkp;
- int ret;
DEBUG(0, "serial_detach(0x%p)\n", link);
*/
serial_remove(link);
- if (link->handle) {
- ret = pcmcia_deregister_client(link->handle);
- if (ret != CS_SUCCESS)
- cs_error(link->handle, DeregisterClient, ret);
- }
-
/* Unlink device structure, free bits */
*linkp = link->next;
kfree(info);
DEBUG(1, "serial_event(0x%06x)\n", event);
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- serial_remove(link);
- break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
},
.attach = serial_attach,
.event = serial_event,
- .detach = serial_detach,
+ .remove = serial_detach,
.id_table = serial_ids,
.suspend = serial_suspend,
.resume = serial_resume,
} ixj_info_t;
static dev_link_t *ixj_attach(void);
-static void ixj_detach(dev_link_t *);
+static void ixj_detach(struct pcmcia_device *p_dev);
static void ixj_config(dev_link_t * link);
static void ixj_cs_release(dev_link_t * link);
static int ixj_event(event_t event, int priority, event_callback_args_t * args);
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
- ixj_detach(link);
+ ixj_detach(link->handle);
return NULL;
}
return link;
}
-static void ixj_detach(dev_link_t * link)
+static void ixj_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
dev_link_t **linkp;
- int ret;
+
DEBUG(0, "ixj_detach(0x%p)\n", link);
for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
if (*linkp == link)
link->state &= ~DEV_RELEASE_PENDING;
if (link->state & DEV_CONFIG)
ixj_cs_release(link);
- if (link->handle) {
- ret = pcmcia_deregister_client(link->handle);
- if (ret != CS_SUCCESS)
- cs_error(link->handle, DeregisterClient, ret);
- }
+
/* Unlink device structure, free bits */
*linkp = link->next;
kfree(link->priv);
dev_link_t *link = args->client_data;
DEBUG(1, "ixj_event(0x%06x)\n", event);
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- link->state |= DEV_RELEASE_PENDING;
- ixj_cs_release(link);
- }
- break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
ixj_config(link);
},
.attach = ixj_attach,
.event = ixj_event,
- .detach = ixj_detach,
+ .remove = ixj_detach,
.id_table = ixj_ids,
.suspend = ixj_suspend,
.resume = ixj_resume,
dev_node_t node;
} local_info_t;
+static void sl811_cs_release(dev_link_t * link);
+
/*====================================================================*/
static void release_platform_dev(struct device * dev)
/*====================================================================*/
-static void sl811_cs_detach(dev_link_t *link)
+static void sl811_cs_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
dev_link_t **linkp;
DBG(0, "sl811_cs_detach(0x%p)\n", link);
if (*linkp == NULL)
return;
- /* Break the link with Card Services */
- if (link->handle)
- pcmcia_deregister_client(link->handle);
+ link->state &= ~DEV_PRESENT;
+ if (link->state & DEV_CONFIG)
+ sl811_cs_release(link);
/* Unlink device structure, and free it */
*linkp = link->next;
DBG(0, "sl811_cs_release(0x%p)\n", link);
- if (link->open) {
- DBG(1, "sl811_cs: release postponed, '%s' still open\n",
- link->dev->dev_name);
- link->state |= DEV_STALE_CONFIG;
- return;
- }
-
/* Unlink the device chain */
link->dev = NULL;
if (link->irq.AssignedIRQ)
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
-
- if (link->state & DEV_STALE_LINK)
- sl811_cs_detach(link);
}
static void sl811_cs_config(dev_link_t *link)
DBG(1, "sl811_cs_event(0x%06x)\n", event);
switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG)
- sl811_cs_release(link);
- break;
-
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
sl811_cs_config(link);
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
- sl811_cs_detach(link);
+ sl811_cs_detach(link->handle);
return NULL;
}
},
.attach = sl811_cs_attach,
.event = sl811_cs_event,
- .detach = sl811_cs_detach,
+ .remove = sl811_cs_detach,
.id_table = sl811_ids,
.suspend = sl811_suspend,
.resume = sl811_resume,
event_callback_args_t *);
void (*detach)(dev_link_t *);
+ void (*remove) (struct pcmcia_device *dev);
+
int (*suspend) (struct pcmcia_device *dev);
int (*resume) (struct pcmcia_device *dev);