Commit 373ed85e authored by Russell King's avatar Russell King Committed by Stephen Hemminger

[netdrvr pcmcia] fix hot unplugging

This patch fixes a deadlock which occurs when a PCMCIA card is
physically removed, and the netdev interface is then downed.

The problem occurs because these drivers delay the call of
unregister_netdev until the netdev is downed.

Since 2.6 now downs the interface on unregister_netdev(), we can
call this function as soon as the card has been removed without
waiting for the netdev to be downed.
parent da11d5bb
......@@ -362,11 +362,8 @@ static void tc574_detach(dev_link_t *link)
if (*linkp == NULL)
return;
if (link->state & DEV_CONFIG) {
if (link->state & DEV_CONFIG)
tc574_release(link);
if (link->state & DEV_STALE_CONFIG)
return;
}
if (link->handle)
CardServices(DeregisterClient, link->handle);
......@@ -554,21 +551,11 @@ static void tc574_release(dev_link_t *link)
{
DEBUG(0, "3c574_release(0x%p)\n", link);
if (link->open) {
DEBUG(1, "3c574_cs: release postponed, '%s' still open\n",
link->dev->dev_name);
link->state |= DEV_STALE_CONFIG;
return;
}
CardServices(ReleaseConfiguration, link->handle);
CardServices(ReleaseIO, link->handle, &link->io);
CardServices(ReleaseIRQ, link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
if (link->state & DEV_STALE_CONFIG)
tc574_detach(link);
}
/*
......@@ -1297,8 +1284,7 @@ static int el3_close(struct net_device *dev)
link->open--;
netif_stop_queue(dev);
del_timer_sync(&lp->media);
if (link->state & DEV_STALE_CONFIG)
tc574_release(link);
return 0;
}
......
......@@ -276,11 +276,8 @@ static void tc589_detach(dev_link_t *link)
if (*linkp == NULL)
return;
if (link->state & DEV_CONFIG) {
if (link->state & DEV_CONFIG)
tc589_release(link);
if (link->state & DEV_STALE_CONFIG)
return;
}
if (link->handle)
CardServices(DeregisterClient, link->handle);
......@@ -430,21 +427,11 @@ static void tc589_release(dev_link_t *link)
{
DEBUG(0, "3c589_release(0x%p)\n", link);
if (link->open) {
DEBUG(1, "3c589_cs: release postponed, '%s' still open\n",
link->dev->dev_name);
link->state |= DEV_STALE_CONFIG;
return;
}
CardServices(ReleaseConfiguration, link->handle);
CardServices(ReleaseIO, link->handle, &link->io);
CardServices(ReleaseIRQ, link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
if (link->state & DEV_STALE_CONFIG)
tc589_detach(link);
}
/*======================================================================
......@@ -1073,8 +1060,6 @@ static int el3_close(struct net_device *dev)
link->open--;
netif_stop_queue(dev);
del_timer_sync(&lp->media);
if (link->state & DEV_STALE_CONFIG)
tc589_release(link);
return 0;
}
......
......@@ -237,11 +237,8 @@ static void axnet_detach(dev_link_t *link)
if (*linkp == NULL)
return;
if (link->state & DEV_CONFIG) {
if (link->state & DEV_CONFIG)
axnet_release(link);
if (link->state & DEV_STALE_CONFIG)
return;
}
if (link->handle)
CardServices(DeregisterClient, link->handle);
......@@ -513,21 +510,11 @@ static void axnet_release(dev_link_t *link)
{
DEBUG(0, "axnet_release(0x%p)\n", link);
if (link->open) {
DEBUG(1, "axnet_cs: release postponed, '%s' still open\n",
((axnet_dev_t *)(link->priv))->node.dev_name);
link->state |= DEV_STALE_CONFIG;
return;
}
CardServices(ReleaseConfiguration, link->handle);
CardServices(ReleaseIO, link->handle, &link->io);
CardServices(ReleaseIRQ, link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
if (link->state & DEV_STALE_CONFIG)
axnet_detach(link);
}
/*======================================================================
......@@ -685,8 +672,6 @@ static int axnet_close(struct net_device *dev)
link->open--;
netif_stop_queue(dev);
del_timer_sync(&info->watchdog);
if (link->state & DEV_STALE_CONFIG)
axnet_release(link);
return 0;
} /* axnet_close */
......
......@@ -263,11 +263,8 @@ static void com20020_detach(dev_link_t *link)
dev = info->dev;
if (link->state & DEV_CONFIG) {
if (link->state & DEV_CONFIG)
com20020_release(link);
if (link->state & DEV_STALE_CONFIG)
return;
}
if (link->handle)
CardServices(DeregisterClient, link->handle);
......@@ -439,21 +436,11 @@ static void com20020_release(dev_link_t *link)
DEBUG(0, "com20020_release(0x%p)\n", link);
if (link->open) {
DEBUG(1,"postpone...\n");
DEBUG(1, "com20020_cs: release postponed, device stll open\n");
link->state |= DEV_STALE_CONFIG;
return;
}
CardServices(ReleaseConfiguration, link->handle);
CardServices(ReleaseIO, link->handle, &link->io);
CardServices(ReleaseIRQ, link->handle, &link->irq);
link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);
if (link->state & DEV_STALE_CONFIG)
com20020_detach(link);
}
/*======================================================================
......
......@@ -332,11 +332,8 @@ static void fmvj18x_detach(dev_link_t *link)
if (*linkp == NULL)
return;
if (link->state & DEV_CONFIG) {
if (link->state & DEV_CONFIG)
fmvj18x_release(link);
if (link->state & DEV_STALE_CONFIG)
return;
}
/* Break the link with Card Services */
if (link->handle)
......@@ -722,17 +719,6 @@ static void fmvj18x_release(dev_link_t *link)
DEBUG(0, "fmvj18x_release(0x%p)\n", link);
/*
If the device is currently in use, we won't release until it
is actually closed.
*/
if (link->open) {
DEBUG(1, "fmvj18x_cs: release postponed, '%s' "
"still open\n", link->dev->dev_name);
link->state |= DEV_STALE_CONFIG;
return;
}
/* Don't bother checking to see if these succeed or not */
CardServices(ReleaseWindow, link->win);
CardServices(ReleaseConfiguration, link->handle);
......@@ -740,9 +726,6 @@ static void fmvj18x_release(dev_link_t *link)
CardServices(ReleaseIRQ, link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
if (link->state & DEV_STALE_CONFIG)
fmvj18x_detach(link);
}
/*====================================================================*/
......@@ -1250,8 +1233,6 @@ static int fjn_close(struct net_device *dev)
outb(INTR_OFF, ioaddr + LAN_CTRL);
link->open--;
if (link->state & DEV_STALE_CONFIG)
fmvj18x_release(link);
return 0;
} /* fjn_close */
......
......@@ -257,11 +257,8 @@ static void ibmtr_detach(dev_link_t *link)
struct tok_info *ti = (struct tok_info *)dev->priv;
del_timer_sync(&(ti->tr_timer));
}
if (link->state & DEV_CONFIG) {
if (link->state & DEV_CONFIG)
ibmtr_release(link);
if (link->state & DEV_STALE_CONFIG)
return;
}
if (link->handle)
CardServices(DeregisterClient, link->handle);
......@@ -412,13 +409,6 @@ static void ibmtr_release(dev_link_t *link)
DEBUG(0, "ibmtr_release(0x%p)\n", link);
if (link->open) {
DEBUG(1, "ibmtr_cs: release postponed, '%s' "
"still open\n", info->node.dev_name);
link->state |= DEV_STALE_CONFIG;
return;
}
CardServices(ReleaseConfiguration, link->handle);
CardServices(ReleaseIO, link->handle, &link->io);
CardServices(ReleaseIRQ, link->handle, &link->irq);
......@@ -430,9 +420,6 @@ static void ibmtr_release(dev_link_t *link)
}
link->state &= ~DEV_CONFIG;
if (link->state & DEV_STALE_CONFIG)
ibmtr_detach(link);
}
/*======================================================================
......
......@@ -551,11 +551,8 @@ static void nmclan_detach(dev_link_t *link)
if (*linkp == NULL)
return;
if (link->state & DEV_CONFIG) {
if (link->state & DEV_CONFIG)
nmclan_release(link);
if (link->state & DEV_STALE_CONFIG)
return;
}
if (link->handle)
CardServices(DeregisterClient, link->handle);
......@@ -809,21 +806,11 @@ static void nmclan_release(dev_link_t *link)
DEBUG(0, "nmclan_release(0x%p)\n", link);
if (link->open) {
DEBUG(1, "nmclan_cs: release postponed, '%s' "
"still open\n", link->dev->dev_name);
link->state |= DEV_STALE_CONFIG;
return;
}
CardServices(ReleaseConfiguration, link->handle);
CardServices(ReleaseIO, link->handle, &link->io);
CardServices(ReleaseIRQ, link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
if (link->state & DEV_STALE_CONFIG)
nmclan_detach(link);
}
/* ----------------------------------------------------------------------------
......@@ -990,8 +977,6 @@ static int mace_close(struct net_device *dev)
link->open--;
netif_stop_queue(dev);
if (link->state & DEV_STALE_CONFIG)
nmclan_release(link);
return 0;
} /* mace_close */
......
......@@ -335,11 +335,8 @@ static void pcnet_detach(dev_link_t *link)
if (*linkp == NULL)
return;
if (link->state & DEV_CONFIG) {
if (link->state & DEV_CONFIG)
pcnet_release(link);
if (link->state & DEV_STALE_CONFIG)
return;
}
if (link->handle)
CardServices(DeregisterClient, link->handle);
......@@ -790,13 +787,6 @@ static void pcnet_release(dev_link_t *link)
DEBUG(0, "pcnet_release(0x%p)\n", link);
if (link->open) {
DEBUG(1, "pcnet_cs: release postponed, '%s' still open\n",
info->node.dev_name);
link->state |= DEV_STALE_CONFIG;
return;
}
if (info->flags & USE_SHMEM) {
iounmap(info->base);
CardServices(ReleaseWindow, link->win);
......@@ -806,9 +796,6 @@ static void pcnet_release(dev_link_t *link)
CardServices(ReleaseIRQ, link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
if (link->state & DEV_STALE_CONFIG)
pcnet_detach(link);
}
/*======================================================================
......@@ -1132,8 +1119,6 @@ static int pcnet_close(struct net_device *dev)
link->open--;
netif_stop_queue(dev);
del_timer_sync(&info->watchdog);
if (link->state & DEV_STALE_CONFIG)
pcnet_release(link);
return 0;
} /* pcnet_close */
......
......@@ -411,11 +411,8 @@ static void smc91c92_detach(dev_link_t *link)
if (*linkp == NULL)
return;
if (link->state & DEV_CONFIG) {
if (link->state & DEV_CONFIG)
smc91c92_release(link);
if (link->state & DEV_STALE_CONFIG)
return;
}
if (link->handle)
CardServices(DeregisterClient, link->handle);
......@@ -1060,13 +1057,6 @@ static void smc91c92_release(dev_link_t *link)
DEBUG(0, "smc91c92_release(0x%p)\n", link);
if (link->open) {
DEBUG(1, "smc91c92_cs: release postponed, '%s' still open\n",
link->dev->dev_name);
link->state |= DEV_STALE_CONFIG;
return;
}
CardServices(ReleaseConfiguration, link->handle);
CardServices(ReleaseIO, link->handle, &link->io);
CardServices(ReleaseIRQ, link->handle, &link->irq);
......@@ -1078,9 +1068,6 @@ static void smc91c92_release(dev_link_t *link)
}
link->state &= ~DEV_CONFIG;
if (link->state & DEV_STALE_CONFIG)
smc91c92_detach(link);
}
/*======================================================================
......@@ -1306,8 +1293,6 @@ static int smc_close(struct net_device *dev)
link->open--;
del_timer_sync(&smc->media);
if (link->state & DEV_STALE_CONFIG)
smc91c92_release(link);
return 0;
} /* smc_close */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment