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 | ||
