summaryrefslogtreecommitdiffstats
path: root/drivers/net/pcmcia
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2008-08-02 14:28:43 +0200
committerDominik Brodowski <linux@dominikbrodowski.net>2008-08-23 01:21:28 +0200
commitb54bf94bf91e4ca2a489eb02bca0424ddb55242a (patch)
tree4a5383d29173e24dd1fe71ce3ee4d010e60f391c /drivers/net/pcmcia
parent5fcd4da0090828bd34a1956cb322a483c6bf163c (diff)
downloadop-kernel-dev-b54bf94bf91e4ca2a489eb02bca0424ddb55242a.zip
op-kernel-dev-b54bf94bf91e4ca2a489eb02bca0424ddb55242a.tar.gz
pcmcia: use pcmcia_loop_config in net pcmcia drivers
Use the config loop helper in (some) net pcmcia drivers. CC: netdev@vger.kernel.org Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/net/pcmcia')
-rw-r--r--drivers/net/pcmcia/axnet_cs.c71
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c79
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c96
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c73
4 files changed, 144 insertions, 175 deletions
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 3f682d4..04ece0b 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -284,58 +284,47 @@ static int try_io_port(struct pcmcia_device *link)
}
}
+static int axnet_configcheck(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ void *priv_data)
+{
+ int i;
+ cistpl_io_t *io = &cfg->io;
+
+ if (cfg->index == 0 || cfg->io.nwin == 0)
+ return -ENODEV;
+
+ p_dev->conf.ConfigIndex = 0x05;
+ /* For multifunction cards, by convention, we configure the
+ network function with window 0, and serial with window 1 */
+ if (io->nwin > 1) {
+ i = (io->win[1].len > io->win[0].len);
+ p_dev->io.BasePort2 = io->win[1-i].base;
+ p_dev->io.NumPorts2 = io->win[1-i].len;
+ } else {
+ i = p_dev->io.NumPorts2 = 0;
+ }
+ p_dev->io.BasePort1 = io->win[i].base;
+ p_dev->io.NumPorts1 = io->win[i].len;
+ p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32)
+ return try_io_port(p_dev);
+
+ return -ENODEV;
+}
+
static int axnet_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
axnet_dev_t *info = PRIV(dev);
- tuple_t tuple;
- cisparse_t parse;
int i, j, last_ret, last_fn;
- u_short buf[64];
DECLARE_MAC_BUF(mac);
DEBUG(0, "axnet_config(0x%p)\n", link);
- tuple.Attributes = 0;
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
-
/* don't trust the CIS on this; Linksys got it wrong */
link->conf.Present = 0x63;
-
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- tuple.Attributes = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- while (last_ret == CS_SUCCESS) {
- cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
- cistpl_io_t *io = &(parse.cftable_entry.io);
-
- if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
- pcmcia_parse_tuple(link, &tuple, &parse) != 0 ||
- cfg->index == 0 || cfg->io.nwin == 0)
- goto next_entry;
-
- link->conf.ConfigIndex = 0x05;
- /* For multifunction cards, by convention, we configure the
- network function with window 0, and serial with window 1 */
- if (io->nwin > 1) {
- i = (io->win[1].len > io->win[0].len);
- link->io.BasePort2 = io->win[1-i].base;
- link->io.NumPorts2 = io->win[1-i].len;
- } else {
- i = link->io.NumPorts2 = 0;
- }
- link->io.BasePort1 = io->win[i].base;
- link->io.NumPorts1 = io->win[i].len;
- link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
- if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) {
- last_ret = try_io_port(link);
- if (last_ret == CS_SUCCESS) break;
- }
- next_entry:
- last_ret = pcmcia_get_next_tuple(link, &tuple);
- }
+ last_ret = pcmcia_loop_config(link, axnet_configcheck, NULL);
if (last_ret != CS_SUCCESS) {
cs_error(link, RequestIO, last_ret);
goto failed;
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 2d4c4ad..7a9eeca 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -512,58 +512,53 @@ static int try_io_port(struct pcmcia_device *link)
}
}
+static int pcnet_confcheck(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ void *priv_data)
+{
+ int *has_shmem = priv_data;
+ int i;
+ cistpl_io_t *io = &cfg->io;
+
+ if (cfg->index == 0 || cfg->io.nwin == 0)
+ return -EINVAL;
+
+ p_dev->conf.ConfigIndex = cfg->index;
+
+ /* For multifunction cards, by convention, we configure the
+ network function with window 0, and serial with window 1 */
+ if (io->nwin > 1) {
+ i = (io->win[1].len > io->win[0].len);
+ p_dev->io.BasePort2 = io->win[1-i].base;
+ p_dev->io.NumPorts2 = io->win[1-i].len;
+ } else {
+ i = p_dev->io.NumPorts2 = 0;
+ }
+
+ *has_shmem = ((cfg->mem.nwin == 1) &&
+ (cfg->mem.win[0].len >= 0x4000));
+ p_dev->io.BasePort1 = io->win[i].base;
+ p_dev->io.NumPorts1 = io->win[i].len;
+ p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32)
+ return try_io_port(p_dev);
+
+ return 0;
+}
+
static int pcnet_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
pcnet_dev_t *info = PRIV(dev);
- tuple_t tuple;
- cisparse_t parse;
- int i, last_ret, last_fn, start_pg, stop_pg, cm_offset;
+ int last_ret, last_fn, start_pg, stop_pg, cm_offset;
int has_shmem = 0;
- u_short buf[64];
hw_info_t *local_hw_info;
DECLARE_MAC_BUF(mac);
DEBUG(0, "pcnet_config(0x%p)\n", link);
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- tuple.Attributes = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- while (last_ret == CS_SUCCESS) {
- cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
- cistpl_io_t *io = &(parse.cftable_entry.io);
-
- if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
- pcmcia_parse_tuple(link, &tuple, &parse) != 0 ||
- cfg->index == 0 || cfg->io.nwin == 0)
- goto next_entry;
-
- link->conf.ConfigIndex = cfg->index;
- /* For multifunction cards, by convention, we configure the
- network function with window 0, and serial with window 1 */
- if (io->nwin > 1) {
- i = (io->win[1].len > io->win[0].len);
- link->io.BasePort2 = io->win[1-i].base;
- link->io.NumPorts2 = io->win[1-i].len;
- } else {
- i = link->io.NumPorts2 = 0;
- }
- has_shmem = ((cfg->mem.nwin == 1) &&
- (cfg->mem.win[0].len >= 0x4000));
- link->io.BasePort1 = io->win[i].base;
- link->io.NumPorts1 = io->win[i].len;
- link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
- if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) {
- last_ret = try_io_port(link);
- if (last_ret == CS_SUCCESS) break;
- }
- next_entry:
- last_ret = pcmcia_get_next_tuple(link, &tuple);
- }
- if (last_ret != CS_SUCCESS) {
+ last_ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem);
+ if (last_ret) {
cs_error(link, RequestIO, last_ret);
goto failed;
}
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 250eb19..c012e34 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -459,28 +459,36 @@ static int mhz_3288_power(struct pcmcia_device *link)
return 0;
}
+static int mhz_mfc_config_check(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cf,
+ void *priv_data)
+{
+ int k;
+ p_dev->conf.ConfigIndex = cf->index;
+ p_dev->io.BasePort2 = cf->io.win[0].base;
+ for (k = 0; k < 0x400; k += 0x10) {
+ if (k & 0x80)
+ continue;
+ p_dev->io.BasePort1 = k ^ 0x300;
+ if (!pcmcia_request_io(p_dev, &p_dev->io))
+ return 0;
+ }
+ return -ENODEV;
+}
+
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;
- tuple_t *tuple;
- cisparse_t *parse;
- cistpl_cftable_entry_t *cf;
- u_char *buf;
win_req_t req;
memreq_t mem;
- int i, k;
+ int i;
cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
if (!cfg_mem)
return CS_OUT_OF_RESOURCE;
- tuple = &cfg_mem->tuple;
- parse = &cfg_mem->parse;
- cf = &parse->cftable_entry;
- buf = cfg_mem->buf;
-
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA;
link->irq.Attributes =
@@ -489,27 +497,9 @@ static int mhz_mfc_config(struct pcmcia_device *link)
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts2 = 8;
- tuple->Attributes = tuple->TupleOffset = 0;
- tuple->TupleData = (cisdata_t *)buf;
- tuple->TupleDataMax = 255;
- tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
-
- i = first_tuple(link, tuple, parse);
/* The Megahertz combo cards have modem-like CIS entries, so
we have to explicitly try a bunch of port combinations. */
- while (i == CS_SUCCESS) {
- link->conf.ConfigIndex = cf->index;
- link->io.BasePort2 = cf->io.win[0].base;
- for (k = 0; k < 0x400; k += 0x10) {
- if (k & 0x80) continue;
- link->io.BasePort1 = k ^ 0x300;
- i = pcmcia_request_io(link, &link->io);
- if (i == CS_SUCCESS) break;
- }
- if (i == CS_SUCCESS) break;
- i = next_tuple(link, tuple, parse);
- }
- if (i != CS_SUCCESS)
+ if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL))
goto free_cfg_mem;
dev->base_addr = link->io.BasePort1;
@@ -533,7 +523,7 @@ static int mhz_mfc_config(struct pcmcia_device *link)
free_cfg_mem:
kfree(cfg_mem);
- return i;
+ return -ENODEV;
}
static int mhz_setup(struct pcmcia_device *link)
@@ -660,46 +650,26 @@ static int mot_setup(struct pcmcia_device *link)
/*====================================================================*/
+static int smc_configcheck(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cf,
+ void *priv_data)
+{
+ p_dev->conf.ConfigIndex = cf->index;
+ p_dev->io.BasePort1 = cf->io.win[0].base;
+ p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
+ return pcmcia_request_io(p_dev, &p_dev->io);
+}
+
static int smc_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
- struct smc_cfg_mem *cfg_mem;
- tuple_t *tuple;
- cisparse_t *parse;
- cistpl_cftable_entry_t *cf;
- u_char *buf;
int i;
- cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
- if (!cfg_mem)
- return CS_OUT_OF_RESOURCE;
-
- tuple = &cfg_mem->tuple;
- parse = &cfg_mem->parse;
- cf = &parse->cftable_entry;
- buf = cfg_mem->buf;
-
- tuple->Attributes = tuple->TupleOffset = 0;
- tuple->TupleData = (cisdata_t *)buf;
- tuple->TupleDataMax = 255;
- tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
-
link->io.NumPorts1 = 16;
- i = first_tuple(link, tuple, parse);
- while (i != CS_NO_MORE_ITEMS) {
- if (i == CS_SUCCESS) {
- link->conf.ConfigIndex = cf->index;
- link->io.BasePort1 = cf->io.win[0].base;
- link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
- i = pcmcia_request_io(link, &link->io);
- if (i == CS_SUCCESS) break;
- }
- i = next_tuple(link, tuple, parse);
- }
- if (i == CS_SUCCESS)
- dev->base_addr = link->io.BasePort1;
+ i = pcmcia_loop_config(link, smc_configcheck, NULL);
+ if (!i)
+ dev->base_addr = link->io.BasePort1;
- kfree(cfg_mem);
return i;
}
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index f6c4698..b57f022 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -715,6 +715,45 @@ has_ce2_string(struct pcmcia_device * p_dev)
return 0;
}
+static int
+xirc2ps_config_modem(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cf,
+ void *priv_data)
+{
+ unsigned int ioaddr;
+
+ if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) {
+ for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
+ p_dev->conf.ConfigIndex = cf->index ;
+ p_dev->io.BasePort2 = cf->io.win[0].base;
+ p_dev->io.BasePort1 = ioaddr;
+ if (!pcmcia_request_io(p_dev, &p_dev->io))
+ return 0;
+ }
+ }
+ return -ENODEV;
+}
+
+static int
+xirc2ps_config_check(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cf,
+ void *priv_data)
+{
+ int *pass = priv_data;
+
+ if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) {
+ p_dev->conf.ConfigIndex = cf->index ;
+ p_dev->io.BasePort2 = cf->io.win[0].base;
+ p_dev->io.BasePort1 = p_dev->io.BasePort2
+ + (*pass ? (cf->index & 0x20 ? -24:8)
+ : (cf->index & 0x20 ? 8:-24));
+ if (!pcmcia_request_io(p_dev, &p_dev->io))
+ return 0;
+ }
+ return -ENODEV;
+
+}
+
/****************
* xirc2ps_config() is scheduled to run after a CARD_INSERTION event
* is received, to configure the PCMCIA socket, and to make the
@@ -725,13 +764,12 @@ xirc2ps_config(struct pcmcia_device * link)
{
struct net_device *dev = link->priv;
local_info_t *local = netdev_priv(dev);
+ unsigned int ioaddr;
tuple_t tuple;
cisparse_t parse;
- unsigned int ioaddr;
int err, i;
u_char buf[64];
cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data;
- cistpl_cftable_entry_t *cf = &parse.cftable_entry;
DECLARE_MAC_BUF(mac);
local->dingo_ccr = NULL;
@@ -846,19 +884,8 @@ xirc2ps_config(struct pcmcia_device * link)
/* Take the Modem IO port from the CIS and scan for a free
* Ethernet port */
link->io.NumPorts1 = 16; /* no Mako stuff anymore */
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- for (err = first_tuple(link, &tuple, &parse); !err;
- err = next_tuple(link, &tuple, &parse)) {
- if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) {
- for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
- link->conf.ConfigIndex = cf->index ;
- link->io.BasePort2 = cf->io.win[0].base;
- link->io.BasePort1 = ioaddr;
- if (!(err=pcmcia_request_io(link, &link->io)))
- goto port_found;
- }
- }
- }
+ if (!pcmcia_loop_config(link, xirc2ps_config_modem, NULL))
+ goto port_found;
} else {
link->io.NumPorts1 = 18;
/* We do 2 passes here: The first one uses the regular mapping and
@@ -866,21 +893,9 @@ xirc2ps_config(struct pcmcia_device * link)
* mirrored every 32 bytes. Actually we use a mirrored port for
* the Mako if (on the first pass) the COR bit 5 is set.
*/
- for (pass=0; pass < 2; pass++) {
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- for (err = first_tuple(link, &tuple, &parse); !err;
- err = next_tuple(link, &tuple, &parse)){
- if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8){
- link->conf.ConfigIndex = cf->index ;
- link->io.BasePort2 = cf->io.win[0].base;
- link->io.BasePort1 = link->io.BasePort2
- + (pass ? (cf->index & 0x20 ? -24:8)
- : (cf->index & 0x20 ? 8:-24));
- if (!(err=pcmcia_request_io(link, &link->io)))
+ for (pass=0; pass < 2; pass++)
+ if (!pcmcia_loop_config(link, xirc2ps_config_check, &pass))
goto port_found;
- }
- }
- }
/* if special option:
* try to configure as Ethernet only.
* .... */
OpenPOWER on IntegriCloud