patch-2.4.6 linux/drivers/net/wireless/orinoco_cs.c
Next file: linux/drivers/net/yellowfin.c
Previous file: linux/drivers/net/wireless/orinoco.h
Back to the patch index
Back to the overall index
- Lines: 208
- Date:
Mon Jul 2 14:03:04 2001
- Orig file:
v2.4.5/linux/drivers/net/wireless/orinoco_cs.c
- Orig date:
Mon May 7 19:42:14 2001
diff -u --recursive --new-file v2.4.5/linux/drivers/net/wireless/orinoco_cs.c linux/drivers/net/wireless/orinoco_cs.c
@@ -1,4 +1,4 @@
-/* orinoco_cs.c 0.05 - (formerly known as dldwd_cs.c)
+/* orinoco_cs.c 0.06 - (formerly known as dldwd_cs.c)
*
* A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
* as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
@@ -50,7 +50,8 @@
struct dldwd_priv priv;
} dldwd_card_t;
-static char *version = "orinoco_cs.c 0.05 (David Gibson <hermes@gibson.dropbear.id.au> and others)";
+static char version[] __initdata =
+"orinoco_cs.c 0.06 (David Gibson <hermes@gibson.dropbear.id.au> and others)";
/*====================================================================*/
@@ -107,8 +108,8 @@
device numbers are used to derive the corresponding array index.
*/
-static dev_link_t *dev_list = NULL;
-static int num_instances = 0;
+static dev_link_t *dev_list;
+static int num_instances;
/*====================================================================*/
@@ -166,6 +167,70 @@
return 0;
}
+/*
+ * Do a soft reset of the Pcmcia card using the Configuration Option Register
+ * Can't do any harm, and actually may do some good on some cards...
+ * In fact, this seem necessary for Spectrum cards...
+ */
+static int
+dldwd_cs_cor_reset(dldwd_priv_t *priv)
+{
+ dldwd_card_t* card = (dldwd_card_t *)priv->card;
+ dev_link_t *link = &card->link;
+ conf_reg_t reg;
+ u_long default_cor;
+
+ TRACE_ENTER(priv->ndev.name);
+
+ /* Doing it if hardware is gone is guaranteed crash */
+ if(!priv->hw_ready)
+ return(0);
+
+ /* Save original COR value */
+ reg.Function = 0;
+ reg.Action = CS_READ;
+ reg.Offset = CISREG_COR;
+ reg.Value = 0;
+ CardServices(AccessConfigurationRegister, link->handle, ®);
+ default_cor = reg.Value;
+
+ DEBUG(2, "dldwd : dldwd_cs_cor_reset() : cor=0x%lX\n", default_cor);
+
+ /* Soft-Reset card */
+ reg.Action = CS_WRITE;
+ reg.Offset = CISREG_COR;
+ reg.Value = (default_cor | COR_SOFT_RESET);
+ CardServices(AccessConfigurationRegister, link->handle, ®);
+
+ /* Wait until the card has acknowledged our reset */
+ mdelay(1);
+
+ /* Restore original COR configuration index */
+ reg.Value = (default_cor & ~COR_SOFT_RESET);
+ CardServices(AccessConfigurationRegister, link->handle, ®);
+
+ /* Wait until the card has finished restarting */
+ mdelay(1);
+
+ TRACE_EXIT(priv->ndev.name);
+
+ return(0);
+}
+
+/* Remove zombie instances (card removed, detach pending) */
+static void
+flush_stale_links(void)
+{
+ dev_link_t *link, *next;
+ TRACE_ENTER("dldwd");
+ for (link = dev_list; link; link = next) {
+ next = link->next;
+ if (link->state & DEV_STALE_LINK)
+ dldwd_cs_detach(link);
+ }
+ TRACE_EXIT("dldwd");
+}
+
/*======================================================================
dldwd_cs_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
@@ -187,6 +252,8 @@
int ret, i;
TRACE_ENTER("dldwd");
+ /* A bit of cleanup */
+ flush_stale_links();
/* Allocate space for private device-specific data */
card = kmalloc(sizeof(*card), GFP_KERNEL);
@@ -237,6 +304,7 @@
/* Overrides */
ndev->open = dldwd_cs_open;
ndev->stop = dldwd_cs_stop;
+ priv->card_reset_handler = dldwd_cs_cor_reset;
/* Register with Card Services */
link->next = dev_list;
@@ -320,45 +388,6 @@
TRACE_EXIT("dldwd");
} /* dldwd_cs_detach */
-/*
- * Do a soft reset of the Pcmcia card using the Configuration Option Register
- * Can't do any harm, and actually may do some good on some cards...
- */
-static int
-dldwd_cs_cor_reset(dev_link_t *link)
-{
- conf_reg_t reg;
- u_long default_cor;
-
- /* Save original COR value */
- reg.Function = 0;
- reg.Action = CS_READ;
- reg.Offset = CISREG_COR;
- reg.Value = 0;
- CardServices(AccessConfigurationRegister, link->handle, ®);
- default_cor = reg.Value;
-
- DEBUG(2, "dldwd : dldwd_cs_cor_reset() : cor=0x%lX\n", default_cor);
-
- /* Soft-Reset card */
- reg.Action = CS_WRITE;
- reg.Offset = CISREG_COR;
- reg.Value = (default_cor | COR_SOFT_RESET);
- CardServices(AccessConfigurationRegister, link->handle, ®);
-
- /* Wait until the card has acknowledged our reset */
- mdelay(1);
-
- /* Restore original COR configuration index */
- reg.Value = (default_cor & COR_CONFIG_MASK);
- CardServices(AccessConfigurationRegister, link->handle, ®);
-
- /* Wait until the card has finished restarting */
- mdelay(1);
-
- return(0);
-}
-
/*======================================================================
dldwd_cs_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
@@ -556,10 +585,6 @@
ndev->base_addr = link->io.BasePort1;
ndev->irq = link->irq.AssignedIRQ;
- /* Do a Pcmcia soft reset of the card (optional) */
- if(reset_cor)
- dldwd_cs_cor_reset(link);
-
/* register_netdev will give us an ethX name */
ndev->name[0] = '\0';
/* Tell the stack we exist */
@@ -586,9 +611,6 @@
link->io.BasePort2 + link->io.NumPorts2 - 1);
printk("\n");
- /* Allow /proc & ioctls to act */
- priv->hw_ready = 1;
-
/* And give us the proc nodes for debugging */
if (dldwd_proc_dev_init(priv) != 0) {
printk(KERN_ERR "orinoco_cs: Failed to create /proc node for %s\n",
@@ -599,6 +621,13 @@
/* Note to myself : this replace MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT */
SET_MODULE_OWNER(ndev);
+ /* Allow cor_reset, /proc & ioctls to act */
+ priv->hw_ready = 1;
+
+ /* Do a Pcmcia soft reset of the card (optional) */
+ if(reset_cor)
+ dldwd_cs_cor_reset(priv);
+
/*
At this point, the dev_node_t structure(s) need to be
initialized and arranged in a linked list at link->dev.
@@ -748,9 +777,8 @@
TRACE_ENTER("dldwd");
- printk(KERN_INFO "dldwd: David's Less Dodgy WaveLAN/IEEE Driver\n");
-
- DEBUG(0, "%s\n", version);
+ printk(KERN_INFO "dldwd: David's Less Dodgy WaveLAN/IEEE Driver\n"
+ KERN_INFO "%s\n", version);
CardServices(GetCardServicesInfo, &serv);
if (serv.Revision != CS_RELEASE_CODE) {
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)