Commit 5f2a71fc authored by Dominik Brodowski's avatar Dominik Brodowski

[PATCH] pcmcia: add pcmcia_disable_device

pcmcia_disable_device(struct pcmcia_device *p_dev) performs the necessary
cleanups upon device or driver removal: it calls the appropriate
pcmcia_release_* functions, and can replace (most) of the current drivers'
_release() functions.
Signed-off-by: default avatarDominik Brodowski <linux@dominikbrodowski.net>
parent 1de9cedf
This file details changes in 2.6 which affect PCMCIA card driver authors:
* New release helper (as of 2.6.17)
Instead of calling pcmcia_release_{configuration,io,irq,win}, all that's
necessary now is calling pcmcia_disable_device. As there is no valid
reason left to call pcmcia_release_io and pcmcia_release_irq, they will
be removed soon.
* Unify detach and REMOVAL event code, as well as attach and INSERTION
code (as of 2.6.16)
void (*remove) (struct pcmcia_device *dev);
......
......@@ -1002,13 +1002,7 @@ static void bluecard_release(dev_link_t *link)
del_timer(&(info->timer));
link->dev = NULL;
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link->handle);
}
static int bluecard_suspend(struct pcmcia_device *dev)
......
......@@ -839,13 +839,7 @@ static void bt3c_release(dev_link_t *link)
if (link->state & DEV_PRESENT)
bt3c_close(info);
link->dev = NULL;
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link->handle);
}
static int bt3c_suspend(struct pcmcia_device *dev)
......
......@@ -768,13 +768,7 @@ static void btuart_release(dev_link_t *link)
if (link->state & DEV_PRESENT)
btuart_close(info);
link->dev = NULL;
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link->handle);
}
static int btuart_suspend(struct pcmcia_device *dev)
......
......@@ -720,13 +720,7 @@ static void dtl1_release(dev_link_t *link)
if (link->state & DEV_PRESENT)
dtl1_close(info);
link->dev = NULL;
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link->handle);
}
static int dtl1_suspend(struct pcmcia_device *dev)
......
......@@ -1899,8 +1899,7 @@ static int cm4000_resume(struct pcmcia_device *p_dev)
static void cm4000_release(dev_link_t *link)
{
cmm_cm4000_release(link->priv); /* delay release until device closed */
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_disable_device(link->handle);
}
static int cm4000_attach(struct pcmcia_device *p_dev)
......
......@@ -654,8 +654,7 @@ static int reader_resume(struct pcmcia_device *p_dev)
static void reader_release(dev_link_t *link)
{
cm4040_reader_release(link->priv);
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_disable_device(link->handle);
}
static int reader_attach(struct pcmcia_device *p_dev)
......
......@@ -710,15 +710,7 @@ static void mgslpc_release(u_long arg)
if (debug_level >= DEBUG_LEVEL_INFO)
printk("mgslpc_release(0x%p)\n", link);
/* Unlink the device chain */
link->dev = NULL;
link->state &= ~DEV_CONFIG;
pcmcia_release_configuration(link->handle);
if (link->io.NumPorts1)
pcmcia_release_io(link->handle, &link->io);
if (link->irq.AssignedIRQ)
pcmcia_release_irq(link->handle, &link->irq);
pcmcia_disable_device(link->handle);
}
static void mgslpc_detach(struct pcmcia_device *p_dev)
......
......@@ -369,14 +369,8 @@ void ide_release(dev_link_t *link)
ide_unregister(info->hd);
}
info->ndev = 0;
link->dev = NULL;
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link->handle);
} /* ide_release */
static int ide_suspend(struct pcmcia_device *dev)
......
......@@ -367,16 +367,8 @@ static void avmcs_config(dev_link_t *link)
static void avmcs_release(dev_link_t *link)
{
b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ);
/* Unlink the device chain */
link->dev = NULL;
/* Don't bother checking to see if these succeed or not */
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ);
pcmcia_disable_device(link->handle);
} /* avmcs_release */
static int avmcs_suspend(struct pcmcia_device *dev)
......
......@@ -373,21 +373,14 @@ static void avma1cs_config(dev_link_t *link)
static void avma1cs_release(dev_link_t *link)
{
local_info_t *local = link->priv;
local_info_t *local = link->priv;
DEBUG(0, "avma1cs_release(0x%p)\n", link);
DEBUG(0, "avma1cs_release(0x%p)\n", link);
/* no unregister function with hisax */
HiSax_closecard(local->node.minor);
/* now unregister function with hisax */
HiSax_closecard(local->node.minor);
/* Unlink the device chain */
link->dev = NULL;
/* Don't bother checking to see if these succeed or not */
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link->handle);
} /* avma1cs_release */
static int avma1cs_suspend(struct pcmcia_device *dev)
......
......@@ -380,16 +380,8 @@ static void elsa_cs_release(dev_link_t *link)
HiSax_closecard(local->cardnr);
}
}
/* Unlink the device chain */
link->dev = NULL;
/* Don't bother checking to see if these succeed or not */
if (link->win)
pcmcia_release_window(link->win);
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link->handle);
} /* elsa_cs_release */
static int elsa_suspend(struct pcmcia_device *p_dev)
......
......@@ -467,23 +467,8 @@ static void sedlbauer_release(dev_link_t *link)
HiSax_closecard(local->cardnr);
}
}
/* Unlink the device chain */
link->dev = NULL;
/*
In a normal driver, additional code may be needed to release
other kernel data structures associated with this device.
*/
/* Don't bother checking to see if these succeed or not */
if (link->win)
pcmcia_release_window(link->win);
pcmcia_release_configuration(link->handle);
if (link->io.NumPorts1)
pcmcia_release_io(link->handle, &link->io);
if (link->irq.AssignedIRQ)
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link->handle);
} /* sedlbauer_release */
static int sedlbauer_suspend(struct pcmcia_device *p_dev)
......
......@@ -371,16 +371,8 @@ static void teles_cs_release(dev_link_t *link)
HiSax_closecard(local->cardnr);
}
}
/* Unlink the device chain */
link->dev = NULL;
/* Don't bother checking to see if these succeed or not */
if (link->win)
pcmcia_release_window(link->win);
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link->handle);
} /* teles_cs_release */
static int teles_suspend(struct pcmcia_device *p_dev)
......
......@@ -511,13 +511,7 @@ static void tc574_config(dev_link_t *link)
static void tc574_release(dev_link_t *link)
{
DEBUG(0, "3c574_release(0x%p)\n", link);
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link->handle);
}
static int tc574_suspend(struct pcmcia_device *p_dev)
......
......@@ -386,13 +386,7 @@ static void tc589_config(dev_link_t *link)
static void tc589_release(dev_link_t *link)
{
DEBUG(0, "3c589_release(0x%p)\n", link);
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link->handle);
}
static int tc589_suspend(struct pcmcia_device *p_dev)
......
......@@ -456,13 +456,7 @@ static void axnet_config(dev_link_t *link)
static void axnet_release(dev_link_t *link)
{
DEBUG(0, "axnet_release(0x%p)\n", link);
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link->handle);
}
static int axnet_suspend(struct pcmcia_device *p_dev)
......
......@@ -377,16 +377,8 @@ static void com20020_config(dev_link_t *link)
static void com20020_release(dev_link_t *link)
{
DEBUG(1,"release...\n");
DEBUG(0, "com20020_release(0x%p)\n", link);
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);
DEBUG(0, "com20020_release(0x%p)\n", link);
pcmcia_disable_device(link->handle);
}
static int com20020_suspend(struct pcmcia_device *p_dev)
......
......@@ -674,16 +674,8 @@ static int fmvj18x_setup_mfc(dev_link_t *link)
static void fmvj18x_release(dev_link_t *link)
{
DEBUG(0, "fmvj18x_release(0x%p)\n", link);
/* Don't bother checking to see if these succeed or not */
pcmcia_release_window(link->win);
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
DEBUG(0, "fmvj18x_release(0x%p)\n", link);
pcmcia_disable_device(link->handle);
}
static int fmvj18x_suspend(struct pcmcia_device *p_dev)
......
......@@ -348,22 +348,17 @@ static void ibmtr_config(dev_link_t *link)
static void ibmtr_release(dev_link_t *link)
{
ibmtr_dev_t *info = link->priv;
struct net_device *dev = info->dev;
DEBUG(0, "ibmtr_release(0x%p)\n", link);
ibmtr_dev_t *info = link->priv;
struct net_device *dev = info->dev;
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
if (link->win) {
struct tok_info *ti = netdev_priv(dev);
iounmap(ti->mmio);
pcmcia_release_window(link->win);
pcmcia_release_window(info->sram_win_handle);
}
DEBUG(0, "ibmtr_release(0x%p)\n", link);
link->state &= ~DEV_CONFIG;
if (link->win) {
struct tok_info *ti = netdev_priv(dev);
iounmap(ti->mmio);
pcmcia_release_window(info->sram_win_handle);
}
pcmcia_disable_device(link->handle);
}
static int ibmtr_suspend(struct pcmcia_device *p_dev)
......
......@@ -765,14 +765,8 @@ nmclan_release
---------------------------------------------------------------------------- */
static void nmclan_release(dev_link_t *link)
{
DEBUG(0, "nmclan_release(0x%p)\n", link);
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
DEBUG(0, "nmclan_release(0x%p)\n", link);
pcmcia_disable_device(link->handle);
}
static int nmclan_suspend(struct pcmcia_device *p_dev)
......
......@@ -732,19 +732,14 @@ static void pcnet_config(dev_link_t *link)
static void pcnet_release(dev_link_t *link)
{
pcnet_dev_t *info = PRIV(link->priv);
pcnet_dev_t *info = PRIV(link->priv);
DEBUG(0, "pcnet_release(0x%p)\n", link);
DEBUG(0, "pcnet_release(0x%p)\n", link);
if (info->flags & USE_SHMEM) {
iounmap(info->base);
pcmcia_release_window(link->win);
}
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
if (info->flags & USE_SHMEM)
iounmap(info->base);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link->handle);
}
/*======================================================================
......
......@@ -1181,20 +1181,13 @@ static void smc91c92_config(dev_link_t *link)
static void smc91c92_release(dev_link_t *link)
{
DEBUG(0, "smc91c92_release(0x%p)\n", link);
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
if (link->win) {
struct net_device *dev = link->priv;
struct smc_private *smc = netdev_priv(dev);
iounmap(smc->base);
pcmcia_release_window(link->win);
}
link->state &= ~DEV_CONFIG;
DEBUG(0, "smc91c92_release(0x%p)\n", link);
if (link->win) {
struct net_device *dev = link->priv;
struct smc_private *smc = netdev_priv(dev);
iounmap(smc->base);
}
pcmcia_disable_device(link->handle);
}
/*======================================================================
......
......@@ -1090,21 +1090,15 @@ xirc2ps_config(dev_link_t * link)
static void
xirc2ps_release(dev_link_t *link)
{
DEBUG(0, "release(0x%p)\n", link);
DEBUG(0, "release(0x%p)\n", link);
if (link->win) {
struct net_device *dev = link->priv;
local_info_t *local = netdev_priv(dev);
if (local->dingo)
iounmap(local->dingo_ccr - 0x0800);
pcmcia_release_window(link->win);
}
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
if (link->win) {
struct net_device *dev = link->priv;
local_info_t *local = netdev_priv(dev);
if (local->dingo)
iounmap(local->dingo_ccr - 0x0800);
}
pcmcia_disable_device(link->handle);
} /* xirc2ps_release */
/*====================================================================*/
......
......@@ -429,24 +429,7 @@ static void airo_config(dev_link_t *link)
static void airo_release(dev_link_t *link)
{
DEBUG(0, "airo_release(0x%p)\n", link);
/* Unlink the device chain */
link->dev = NULL;
/*
In a normal driver, additional code may be needed to release
other kernel data structures associated with this device.
*/
/* Don't bother checking to see if these succeed or not */
if (link->win)
pcmcia_release_window(link->win);
pcmcia_release_configuration(link->handle);
if (link->io.NumPorts1)
pcmcia_release_io(link->handle, &link->io);
if (link->irq.AssignedIRQ)
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link->handle);
}
static int airo_suspend(struct pcmcia_device *p_dev)
......
......@@ -418,23 +418,14 @@ static void atmel_config(dev_link_t *link)
static void atmel_release(dev_link_t *link)
{
struct net_device *dev = ((local_info_t*)link->priv)->eth_dev;
DEBUG(0, "atmel_release(0x%p)\n", link);
/* Unlink the device chain */
link->dev = NULL;
if (dev)
if (dev)
stop_atmel_card(dev);
((local_info_t*)link->priv)->eth_dev = NULL;
/* Don't bother checking to see if these succeed or not */
pcmcia_release_configuration(link->handle);
if (link->io.NumPorts1)
pcmcia_release_io(link->handle, &link->io);
if (link->irq.AssignedIRQ)
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
((local_info_t*)link->priv)->eth_dev = NULL;
pcmcia_disable_device(link->handle);
}
static int atmel_suspend(struct pcmcia_device *dev)
......
......@@ -804,16 +804,7 @@ static void prism2_release(u_long arg)
iface->local->shutdown = 1;
}
if (link->win)
pcmcia_release_window(link->win);
pcmcia_release_configuration(link->handle);
if (link->io.NumPorts1)
pcmcia_release_io(link->handle, &link->io);
if (link->irq.AssignedIRQ)
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link->handle);
PDEBUG(DEBUG_FLOW, "release - done\n");
}
......
......@@ -869,21 +869,14 @@ static void netwave_pcmcia_config(dev_link_t *link) {
*/
static void netwave_release(dev_link_t *link)
{
struct net_device *dev = link->priv;
netwave_private *priv = netdev_priv(dev);
DEBUG(0, "netwave_release(0x%p)\n", link);
struct net_device *dev = link->priv;
netwave_private *priv = netdev_priv(dev);
/* Don't bother checking to see if these succeed or not */
if (link->win) {
iounmap(priv->ramBase);
pcmcia_release_window(link->win);
}
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
DEBUG(0, "netwave_release(0x%p)\n", link);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link->handle);
if (link->win)
iounmap(priv->ramBase);
}
static int netwave_suspend(struct pcmcia_device *p_dev)
......
......@@ -416,13 +416,7 @@ orinoco_cs_release(dev_link_t *link)
priv->hw_unavailable++;
spin_unlock_irqrestore(&priv->lock, flags);
/* Don't bother checking to see if these succeed or not */
pcmcia_release_configuration(link->handle);
if (link->io.NumPorts1)
pcmcia_release_io(link->handle, &link->io);
if (link->irq.AssignedIRQ)
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link->handle);
if (priv->hw.iobase)
ioport_unmap(priv->hw.iobase);
} /* orinoco_cs_release */
......
......@@ -894,13 +894,7 @@ spectrum_cs_release(dev_link_t *link)
priv->hw_unavailable++;
spin_unlock_irqrestore(&priv->lock, flags);
/* Don't bother checking to see if these succeed or not */
pcmcia_release_configuration(link->handle);
if (link->io.NumPorts1)
pcmcia_release_io(link->handle, &link->io);
if (link->irq.AssignedIRQ)
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link->handle);
if (priv->hw.iobase)
ioport_unmap(priv->hw.iobase);
} /* spectrum_cs_release */
......
......@@ -4098,24 +4098,18 @@ wv_pcmcia_config(dev_link_t * link)
static void
wv_pcmcia_release(dev_link_t *link)
{
struct net_device * dev = (struct net_device *) link->priv;
net_local * lp = netdev_priv(dev);
struct net_device * dev = (struct net_device *) link->priv;
net_local * lp = netdev_priv(dev);
#ifdef DEBUG_CONFIG_TRACE
printk(KERN_DEBUG "%s: -> wv_pcmcia_release(0x%p)\n", dev->name, link);
printk(KERN_DEBUG "%s: -> wv_pcmcia_release(0x%p)\n", dev->name, link);
#endif
/* Don't bother checking to see if these succeed or not */
iounmap(lp->mem);
pcmcia_release_window(link->win);
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
iounmap(lp->mem);
pcmcia_disable_device(link->handle);
#ifdef DEBUG_CONFIG_TRACE
printk(KERN_DEBUG "%s: <- wv_pcmcia_release()\n", dev->name);
printk(KERN_DEBUG "%s: <- wv_pcmcia_release()\n", dev->name);
#endif
}
......
......@@ -2149,16 +2149,10 @@ static void wl3501_release(dev_link_t *link)
struct net_device *dev = link->priv;
/* Unlink the device chain */
if (link->dev) {
if (link->dev)
unregister_netdev(dev);
link->dev = NULL;
}
/* Don't bother checking to see if these succeed or not */
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
pcmcia_disable_device(link->handle);
}
static int wl3501_suspend(struct pcmcia_device *p_dev)
......
......@@ -267,23 +267,17 @@ void parport_config(dev_link_t *link)
void parport_cs_release(dev_link_t *link)
{
parport_info_t *info = link->priv;
DEBUG(0, "parport_release(0x%p)\n", link);
parport_info_t *info = link->priv;
if (info->ndev) {
struct parport *p = info->port;
parport_pc_unregister_port(p);
}
info->ndev = 0;
link->dev = NULL;
pcmcia_release_configuration(link->handle);
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
DEBUG(0, "parport_release(0x%p)\n", link);
if (info->ndev) {
struct parport *p = info->port;
parport_pc_unregister_port(p);
}
info->ndev = 0;
pcmcia_disable_device(link->handle);
} /* parport_cs_release */
static int parport_suspend(struct pcmcia_device *dev)
......
......@@ -451,20 +451,20 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev)
{
pccard_io_map io = { 0, 0, 0, 0, 1 };
struct pcmcia_socket *s = p_dev->socket;
config_t *c = p_dev->function_config;
int i;
if (!(p_dev->state & CLIENT_CONFIG_LOCKED))