diff options
| -rw-r--r-- | drivers/net/pcmcia/smc91c92_cs.c | 287 |
1 files changed, 189 insertions, 98 deletions
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 85a152173148..8a5e52c40e46 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c | |||
| @@ -127,6 +127,12 @@ struct smc_private { | |||
| 127 | int rx_ovrn; | 127 | int rx_ovrn; |
| 128 | }; | 128 | }; |
| 129 | 129 | ||
| 130 | struct smc_cfg_mem { | ||
| 131 | tuple_t tuple; | ||
| 132 | cisparse_t parse; | ||
| 133 | u_char buf[255]; | ||
| 134 | }; | ||
| 135 | |||
| 130 | /* Special definitions for Megahertz multifunction cards */ | 136 | /* Special definitions for Megahertz multifunction cards */ |
| 131 | #define MEGAHERTZ_ISR 0x0380 | 137 | #define MEGAHERTZ_ISR 0x0380 |
| 132 | 138 | ||
| @@ -498,14 +504,24 @@ static int mhz_mfc_config(dev_link_t *link) | |||
| 498 | { | 504 | { |
| 499 | struct net_device *dev = link->priv; | 505 | struct net_device *dev = link->priv; |
| 500 | struct smc_private *smc = netdev_priv(dev); | 506 | struct smc_private *smc = netdev_priv(dev); |
| 501 | tuple_t tuple; | 507 | struct smc_cfg_mem *cfg_mem; |
| 502 | cisparse_t parse; | 508 | tuple_t *tuple; |
| 503 | u_char buf[255]; | 509 | cisparse_t *parse; |
| 504 | cistpl_cftable_entry_t *cf = &parse.cftable_entry; | 510 | cistpl_cftable_entry_t *cf; |
| 511 | u_char *buf; | ||
| 505 | win_req_t req; | 512 | win_req_t req; |
| 506 | memreq_t mem; | 513 | memreq_t mem; |
| 507 | int i, k; | 514 | int i, k; |
| 508 | 515 | ||
| 516 | cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); | ||
| 517 | if (!cfg_mem) | ||
| 518 | return CS_OUT_OF_RESOURCE; | ||
| 519 | |||
| 520 | tuple = &cfg_mem->tuple; | ||
| 521 | parse = &cfg_mem->parse; | ||
| 522 | cf = &parse->cftable_entry; | ||
| 523 | buf = cfg_mem->buf; | ||
| 524 | |||
| 509 | link->conf.Attributes |= CONF_ENABLE_SPKR; | 525 | link->conf.Attributes |= CONF_ENABLE_SPKR; |
| 510 | link->conf.Status = CCSR_AUDIO_ENA; | 526 | link->conf.Status = CCSR_AUDIO_ENA; |
| 511 | link->irq.Attributes = | 527 | link->irq.Attributes = |
| @@ -514,12 +530,12 @@ static int mhz_mfc_config(dev_link_t *link) | |||
| 514 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; | 530 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; |
| 515 | link->io.NumPorts2 = 8; | 531 | link->io.NumPorts2 = 8; |
| 516 | 532 | ||
| 517 | tuple.Attributes = tuple.TupleOffset = 0; | 533 | tuple->Attributes = tuple->TupleOffset = 0; |
| 518 | tuple.TupleData = (cisdata_t *)buf; | 534 | tuple->TupleData = (cisdata_t *)buf; |
| 519 | tuple.TupleDataMax = sizeof(buf); | 535 | tuple->TupleDataMax = 255; |
| 520 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 536 | tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; |
| 521 | 537 | ||
| 522 | i = first_tuple(link->handle, &tuple, &parse); | 538 | i = first_tuple(link->handle, tuple, parse); |
| 523 | /* The Megahertz combo cards have modem-like CIS entries, so | 539 | /* The Megahertz combo cards have modem-like CIS entries, so |
| 524 | we have to explicitly try a bunch of port combinations. */ | 540 | we have to explicitly try a bunch of port combinations. */ |
| 525 | while (i == CS_SUCCESS) { | 541 | while (i == CS_SUCCESS) { |
| @@ -532,10 +548,10 @@ static int mhz_mfc_config(dev_link_t *link) | |||
| 532 | if (i == CS_SUCCESS) break; | 548 | if (i == CS_SUCCESS) break; |
| 533 | } | 549 | } |
| 534 | if (i == CS_SUCCESS) break; | 550 | if (i == CS_SUCCESS) break; |
| 535 | i = next_tuple(link->handle, &tuple, &parse); | 551 | i = next_tuple(link->handle, tuple, parse); |
| 536 | } | 552 | } |
| 537 | if (i != CS_SUCCESS) | 553 | if (i != CS_SUCCESS) |
| 538 | return i; | 554 | goto free_cfg_mem; |
| 539 | dev->base_addr = link->io.BasePort1; | 555 | dev->base_addr = link->io.BasePort1; |
| 540 | 556 | ||
| 541 | /* Allocate a memory window, for accessing the ISR */ | 557 | /* Allocate a memory window, for accessing the ISR */ |
| @@ -544,7 +560,7 @@ static int mhz_mfc_config(dev_link_t *link) | |||
| 544 | req.AccessSpeed = 0; | 560 | req.AccessSpeed = 0; |
| 545 | i = pcmcia_request_window(&link->handle, &req, &link->win); | 561 | i = pcmcia_request_window(&link->handle, &req, &link->win); |
| 546 | if (i != CS_SUCCESS) | 562 | if (i != CS_SUCCESS) |
| 547 | return i; | 563 | goto free_cfg_mem; |
| 548 | smc->base = ioremap(req.Base, req.Size); | 564 | smc->base = ioremap(req.Base, req.Size); |
| 549 | mem.CardOffset = mem.Page = 0; | 565 | mem.CardOffset = mem.Page = 0; |
| 550 | if (smc->manfid == MANFID_MOTOROLA) | 566 | if (smc->manfid == MANFID_MOTOROLA) |
| @@ -556,6 +572,8 @@ static int mhz_mfc_config(dev_link_t *link) | |||
| 556 | && (smc->cardid == PRODID_MEGAHERTZ_EM3288)) | 572 | && (smc->cardid == PRODID_MEGAHERTZ_EM3288)) |
| 557 | mhz_3288_power(link); | 573 | mhz_3288_power(link); |
| 558 | 574 | ||
| 575 | free_cfg_mem: | ||
| 576 | kfree(cfg_mem); | ||
| 559 | return i; | 577 | return i; |
| 560 | } | 578 | } |
| 561 | 579 | ||
| @@ -563,39 +581,61 @@ static int mhz_setup(dev_link_t *link) | |||
| 563 | { | 581 | { |
| 564 | client_handle_t handle = link->handle; | 582 | client_handle_t handle = link->handle; |
| 565 | struct net_device *dev = link->priv; | 583 | struct net_device *dev = link->priv; |
| 566 | tuple_t tuple; | 584 | struct smc_cfg_mem *cfg_mem; |
| 567 | cisparse_t parse; | 585 | tuple_t *tuple; |
| 568 | u_char buf[255], *station_addr; | 586 | cisparse_t *parse; |
| 587 | u_char *buf, *station_addr; | ||
| 588 | int rc; | ||
| 589 | |||
| 590 | cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); | ||
| 591 | if (!cfg_mem) | ||
| 592 | return -1; | ||
| 593 | |||
| 594 | tuple = &cfg_mem->tuple; | ||
| 595 | parse = &cfg_mem->parse; | ||
| 596 | buf = cfg_mem->buf; | ||
| 569 | 597 | ||
| 570 | tuple.Attributes = tuple.TupleOffset = 0; | 598 | tuple->Attributes = tuple->TupleOffset = 0; |
| 571 | tuple.TupleData = buf; | 599 | tuple->TupleData = (cisdata_t *)buf; |
| 572 | tuple.TupleDataMax = sizeof(buf); | 600 | tuple->TupleDataMax = 255; |
| 573 | 601 | ||
| 574 | /* Read the station address from the CIS. It is stored as the last | 602 | /* Read the station address from the CIS. It is stored as the last |
| 575 | (fourth) string in the Version 1 Version/ID tuple. */ | 603 | (fourth) string in the Version 1 Version/ID tuple. */ |
| 576 | tuple.DesiredTuple = CISTPL_VERS_1; | 604 | tuple->DesiredTuple = CISTPL_VERS_1; |
| 577 | if (first_tuple(handle, &tuple, &parse) != CS_SUCCESS) | 605 | if (first_tuple(handle, tuple, parse) != CS_SUCCESS) { |
| 578 | return -1; | 606 | rc = -1; |
| 607 | goto free_cfg_mem; | ||
| 608 | } | ||
| 579 | /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */ | 609 | /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */ |
| 580 | if (next_tuple(handle, &tuple, &parse) != CS_SUCCESS) | 610 | if (next_tuple(handle, tuple, parse) != CS_SUCCESS) |
| 581 | first_tuple(handle, &tuple, &parse); | 611 | first_tuple(handle, tuple, parse); |
| 582 | if (parse.version_1.ns > 3) { | 612 | if (parse->version_1.ns > 3) { |
| 583 | station_addr = parse.version_1.str + parse.version_1.ofs[3]; | 613 | station_addr = parse->version_1.str + parse->version_1.ofs[3]; |
| 584 | if (cvt_ascii_address(dev, station_addr) == 0) | 614 | if (cvt_ascii_address(dev, station_addr) == 0) { |
| 585 | return 0; | 615 | rc = 0; |
| 616 | goto free_cfg_mem; | ||
| 617 | } | ||
| 586 | } | 618 | } |
| 587 | 619 | ||
| 588 | /* Another possibility: for the EM3288, in a special tuple */ | 620 | /* Another possibility: for the EM3288, in a special tuple */ |
| 589 | tuple.DesiredTuple = 0x81; | 621 | tuple->DesiredTuple = 0x81; |
| 590 | if (pcmcia_get_first_tuple(handle, &tuple) != CS_SUCCESS) | 622 | if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) { |
| 591 | return -1; | 623 | rc = -1; |
| 592 | if (pcmcia_get_tuple_data(handle, &tuple) != CS_SUCCESS) | 624 | goto free_cfg_mem; |
| 593 | return -1; | 625 | } |
| 626 | if (pcmcia_get_tuple_data(handle, tuple) != CS_SUCCESS) { | ||
| 627 | rc = -1; | ||
| 628 | goto free_cfg_mem; | ||
| 629 | } | ||
| 594 | buf[12] = '\0'; | 630 | buf[12] = '\0'; |
| 595 | if (cvt_ascii_address(dev, buf) == 0) | 631 | if (cvt_ascii_address(dev, buf) == 0) { |
| 596 | return 0; | 632 | rc = 0; |
| 597 | 633 | goto free_cfg_mem; | |
| 598 | return -1; | 634 | } |
| 635 | rc = -1; | ||
| 636 | free_cfg_mem: | ||
| 637 | kfree(cfg_mem); | ||
| 638 | return rc; | ||
| 599 | } | 639 | } |
| 600 | 640 | ||
| 601 | /*====================================================================== | 641 | /*====================================================================== |
| @@ -665,19 +705,29 @@ static int mot_setup(dev_link_t *link) | |||
| 665 | static int smc_config(dev_link_t *link) | 705 | static int smc_config(dev_link_t *link) |
| 666 | { | 706 | { |
| 667 | struct net_device *dev = link->priv; | 707 | struct net_device *dev = link->priv; |
| 668 | tuple_t tuple; | 708 | struct smc_cfg_mem *cfg_mem; |
| 669 | cisparse_t parse; | 709 | tuple_t *tuple; |
| 670 | u_char buf[255]; | 710 | cisparse_t *parse; |
| 671 | cistpl_cftable_entry_t *cf = &parse.cftable_entry; | 711 | cistpl_cftable_entry_t *cf; |
| 712 | u_char *buf; | ||
| 672 | int i; | 713 | int i; |
| 673 | 714 | ||
| 674 | tuple.Attributes = tuple.TupleOffset = 0; | 715 | cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); |
| 675 | tuple.TupleData = (cisdata_t *)buf; | 716 | if (!cfg_mem) |
| 676 | tuple.TupleDataMax = sizeof(buf); | 717 | return CS_OUT_OF_RESOURCE; |
| 677 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 718 | |
| 719 | tuple = &cfg_mem->tuple; | ||
| 720 | parse = &cfg_mem->parse; | ||
| 721 | cf = &parse->cftable_entry; | ||
| 722 | buf = cfg_mem->buf; | ||
| 723 | |||
| 724 | tuple->Attributes = tuple->TupleOffset = 0; | ||
| 725 | tuple->TupleData = (cisdata_t *)buf; | ||
| 726 | tuple->TupleDataMax = 255; | ||
| 727 | tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; | ||
| 678 | 728 | ||
| 679 | link->io.NumPorts1 = 16; | 729 | link->io.NumPorts1 = 16; |
| 680 | i = first_tuple(link->handle, &tuple, &parse); | 730 | i = first_tuple(link->handle, tuple, parse); |
| 681 | while (i != CS_NO_MORE_ITEMS) { | 731 | while (i != CS_NO_MORE_ITEMS) { |
| 682 | if (i == CS_SUCCESS) { | 732 | if (i == CS_SUCCESS) { |
| 683 | link->conf.ConfigIndex = cf->index; | 733 | link->conf.ConfigIndex = cf->index; |
| @@ -686,10 +736,12 @@ static int smc_config(dev_link_t *link) | |||
| 686 | i = pcmcia_request_io(link->handle, &link->io); | 736 | i = pcmcia_request_io(link->handle, &link->io); |
| 687 | if (i == CS_SUCCESS) break; | 737 | if (i == CS_SUCCESS) break; |
| 688 | } | 738 | } |
| 689 | i = next_tuple(link->handle, &tuple, &parse); | 739 | i = next_tuple(link->handle, tuple, parse); |
| 690 | } | 740 | } |
| 691 | if (i == CS_SUCCESS) | 741 | if (i == CS_SUCCESS) |
| 692 | dev->base_addr = link->io.BasePort1; | 742 | dev->base_addr = link->io.BasePort1; |
| 743 | |||
| 744 | kfree(cfg_mem); | ||
| 693 | return i; | 745 | return i; |
| 694 | } | 746 | } |
| 695 | 747 | ||
| @@ -697,41 +749,58 @@ static int smc_setup(dev_link_t *link) | |||
| 697 | { | 749 | { |
| 698 | client_handle_t handle = link->handle; | 750 | client_handle_t handle = link->handle; |
| 699 | struct net_device *dev = link->priv; | 751 | struct net_device *dev = link->priv; |
| 700 | tuple_t tuple; | 752 | struct smc_cfg_mem *cfg_mem; |
| 701 | cisparse_t parse; | 753 | tuple_t *tuple; |
| 754 | cisparse_t *parse; | ||
| 702 | cistpl_lan_node_id_t *node_id; | 755 | cistpl_lan_node_id_t *node_id; |
| 703 | u_char buf[255], *station_addr; | 756 | u_char *buf, *station_addr; |
| 704 | int i; | 757 | int i, rc; |
| 705 | 758 | ||
| 706 | tuple.Attributes = tuple.TupleOffset = 0; | 759 | cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); |
| 707 | tuple.TupleData = buf; | 760 | if (!cfg_mem) |
| 708 | tuple.TupleDataMax = sizeof(buf); | 761 | return CS_OUT_OF_RESOURCE; |
| 762 | |||
| 763 | tuple = &cfg_mem->tuple; | ||
| 764 | parse = &cfg_mem->parse; | ||
| 765 | buf = cfg_mem->buf; | ||
| 766 | |||
| 767 | tuple->Attributes = tuple->TupleOffset = 0; | ||
| 768 | tuple->TupleData = (cisdata_t *)buf; | ||
| 769 | tuple->TupleDataMax = 255; | ||
| 709 | 770 | ||
| 710 | /* Check for a LAN function extension tuple */ | 771 | /* Check for a LAN function extension tuple */ |
| 711 | tuple.DesiredTuple = CISTPL_FUNCE; | 772 | tuple->DesiredTuple = CISTPL_FUNCE; |
| 712 | i = first_tuple(handle, &tuple, &parse); | 773 | i = first_tuple(handle, tuple, parse); |
| 713 | while (i == CS_SUCCESS) { | 774 | while (i == CS_SUCCESS) { |
| 714 | if (parse.funce.type == CISTPL_FUNCE_LAN_NODE_ID) | 775 | if (parse->funce.type == CISTPL_FUNCE_LAN_NODE_ID) |
| 715 | break; | 776 | break; |
| 716 | i = next_tuple(handle, &tuple, &parse); | 777 | i = next_tuple(handle, tuple, parse); |
| 717 | } | 778 | } |
| 718 | if (i == CS_SUCCESS) { | 779 | if (i == CS_SUCCESS) { |
| 719 | node_id = (cistpl_lan_node_id_t *)parse.funce.data; | 780 | node_id = (cistpl_lan_node_id_t *)parse->funce.data; |
| 720 | if (node_id->nb == 6) { | 781 | if (node_id->nb == 6) { |
| 721 | for (i = 0; i < 6; i++) | 782 | for (i = 0; i < 6; i++) |
| 722 | dev->dev_addr[i] = node_id->id[i]; | 783 | dev->dev_addr[i] = node_id->id[i]; |
| 723 | return 0; | 784 | rc = 0; |
| 785 | goto free_cfg_mem; | ||
| 724 | } | 786 | } |
| 725 | } | 787 | } |
| 726 | /* Try the third string in the Version 1 Version/ID tuple. */ | 788 | /* Try the third string in the Version 1 Version/ID tuple. */ |
| 727 | tuple.DesiredTuple = CISTPL_VERS_1; | 789 | tuple->DesiredTuple = CISTPL_VERS_1; |
| 728 | if (first_tuple(handle, &tuple, &parse) != CS_SUCCESS) | 790 | if (first_tuple(handle, tuple, parse) != CS_SUCCESS) { |
| 729 | return -1; | 791 | rc = -1; |
| 730 | station_addr = parse.version_1.str + parse.version_1.ofs[2]; | 792 | goto free_cfg_mem; |
| 731 | if (cvt_ascii_address(dev, station_addr) == 0) | 793 | } |
| 732 | return 0; | 794 | station_addr = parse->version_1.str + parse->version_1.ofs[2]; |
| 795 | if (cvt_ascii_address(dev, station_addr) == 0) { | ||
| 796 | rc = 0; | ||
| 797 | goto free_cfg_mem; | ||
| 798 | } | ||
| 733 | 799 | ||
| 734 | return -1; | 800 | rc = -1; |
| 801 | free_cfg_mem: | ||
| 802 | kfree(cfg_mem); | ||
| 803 | return rc; | ||
| 735 | } | 804 | } |
| 736 | 805 | ||
| 737 | /*====================================================================*/ | 806 | /*====================================================================*/ |
| @@ -773,26 +842,36 @@ static int osi_setup(dev_link_t *link, u_short manfid, u_short cardid) | |||
| 773 | { | 842 | { |
| 774 | client_handle_t handle = link->handle; | 843 | client_handle_t handle = link->handle; |
| 775 | struct net_device *dev = link->priv; | 844 | struct net_device *dev = link->priv; |
| 776 | tuple_t tuple; | 845 | struct smc_cfg_mem *cfg_mem; |
| 777 | u_char buf[255]; | 846 | tuple_t *tuple; |
| 778 | int i; | 847 | u_char *buf; |
| 848 | int i, rc; | ||
| 779 | 849 | ||
| 780 | tuple.Attributes = TUPLE_RETURN_COMMON; | 850 | cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); |
| 781 | tuple.TupleData = buf; | 851 | if (!cfg_mem) |
| 782 | tuple.TupleDataMax = sizeof(buf); | 852 | return -1; |
| 783 | tuple.TupleOffset = 0; | 853 | |
| 854 | tuple = &cfg_mem->tuple; | ||
| 855 | buf = cfg_mem->buf; | ||
| 856 | |||
| 857 | tuple->Attributes = TUPLE_RETURN_COMMON; | ||
| 858 | tuple->TupleData = (cisdata_t *)buf; | ||
| 859 | tuple->TupleDataMax = 255; | ||
| 860 | tuple->TupleOffset = 0; | ||
| 784 | 861 | ||
| 785 | /* Read the station address from tuple 0x90, subtuple 0x04 */ | 862 | /* Read the station address from tuple 0x90, subtuple 0x04 */ |
| 786 | tuple.DesiredTuple = 0x90; | 863 | tuple->DesiredTuple = 0x90; |
| 787 | i = pcmcia_get_first_tuple(handle, &tuple); | 864 | i = pcmcia_get_first_tuple(handle, tuple); |
| 788 | while (i == CS_SUCCESS) { | 865 | while (i == CS_SUCCESS) { |
| 789 | i = pcmcia_get_tuple_data(handle, &tuple); | 866 | i = pcmcia_get_tuple_data(handle, tuple); |
| 790 | if ((i != CS_SUCCESS) || (buf[0] == 0x04)) | 867 | if ((i != CS_SUCCESS) || (buf[0] == 0x04)) |
| 791 | break; | 868 | break; |
| 792 | i = pcmcia_get_next_tuple(handle, &tuple); | 869 | i = pcmcia_get_next_tuple(handle, tuple); |
| 870 | } | ||
| 871 | if (i != CS_SUCCESS) { | ||
| 872 | rc = -1; | ||
| 873 | goto free_cfg_mem; | ||
| 793 | } | 874 | } |
| 794 | if (i != CS_SUCCESS) | ||
| 795 | return -1; | ||
| 796 | for (i = 0; i < 6; i++) | 875 | for (i = 0; i < 6; i++) |
| 797 | dev->dev_addr[i] = buf[i+2]; | 876 | dev->dev_addr[i] = buf[i+2]; |
| 798 | 877 | ||
| @@ -814,8 +893,10 @@ static int osi_setup(dev_link_t *link, u_short manfid, u_short cardid) | |||
| 814 | inw(link->io.BasePort1 + OSITECH_AUI_PWR), | 893 | inw(link->io.BasePort1 + OSITECH_AUI_PWR), |
| 815 | inw(link->io.BasePort1 + OSITECH_RESET_ISR)); | 894 | inw(link->io.BasePort1 + OSITECH_RESET_ISR)); |
| 816 | } | 895 | } |
| 817 | 896 | rc = 0; | |
| 818 | return 0; | 897 | free_cfg_mem: |
| 898 | kfree(cfg_mem); | ||
| 899 | return rc; | ||
| 819 | } | 900 | } |
| 820 | 901 | ||
| 821 | /*====================================================================== | 902 | /*====================================================================== |
| @@ -887,9 +968,10 @@ static void smc91c92_config(dev_link_t *link) | |||
| 887 | client_handle_t handle = link->handle; | 968 | client_handle_t handle = link->handle; |
| 888 | struct net_device *dev = link->priv; | 969 | struct net_device *dev = link->priv; |
| 889 | struct smc_private *smc = netdev_priv(dev); | 970 | struct smc_private *smc = netdev_priv(dev); |
| 890 | tuple_t tuple; | 971 | struct smc_cfg_mem *cfg_mem; |
| 891 | cisparse_t parse; | 972 | tuple_t *tuple; |
| 892 | u_short buf[32]; | 973 | cisparse_t *parse; |
| 974 | u_char *buf; | ||
| 893 | char *name; | 975 | char *name; |
| 894 | int i, j, rev; | 976 | int i, j, rev; |
| 895 | kio_addr_t ioaddr; | 977 | kio_addr_t ioaddr; |
| @@ -897,21 +979,29 @@ static void smc91c92_config(dev_link_t *link) | |||
| 897 | 979 | ||
| 898 | DEBUG(0, "smc91c92_config(0x%p)\n", link); | 980 | DEBUG(0, "smc91c92_config(0x%p)\n", link); |
| 899 | 981 | ||
| 900 | tuple.Attributes = tuple.TupleOffset = 0; | 982 | cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); |
| 901 | tuple.TupleData = (cisdata_t *)buf; | 983 | if (!cfg_mem) |
| 902 | tuple.TupleDataMax = sizeof(buf); | 984 | goto config_failed; |
| 903 | 985 | ||
| 904 | tuple.DesiredTuple = CISTPL_CONFIG; | 986 | tuple = &cfg_mem->tuple; |
| 905 | i = first_tuple(handle, &tuple, &parse); | 987 | parse = &cfg_mem->parse; |
| 906 | CS_EXIT_TEST(i, ParseTuple, config_failed); | 988 | buf = cfg_mem->buf; |
| 907 | link->conf.ConfigBase = parse.config.base; | ||
| 908 | link->conf.Present = parse.config.rmask[0]; | ||
| 909 | 989 | ||
| 910 | tuple.DesiredTuple = CISTPL_MANFID; | 990 | tuple->Attributes = tuple->TupleOffset = 0; |
| 911 | tuple.Attributes = TUPLE_RETURN_COMMON; | 991 | tuple->TupleData = (cisdata_t *)buf; |
| 912 | if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) { | 992 | tuple->TupleDataMax = 64; |
| 913 | smc->manfid = parse.manfid.manf; | 993 | |
| 914 | smc->cardid = parse.manfid.card; | 994 | tuple->DesiredTuple = CISTPL_CONFIG; |
| 995 | i = first_tuple(handle, tuple, parse); | ||
| 996 | CS_EXIT_TEST(i, ParseTuple, config_failed); | ||
| 997 | link->conf.ConfigBase = parse->config.base; | ||
| 998 | link->conf.Present = parse->config.rmask[0]; | ||
| 999 | |||
| 1000 | tuple->DesiredTuple = CISTPL_MANFID; | ||
| 1001 | tuple->Attributes = TUPLE_RETURN_COMMON; | ||
| 1002 | if (first_tuple(handle, tuple, parse) == CS_SUCCESS) { | ||
| 1003 | smc->manfid = parse->manfid.manf; | ||
| 1004 | smc->cardid = parse->manfid.card; | ||
| 915 | } | 1005 | } |
| 916 | 1006 | ||
| 917 | /* Configure card */ | 1007 | /* Configure card */ |
| @@ -1046,7 +1136,7 @@ static void smc91c92_config(dev_link_t *link) | |||
| 1046 | printk(KERN_NOTICE " No MII transceivers found!\n"); | 1136 | printk(KERN_NOTICE " No MII transceivers found!\n"); |
| 1047 | } | 1137 | } |
| 1048 | } | 1138 | } |
| 1049 | 1139 | kfree(cfg_mem); | |
| 1050 | return; | 1140 | return; |
| 1051 | 1141 | ||
| 1052 | config_undo: | 1142 | config_undo: |
| @@ -1054,6 +1144,7 @@ config_undo: | |||
| 1054 | config_failed: /* CS_EXIT_TEST() calls jump to here... */ | 1144 | config_failed: /* CS_EXIT_TEST() calls jump to here... */ |
| 1055 | smc91c92_release(link); | 1145 | smc91c92_release(link); |
| 1056 | link->state &= ~DEV_CONFIG_PENDING; | 1146 | link->state &= ~DEV_CONFIG_PENDING; |
| 1147 | kfree(cfg_mem); | ||
| 1057 | 1148 | ||
| 1058 | } /* smc91c92_config */ | 1149 | } /* smc91c92_config */ |
| 1059 | 1150 | ||
