patch-2.4.18 linux/drivers/net/wireless/orinoco_cs.c

Next file: linux/drivers/net/wireless/orinoco_plx.c
Previous file: linux/drivers/net/wireless/orinoco.h
Back to the patch index
Back to the overall index

diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/wireless/orinoco_cs.c linux/drivers/net/wireless/orinoco_cs.c
@@ -1,4 +1,4 @@
-/* orinoco_cs.c 0.08a	- (formerly known as dldwd_cs.c)
+/* orinoco_cs.c 0.09b	- (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/
@@ -44,11 +44,13 @@
 
 /*====================================================================*/
 
-static char version[] __initdata = "orinoco_cs.c 0.08a (David Gibson <hermes@gibson.dropbear.id.au> and others)";
+static char version[] __initdata = "orinoco_cs.c 0.09b (David Gibson <hermes@gibson.dropbear.id.au> and others)";
 
 MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
 MODULE_DESCRIPTION("Driver for PCMCIA Lucent Orinoco, Prism II based and similar wireless cards");
+#ifdef MODULE_LICENSE
 MODULE_LICENSE("Dual MPL/GPL");
+#endif
 
 /* Parameters that can be set with 'insmod' */
 
@@ -68,33 +70,31 @@
 MODULE_PARM(reset_cor, "i");
 MODULE_PARM(ignore_cis_vcc, "i");
 
-
 /* Pcmcia specific structure */
-typedef struct dldwd_card {
+struct orinoco_pccard {
 	dev_link_t link;
 	dev_node_t node;
-	int instance;
 
 	/* Common structure (fully included), see orinoco.h */
-	struct dldwd_priv  priv;
-} dldwd_card_t;
+	struct orinoco_private  priv;
+};
 
 /*
  * Function prototypes
  */
 
 /* struct net_device methods */
-static int dldwd_cs_open(struct net_device *dev);
-static int dldwd_cs_stop(struct net_device *dev);
+static int orinoco_cs_open(struct net_device *dev);
+static int orinoco_cs_stop(struct net_device *dev);
 
 /* PCMCIA gumpf */
-static void dldwd_cs_config(dev_link_t * link);
-static void dldwd_cs_release(u_long arg);
-static int dldwd_cs_event(event_t event, int priority,
+static void orinoco_cs_config(dev_link_t * link);
+static void orinoco_cs_release(u_long arg);
+static int orinoco_cs_event(event_t event, int priority,
 		       event_callback_args_t * args);
 
-static dev_link_t *dldwd_cs_attach(void);
-static void dldwd_cs_detach(dev_link_t *);
+static dev_link_t *orinoco_cs_attach(void);
+static void orinoco_cs_detach(dev_link_t *);
 
 /*
    The dev_info variable is the "key" that is used to match up this
@@ -115,7 +115,6 @@
 */
 
 static dev_link_t *dev_list; /* = NULL */
-static int num_instances; /* = 0 */
 
 /*====================================================================*/
 
@@ -127,10 +126,10 @@
 }
 
 static int
-dldwd_cs_open(struct net_device *dev)
+orinoco_cs_open(struct net_device *dev)
 {
-	dldwd_priv_t *priv = (dldwd_priv_t *)dev->priv;
-	dldwd_card_t* card = (dldwd_card_t *)priv->card;
+	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;
+	struct orinoco_pccard* card = (struct orinoco_pccard *)priv->card;
 	dev_link_t *link = &card->link;
 	int err;
 	
@@ -139,9 +138,9 @@
 	link->open++;
 	netif_device_attach(dev);
 	
-	err = dldwd_reset(priv);
+	err = orinoco_reset(priv);
 	if (err)
-		dldwd_cs_stop(dev);
+		orinoco_cs_stop(dev);
 	else
 		netif_start_queue(dev);
 
@@ -151,17 +150,17 @@
 }
 
 static int
-dldwd_cs_stop(struct net_device *dev)
+orinoco_cs_stop(struct net_device *dev)
 {
-	dldwd_priv_t *priv = (dldwd_priv_t *)dev->priv;
-	dldwd_card_t* card = (dldwd_card_t *)priv->card;
+	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;
+	struct orinoco_pccard* card = (struct orinoco_pccard *)priv->card;
 	dev_link_t *link = &card->link;
 
 	TRACE_ENTER(priv->ndev.name);
 
 	netif_stop_queue(dev);
 
-	dldwd_shutdown(priv);
+	orinoco_shutdown(priv);
 	
 	link->open--;
 
@@ -179,9 +178,9 @@
  * In fact, this seem necessary for Spectrum cards...
  */
 static int
-dldwd_cs_cor_reset(dldwd_priv_t *priv)
+orinoco_cs_cor_reset(struct orinoco_private *priv)
 {
-	dldwd_card_t* card = (dldwd_card_t *)priv->card;
+	struct orinoco_pccard* card = (struct orinoco_pccard *)priv->card;
 	dev_link_t *link = &card->link;
 	conf_reg_t reg;
 	u_int default_cor; 
@@ -189,8 +188,8 @@
 	TRACE_ENTER(priv->ndev.name);
 
 	/* Doing it if hardware is gone is guaranteed crash */
-	if(!priv->hw_ready)
-		return(0);
+	if(! (link->state & DEV_CONFIG) )
+		return -ENODEV;
 
 	/* Save original COR value */
 	reg.Function = 0;
@@ -200,7 +199,7 @@
 	CardServices(AccessConfigurationRegister, link->handle, &reg);
 	default_cor = reg.Value;
 
-	DEBUG(2, "dldwd : dldwd_cs_cor_reset() : cor=0x%X\n", default_cor);
+	DEBUG(2, "orinoco : orinoco_cs_cor_reset() : cor=0x%X\n", default_cor);
 
 	/* Soft-Reset card */
 	reg.Action = CS_WRITE;
@@ -209,6 +208,7 @@
 	CardServices(AccessConfigurationRegister, link->handle, &reg);
 
 	/* Wait until the card has acknowledged our reset */
+	/* FIXME: mdelay() is deprecated -dgibson */
 	mdelay(1);
 
 	/* Restore original COR configuration index */
@@ -216,11 +216,12 @@
 	CardServices(AccessConfigurationRegister, link->handle, &reg);
 
 	/* Wait until the card has finished restarting */
+	/* FIXME: mdelay() is deprecated -dgibson */
 	mdelay(1);
 
 	TRACE_EXIT(priv->ndev.name);
 
-	return(0);
+	return 0;
 }
 
 /* Remove zombie instances (card removed, detach pending) */
@@ -228,17 +229,17 @@
 flush_stale_links(void)
 {
 	dev_link_t *link, *next;
-	TRACE_ENTER("dldwd");
+	TRACE_ENTER("orinoco");
 	for (link = dev_list; link; link = next) {
 		next = link->next;
 		if (link->state & DEV_STALE_LINK)
-			dldwd_cs_detach(link);
+			orinoco_cs_detach(link);
 	}
-	TRACE_EXIT("dldwd");
+	TRACE_EXIT("orinoco");
 }
 
 /*======================================================================
-  dldwd_cs_attach() creates an "instance" of the driver, allocating
+  orinoco_cs_attach() creates an "instance" of the driver, allocating
   local data structures for one device.  The device is registered
   with Card Services.
   
@@ -248,16 +249,16 @@
   ======================================================================*/
 
 static dev_link_t *
-dldwd_cs_attach(void)
+orinoco_cs_attach(void)
 {
-	dldwd_card_t *card;
-	dldwd_priv_t *priv;
+	struct orinoco_pccard *card;
+	struct orinoco_private *priv;
 	dev_link_t *link;
 	struct net_device *ndev;
 	client_reg_t client_reg;
 	int ret, i;
 
-	TRACE_ENTER("dldwd");
+	TRACE_ENTER("orinoco");
 	/* A bit of cleanup */
 	flush_stale_links();
 
@@ -272,13 +273,12 @@
 	/* Link both structure together */
 	priv = &(card->priv);
 	priv->card = card;
-	card->instance = num_instances++; /* FIXME: Racy? */
 	link = &card->link;
 	ndev = &priv->ndev;
 	link->priv = priv;
 
 	/* Initialize the dev_link_t structure */
-	link->release.function = &dldwd_cs_release;
+	link->release.function = &orinoco_cs_release;
 	link->release.data = (u_long) link;
 
 	/* Interrupt setup */
@@ -302,15 +302,15 @@
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
 	/* Setup the common part */
-	if(dldwd_setup(priv) < 0) {
+	if(orinoco_setup(priv) < 0) {
 		kfree(card);
 		return NULL;
 	}
 
 	/* Overrides */
-	ndev->open = dldwd_cs_open;
-	ndev->stop = dldwd_cs_stop;
-	priv->card_reset_handler = dldwd_cs_cor_reset;
+	ndev->open = orinoco_cs_open;
+	ndev->stop = orinoco_cs_stop;
+	priv->card_reset_handler = orinoco_cs_cor_reset;
 
 	/* Register with Card Services */
 	link->next = dev_list;
@@ -321,21 +321,21 @@
 	    CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 	    CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
 	    CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-	client_reg.event_handler = &dldwd_cs_event;
+	client_reg.event_handler = &orinoco_cs_event;
 	client_reg.Version = 0x0210;
 	client_reg.event_callback_args.client_data = link;
 	ret = CardServices(RegisterClient, &link->handle, &client_reg);
 	if (ret != CS_SUCCESS) {
 		cs_error(link->handle, RegisterClient, ret);
-		dldwd_cs_detach(link);
+		orinoco_cs_detach(link);
 		link = NULL;
 		goto out;
 	}
 
  out:
-	TRACE_EXIT("dldwd");
+	TRACE_EXIT("orinoco");
 	return link;
-}				/* dldwd_cs_attach */
+}				/* orinoco_cs_attach */
 
 /*======================================================================
   This deletes a driver "instance".  The device is de-registered
@@ -345,12 +345,12 @@
   ======================================================================*/
 
 static void
-dldwd_cs_detach(dev_link_t * link)
+orinoco_cs_detach(dev_link_t * link)
 {
 	dev_link_t **linkp;
-	dldwd_priv_t *priv = link->priv;
+	struct orinoco_private *priv = link->priv;
 
-	TRACE_ENTER("dldwd");
+	TRACE_ENTER("orinoco");
 
 	/* Locate device structure */
 	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
@@ -388,14 +388,12 @@
 	}
 	kfree(priv->card);
 
-	num_instances--; /* FIXME: Racy? */
-
  out:
-	TRACE_EXIT("dldwd");
-}				/* dldwd_cs_detach */
+	TRACE_EXIT("orinoco");
+}				/* orinoco_cs_detach */
 
 /*======================================================================
-  dldwd_cs_config() is scheduled to run after a CARD_INSERTION event
+  orinoco_cs_config() is scheduled to run after a CARD_INSERTION event
   is received, to configure the PCMCIA socket, and to make the
   device available to the system.
   ======================================================================*/
@@ -407,11 +405,11 @@
 if (CardServices(fn, args) != 0) goto next_entry
 
 static void
-dldwd_cs_config(dev_link_t * link)
+orinoco_cs_config(dev_link_t * link)
 {
 	client_handle_t handle = link->handle;
-	dldwd_priv_t *priv = link->priv;
-	dldwd_card_t *card = (dldwd_card_t *)priv->card;
+	struct orinoco_private *priv = link->priv;
+	struct orinoco_pccard *card = (struct orinoco_pccard *)priv->card;
 	hermes_t *hw = &priv->hw;
 	struct net_device *ndev = &priv->ndev;
 	tuple_t tuple;
@@ -422,7 +420,7 @@
 	cistpl_cftable_entry_t dflt = { 0 };
 	cisinfo_t info;
 
-	TRACE_ENTER("dldwd");
+	TRACE_ENTER("orinoco");
 
 	CS_CHECK(ValidateCIS, handle, &info);
 
@@ -448,7 +446,7 @@
 	CS_CHECK(GetConfigurationInfo, handle, &conf);
 	link->conf.Vcc = conf.Vcc;
 
-	DEBUG(0, "dldwd_cs_config: ConfigBase = 0x%x link->conf.Vcc = %d\n", 
+	DEBUG(0, "orinoco_cs_config: ConfigBase = 0x%x link->conf.Vcc = %d\n", 
 	      link->conf.ConfigBase, link->conf.Vcc);
 
 	/*
@@ -470,7 +468,7 @@
 		CFG_CHECK(GetTupleData, handle, &tuple);
 		CFG_CHECK(ParseTuple, handle, &tuple, &parse);
 
-		DEBUG(0, "dldwd_cs_config: index = 0x%x, flags = 0x%x\n",
+		DEBUG(0, "orinoco_cs_config: index = 0x%x, flags = 0x%x\n",
 		      cfg->index, cfg->flags);
 
 		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
@@ -490,14 +488,14 @@
 		if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
 			if (conf.Vcc !=
 			    cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
-				DEBUG(2, "dldwd_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n",  conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
+				DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n",  conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
 				if(!ignore_cis_vcc)
 					goto next_entry;
 			}
 		} else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
 			if (conf.Vcc !=
 			    dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
-				DEBUG(2, "dldwd_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n",  conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
+				DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n",  conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
 				if(!ignore_cis_vcc)
 					goto next_entry;
 			}
@@ -510,7 +508,7 @@
 			link->conf.Vpp1 = link->conf.Vpp2 =
 			    dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
 		
-		DEBUG(0, "dldwd_cs_config: We seem to have configured Vcc and Vpp\n");
+		DEBUG(0, "orinoco_cs_config: We seem to have configured Vcc and Vpp\n");
 
 		/* Do we need to allocate an interrupt? */
 		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
@@ -570,7 +568,7 @@
 			for (i=0; i<4; i++)
 				link->irq.IRQInfo2 |= 1 << irq_list[i];
 		
-  		link->irq.Handler = dldwd_interrupt; 
+  		link->irq.Handler = orinoco_interrupt; 
   		link->irq.Instance = priv; 
 		
 		CS_CHECK(RequestIRQ, link->handle, &link->irq);
@@ -591,6 +589,12 @@
 	ndev->base_addr = link->io.BasePort1;
 	ndev->irq = link->irq.AssignedIRQ;
 
+	/* Now do a PCMCIA soft reset on the card, to make sure its in
+	   a sane state */
+	/* Optional because it really mess up old Lucent firmwares - Jean II */
+	if (reset_cor)
+		orinoco_cs_cor_reset(priv);
+
 	/* register_netdev will give us an ethX name */
 	ndev->name[0] = '\0';
 	/* Tell the stack we exist */
@@ -618,7 +622,7 @@
 	printk("\n");
 
 	/* And give us the proc nodes for debugging */
-	if (dldwd_proc_dev_init(priv) != 0) {
+	if (orinoco_proc_dev_init(priv) != 0) {
 		printk(KERN_ERR "orinoco_cs: Failed to create /proc node for %s\n",
 		       ndev->name);
 		goto failed;
@@ -627,12 +631,9 @@
 	/* 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);
+	if (reset_cor)
+		orinoco_cs_cor_reset(priv);
 
 	/*
 	   At this point, the dev_node_t structure(s) need to be
@@ -642,29 +643,29 @@
 	link->dev = &card->node;
 	link->state &= ~DEV_CONFIG_PENDING;
 
-	TRACE_EXIT("dldwd");
+	TRACE_EXIT("orinoco");
 
 	return;
 
  cs_failed:
 	cs_error(link->handle, last_fn, last_ret);
  failed:
-	dldwd_cs_release((u_long) link);
+	orinoco_cs_release((u_long) link);
 
-	TRACE_EXIT("dldwd");
-}				/* dldwd_cs_config */
+	TRACE_EXIT("orinoco");
+}				/* orinoco_cs_config */
 
 /*======================================================================
-  After a card is removed, dldwd_cs_release() will unregister the
+  After a card is removed, orinoco_cs_release() will unregister the
   device, and release the PCMCIA configuration.  If the device is
   still open, this will be postponed until it is closed.
   ======================================================================*/
 
 static void
-dldwd_cs_release(u_long arg)
+orinoco_cs_release(u_long arg)
 {
 	dev_link_t *link = (dev_link_t *) arg;
-	dldwd_priv_t *priv = link->priv;
+	struct orinoco_private *priv = link->priv;
 
 	TRACE_ENTER(link->dev->dev_name);
 
@@ -681,7 +682,7 @@
 	}
 
 	/* Unregister proc entry */
-	dldwd_proc_dev_cleanup(priv);
+	orinoco_proc_dev_cleanup(priv);
 
 	/* Don't bother checking to see if these succeed or not */
 	CardServices(ReleaseConfiguration, link->handle);
@@ -692,7 +693,7 @@
 	link->state &= ~DEV_CONFIG;
 
 	TRACE_EXIT(link->dev->dev_name);
-}				/* dldwd_cs_release */
+}				/* orinoco_cs_release */
 
 /*======================================================================
   The card status event handler.  Mostly, this schedules other
@@ -705,39 +706,37 @@
   ======================================================================*/
 
 static int
-dldwd_cs_event(event_t event, int priority,
+orinoco_cs_event(event_t event, int priority,
 		       event_callback_args_t * args)
 {
 	dev_link_t *link = args->client_data;
-	dldwd_priv_t *priv = (dldwd_priv_t *)link->priv;
+	struct orinoco_private *priv = (struct orinoco_private *)link->priv;
 	struct net_device *dev = &priv->ndev;
 
-	TRACE_ENTER("dldwd");
+	TRACE_ENTER("orinoco");
 
 	switch (event) {
 	case CS_EVENT_CARD_REMOVAL:
-		/* FIXME: Erg.. this whole hw_ready thing looks racy
-		   to me.  this may not be fixable without changin the
-		   PCMCIA subsystem, though */
-		priv->hw_ready = 0;
-		dldwd_shutdown(priv);
 		link->state &= ~DEV_PRESENT;
 		if (link->state & DEV_CONFIG) {
 			netif_stop_queue(dev);
+		}
+		orinoco_shutdown(priv);
+		if (link->state & DEV_CONFIG) {
 			netif_device_detach(dev);
 			mod_timer(&link->release, jiffies + HZ / 20);
 		}
 		break;
 	case CS_EVENT_CARD_INSERTION:
 		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		dldwd_cs_config(link);
+		orinoco_cs_config(link);
 		break;
 	case CS_EVENT_PM_SUSPEND:
 
 		link->state |= DEV_SUSPEND;
 		/* Fall through... */
 	case CS_EVENT_RESET_PHYSICAL:
-		dldwd_shutdown(priv);
+		orinoco_shutdown(priv);
 		/* Mark the device as stopped, to block IO until later */
 
 		if (link->state & DEV_CONFIG) {
@@ -757,13 +756,13 @@
 				     &link->conf);
 
 			if (link->open) {
-				if (dldwd_reset(priv) == 0) {
+				if (orinoco_reset(priv) == 0) {
 					netif_device_attach(dev);
 					netif_start_queue(dev);
 				} else {
 					printk(KERN_ERR "%s: Error resetting device on PCMCIA event\n",
 					       dev->name);
-					dldwd_cs_stop(dev);
+					orinoco_cs_stop(dev);
 				}
 			}
 		}
@@ -774,17 +773,17 @@
 		break;
 	}
 
-	TRACE_EXIT("dldwd");
+	TRACE_EXIT("orinoco");
 
 	return 0;
-}				/* dldwd_cs_event */
+}				/* orinoco_cs_event */
 
 static int __init
-init_dldwd_cs(void)
+init_orinoco_cs(void)
 {
 	servinfo_t serv;
 
-	TRACE_ENTER("dldwd");
+	TRACE_ENTER("orinoco");
 
 	printk(KERN_DEBUG "%s\n", version);
 
@@ -795,17 +794,17 @@
 		return -1;
 	}
 
-	register_pccard_driver(&dev_info, &dldwd_cs_attach, &dldwd_cs_detach);
+	register_pccard_driver(&dev_info, &orinoco_cs_attach, &orinoco_cs_detach);
 
 
-	TRACE_EXIT("dldwd");
+	TRACE_EXIT("orinoco");
 	return 0;
 }
 
 static void __exit
-exit_dldwd_cs(void)
+exit_orinoco_cs(void)
 {
-	TRACE_ENTER("dldwd");
+	TRACE_ENTER("orinoco");
 
 	unregister_pccard_driver(&dev_info);
 
@@ -814,12 +813,12 @@
 	while (dev_list != NULL) {
 		del_timer(&dev_list->release);
 		if (dev_list->state & DEV_CONFIG)
-			dldwd_cs_release((u_long) dev_list);
-		dldwd_cs_detach(dev_list);
+			orinoco_cs_release((u_long) dev_list);
+		orinoco_cs_detach(dev_list);
 	}
 
-	TRACE_EXIT("dldwd");
+	TRACE_EXIT("orinoco");
 }
 
-module_init(init_dldwd_cs);
-module_exit(exit_dldwd_cs);
+module_init(init_orinoco_cs);
+module_exit(exit_orinoco_cs);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)