patch-2.4.0-test8 linux/drivers/net/pcmcia/ray_cs.c
Next file: linux/drivers/net/pcmcia/smc91c92_cs.c
Previous file: linux/drivers/net/pcmcia/pcnet_cs.c
Back to the patch index
Back to the overall index
- Lines: 157
- Date:
Sat Sep 2 00:15:37 2000
- Orig file:
v2.4.0-test7/linux/drivers/net/pcmcia/ray_cs.c
- Orig date:
Wed Aug 9 19:19:50 2000
diff -u --recursive --new-file v2.4.0-test7/linux/drivers/net/pcmcia/ray_cs.c linux/drivers/net/pcmcia/ray_cs.c
@@ -318,6 +318,23 @@
error_info_t err = { func, ret };
pcmcia_report_error(handle, &err);
}
+/*======================================================================
+
+ This bit of code is used to avoid unregistering network devices
+ at inappropriate times. 2.2 and later kernels are fairly picky
+ about when this can happen.
+
+======================================================================*/
+
+static void flush_stale_links(void)
+{
+ dev_link_t *link, *next;
+ for (link = dev_list; link; link = next) {
+ next = link->next;
+ if (link->state & DEV_STALE_LINK)
+ ray_detach(link);
+ }
+}
/*=============================================================================
ray_attach() creates an "instance" of the driver, allocating
@@ -336,6 +353,7 @@
struct net_device *dev;
DEBUG(1, "ray_attach()\n");
+ flush_stale_links();
/* Initialize the dev_link_t structure */
link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
@@ -384,7 +402,6 @@
dev->priv = local;
local->finder = link;
- link->dev = &local->node;
local->card_status = CARD_INSERTED;
local->authentication_state = UNAUTHENTICATED;
local->num_multi = 0;
@@ -451,8 +468,6 @@
static void ray_detach(dev_link_t *link)
{
dev_link_t **linkp;
- struct net_device *dev;
- long flags;
DEBUG(1, "ray_detach(0x%p)\n", link);
@@ -462,19 +477,12 @@
if (*linkp == NULL)
return;
- save_flags(flags);
- cli();
- if (link->state & DEV_RELEASE_PENDING) {
- del_timer(&link->release);
- link->state &= ~DEV_RELEASE_PENDING;
- }
- restore_flags(flags);
-
/* 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().
*/
+ del_timer(&link->release);
if (link->state & DEV_CONFIG) {
ray_release((u_long)link);
if(link->state & DEV_STALE_CONFIG) {
@@ -490,10 +498,10 @@
/* Unlink device structure, free pieces */
*linkp = link->next;
if (link->priv) {
- dev = link->priv;
+ struct net_device *dev = link->priv;
+ if (link->dev) unregister_netdev(dev);
if (dev->priv)
kfree(dev->priv);
-
kfree(link->priv);
}
kfree(link);
@@ -606,6 +614,7 @@
}
strcpy(local->node.dev_name, dev->name);
+ link->dev = &local->node;
link->state &= ~DEV_CONFIG_PENDING;
printk(KERN_INFO "%s: RayLink, irq %d, hw_addr ",
@@ -907,9 +916,7 @@
return;
}
del_timer(&local->timer);
- if (link->dev != '\0') unregister_netdev(dev);
- /* Unlink the device chain */
- link->dev = NULL;
+ link->state &= ~DEV_CONFIG;
iounmap(local->sram);
iounmap(local->rmem);
@@ -926,8 +933,6 @@
i = pcmcia_release_irq(link->handle, &link->irq);
if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseIRQ ret = %x\n",i);
- link->state &= ~DEV_CONFIG;
- if (link->state & DEV_STALE_LINK) ray_detach(link);
DEBUG(2,"ray_release ending\n");
} /* ray_release */
/*=============================================================================
@@ -954,8 +959,7 @@
link->state &= ~DEV_PRESENT;
netif_device_detach(dev);
if (link->state & DEV_CONFIG) {
- link->release.expires = jiffies + HZ/20;
- add_timer(&link->release);
+ mod_timer(&link->release, jiffies + HZ/20);
del_timer(&local->timer);
}
break;
@@ -1006,7 +1010,7 @@
if ( (i = dl_startup_params(dev)) < 0)
{
printk(KERN_INFO "ray_dev_init dl_startup_params failed - "
- "returns 0x%x/n",i);
+ "returns 0x%x\n",i);
return -1;
}
@@ -1554,11 +1558,8 @@
link->open--;
netif_stop_queue(dev);
- if (link->state & DEV_STALE_CONFIG) {
- link->release.expires = jiffies + HZ/20;
- link->state |= DEV_RELEASE_PENDING;
- add_timer(&link->release);
- }
+ if (link->state & DEV_STALE_CONFIG)
+ mod_timer(&link->release, jiffies + HZ/20);
MOD_DEC_USE_COUNT;
@@ -2773,10 +2774,9 @@
#endif
unregister_pcmcia_driver(&dev_info);
- while (dev_list != NULL) {
- if (dev_list->state & DEV_CONFIG) ray_release((u_long)dev_list);
+ while (dev_list != NULL)
ray_detach(dev_list);
- }
+
#ifdef CONFIG_PROC_FS
remove_proc_entry("driver/ray_cs/ray_cs", NULL);
remove_proc_entry("driver/ray_cs/essid", NULL);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)