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.c139
1 files changed, 83 insertions, 56 deletions
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index e180832c278f..c94311aed1ab 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -506,7 +506,8 @@ static int pcnet_confcheck(struct pcmcia_device *p_dev,
506 unsigned int vcc, 506 unsigned int vcc,
507 void *priv_data) 507 void *priv_data)
508{ 508{
509 int *has_shmem = priv_data; 509 int *priv = priv_data;
510 int try = (*priv & 0x1);
510 int i; 511 int i;
511 cistpl_io_t *io = &cfg->io; 512 cistpl_io_t *io = &cfg->io;
512 513
@@ -523,77 +524,103 @@ static int pcnet_confcheck(struct pcmcia_device *p_dev,
523 i = p_dev->resource[1]->end = 0; 524 i = p_dev->resource[1]->end = 0;
524 } 525 }
525 526
526 *has_shmem = ((cfg->mem.nwin == 1) && 527 *priv &= ((cfg->mem.nwin == 1) &&
527 (cfg->mem.win[0].len >= 0x4000)); 528 (cfg->mem.win[0].len >= 0x4000)) ? 0x10 : ~0x10;
529
528 p_dev->resource[0]->start = io->win[i].base; 530 p_dev->resource[0]->start = io->win[i].base;
529 p_dev->resource[0]->end = io->win[i].len; 531 p_dev->resource[0]->end = io->win[i].len;
530 p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK; 532 if (!try)
533 p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
534 else
535 p_dev->io_lines = 16;
531 if (p_dev->resource[0]->end + p_dev->resource[1]->end >= 32) 536 if (p_dev->resource[0]->end + p_dev->resource[1]->end >= 32)
532 return try_io_port(p_dev); 537 return try_io_port(p_dev);
533 538
534 return 0; 539 return -EINVAL;
540}
541
542static hw_info_t *pcnet_try_config(struct pcmcia_device *link,
543 int *has_shmem, int try)
544{
545 struct net_device *dev = link->priv;
546 hw_info_t *local_hw_info;
547 pcnet_dev_t *info = PRIV(dev);
548 int priv = try;
549 int ret;
550
551 ret = pcmcia_loop_config(link, pcnet_confcheck, &priv);
552 if (ret) {
553 dev_warn(&link->dev, "no useable port range found\n");
554 return NULL;
555 }
556 *has_shmem = (priv & 0x10);
557
558 if (!link->irq)
559 return NULL;
560
561 if (resource_size(link->resource[1]) == 8) {
562 link->conf.Attributes |= CONF_ENABLE_SPKR;
563 link->conf.Status = CCSR_AUDIO_ENA;
564 }
565 if ((link->manf_id == MANFID_IBM) &&
566 (link->card_id == PRODID_IBM_HOME_AND_AWAY))
567 link->conf.ConfigIndex |= 0x10;
568
569 ret = pcmcia_request_configuration(link, &link->conf);
570 if (ret)
571 return NULL;
572
573 dev->irq = link->irq;
574 dev->base_addr = link->resource[0]->start;
575
576 if (info->flags & HAS_MISC_REG) {
577 if ((if_port == 1) || (if_port == 2))
578 dev->if_port = if_port;
579 else
580 dev_notice(&link->dev, "invalid if_port requested\n");
581 } else
582 dev->if_port = 0;
583
584 if ((link->conf.ConfigBase == 0x03c0) &&
585 (link->manf_id == 0x149) && (link->card_id == 0xc1ab)) {
586 dev_info(&link->dev,
587 "this is an AX88190 card - use axnet_cs instead.\n");
588 return NULL;
589 }
590
591 local_hw_info = get_hwinfo(link);
592 if (!local_hw_info)
593 local_hw_info = get_prom(link);
594 if (!local_hw_info)
595 local_hw_info = get_dl10019(link);
596 if (!local_hw_info)
597 local_hw_info = get_ax88190(link);
598 if (!local_hw_info)
599 local_hw_info = get_hwired(link);
600
601 return local_hw_info;
535} 602}
536 603
537static int pcnet_config(struct pcmcia_device *link) 604static int pcnet_config(struct pcmcia_device *link)
538{ 605{
539 struct net_device *dev = link->priv; 606 struct net_device *dev = link->priv;
540 pcnet_dev_t *info = PRIV(dev); 607 pcnet_dev_t *info = PRIV(dev);
541 int ret, start_pg, stop_pg, cm_offset; 608 int start_pg, stop_pg, cm_offset;
542 int has_shmem = 0; 609 int has_shmem = 0;
543 hw_info_t *local_hw_info; 610 hw_info_t *local_hw_info;
544 611
545 dev_dbg(&link->dev, "pcnet_config\n"); 612 dev_dbg(&link->dev, "pcnet_config\n");
546 613
547 ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem); 614 local_hw_info = pcnet_try_config(link, &has_shmem, 0);
548 if (ret) 615 if (!local_hw_info) {
549 goto failed; 616 /* check whether forcing io_lines to 16 helps... */
550 617 pcmcia_disable_device(link);
551 if (!link->irq) 618 local_hw_info = pcnet_try_config(link, &has_shmem, 1);
552 goto failed; 619 if (local_hw_info == NULL) {
553 620 dev_notice(&link->dev, "unable to read hardware net"
554 if (resource_size(link->resource[1]) == 8) { 621 " address for io base %#3lx\n", dev->base_addr);
555 link->conf.Attributes |= CONF_ENABLE_SPKR; 622 goto failed;
556 link->conf.Status = CCSR_AUDIO_ENA; 623 }
557 }
558 if ((link->manf_id == MANFID_IBM) &&
559 (link->card_id == PRODID_IBM_HOME_AND_AWAY))
560 link->conf.ConfigIndex |= 0x10;
561
562 ret = pcmcia_request_configuration(link, &link->conf);
563 if (ret)
564 goto failed;
565 dev->irq = link->irq;
566 dev->base_addr = link->resource[0]->start;
567 if (info->flags & HAS_MISC_REG) {
568 if ((if_port == 1) || (if_port == 2))
569 dev->if_port = if_port;
570 else
571 pr_notice("invalid if_port requested\n");
572 } else {
573 dev->if_port = 0;
574 }
575
576 if ((link->conf.ConfigBase == 0x03c0) &&
577 (link->manf_id == 0x149) && (link->card_id == 0xc1ab)) {
578 pr_notice("this is an AX88190 card!\n");
579 pr_notice("use axnet_cs instead.\n");
580 goto failed;
581 }
582
583 local_hw_info = get_hwinfo(link);
584 if (local_hw_info == NULL)
585 local_hw_info = get_prom(link);
586 if (local_hw_info == NULL)
587 local_hw_info = get_dl10019(link);
588 if (local_hw_info == NULL)
589 local_hw_info = get_ax88190(link);
590 if (local_hw_info == NULL)
591 local_hw_info = get_hwired(link);
592
593 if (local_hw_info == NULL) {
594 pr_notice("unable to read hardware net address for io base %#3lx\n",
595 dev->base_addr);
596 goto failed;
597 } 624 }
598 625
599 info->flags = local_hw_info->flags; 626 info->flags = local_hw_info->flags;