* [PATCH 2/9] pcmcia: use pre-determined values
[not found] <1255907255-28297-1-git-send-email-linux@dominikbrodowski.net>
@ 2009-10-18 23:07 ` Dominik Brodowski
2009-10-18 23:07 ` [PATCH 3/9] pcmcia: use pcmcia_loop_config in misc pcmcia drivers Dominik Brodowski
2009-10-27 19:28 ` [PATCH 2/9] pcmcia: use pre-determined values John W. Linville
0 siblings, 2 replies; 6+ messages in thread
From: Dominik Brodowski @ 2009-10-18 23:07 UTC (permalink / raw)
To: linux-pcmcia
Cc: Dominik Brodowski, David S. Miller, John W. Linville, netdev,
linux-wireless
A few PCMCIA network drivers can make use of values provided by the pcmcia
core, instead of tedious, independent CIS parsing.
xirc32ps_cs.c: manf_id
hostap_cs.c: multifunction count
b43/pcmcia.c: ConfigBase address and "Present"
smc91c92_cs.c: By default, mhz_setup() can use VERS_1 as it is stored
in struct pcmcia_device. Only some cards require workarounds, such as
reading out VERS_1 twice.
CC: David S. Miller <davem@davemloft.net>
CC: John W. Linville <linville@tuxdriver.com>
CC: netdev@vger.kernel.org
CC: linux-wireless@vger.kernel.org
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
---
drivers/net/pcmcia/smc91c92_cs.c | 11 +++++++++--
drivers/net/pcmcia/xirc2ps_cs.c | 5 ++---
drivers/net/wireless/b43/pcmcia.c | 20 --------------------
drivers/net/wireless/hostap/hostap_cs.c | 21 +--------------------
4 files changed, 12 insertions(+), 45 deletions(-)
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 7bde2cd..af03759 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -545,6 +545,14 @@ static int mhz_setup(struct pcmcia_device *link)
u_char *buf, *station_addr;
int rc;
+ /* Read the station address from the CIS. It is stored as the last
+ (fourth) string in the Version 1 Version/ID tuple. */
+ if ((link->prod_id[3]) &&
+ (cvt_ascii_address(dev, link->prod_id[3]) == 0))
+ return 0;
+
+ /* Workarounds for broken cards start here. */
+
cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
if (!cfg_mem)
return -1;
@@ -557,8 +565,7 @@ static int mhz_setup(struct pcmcia_device *link)
tuple->TupleData = (cisdata_t *)buf;
tuple->TupleDataMax = 255;
- /* Read the station address from the CIS. It is stored as the last
- (fourth) string in the Version 1 Version/ID tuple. */
+ /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
tuple->DesiredTuple = CISTPL_VERS_1;
if (first_tuple(link, tuple, parse) != 0) {
rc = -1;
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index cf84231..3dd6ba6 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -792,13 +792,12 @@ xirc2ps_config(struct pcmcia_device * link)
tuple.TupleOffset = 0;
/* Is this a valid card */
- tuple.DesiredTuple = CISTPL_MANFID;
- if ((err=first_tuple(link, &tuple, &parse))) {
+ if (link->has_manf_id == 0) {
printk(KNOT_XIRC "manfid not found in CIS\n");
goto failure;
}
- switch(parse.manfid.manf) {
+ switch (link->manf_id) {
case MANFID_XIRCOM:
local->manf_str = "Xircom";
break;
diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c
index 6c3a749..cd14b7e 100644
--- a/drivers/net/wireless/b43/pcmcia.c
+++ b/drivers/net/wireless/b43/pcmcia.c
@@ -65,35 +65,15 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
struct ssb_bus *ssb;
win_req_t win;
memreq_t mem;
- tuple_t tuple;
- cisparse_t parse;
int err = -ENOMEM;
int res = 0;
- unsigned char buf[64];
ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
if (!ssb)
goto out_error;
err = -ENODEV;
- tuple.DesiredTuple = CISTPL_CONFIG;
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
- res = pcmcia_get_first_tuple(dev, &tuple);
- if (res != 0)
- goto err_kfree_ssb;
- res = pcmcia_get_tuple_data(dev, &tuple);
- if (res != 0)
- goto err_kfree_ssb;
- res = pcmcia_parse_tuple(&tuple, &parse);
- if (res != 0)
- goto err_kfree_ssb;
-
- dev->conf.ConfigBase = parse.config.base;
- dev->conf.Present = parse.config.rmask[0];
dev->conf.Attributes = CONF_ENABLE_IRQ;
dev->conf.IntType = INT_MEMORY_AND_IO;
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index ad8eab4..31b60dd 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -274,9 +274,6 @@ static int sandisk_enable_wireless(struct net_device *dev)
conf_reg_t reg;
struct hostap_interface *iface = netdev_priv(dev);
local_info_t *local = iface->local;
- tuple_t tuple;
- cisparse_t *parse = NULL;
- u_char buf[64];
struct hostap_cs_priv *hw_priv = local->hw_priv;
if (hw_priv->link->io.NumPorts1 < 0x42) {
@@ -285,28 +282,13 @@ static int sandisk_enable_wireless(struct net_device *dev)
goto done;
}
- parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
- if (parse == NULL) {
- ret = -ENOMEM;
- goto done;
- }
-
- tuple.Attributes = TUPLE_RETURN_COMMON;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
-
if (hw_priv->link->manf_id != 0xd601 || hw_priv->link->card_id != 0x0101) {
/* No SanDisk manfid found */
ret = -ENODEV;
goto done;
}
- tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
- if (pcmcia_get_first_tuple(hw_priv->link, &tuple) ||
- pcmcia_get_tuple_data(hw_priv->link, &tuple) ||
- pcmcia_parse_tuple(&tuple, parse) ||
- parse->longlink_mfc.nfn < 2) {
+ if (hw_priv->link->socket->functions < 2) {
/* No multi-function links found */
ret = -ENODEV;
goto done;
@@ -354,7 +336,6 @@ static int sandisk_enable_wireless(struct net_device *dev)
udelay(10);
done:
- kfree(parse);
return ret;
}
--
1.6.0.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/9] pcmcia: use pcmcia_loop_config in misc pcmcia drivers
2009-10-18 23:07 ` [PATCH 2/9] pcmcia: use pre-determined values Dominik Brodowski
@ 2009-10-18 23:07 ` Dominik Brodowski
[not found] ` <1255907255-28297-4-git-send-email-linux@dominikbrodowski.net>
` (2 more replies)
2009-10-27 19:28 ` [PATCH 2/9] pcmcia: use pre-determined values John W. Linville
1 sibling, 3 replies; 6+ messages in thread
From: Dominik Brodowski @ 2009-10-18 23:07 UTC (permalink / raw)
To: linux-pcmcia
Cc: Dominik Brodowski, David S. Miller, John W. Linville, Jiri Kosina,
David Sterba, netdev, linux-wireless
Use pcmcia_loop_config() in a few drivers missed during the first
round. On fmvj18x_cs.c it -- strangely -- only requries us to set
conf.ConfigIndex, which is done by the core, so include an empty
loop function which returns 0 unconditionally.
CC: David S. Miller <davem@davemloft.net>
CC: John W. Linville <linville@tuxdriver.com>
CC: Jiri Kosina <jkosina@suse.cz>
CC: David Sterba <dsterba@suse.cz>
CC: netdev@vger.kernel.org
CC: linux-wireless@vger.kernel.org
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
---
drivers/char/pcmcia/ipwireless/main.c | 103 +++++++--------------------------
drivers/char/pcmcia/synclink_cs.c | 64 ++++++++-------------
drivers/net/pcmcia/fmvj18x_cs.c | 22 +++++--
drivers/net/wireless/libertas/if_cs.c | 67 +++++++++-------------
4 files changed, 88 insertions(+), 168 deletions(-)
diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c
index 5216fce..263a18f 100644
--- a/drivers/char/pcmcia/ipwireless/main.c
+++ b/drivers/char/pcmcia/ipwireless/main.c
@@ -79,14 +79,32 @@ static void signalled_reboot_callback(void *callback_data)
schedule_work(&ipw->work_reboot);
}
+static int ipwireless_ioprobe(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ p_dev->io.BasePort1 = cfg->io.win[0].base;
+ p_dev->io.NumPorts1 = cfg->io.win[0].len;
+ p_dev->io.IOAddrLines = 16;
+
+ p_dev->irq.IRQInfo1 = cfg->irq.IRQInfo1;
+
+ /* 0x40 causes it to generate level mode interrupts. */
+ /* 0x04 enables IREQ pin. */
+ p_dev->conf.ConfigIndex = cfg->index | 0x44;
+ return pcmcia_request_io(p_dev, &p_dev->io);
+}
+
static int config_ipwireless(struct ipw_dev *ipw)
{
struct pcmcia_device *link = ipw->link;
- int ret;
+ int ret = 0;
tuple_t tuple;
unsigned short buf[64];
cisparse_t parse;
- unsigned short cor_value;
memreq_t memreq_attr_memory;
memreq_t memreq_common_memory;
@@ -97,103 +115,26 @@ static int config_ipwireless(struct ipw_dev *ipw)
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
- tuple.DesiredTuple = RETURN_FIRST_TUPLE;
-
- ret = pcmcia_get_first_tuple(link, &tuple);
-
- while (ret == 0) {
- ret = pcmcia_get_tuple_data(link, &tuple);
-
- if (ret != 0) {
- cs_error(link, GetTupleData, ret);
- goto exit0;
- }
- ret = pcmcia_get_next_tuple(link, &tuple);
- }
-
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-
- ret = pcmcia_get_first_tuple(link, &tuple);
-
- if (ret != 0) {
- cs_error(link, GetFirstTuple, ret);
- goto exit0;
- }
-
- ret = pcmcia_get_tuple_data(link, &tuple);
-
- if (ret != 0) {
- cs_error(link, GetTupleData, ret);
- goto exit0;
- }
-
- ret = pcmcia_parse_tuple(&tuple, &parse);
-
- if (ret != 0) {
- cs_error(link, ParseTuple, ret);
- goto exit0;
- }
-
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
- link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
- link->io.IOAddrLines = 16;
-
- link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1;
-
- /* 0x40 causes it to generate level mode interrupts. */
- /* 0x04 enables IREQ pin. */
- cor_value = parse.cftable_entry.index | 0x44;
- link->conf.ConfigIndex = cor_value;
-
- /* IRQ and I/O settings */
- tuple.DesiredTuple = CISTPL_CONFIG;
-
- ret = pcmcia_get_first_tuple(link, &tuple);
-
+ ret = pcmcia_loop_config(link, ipwireless_ioprobe, NULL);
if (ret != 0) {
- cs_error(link, GetFirstTuple, ret);
- goto exit0;
- }
-
- ret = pcmcia_get_tuple_data(link, &tuple);
-
- if (ret != 0) {
- cs_error(link, GetTupleData, ret);
+ cs_error(link, RequestIO, ret);
goto exit0;
}
- ret = pcmcia_parse_tuple(&tuple, &parse);
-
- if (ret != 0) {
- cs_error(link, GetTupleData, ret);
- goto exit0;
- }
link->conf.Attributes = CONF_ENABLE_IRQ;
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
link->conf.IntType = INT_MEMORY_AND_IO;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
link->irq.Handler = ipwireless_interrupt;
link->irq.Instance = ipw->hardware;
- ret = pcmcia_request_io(link, &link->io);
-
- if (ret != 0) {
- cs_error(link, RequestIO, ret);
- goto exit0;
- }
-
request_region(link->io.BasePort1, link->io.NumPorts1,
IPWIRELESS_PCCARD_NAME);
/* memory settings */
-
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
ret = pcmcia_get_first_tuple(link, &tuple);
-
if (ret != 0) {
cs_error(link, GetFirstTuple, ret);
goto exit1;
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index caf6e4d..429b731 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -575,55 +575,39 @@ static int mgslpc_probe(struct pcmcia_device *link)
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+static int mgslpc_ioprobe(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ if (cfg->io.nwin > 0) {
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(cfg->io.flags & CISTPL_IO_8BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(cfg->io.flags & CISTPL_IO_16BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
+ p_dev->io.BasePort1 = cfg->io.win[0].base;
+ p_dev->io.NumPorts1 = cfg->io.win[0].len;
+ return pcmcia_request_io(p_dev, &p_dev->io);
+ }
+ return -ENODEV;
+}
+
static int mgslpc_config(struct pcmcia_device *link)
{
MGSLPC_INFO *info = link->priv;
- tuple_t tuple;
- cisparse_t parse;
- int last_fn, last_ret;
- u_char buf[64];
- cistpl_cftable_entry_t dflt = { 0 };
- cistpl_cftable_entry_t *cfg;
+ int last_fn = RequestIO;
+ int last_ret;
if (debug_level >= DEBUG_LEVEL_INFO)
printk("mgslpc_config(0x%p)\n", link);
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
-
- /* get CIS configuration entry */
-
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-
- cfg = &(parse.cftable_entry);
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse));
-
- if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
- if (cfg->index == 0)
+ last_ret = pcmcia_loop_config(link, mgslpc_ioprobe, NULL);
+ if (last_ret != 0)
goto cs_failed;
- link->conf.ConfigIndex = cfg->index;
- link->conf.Attributes |= CONF_ENABLE_IRQ;
-
- /* IO window settings */
- link->io.NumPorts1 = 0;
- if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
- cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- if (!(io->flags & CISTPL_IO_8BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
- if (!(io->flags & CISTPL_IO_16BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
- link->io.BasePort1 = io->win[0].base;
- link->io.NumPorts1 = io->win[0].len;
- CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
- }
-
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 8;
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 7e01fbd..c7a2bbf 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -341,14 +341,23 @@ static int ungermann_try_io_port(struct pcmcia_device *link)
return ret; /* RequestIO failed */
}
+static int fmvj18x_ioprobe(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ return 0; /* strange, but that's what the code did already before... */
+}
+
+
static int fmvj18x_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
local_info_t *lp = netdev_priv(dev);
tuple_t tuple;
- cisparse_t parse;
u_short buf[32];
- int i, last_fn = 0, last_ret = 0, ret;
+ int i, last_fn = RequestIO, last_ret = 0, ret;
unsigned int ioaddr;
cardtype_t cardtype;
char *card_name = "unknown";
@@ -362,12 +371,11 @@ static int fmvj18x_config(struct pcmcia_device *link)
tuple.DesiredTuple = CISTPL_FUNCE;
tuple.TupleOffset = 0;
if (pcmcia_get_first_tuple(link, &tuple) == 0) {
+ last_ret = pcmcia_loop_config(link, fmvj18x_ioprobe, NULL);
+ if (last_ret != 0)
+ goto cs_failed;
+
/* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse));
- link->conf.ConfigIndex = parse.cftable_entry.index;
switch (link->manf_id) {
case MANFID_TDK:
cardtype = TDK;
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 6238176..cb40c38 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -793,18 +793,37 @@ static void if_cs_release(struct pcmcia_device *p_dev)
* configure the card at this point -- we wait until we receive a card
* insertion event.
*/
+
+static int if_cs_ioprobe(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ p_dev->io.BasePort1 = cfg->io.win[0].base;
+ p_dev->io.NumPorts1 = cfg->io.win[0].len;
+
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1)
+ p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ if (cfg->io.nwin != 1) {
+ lbs_pr_err("wrong CIS (check number of IO windows)\n");
+ return -ENODEV;
+ }
+
+ /* This reserves IO space but doesn't actually enable it */
+ return pcmcia_request_io(p_dev, &p_dev->io);
+}
+
static int if_cs_probe(struct pcmcia_device *p_dev)
{
int ret = -ENOMEM;
unsigned int prod_id;
struct lbs_private *priv;
struct if_cs_card *card;
- /* CIS parsing */
- tuple_t tuple;
- cisparse_t parse;
- cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
- cistpl_io_t *io = &cfg->io;
- u_char buf[64];
lbs_deb_enter(LBS_DEB_CS);
@@ -823,43 +842,11 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
p_dev->conf.Attributes = 0;
p_dev->conf.IntType = INT_MEMORY_AND_IO;
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
-
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- if ((ret = pcmcia_get_first_tuple(p_dev, &tuple)) != 0 ||
- (ret = pcmcia_get_tuple_data(p_dev, &tuple)) != 0 ||
- (ret = pcmcia_parse_tuple(&tuple, &parse)) != 0)
- {
- lbs_pr_err("error in pcmcia_get_first_tuple etc\n");
- goto out1;
- }
-
- p_dev->conf.ConfigIndex = cfg->index;
-
- /* Do we need to allocate an interrupt? */
- if (cfg->irq.IRQInfo1) {
- p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
- }
-
- /* IO window settings */
- if (cfg->io.nwin != 1) {
- lbs_pr_err("wrong CIS (check number of IO windows)\n");
- ret = -ENODEV;
+ if (pcmcia_loop_config(p_dev, if_cs_ioprobe, NULL)) {
+ lbs_pr_err("error in pcmcia_loop_config\n");
goto out1;
}
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- p_dev->io.BasePort1 = io->win[0].base;
- p_dev->io.NumPorts1 = io->win[0].len;
- /* This reserves IO space but doesn't actually enable it */
- ret = pcmcia_request_io(p_dev, &p_dev->io);
- if (ret) {
- lbs_pr_err("error in pcmcia_request_io\n");
- goto out1;
- }
/*
* Allocate an interrupt line. Note that this does not assign
--
1.6.0.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 6/9] pcmcia: convert net pcmcia drivers to use new CIS helpers
[not found] ` <1255907255-28297-5-git-send-email-linux@dominikbrodowski.net>
@ 2009-10-18 23:07 ` Dominik Brodowski
0 siblings, 0 replies; 6+ messages in thread
From: Dominik Brodowski @ 2009-10-18 23:07 UTC (permalink / raw)
To: linux-pcmcia; +Cc: Dominik Brodowski, David S. Miller, netdev
Use the new CIS helpers in net pcmcia drivers, which allows for
a few code cleanups.
CC: David S. Miller <davem@davemloft.net>
CC: netdev@vger.kernel.org
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
---
drivers/net/pcmcia/3c574_cs.c | 18 ++--
drivers/net/pcmcia/3c589_cs.c | 24 ++---
drivers/net/pcmcia/fmvj18x_cs.c | 51 ++++-----
drivers/net/pcmcia/nmclan_cs.c | 19 ++--
drivers/net/pcmcia/smc91c92_cs.c | 238 +++++++++++---------------------------
drivers/net/pcmcia/xirc2ps_cs.c | 101 ++++++----------
6 files changed, 154 insertions(+), 297 deletions(-)
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index b58965a..6449290 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -344,13 +344,13 @@ static int tc574_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
struct el3_private *lp = netdev_priv(dev);
- tuple_t tuple;
- __le16 buf[32];
int last_fn, last_ret, i, j;
unsigned int ioaddr;
__be16 *phys_addr;
char *cardname;
__u32 config;
+ u8 *buf;
+ size_t len;
phys_addr = (__be16 *)dev->dev_addr;
@@ -378,16 +378,14 @@ static int tc574_config(struct pcmcia_device *link)
/* The 3c574 normally uses an EEPROM for configuration info, including
the hardware address. The future products may include a modem chip
and put the address in the CIS. */
- tuple.Attributes = 0;
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleDataMax = 64;
- tuple.TupleOffset = 0;
- tuple.DesiredTuple = 0x88;
- if (pcmcia_get_first_tuple(link, &tuple) == 0) {
- pcmcia_get_tuple_data(link, &tuple);
+
+ len = pcmcia_get_tuple(link, 0x88, &buf);
+ if (buf && len >= 6) {
for (i = 0; i < 3; i++)
- phys_addr[i] = htons(le16_to_cpu(buf[i]));
+ phys_addr[i] = htons(le16_to_cpu(buf[i * 2]));
+ kfree(buf);
} else {
+ kfree(buf); /* 0 < len < 6 */
EL3WINDOW(0);
for (i = 0; i < 3; i++)
phys_addr[i] = htons(read_eeprom(ioaddr, i + 10));
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index 569fb06..ea04356 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -256,22 +256,15 @@ static int tc589_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
struct el3_private *lp = netdev_priv(dev);
- tuple_t tuple;
- __le16 buf[32];
- __be16 *phys_addr;
+ __be16 *phys_addr = NULL;
int last_fn, last_ret, i, j, multi = 0, fifo;
unsigned int ioaddr;
char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
+ u8 *buf;
+ size_t len;
DEBUG(0, "3c589_config(0x%p)\n", link);
- phys_addr = (__be16 *)dev->dev_addr;
- tuple.Attributes = 0;
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
- tuple.Attributes = TUPLE_RETURN_COMMON;
-
/* Is this a 3c562? */
if (link->manf_id != MANFID_3COM)
printk(KERN_INFO "3c589_cs: hmmm, is this really a "
@@ -301,12 +294,13 @@ static int tc589_config(struct pcmcia_device *link)
/* The 3c589 has an extra EEPROM for configuration info, including
the hardware address. The 3c562 puts the address in the CIS. */
- tuple.DesiredTuple = 0x88;
- if (pcmcia_get_first_tuple(link, &tuple) == 0) {
- pcmcia_get_tuple_data(link, &tuple);
- for (i = 0; i < 3; i++)
- phys_addr[i] = htons(le16_to_cpu(buf[i]));
+ len = pcmcia_get_tuple(link, 0x88, &buf);
+ if (buf && len >= 6) {
+ for (i = 0; i < 3; i++)
+ phys_addr[i] = htons(le16_to_cpu(buf[i*2]));
+ kfree(buf);
} else {
+ kfree(buf); /* 0 < len < 6 */
for (i = 0; i < 3; i++)
phys_addr[i] = htons(read_eeprom(ioaddr, i));
if (phys_addr[0] == htons(0x6060)) {
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index c7a2bbf..58954a6 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -350,32 +350,30 @@ static int fmvj18x_ioprobe(struct pcmcia_device *p_dev,
return 0; /* strange, but that's what the code did already before... */
}
-
static int fmvj18x_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
local_info_t *lp = netdev_priv(dev);
- tuple_t tuple;
- u_short buf[32];
int i, last_fn = RequestIO, last_ret = 0, ret;
unsigned int ioaddr;
cardtype_t cardtype;
char *card_name = "unknown";
- u_char *node_id;
+ u8 *buf;
+ size_t len;
+ u_char buggybuf[32];
DEBUG(0, "fmvj18x_config(0x%p)\n", link);
- tuple.TupleData = (u_char *)buf;
- tuple.TupleDataMax = 64;
- tuple.TupleOffset = 0;
- tuple.DesiredTuple = CISTPL_FUNCE;
- tuple.TupleOffset = 0;
- if (pcmcia_get_first_tuple(link, &tuple) == 0) {
+ len = pcmcia_get_tuple(link, CISTPL_FUNCE, &buf);
+ if (buf)
+ kfree(buf);
+
+ if (len) {
+ /* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */
last_ret = pcmcia_loop_config(link, fmvj18x_ioprobe, NULL);
if (last_ret != 0)
goto cs_failed;
- /* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */
switch (link->manf_id) {
case MANFID_TDK:
cardtype = TDK;
@@ -482,21 +480,21 @@ static int fmvj18x_config(struct pcmcia_device *link)
case CONTEC:
case NEC:
case KME:
- tuple.DesiredTuple = CISTPL_FUNCE;
- tuple.TupleOffset = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- tuple.TupleOffset = 0;
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
if (cardtype == MBH10304) {
- /* MBH10304's CIS_FUNCE is corrupted */
- node_id = &(tuple.TupleData[5]);
card_name = "FMV-J182";
- } else {
- while (tuple.TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID ) {
- CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
+
+ len = pcmcia_get_tuple(link, CISTPL_FUNCE, &buf);
+ if (len < 11) {
+ kfree(buf);
+ goto failed;
}
- node_id = &(tuple.TupleData[2]);
+ /* Read MACID from CIS */
+ for (i = 5; i < 11; i++)
+ dev->dev_addr[i] = buf[i];
+ kfree(buf);
+ } else {
+ if (pcmcia_get_mac_from_cis(link, dev))
+ goto failed;
if( cardtype == TDK ) {
card_name = "TDK LAK-CD021";
} else if( cardtype == LA501 ) {
@@ -509,9 +507,6 @@ static int fmvj18x_config(struct pcmcia_device *link)
card_name = "C-NET(PC)C";
}
}
- /* Read MACID from CIS */
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = node_id[i];
break;
case UNGERMANN:
/* Read MACID from register */
@@ -521,12 +516,12 @@ static int fmvj18x_config(struct pcmcia_device *link)
break;
case XXX10304:
/* Read MACID from Buggy CIS */
- if (fmvj18x_get_hwinfo(link, tuple.TupleData) == -1) {
+ if (fmvj18x_get_hwinfo(link, buggybuf) == -1) {
printk(KERN_NOTICE "fmvj18x_cs: unable to read hardware net address.\n");
goto failed;
}
for (i = 0 ; i < 6; i++) {
- dev->dev_addr[i] = tuple.TupleData[i];
+ dev->dev_addr[i] = buggybuf[i];
}
card_name = "FMV-J182";
break;
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 5ed6339..4b96b35 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -661,8 +661,8 @@ static int nmclan_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
mace_private *lp = netdev_priv(dev);
- tuple_t tuple;
- u_char buf[64];
+ u8 *buf;
+ size_t len;
int i, last_ret, last_fn;
unsigned int ioaddr;
@@ -677,14 +677,13 @@ static int nmclan_config(struct pcmcia_device *link)
ioaddr = dev->base_addr;
/* Read the ethernet address from the CIS. */
- tuple.DesiredTuple = 0x80 /* CISTPL_CFTABLE_ENTRY_MISC */;
- tuple.TupleData = buf;
- tuple.TupleDataMax = 64;
- tuple.TupleOffset = 0;
- tuple.Attributes = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- memcpy(dev->dev_addr, tuple.TupleData, ETHER_ADDR_LEN);
+ len = pcmcia_get_tuple(link, 0x80, &buf);
+ if (!buf || len < ETHER_ADDR_LEN) {
+ kfree(buf);
+ goto failed;
+ }
+ memcpy(dev->dev_addr, buf, ETHER_ADDR_LEN);
+ kfree(buf);
/* Verify configuration by reading the MACE ID. */
{
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index af03759..df92bcd 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -126,12 +126,6 @@ struct smc_private {
int rx_ovrn;
};
-struct smc_cfg_mem {
- tuple_t tuple;
- cisparse_t parse;
- u_char buf[255];
-};
-
/* Special definitions for Megahertz multifunction cards */
#define MEGAHERTZ_ISR 0x0380
@@ -408,34 +402,7 @@ static int cvt_ascii_address(struct net_device *dev, char *s)
return 0;
}
-/*====================================================================*/
-
-static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
- cisparse_t *parse)
-{
- int i;
-
- i = pcmcia_get_first_tuple(handle, tuple);
- if (i != 0)
- return i;
- i = pcmcia_get_tuple_data(handle, tuple);
- if (i != 0)
- return i;
- return pcmcia_parse_tuple(tuple, parse);
-}
-
-static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
- cisparse_t *parse)
-{
- int i;
-
- if ((i = pcmcia_get_next_tuple(handle, tuple)) != 0 ||
- (i = pcmcia_get_tuple_data(handle, tuple)) != 0)
- return i;
- return pcmcia_parse_tuple(tuple, parse);
-}
-
-/*======================================================================
+/*====================================================================
Configuration stuff for Megahertz cards
@@ -490,15 +457,10 @@ static int mhz_mfc_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
struct smc_private *smc = netdev_priv(dev);
- struct smc_cfg_mem *cfg_mem;
win_req_t req;
memreq_t mem;
int i;
- cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
- if (!cfg_mem)
- return -ENOMEM;
-
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA;
link->irq.Attributes =
@@ -510,7 +472,8 @@ static int mhz_mfc_config(struct pcmcia_device *link)
/* The Megahertz combo cards have modem-like CIS entries, so
we have to explicitly try a bunch of port combinations. */
if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL))
- goto free_cfg_mem;
+ return -ENODEV;
+
dev->base_addr = link->io.BasePort1;
/* Allocate a memory window, for accessing the ISR */
@@ -519,7 +482,8 @@ static int mhz_mfc_config(struct pcmcia_device *link)
req.AccessSpeed = 0;
i = pcmcia_request_window(&link, &req, &link->win);
if (i != 0)
- goto free_cfg_mem;
+ return -ENODEV;
+
smc->base = ioremap(req.Base, req.Size);
mem.CardOffset = mem.Page = 0;
if (smc->manfid == MANFID_MOTOROLA)
@@ -531,18 +495,32 @@ static int mhz_mfc_config(struct pcmcia_device *link)
&& (smc->cardid == PRODID_MEGAHERTZ_EM3288))
mhz_3288_power(link);
-free_cfg_mem:
- kfree(cfg_mem);
- return -ENODEV;
+ return 0;
}
+static int pcmcia_get_versmac(struct pcmcia_device *p_dev,
+ tuple_t *tuple,
+ void *priv)
+{
+ struct net_device *dev = priv;
+ cisparse_t parse;
+
+ if (pcmcia_parse_tuple(tuple, &parse))
+ return -EINVAL;
+
+ if ((parse.version_1.ns > 3) &&
+ (cvt_ascii_address(dev,
+ (parse.version_1.str + parse.version_1.ofs[3]))))
+ return 0;
+
+ return -EINVAL;
+};
+
static int mhz_setup(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
- struct smc_cfg_mem *cfg_mem;
- tuple_t *tuple;
- cisparse_t *parse;
- u_char *buf, *station_addr;
+ size_t len;
+ u8 *buf;
int rc;
/* Read the station address from the CIS. It is stored as the last
@@ -552,56 +530,22 @@ static int mhz_setup(struct pcmcia_device *link)
return 0;
/* Workarounds for broken cards start here. */
-
- cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
- if (!cfg_mem)
- return -1;
-
- tuple = &cfg_mem->tuple;
- parse = &cfg_mem->parse;
- buf = cfg_mem->buf;
-
- tuple->Attributes = tuple->TupleOffset = 0;
- tuple->TupleData = (cisdata_t *)buf;
- tuple->TupleDataMax = 255;
-
/* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
- tuple->DesiredTuple = CISTPL_VERS_1;
- if (first_tuple(link, tuple, parse) != 0) {
- rc = -1;
- goto free_cfg_mem;
- }
- /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
- if (next_tuple(link, tuple, parse) != 0)
- first_tuple(link, tuple, parse);
- if (parse->version_1.ns > 3) {
- station_addr = parse->version_1.str + parse->version_1.ofs[3];
- if (cvt_ascii_address(dev, station_addr) == 0) {
- rc = 0;
- goto free_cfg_mem;
- }
- }
+ if (!pcmcia_loop_tuple(link, CISTPL_VERS_1, pcmcia_get_versmac, dev))
+ return 0;
/* Another possibility: for the EM3288, in a special tuple */
- tuple->DesiredTuple = 0x81;
- if (pcmcia_get_first_tuple(link, tuple) != 0) {
- rc = -1;
- goto free_cfg_mem;
- }
- if (pcmcia_get_tuple_data(link, tuple) != 0) {
- rc = -1;
- goto free_cfg_mem;
- }
- buf[12] = '\0';
- if (cvt_ascii_address(dev, buf) == 0) {
- rc = 0;
- goto free_cfg_mem;
- }
rc = -1;
-free_cfg_mem:
- kfree(cfg_mem);
- return rc;
-}
+ len = pcmcia_get_tuple(link, 0x81, &buf);
+ if (buf && len >= 13) {
+ buf[12] = '\0';
+ if (cvt_ascii_address(dev, buf))
+ rc = 0;
+ }
+ kfree(buf);
+
+ return rc;
+};
/*======================================================================
@@ -691,58 +635,21 @@ static int smc_config(struct pcmcia_device *link)
return i;
}
+
static int smc_setup(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
- struct smc_cfg_mem *cfg_mem;
- tuple_t *tuple;
- cisparse_t *parse;
- cistpl_lan_node_id_t *node_id;
- u_char *buf, *station_addr;
- int i, rc;
-
- cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
- if (!cfg_mem)
- return -ENOMEM;
-
- tuple = &cfg_mem->tuple;
- parse = &cfg_mem->parse;
- buf = cfg_mem->buf;
-
- tuple->Attributes = tuple->TupleOffset = 0;
- tuple->TupleData = (cisdata_t *)buf;
- tuple->TupleDataMax = 255;
/* Check for a LAN function extension tuple */
- tuple->DesiredTuple = CISTPL_FUNCE;
- i = first_tuple(link, tuple, parse);
- while (i == 0) {
- if (parse->funce.type == CISTPL_FUNCE_LAN_NODE_ID)
- break;
- i = next_tuple(link, tuple, parse);
- }
- if (i == 0) {
- node_id = (cistpl_lan_node_id_t *)parse->funce.data;
- if (node_id->nb == 6) {
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = node_id->id[i];
- rc = 0;
- goto free_cfg_mem;
- }
- }
+ if (!pcmcia_get_mac_from_cis(link, dev))
+ return 0;
+
/* Try the third string in the Version 1 Version/ID tuple. */
if (link->prod_id[2]) {
- station_addr = link->prod_id[2];
- if (cvt_ascii_address(dev, station_addr) == 0) {
- rc = 0;
- goto free_cfg_mem;
- }
+ if (cvt_ascii_address(dev, link->prod_id[2]) == 0)
+ return 0;
}
-
- rc = -1;
-free_cfg_mem:
- kfree(cfg_mem);
- return rc;
+ return -1;
}
/*====================================================================*/
@@ -801,41 +708,31 @@ static int osi_load_firmware(struct pcmcia_device *link)
return err;
}
-static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
+static int pcmcia_osi_mac(struct pcmcia_device *p_dev,
+ tuple_t *tuple,
+ void *priv)
{
- struct net_device *dev = link->priv;
- struct smc_cfg_mem *cfg_mem;
- tuple_t *tuple;
- u_char *buf;
- int i, rc;
+ struct net_device *dev = priv;
+ int i;
- cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
- if (!cfg_mem)
- return -1;
+ if (tuple->TupleDataLen < 8)
+ return -EINVAL;
+ if (tuple->TupleData[0] != 0x04)
+ return -EINVAL;
+ for (i = 0; i < 6; i++)
+ dev->dev_addr[i] = tuple->TupleData[i+2];
+ return 0;
+};
- tuple = &cfg_mem->tuple;
- buf = cfg_mem->buf;
- tuple->Attributes = TUPLE_RETURN_COMMON;
- tuple->TupleData = (cisdata_t *)buf;
- tuple->TupleDataMax = 255;
- tuple->TupleOffset = 0;
+static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
+{
+ struct net_device *dev = link->priv;
+ int rc;
/* Read the station address from tuple 0x90, subtuple 0x04 */
- tuple->DesiredTuple = 0x90;
- i = pcmcia_get_first_tuple(link, tuple);
- while (i == 0) {
- i = pcmcia_get_tuple_data(link, tuple);
- if ((i != 0) || (buf[0] == 0x04))
- break;
- i = pcmcia_get_next_tuple(link, tuple);
- }
- if (i != 0) {
- rc = -1;
- goto free_cfg_mem;
- }
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = buf[i+2];
+ if (pcmcia_loop_tuple(link, 0x90, pcmcia_osi_mac, dev))
+ return -1;
if (((manfid == MANFID_OSITECH) &&
(cardid == PRODID_OSITECH_SEVEN)) ||
@@ -843,7 +740,7 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
(cardid == PRODID_PSION_NET100))) {
rc = osi_load_firmware(link);
if (rc)
- goto free_cfg_mem;
+ return rc;
} else if (manfid == MANFID_OSITECH) {
/* Make sure both functions are powered up */
set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR);
@@ -853,10 +750,7 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
inw(link->io.BasePort1 + OSITECH_AUI_PWR),
inw(link->io.BasePort1 + OSITECH_RESET_ISR));
}
- rc = 0;
-free_cfg_mem:
- kfree(cfg_mem);
- return rc;
+ return 0;
}
static int smc91c92_suspend(struct pcmcia_device *link)
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index 3dd6ba6..8ed8449 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -371,28 +371,6 @@ static void do_powerdown(struct net_device *dev);
static int do_stop(struct net_device *dev);
/*=============== Helper functions =========================*/
-static int
-first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
-{
- int err;
-
- if ((err = pcmcia_get_first_tuple(handle, tuple)) == 0 &&
- (err = pcmcia_get_tuple_data(handle, tuple)) == 0)
- err = pcmcia_parse_tuple(tuple, parse);
- return err;
-}
-
-static int
-next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
-{
- int err;
-
- if ((err = pcmcia_get_next_tuple(handle, tuple)) == 0 &&
- (err = pcmcia_get_tuple_data(handle, tuple)) == 0)
- err = pcmcia_parse_tuple(tuple, parse);
- return err;
-}
-
#define SelectPage(pgnr) outb((pgnr), ioaddr + XIRCREG_PR)
#define GetByte(reg) ((unsigned)inb(ioaddr + (reg)))
#define GetWord(reg) ((unsigned)inw(ioaddr + (reg)))
@@ -761,6 +739,26 @@ xirc2ps_config_check(struct pcmcia_device *p_dev,
}
+
+static int pcmcia_get_mac_ce(struct pcmcia_device *p_dev,
+ tuple_t *tuple,
+ void *priv)
+{
+ struct net_device *dev = priv;
+ int i;
+
+ if (tuple->TupleDataLen != 13)
+ return -EINVAL;
+ if ((tuple->TupleData[0] != 2) || (tuple->TupleData[1] != 1) ||
+ (tuple->TupleData[2] != 6))
+ return -EINVAL;
+ /* another try (James Lehmer's CE2 version 4.1)*/
+ for (i = 2; i < 6; i++)
+ dev->dev_addr[i] = tuple->TupleData[i+2];
+ return 0;
+};
+
+
/****************
* xirc2ps_config() is scheduled to run after a CARD_INSERTION event
* is received, to configure the PCMCIA socket, and to make the
@@ -774,9 +772,9 @@ xirc2ps_config(struct pcmcia_device * link)
unsigned int ioaddr;
tuple_t tuple;
cisparse_t parse;
- int err, i;
- u_char buf[64];
- cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data;
+ int err;
+ u8 *buf;
+ size_t len;
local->dingo_ccr = NULL;
@@ -827,49 +825,28 @@ xirc2ps_config(struct pcmcia_device * link)
}
/* get the ethernet address from the CIS */
- tuple.DesiredTuple = CISTPL_FUNCE;
- for (err = first_tuple(link, &tuple, &parse); !err;
- err = next_tuple(link, &tuple, &parse)) {
- /* Once I saw two CISTPL_FUNCE_LAN_NODE_ID entries:
- * the first one with a length of zero the second correct -
- * so I skip all entries with length 0 */
- if (parse.funce.type == CISTPL_FUNCE_LAN_NODE_ID
- && ((cistpl_lan_node_id_t *)parse.funce.data)->nb)
- break;
- }
- if (err) { /* not found: try to get the node-id from tuple 0x89 */
- tuple.DesiredTuple = 0x89; /* data layout looks like tuple 0x22 */
- if ((err = pcmcia_get_first_tuple(link, &tuple)) == 0 &&
- (err = pcmcia_get_tuple_data(link, &tuple)) == 0) {
- if (tuple.TupleDataLen == 8 && *buf == CISTPL_FUNCE_LAN_NODE_ID)
- memcpy(&parse, buf, 8);
- else
- err = -1;
- }
- }
- if (err) { /* another try (James Lehmer's CE2 version 4.1)*/
- tuple.DesiredTuple = CISTPL_FUNCE;
- for (err = first_tuple(link, &tuple, &parse); !err;
- err = next_tuple(link, &tuple, &parse)) {
- if (parse.funce.type == 0x02 && parse.funce.data[0] == 1
- && parse.funce.data[1] == 6 && tuple.TupleDataLen == 13) {
- buf[1] = 4;
- memcpy(&parse, buf+1, 8);
- break;
+ err = pcmcia_get_mac_from_cis(link, dev);
+
+ /* not found: try to get the node-id from tuple 0x89 */
+ if (err) {
+ len = pcmcia_get_tuple(link, 0x89, &buf);
+ /* data layout looks like tuple 0x22 */
+ if (buf && len == 8) {
+ if (*buf == CISTPL_FUNCE_LAN_NODE_ID)
+ memcpy(&parse, buf, 8);
+ else
+ err = -1;
}
- }
+ kfree(buf);
}
+
+ if (err)
+ err = pcmcia_loop_tuple(link, CISTPL_FUNCE, pcmcia_get_mac_ce, dev);
+
if (err) {
printk(KNOT_XIRC "node-id not found in CIS\n");
goto failure;
}
- node_id = (cistpl_lan_node_id_t *)parse.funce.data;
- if (node_id->nb != 6) {
- printk(KNOT_XIRC "malformed node-id in CIS\n");
- goto failure;
- }
- for (i=0; i < 6; i++)
- dev->dev_addr[i] = node_id->id[i];
link->io.IOAddrLines =10;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
--
1.6.0.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 3/9] pcmcia: use pcmcia_loop_config in misc pcmcia drivers
2009-10-18 23:07 ` [PATCH 3/9] pcmcia: use pcmcia_loop_config in misc pcmcia drivers Dominik Brodowski
[not found] ` <1255907255-28297-4-git-send-email-linux@dominikbrodowski.net>
@ 2009-10-19 13:45 ` Jiri Kosina
[not found] ` <1255907255-28297-3-git-send-email-linux-X3ehHDuj6sIIGcDfoQAp7OTW4wlIGRCZ@public.gmane.org>
2 siblings, 0 replies; 6+ messages in thread
From: Jiri Kosina @ 2009-10-19 13:45 UTC (permalink / raw)
To: Dominik Brodowski
Cc: linux-pcmcia, David S. Miller, John W. Linville, David Sterba,
netdev, linux-wireless
On Mon, 19 Oct 2009, Dominik Brodowski wrote:
> Use pcmcia_loop_config() in a few drivers missed during the first
> round. On fmvj18x_cs.c it -- strangely -- only requries us to set
> conf.ConfigIndex, which is done by the core, so include an empty
> loop function which returns 0 unconditionally.
>
> CC: David S. Miller <davem@davemloft.net>
> CC: John W. Linville <linville@tuxdriver.com>
> CC: Jiri Kosina <jkosina@suse.cz>
> CC: David Sterba <dsterba@suse.cz>
> CC: netdev@vger.kernel.org
> CC: linux-wireless@vger.kernel.org
> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
> ---
> drivers/char/pcmcia/ipwireless/main.c | 103 +++++++--------------------------
For the ipwireless part
Acked-by: Jiri Kosina <jkosina@suse.cz>
Thanks,
--
Jiri Kosina
SUSE Labs, Novell Inc.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/9] pcmcia: use pre-determined values
2009-10-18 23:07 ` [PATCH 2/9] pcmcia: use pre-determined values Dominik Brodowski
2009-10-18 23:07 ` [PATCH 3/9] pcmcia: use pcmcia_loop_config in misc pcmcia drivers Dominik Brodowski
@ 2009-10-27 19:28 ` John W. Linville
1 sibling, 0 replies; 6+ messages in thread
From: John W. Linville @ 2009-10-27 19:28 UTC (permalink / raw)
To: Dominik Brodowski; +Cc: linux-pcmcia, David S. Miller, netdev, linux-wireless
On Mon, Oct 19, 2009 at 01:07:28AM +0200, Dominik Brodowski wrote:
> A few PCMCIA network drivers can make use of values provided by the pcmcia
> core, instead of tedious, independent CIS parsing.
>
> xirc32ps_cs.c: manf_id
>
> hostap_cs.c: multifunction count
>
> b43/pcmcia.c: ConfigBase address and "Present"
>
> smc91c92_cs.c: By default, mhz_setup() can use VERS_1 as it is stored
> in struct pcmcia_device. Only some cards require workarounds, such as
> reading out VERS_1 twice.
>
> CC: David S. Miller <davem@davemloft.net>
> CC: John W. Linville <linville@tuxdriver.com>
> CC: netdev@vger.kernel.org
> CC: linux-wireless@vger.kernel.org
> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Acked-by: John W. Linville <linville@tuxdriver.com>
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 3/9] pcmcia: use pcmcia_loop_config in misc pcmcia drivers
[not found] ` <1255907255-28297-3-git-send-email-linux-X3ehHDuj6sIIGcDfoQAp7OTW4wlIGRCZ@public.gmane.org>
@ 2009-10-27 19:28 ` John W. Linville
0 siblings, 0 replies; 6+ messages in thread
From: John W. Linville @ 2009-10-27 19:28 UTC (permalink / raw)
To: Dominik Brodowski
Cc: linux-pcmcia-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, David S. Miller,
Jiri Kosina, David Sterba, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA
On Mon, Oct 19, 2009 at 01:07:29AM +0200, Dominik Brodowski wrote:
> Use pcmcia_loop_config() in a few drivers missed during the first
> round. On fmvj18x_cs.c it -- strangely -- only requries us to set
> conf.ConfigIndex, which is done by the core, so include an empty
> loop function which returns 0 unconditionally.
>
> CC: David S. Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
> CC: John W. Linville <linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
> CC: Jiri Kosina <jkosina-AlSwsSmVLrQ@public.gmane.org>
> CC: David Sterba <dsterba-AlSwsSmVLrQ@public.gmane.org>
> CC: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> CC: linux-wireless-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Signed-off-by: Dominik Brodowski <linux-X3ehHDuj6sIIGcDfoQAp7OTW4wlIGRCZ@public.gmane.org>
Acked-by: John W. Linville <linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
--
John W. Linville Someday the world will need a hero, and you
linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org might be all we have. Be ready.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2009-10-27 19:31 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1255907255-28297-1-git-send-email-linux@dominikbrodowski.net>
2009-10-18 23:07 ` [PATCH 2/9] pcmcia: use pre-determined values Dominik Brodowski
2009-10-18 23:07 ` [PATCH 3/9] pcmcia: use pcmcia_loop_config in misc pcmcia drivers Dominik Brodowski
[not found] ` <1255907255-28297-4-git-send-email-linux@dominikbrodowski.net>
[not found] ` <1255907255-28297-5-git-send-email-linux@dominikbrodowski.net>
2009-10-18 23:07 ` [PATCH 6/9] pcmcia: convert net pcmcia drivers to use new CIS helpers Dominik Brodowski
2009-10-19 13:45 ` [PATCH 3/9] pcmcia: use pcmcia_loop_config in misc pcmcia drivers Jiri Kosina
[not found] ` <1255907255-28297-3-git-send-email-linux-X3ehHDuj6sIIGcDfoQAp7OTW4wlIGRCZ@public.gmane.org>
2009-10-27 19:28 ` John W. Linville
2009-10-27 19:28 ` [PATCH 2/9] pcmcia: use pre-determined values John W. Linville
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).