diff options
Diffstat (limited to 'drivers/net/pcmcia/smc91c92_cs.c')
-rw-r--r-- | drivers/net/pcmcia/smc91c92_cs.c | 96 |
1 files changed, 33 insertions, 63 deletions
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 250eb1954c34..c012e3400736 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) | |||
459 | return 0; | 459 | return 0; |
460 | } | 460 | } |
461 | 461 | ||
462 | static int mhz_mfc_config_check(struct pcmcia_device *p_dev, | ||
463 | cistpl_cftable_entry_t *cf, | ||
464 | void *priv_data) | ||
465 | { | ||
466 | int k; | ||
467 | p_dev->conf.ConfigIndex = cf->index; | ||
468 | p_dev->io.BasePort2 = cf->io.win[0].base; | ||
469 | for (k = 0; k < 0x400; k += 0x10) { | ||
470 | if (k & 0x80) | ||
471 | continue; | ||
472 | p_dev->io.BasePort1 = k ^ 0x300; | ||
473 | if (!pcmcia_request_io(p_dev, &p_dev->io)) | ||
474 | return 0; | ||
475 | } | ||
476 | return -ENODEV; | ||
477 | } | ||
478 | |||
462 | static int mhz_mfc_config(struct pcmcia_device *link) | 479 | static int mhz_mfc_config(struct pcmcia_device *link) |
463 | { | 480 | { |
464 | struct net_device *dev = link->priv; | 481 | struct net_device *dev = link->priv; |
465 | struct smc_private *smc = netdev_priv(dev); | 482 | struct smc_private *smc = netdev_priv(dev); |
466 | struct smc_cfg_mem *cfg_mem; | 483 | struct smc_cfg_mem *cfg_mem; |
467 | tuple_t *tuple; | ||
468 | cisparse_t *parse; | ||
469 | cistpl_cftable_entry_t *cf; | ||
470 | u_char *buf; | ||
471 | win_req_t req; | 484 | win_req_t req; |
472 | memreq_t mem; | 485 | memreq_t mem; |
473 | int i, k; | 486 | int i; |
474 | 487 | ||
475 | cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); | 488 | cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); |
476 | if (!cfg_mem) | 489 | if (!cfg_mem) |
477 | return CS_OUT_OF_RESOURCE; | 490 | return CS_OUT_OF_RESOURCE; |
478 | 491 | ||
479 | tuple = &cfg_mem->tuple; | ||
480 | parse = &cfg_mem->parse; | ||
481 | cf = &parse->cftable_entry; | ||
482 | buf = cfg_mem->buf; | ||
483 | |||
484 | link->conf.Attributes |= CONF_ENABLE_SPKR; | 492 | link->conf.Attributes |= CONF_ENABLE_SPKR; |
485 | link->conf.Status = CCSR_AUDIO_ENA; | 493 | link->conf.Status = CCSR_AUDIO_ENA; |
486 | link->irq.Attributes = | 494 | link->irq.Attributes = |
@@ -489,27 +497,9 @@ static int mhz_mfc_config(struct pcmcia_device *link) | |||
489 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; | 497 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; |
490 | link->io.NumPorts2 = 8; | 498 | link->io.NumPorts2 = 8; |
491 | 499 | ||
492 | tuple->Attributes = tuple->TupleOffset = 0; | ||
493 | tuple->TupleData = (cisdata_t *)buf; | ||
494 | tuple->TupleDataMax = 255; | ||
495 | tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; | ||
496 | |||
497 | i = first_tuple(link, tuple, parse); | ||
498 | /* The Megahertz combo cards have modem-like CIS entries, so | 500 | /* The Megahertz combo cards have modem-like CIS entries, so |
499 | we have to explicitly try a bunch of port combinations. */ | 501 | we have to explicitly try a bunch of port combinations. */ |
500 | while (i == CS_SUCCESS) { | 502 | if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL)) |
501 | link->conf.ConfigIndex = cf->index; | ||
502 | link->io.BasePort2 = cf->io.win[0].base; | ||
503 | for (k = 0; k < 0x400; k += 0x10) { | ||
504 | if (k & 0x80) continue; | ||
505 | link->io.BasePort1 = k ^ 0x300; | ||
506 | i = pcmcia_request_io(link, &link->io); | ||
507 | if (i == CS_SUCCESS) break; | ||
508 | } | ||
509 | if (i == CS_SUCCESS) break; | ||
510 | i = next_tuple(link, tuple, parse); | ||
511 | } | ||
512 | if (i != CS_SUCCESS) | ||
513 | goto free_cfg_mem; | 503 | goto free_cfg_mem; |
514 | dev->base_addr = link->io.BasePort1; | 504 | dev->base_addr = link->io.BasePort1; |
515 | 505 | ||
@@ -533,7 +523,7 @@ static int mhz_mfc_config(struct pcmcia_device *link) | |||
533 | 523 | ||
534 | free_cfg_mem: | 524 | free_cfg_mem: |
535 | kfree(cfg_mem); | 525 | kfree(cfg_mem); |
536 | return i; | 526 | return -ENODEV; |
537 | } | 527 | } |
538 | 528 | ||
539 | static int mhz_setup(struct pcmcia_device *link) | 529 | static int mhz_setup(struct pcmcia_device *link) |
@@ -660,46 +650,26 @@ static int mot_setup(struct pcmcia_device *link) | |||
660 | 650 | ||
661 | /*====================================================================*/ | 651 | /*====================================================================*/ |
662 | 652 | ||
653 | static int smc_configcheck(struct pcmcia_device *p_dev, | ||
654 | cistpl_cftable_entry_t *cf, | ||
655 | void *priv_data) | ||
656 | { | ||
657 | p_dev->conf.ConfigIndex = cf->index; | ||
658 | p_dev->io.BasePort1 = cf->io.win[0].base; | ||
659 | p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; | ||
660 | return pcmcia_request_io(p_dev, &p_dev->io); | ||
661 | } | ||
662 | |||
663 | static int smc_config(struct pcmcia_device *link) | 663 | static int smc_config(struct pcmcia_device *link) |
664 | { | 664 | { |
665 | struct net_device *dev = link->priv; | 665 | struct net_device *dev = link->priv; |
666 | struct smc_cfg_mem *cfg_mem; | ||
667 | tuple_t *tuple; | ||
668 | cisparse_t *parse; | ||
669 | cistpl_cftable_entry_t *cf; | ||
670 | u_char *buf; | ||
671 | int i; | 666 | int i; |
672 | 667 | ||
673 | cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); | ||
674 | if (!cfg_mem) | ||
675 | return CS_OUT_OF_RESOURCE; | ||
676 | |||
677 | tuple = &cfg_mem->tuple; | ||
678 | parse = &cfg_mem->parse; | ||
679 | cf = &parse->cftable_entry; | ||
680 | buf = cfg_mem->buf; | ||
681 | |||
682 | tuple->Attributes = tuple->TupleOffset = 0; | ||
683 | tuple->TupleData = (cisdata_t *)buf; | ||
684 | tuple->TupleDataMax = 255; | ||
685 | tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; | ||
686 | |||
687 | link->io.NumPorts1 = 16; | 668 | link->io.NumPorts1 = 16; |
688 | i = first_tuple(link, tuple, parse); | 669 | i = pcmcia_loop_config(link, smc_configcheck, NULL); |
689 | while (i != CS_NO_MORE_ITEMS) { | 670 | if (!i) |
690 | if (i == CS_SUCCESS) { | 671 | dev->base_addr = link->io.BasePort1; |
691 | link->conf.ConfigIndex = cf->index; | ||
692 | link->io.BasePort1 = cf->io.win[0].base; | ||
693 | link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; | ||
694 | i = pcmcia_request_io(link, &link->io); | ||
695 | if (i == CS_SUCCESS) break; | ||
696 | } | ||
697 | i = next_tuple(link, tuple, parse); | ||
698 | } | ||
699 | if (i == CS_SUCCESS) | ||
700 | dev->base_addr = link->io.BasePort1; | ||
701 | 672 | ||
702 | kfree(cfg_mem); | ||
703 | return i; | 673 | return i; |
704 | } | 674 | } |
705 | 675 | ||