patch-2.4.19 linux-2.4.19/drivers/net/wireless/orinoco_cs.c
Next file: linux-2.4.19/drivers/net/wireless/orinoco_pci.c
Previous file: linux-2.4.19/drivers/net/wireless/orinoco.h
Back to the patch index
Back to the overall index
- Lines: 325
- Date:
Fri Aug 2 17:39:44 2002
- Orig file:
linux-2.4.18/drivers/net/wireless/orinoco_cs.c
- Orig date:
Mon Feb 25 11:38:03 2002
diff -urN linux-2.4.18/drivers/net/wireless/orinoco_cs.c linux-2.4.19/drivers/net/wireless/orinoco_cs.c
@@ -1,4 +1,4 @@
-/* orinoco_cs.c 0.09b - (formerly known as dldwd_cs.c)
+/* orinoco_cs.c 0.11b - (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/
@@ -11,6 +11,9 @@
*/
#include <linux/config.h>
+#ifdef __IN_PCMCIA_PACKAGE__
+#include <pcmcia/k_compat.h>
+#endif /* __IN_PCMCIA_PACKAGE__ */
#include <linux/module.h>
#include <linux/kernel.h>
@@ -44,7 +47,7 @@
/*====================================================================*/
-static char version[] __initdata = "orinoco_cs.c 0.09b (David Gibson <hermes@gibson.dropbear.id.au> and others)";
+static char version[] __initdata = "orinoco_cs.c 0.11b (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");
@@ -60,7 +63,7 @@
/* Newer, simpler way of listing specific interrupts */
static int irq_list[4] = { -1 };
/* Do a Pcmcia soft reset (may help some cards) */
-static int reset_cor = 0;
+static int reset_cor = -1;
/* Some D-Link cards have buggy CIS. They do work at 5v properly, but
* don't have any CIS entry for it. This workaround it... */
static int ignore_cis_vcc; /* = 0 */
@@ -74,9 +77,6 @@
struct orinoco_pccard {
dev_link_t link;
dev_node_t node;
-
- /* Common structure (fully included), see orinoco.h */
- struct orinoco_private priv;
};
/*
@@ -101,7 +101,6 @@
device driver with appropriate cards, through the card configuration
database.
*/
-
static dev_info_t dev_info = "orinoco_cs";
/*
@@ -133,7 +132,7 @@
dev_link_t *link = &card->link;
int err;
- TRACE_ENTER(priv->ndev.name);
+ TRACE_ENTER(dev->name);
link->open++;
netif_device_attach(dev);
@@ -144,7 +143,7 @@
else
netif_start_queue(dev);
- TRACE_EXIT(priv->ndev.name);
+ TRACE_EXIT(dev->name);
return err;
}
@@ -156,7 +155,7 @@
struct orinoco_pccard* card = (struct orinoco_pccard *)priv->card;
dev_link_t *link = &card->link;
- TRACE_ENTER(priv->ndev.name);
+ TRACE_ENTER(dev->name);
netif_stop_queue(dev);
@@ -167,7 +166,7 @@
if (link->state & DEV_STALE_CONFIG)
mod_timer(&link->release, jiffies + HZ/20);
- TRACE_EXIT(priv->ndev.name);
+ TRACE_EXIT(dev->name);
return 0;
}
@@ -185,7 +184,7 @@
conf_reg_t reg;
u_int default_cor;
- TRACE_ENTER(priv->ndev.name);
+ TRACE_ENTER(priv->ndev->name);
/* Doing it if hardware is gone is guaranteed crash */
if(! (link->state & DEV_CONFIG) )
@@ -211,7 +210,23 @@
/* FIXME: mdelay() is deprecated -dgibson */
mdelay(1);
+#if 0 /* This seems to help on Symbol cards, but we're not sure why,
+ and we don't know what it will do to other cards */
+ reg.Action = CS_READ;
+ reg.Offset = CISREG_CCSR;
+ CardServices(AccessConfigurationRegister, link->handle, ®);
+
+ /* Write 7 (RUN) to CCSR, but preserve the original bit 4 */
+ reg.Action = CS_WRITE;
+ reg.Offset = CISREG_CCSR;
+ reg.Value = 7 | (reg.Value & 0x10);
+ CardServices(AccessConfigurationRegister, link->handle, ®);
+ mdelay(1);
+#endif
+
/* Restore original COR configuration index */
+ reg.Action = CS_WRITE;
+ reg.Offset = CISREG_COR;
reg.Value = (default_cor & ~COR_SOFT_RESET);
CardServices(AccessConfigurationRegister, link->handle, ®);
@@ -219,11 +234,32 @@
/* FIXME: mdelay() is deprecated -dgibson */
mdelay(1);
- TRACE_EXIT(priv->ndev.name);
+ TRACE_EXIT(priv->ndev->name);
return 0;
}
+static int
+orinoco_cs_hard_reset(struct orinoco_private *priv)
+{
+ if (! priv->broken_cor_reset)
+ return orinoco_cs_cor_reset(priv);
+ else
+ return 0;
+
+#if 0 /* We'd like to use ResetCard, but we can't for the moment - it sleeps */
+ /* Not sure what the second parameter is supposed to be - the
+ PCMCIA code doesn't actually use it */
+ if (in_interrupt()) {
+ printk("Not resetting card, in_interrupt() is true\n");
+ return 0;
+ } else {
+ printk("Doing ResetCard\n");
+ return CardServices(ResetCard, link->handle, NULL);
+ }
+#endif
+}
+
/* Remove zombie instances (card removed, detach pending) */
static void
flush_stale_links(void)
@@ -251,10 +287,10 @@
static dev_link_t *
orinoco_cs_attach(void)
{
- struct orinoco_pccard *card;
+ struct net_device *dev;
struct orinoco_private *priv;
+ struct orinoco_pccard *card;
dev_link_t *link;
- struct net_device *ndev;
client_reg_t client_reg;
int ret, i;
@@ -262,19 +298,18 @@
/* A bit of cleanup */
flush_stale_links();
- /* Allocate space for private device-specific data */
- card = kmalloc(sizeof(*card), GFP_KERNEL);
- if (! card) {
- link = NULL;
- goto out;
- }
- memset(card, 0, sizeof(*card));
+ dev = alloc_orinocodev(sizeof(*card));
+ if (! dev)
+ return NULL;
+ priv = dev->priv;
+ card = priv->card;
+ /* Overrides */
+ dev->open = orinoco_cs_open;
+ dev->stop = orinoco_cs_stop;
+ priv->hard_reset = orinoco_cs_hard_reset;
- /* Link both structure together */
- priv = &(card->priv);
- priv->card = card;
+ /* Link both structures together */
link = &card->link;
- ndev = &priv->ndev;
link->priv = priv;
/* Initialize the dev_link_t structure */
@@ -301,17 +336,6 @@
link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY_AND_IO;
- /* Setup the common part */
- if(orinoco_setup(priv) < 0) {
- kfree(card);
- return NULL;
- }
-
- /* Overrides */
- 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;
dev_list = link;
@@ -349,6 +373,7 @@
{
dev_link_t **linkp;
struct orinoco_private *priv = link->priv;
+ struct net_device *dev = priv->ndev;
TRACE_ENTER("orinoco");
@@ -383,10 +408,10 @@
DEBUG(0, "orinoco_cs: detach: link=%p link->dev=%p\n", link, link->dev);
if (link->dev) {
DEBUG(0, "orinoco_cs: About to unregister net device %p\n",
- &priv->ndev);
- unregister_netdev(&priv->ndev);
+ priv->ndev);
+ unregister_netdev(dev);
}
- kfree(priv->card);
+ kfree(dev);
out:
TRACE_EXIT("orinoco");
@@ -411,7 +436,7 @@
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;
+ struct net_device *ndev = priv->ndev;
tuple_t tuple;
cisparse_t parse;
int last_fn, last_ret;
@@ -486,15 +511,13 @@
/* Use power settings for Vcc and Vpp if present */
/* Note that the CIS values need to be rescaled */
if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
- if (conf.Vcc !=
- cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
+ if (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)
+ 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) {
+ if (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;
@@ -549,7 +572,12 @@
next_entry:
if (link->io.NumPorts1)
CardServices(ReleaseIO, link->handle, &link->io);
- CS_CHECK(GetNextTuple, handle, &tuple);
+ last_ret = CardServices(GetNextTuple, handle, &tuple);
+ if (last_ret == CS_NO_MORE_ITEMS) {
+ printk(KERN_ERR "GetNextTuple(). No matching CIS configuration, "
+ "maybe you need the ignore_cis_vcc=1 parameter.\n");
+ goto cs_failed;
+ }
}
/*
@@ -577,7 +605,8 @@
/* We initialize the hermes structure before completing PCMCIA
configuration just in case the interrupt handler gets
called. */
- hermes_struct_init(hw, link->io.BasePort1);
+ hermes_struct_init(hw, link->io.BasePort1,
+ HERMES_IO, HERMES_16BIT_REGSPACING);
/*
This actually configures the PCMCIA socket -- setting up
@@ -589,12 +618,6 @@
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 */
@@ -631,9 +654,9 @@
/* Note to myself : this replace MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT */
SET_MODULE_OWNER(ndev);
- /* Do a Pcmcia soft reset of the card (optional) */
- if (reset_cor)
- orinoco_cs_cor_reset(priv);
+ /* Let reset_cor parameter override determine_firmware()'s guess */
+ if (reset_cor != -1)
+ priv->broken_cor_reset = ! reset_cor;
/*
At this point, the dev_node_t structure(s) need to be
@@ -711,7 +734,7 @@
{
dev_link_t *link = args->client_data;
struct orinoco_private *priv = (struct orinoco_private *)link->priv;
- struct net_device *dev = &priv->ndev;
+ struct net_device *dev = priv->ndev;
TRACE_ENTER("orinoco");
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)