aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pcmcia/smc91c92_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/pcmcia/smc91c92_cs.c')
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c287
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
130struct 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
575free_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;
636free_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)
665static int smc_config(dev_link_t *link) 705static 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;
801free_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; 897free_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
1052config_undo: 1142config_undo:
@@ -1054,6 +1144,7 @@ config_undo:
1054config_failed: /* CS_EXIT_TEST() calls jump to here... */ 1144config_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