aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pcmcia/pcnet_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/pcmcia/pcnet_cs.c')
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c79
1 files changed, 37 insertions, 42 deletions
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 2d4c4ad89b8d..7a9eeca6adc2 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)
512 } 512 }
513} 513}
514 514
515static int pcnet_confcheck(struct pcmcia_device *p_dev,
516 cistpl_cftable_entry_t *cfg,
517 void *priv_data)
518{
519 int *has_shmem = priv_data;
520 int i;
521 cistpl_io_t *io = &cfg->io;
522
523 if (cfg->index == 0 || cfg->io.nwin == 0)
524 return -EINVAL;
525
526 p_dev->conf.ConfigIndex = cfg->index;
527
528 /* For multifunction cards, by convention, we configure the
529 network function with window 0, and serial with window 1 */
530 if (io->nwin > 1) {
531 i = (io->win[1].len > io->win[0].len);
532 p_dev->io.BasePort2 = io->win[1-i].base;
533 p_dev->io.NumPorts2 = io->win[1-i].len;
534 } else {
535 i = p_dev->io.NumPorts2 = 0;
536 }
537
538 *has_shmem = ((cfg->mem.nwin == 1) &&
539 (cfg->mem.win[0].len >= 0x4000));
540 p_dev->io.BasePort1 = io->win[i].base;
541 p_dev->io.NumPorts1 = io->win[i].len;
542 p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
543 if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32)
544 return try_io_port(p_dev);
545
546 return 0;
547}
548
515static int pcnet_config(struct pcmcia_device *link) 549static int pcnet_config(struct pcmcia_device *link)
516{ 550{
517 struct net_device *dev = link->priv; 551 struct net_device *dev = link->priv;
518 pcnet_dev_t *info = PRIV(dev); 552 pcnet_dev_t *info = PRIV(dev);
519 tuple_t tuple; 553 int last_ret, last_fn, start_pg, stop_pg, cm_offset;
520 cisparse_t parse;
521 int i, last_ret, last_fn, start_pg, stop_pg, cm_offset;
522 int has_shmem = 0; 554 int has_shmem = 0;
523 u_short buf[64];
524 hw_info_t *local_hw_info; 555 hw_info_t *local_hw_info;
525 DECLARE_MAC_BUF(mac); 556 DECLARE_MAC_BUF(mac);
526 557
527 DEBUG(0, "pcnet_config(0x%p)\n", link); 558 DEBUG(0, "pcnet_config(0x%p)\n", link);
528 559
529 tuple.TupleData = (cisdata_t *)buf; 560 last_ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem);
530 tuple.TupleDataMax = sizeof(buf); 561 if (last_ret) {
531 tuple.TupleOffset = 0;
532 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
533 tuple.Attributes = 0;
534 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
535 while (last_ret == CS_SUCCESS) {
536 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
537 cistpl_io_t *io = &(parse.cftable_entry.io);
538
539 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
540 pcmcia_parse_tuple(link, &tuple, &parse) != 0 ||
541 cfg->index == 0 || cfg->io.nwin == 0)
542 goto next_entry;
543
544 link->conf.ConfigIndex = cfg->index;
545 /* For multifunction cards, by convention, we configure the
546 network function with window 0, and serial with window 1 */
547 if (io->nwin > 1) {
548 i = (io->win[1].len > io->win[0].len);
549 link->io.BasePort2 = io->win[1-i].base;
550 link->io.NumPorts2 = io->win[1-i].len;
551 } else {
552 i = link->io.NumPorts2 = 0;
553 }
554 has_shmem = ((cfg->mem.nwin == 1) &&
555 (cfg->mem.win[0].len >= 0x4000));
556 link->io.BasePort1 = io->win[i].base;
557 link->io.NumPorts1 = io->win[i].len;
558 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
559 if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) {
560 last_ret = try_io_port(link);
561 if (last_ret == CS_SUCCESS) break;
562 }
563 next_entry:
564 last_ret = pcmcia_get_next_tuple(link, &tuple);
565 }
566 if (last_ret != CS_SUCCESS) {
567 cs_error(link, RequestIO, last_ret); 562 cs_error(link, RequestIO, last_ret);
568 goto failed; 563 goto failed;
569 } 564 }