aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pcmcia/smc91c92_cs.c
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2009-10-18 17:54:24 -0400
committerDominik Brodowski <linux@dominikbrodowski.net>2009-11-08 12:23:05 -0500
commitdddfbd824b96a25da0b2f1cf35c0be33ef2422fe (patch)
tree0f48f2883bd00ec5f15d8d32a3c826a3184f47ba /drivers/net/pcmcia/smc91c92_cs.c
parent91284224da5b15ec6c2b45e10fa5eccd1c92a204 (diff)
pcmcia: convert net pcmcia drivers to use new CIS helpers
Use the new CIS helpers in net pcmcia drivers, which allows for a few code cleanups. This revision does not remove the phys_addr assignment in 3c589_cs.c -- a bug noted by Komuro <komurojun-mbn@nifty.com> CC: David S. Miller <davem@davemloft.net> CC: netdev@vger.kernel.org Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/net/pcmcia/smc91c92_cs.c')
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c238
1 files changed, 66 insertions, 172 deletions
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index af03759d186d..df92bcde9bcf 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -126,12 +126,6 @@ struct smc_private {
126 int rx_ovrn; 126 int rx_ovrn;
127}; 127};
128 128
129struct smc_cfg_mem {
130 tuple_t tuple;
131 cisparse_t parse;
132 u_char buf[255];
133};
134
135/* Special definitions for Megahertz multifunction cards */ 129/* Special definitions for Megahertz multifunction cards */
136#define MEGAHERTZ_ISR 0x0380 130#define MEGAHERTZ_ISR 0x0380
137 131
@@ -408,34 +402,7 @@ static int cvt_ascii_address(struct net_device *dev, char *s)
408 return 0; 402 return 0;
409} 403}
410 404
411/*====================================================================*/ 405/*====================================================================
412
413static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
414 cisparse_t *parse)
415{
416 int i;
417
418 i = pcmcia_get_first_tuple(handle, tuple);
419 if (i != 0)
420 return i;
421 i = pcmcia_get_tuple_data(handle, tuple);
422 if (i != 0)
423 return i;
424 return pcmcia_parse_tuple(tuple, parse);
425}
426
427static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
428 cisparse_t *parse)
429{
430 int i;
431
432 if ((i = pcmcia_get_next_tuple(handle, tuple)) != 0 ||
433 (i = pcmcia_get_tuple_data(handle, tuple)) != 0)
434 return i;
435 return pcmcia_parse_tuple(tuple, parse);
436}
437
438/*======================================================================
439 406
440 Configuration stuff for Megahertz cards 407 Configuration stuff for Megahertz cards
441 408
@@ -490,15 +457,10 @@ static int mhz_mfc_config(struct pcmcia_device *link)
490{ 457{
491 struct net_device *dev = link->priv; 458 struct net_device *dev = link->priv;
492 struct smc_private *smc = netdev_priv(dev); 459 struct smc_private *smc = netdev_priv(dev);
493 struct smc_cfg_mem *cfg_mem;
494 win_req_t req; 460 win_req_t req;
495 memreq_t mem; 461 memreq_t mem;
496 int i; 462 int i;
497 463
498 cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
499 if (!cfg_mem)
500 return -ENOMEM;
501
502 link->conf.Attributes |= CONF_ENABLE_SPKR; 464 link->conf.Attributes |= CONF_ENABLE_SPKR;
503 link->conf.Status = CCSR_AUDIO_ENA; 465 link->conf.Status = CCSR_AUDIO_ENA;
504 link->irq.Attributes = 466 link->irq.Attributes =
@@ -510,7 +472,8 @@ static int mhz_mfc_config(struct pcmcia_device *link)
510 /* The Megahertz combo cards have modem-like CIS entries, so 472 /* The Megahertz combo cards have modem-like CIS entries, so
511 we have to explicitly try a bunch of port combinations. */ 473 we have to explicitly try a bunch of port combinations. */
512 if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL)) 474 if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL))
513 goto free_cfg_mem; 475 return -ENODEV;
476
514 dev->base_addr = link->io.BasePort1; 477 dev->base_addr = link->io.BasePort1;
515 478
516 /* Allocate a memory window, for accessing the ISR */ 479 /* Allocate a memory window, for accessing the ISR */
@@ -519,7 +482,8 @@ static int mhz_mfc_config(struct pcmcia_device *link)
519 req.AccessSpeed = 0; 482 req.AccessSpeed = 0;
520 i = pcmcia_request_window(&link, &req, &link->win); 483 i = pcmcia_request_window(&link, &req, &link->win);
521 if (i != 0) 484 if (i != 0)
522 goto free_cfg_mem; 485 return -ENODEV;
486
523 smc->base = ioremap(req.Base, req.Size); 487 smc->base = ioremap(req.Base, req.Size);
524 mem.CardOffset = mem.Page = 0; 488 mem.CardOffset = mem.Page = 0;
525 if (smc->manfid == MANFID_MOTOROLA) 489 if (smc->manfid == MANFID_MOTOROLA)
@@ -531,18 +495,32 @@ static int mhz_mfc_config(struct pcmcia_device *link)
531 && (smc->cardid == PRODID_MEGAHERTZ_EM3288)) 495 && (smc->cardid == PRODID_MEGAHERTZ_EM3288))
532 mhz_3288_power(link); 496 mhz_3288_power(link);
533 497
534free_cfg_mem: 498 return 0;
535 kfree(cfg_mem);
536 return -ENODEV;
537} 499}
538 500
501static int pcmcia_get_versmac(struct pcmcia_device *p_dev,
502 tuple_t *tuple,
503 void *priv)
504{
505 struct net_device *dev = priv;
506 cisparse_t parse;
507
508 if (pcmcia_parse_tuple(tuple, &parse))
509 return -EINVAL;
510
511 if ((parse.version_1.ns > 3) &&
512 (cvt_ascii_address(dev,
513 (parse.version_1.str + parse.version_1.ofs[3]))))
514 return 0;
515
516 return -EINVAL;
517};
518
539static int mhz_setup(struct pcmcia_device *link) 519static int mhz_setup(struct pcmcia_device *link)
540{ 520{
541 struct net_device *dev = link->priv; 521 struct net_device *dev = link->priv;
542 struct smc_cfg_mem *cfg_mem; 522 size_t len;
543 tuple_t *tuple; 523 u8 *buf;
544 cisparse_t *parse;
545 u_char *buf, *station_addr;
546 int rc; 524 int rc;
547 525
548 /* Read the station address from the CIS. It is stored as the last 526 /* Read the station address from the CIS. It is stored as the last
@@ -552,56 +530,22 @@ static int mhz_setup(struct pcmcia_device *link)
552 return 0; 530 return 0;
553 531
554 /* Workarounds for broken cards start here. */ 532 /* Workarounds for broken cards start here. */
555
556 cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
557 if (!cfg_mem)
558 return -1;
559
560 tuple = &cfg_mem->tuple;
561 parse = &cfg_mem->parse;
562 buf = cfg_mem->buf;
563
564 tuple->Attributes = tuple->TupleOffset = 0;
565 tuple->TupleData = (cisdata_t *)buf;
566 tuple->TupleDataMax = 255;
567
568 /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */ 533 /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
569 tuple->DesiredTuple = CISTPL_VERS_1; 534 if (!pcmcia_loop_tuple(link, CISTPL_VERS_1, pcmcia_get_versmac, dev))
570 if (first_tuple(link, tuple, parse) != 0) { 535 return 0;
571 rc = -1;
572 goto free_cfg_mem;
573 }
574 /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
575 if (next_tuple(link, tuple, parse) != 0)
576 first_tuple(link, tuple, parse);
577 if (parse->version_1.ns > 3) {
578 station_addr = parse->version_1.str + parse->version_1.ofs[3];
579 if (cvt_ascii_address(dev, station_addr) == 0) {
580 rc = 0;
581 goto free_cfg_mem;
582 }
583 }
584 536
585 /* Another possibility: for the EM3288, in a special tuple */ 537 /* Another possibility: for the EM3288, in a special tuple */
586 tuple->DesiredTuple = 0x81;
587 if (pcmcia_get_first_tuple(link, tuple) != 0) {
588 rc = -1;
589 goto free_cfg_mem;
590 }
591 if (pcmcia_get_tuple_data(link, tuple) != 0) {
592 rc = -1;
593 goto free_cfg_mem;
594 }
595 buf[12] = '\0';
596 if (cvt_ascii_address(dev, buf) == 0) {
597 rc = 0;
598 goto free_cfg_mem;
599 }
600 rc = -1; 538 rc = -1;
601free_cfg_mem: 539 len = pcmcia_get_tuple(link, 0x81, &buf);
602 kfree(cfg_mem); 540 if (buf && len >= 13) {
603 return rc; 541 buf[12] = '\0';
604} 542 if (cvt_ascii_address(dev, buf))
543 rc = 0;
544 }
545 kfree(buf);
546
547 return rc;
548};
605 549
606/*====================================================================== 550/*======================================================================
607 551
@@ -691,58 +635,21 @@ static int smc_config(struct pcmcia_device *link)
691 return i; 635 return i;
692} 636}
693 637
638
694static int smc_setup(struct pcmcia_device *link) 639static int smc_setup(struct pcmcia_device *link)
695{ 640{
696 struct net_device *dev = link->priv; 641 struct net_device *dev = link->priv;
697 struct smc_cfg_mem *cfg_mem;
698 tuple_t *tuple;
699 cisparse_t *parse;
700 cistpl_lan_node_id_t *node_id;
701 u_char *buf, *station_addr;
702 int i, rc;
703
704 cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
705 if (!cfg_mem)
706 return -ENOMEM;
707
708 tuple = &cfg_mem->tuple;
709 parse = &cfg_mem->parse;
710 buf = cfg_mem->buf;
711
712 tuple->Attributes = tuple->TupleOffset = 0;
713 tuple->TupleData = (cisdata_t *)buf;
714 tuple->TupleDataMax = 255;
715 642
716 /* Check for a LAN function extension tuple */ 643 /* Check for a LAN function extension tuple */
717 tuple->DesiredTuple = CISTPL_FUNCE; 644 if (!pcmcia_get_mac_from_cis(link, dev))
718 i = first_tuple(link, tuple, parse); 645 return 0;
719 while (i == 0) { 646
720 if (parse->funce.type == CISTPL_FUNCE_LAN_NODE_ID)
721 break;
722 i = next_tuple(link, tuple, parse);
723 }
724 if (i == 0) {
725 node_id = (cistpl_lan_node_id_t *)parse->funce.data;
726 if (node_id->nb == 6) {
727 for (i = 0; i < 6; i++)
728 dev->dev_addr[i] = node_id->id[i];
729 rc = 0;
730 goto free_cfg_mem;
731 }
732 }
733 /* Try the third string in the Version 1 Version/ID tuple. */ 647 /* Try the third string in the Version 1 Version/ID tuple. */
734 if (link->prod_id[2]) { 648 if (link->prod_id[2]) {
735 station_addr = link->prod_id[2]; 649 if (cvt_ascii_address(dev, link->prod_id[2]) == 0)
736 if (cvt_ascii_address(dev, station_addr) == 0) { 650 return 0;
737 rc = 0;
738 goto free_cfg_mem;
739 }
740 } 651 }
741 652 return -1;
742 rc = -1;
743free_cfg_mem:
744 kfree(cfg_mem);
745 return rc;
746} 653}
747 654
748/*====================================================================*/ 655/*====================================================================*/
@@ -801,41 +708,31 @@ static int osi_load_firmware(struct pcmcia_device *link)
801 return err; 708 return err;
802} 709}
803 710
804static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid) 711static int pcmcia_osi_mac(struct pcmcia_device *p_dev,
712 tuple_t *tuple,
713 void *priv)
805{ 714{
806 struct net_device *dev = link->priv; 715 struct net_device *dev = priv;
807 struct smc_cfg_mem *cfg_mem; 716 int i;
808 tuple_t *tuple;
809 u_char *buf;
810 int i, rc;
811 717
812 cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); 718 if (tuple->TupleDataLen < 8)
813 if (!cfg_mem) 719 return -EINVAL;
814 return -1; 720 if (tuple->TupleData[0] != 0x04)
721 return -EINVAL;
722 for (i = 0; i < 6; i++)
723 dev->dev_addr[i] = tuple->TupleData[i+2];
724 return 0;
725};
815 726
816 tuple = &cfg_mem->tuple;
817 buf = cfg_mem->buf;
818 727
819 tuple->Attributes = TUPLE_RETURN_COMMON; 728static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
820 tuple->TupleData = (cisdata_t *)buf; 729{
821 tuple->TupleDataMax = 255; 730 struct net_device *dev = link->priv;
822 tuple->TupleOffset = 0; 731 int rc;
823 732
824 /* Read the station address from tuple 0x90, subtuple 0x04 */ 733 /* Read the station address from tuple 0x90, subtuple 0x04 */
825 tuple->DesiredTuple = 0x90; 734 if (pcmcia_loop_tuple(link, 0x90, pcmcia_osi_mac, dev))
826 i = pcmcia_get_first_tuple(link, tuple); 735 return -1;
827 while (i == 0) {
828 i = pcmcia_get_tuple_data(link, tuple);
829 if ((i != 0) || (buf[0] == 0x04))
830 break;
831 i = pcmcia_get_next_tuple(link, tuple);
832 }
833 if (i != 0) {
834 rc = -1;
835 goto free_cfg_mem;
836 }
837 for (i = 0; i < 6; i++)
838 dev->dev_addr[i] = buf[i+2];
839 736
840 if (((manfid == MANFID_OSITECH) && 737 if (((manfid == MANFID_OSITECH) &&
841 (cardid == PRODID_OSITECH_SEVEN)) || 738 (cardid == PRODID_OSITECH_SEVEN)) ||
@@ -843,7 +740,7 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
843 (cardid == PRODID_PSION_NET100))) { 740 (cardid == PRODID_PSION_NET100))) {
844 rc = osi_load_firmware(link); 741 rc = osi_load_firmware(link);
845 if (rc) 742 if (rc)
846 goto free_cfg_mem; 743 return rc;
847 } else if (manfid == MANFID_OSITECH) { 744 } else if (manfid == MANFID_OSITECH) {
848 /* Make sure both functions are powered up */ 745 /* Make sure both functions are powered up */
849 set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR); 746 set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR);
@@ -853,10 +750,7 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
853 inw(link->io.BasePort1 + OSITECH_AUI_PWR), 750 inw(link->io.BasePort1 + OSITECH_AUI_PWR),
854 inw(link->io.BasePort1 + OSITECH_RESET_ISR)); 751 inw(link->io.BasePort1 + OSITECH_RESET_ISR));
855 } 752 }
856 rc = 0; 753 return 0;
857free_cfg_mem:
858 kfree(cfg_mem);
859 return rc;
860} 754}
861 755
862static int smc91c92_suspend(struct pcmcia_device *link) 756static int smc91c92_suspend(struct pcmcia_device *link)