diff options
Diffstat (limited to 'drivers/net/pcmcia/pcnet_cs.c')
-rw-r--r-- | drivers/net/pcmcia/pcnet_cs.c | 79 |
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 | ||
515 | static 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 | |||
515 | static int pcnet_config(struct pcmcia_device *link) | 549 | static 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 | } |