diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2009-10-18 17:54:24 -0400 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2009-11-08 12:23:05 -0500 |
commit | dddfbd824b96a25da0b2f1cf35c0be33ef2422fe (patch) | |
tree | 0f48f2883bd00ec5f15d8d32a3c826a3184f47ba /drivers/net/pcmcia/xirc2ps_cs.c | |
parent | 91284224da5b15ec6c2b45e10fa5eccd1c92a204 (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/xirc2ps_cs.c')
-rw-r--r-- | drivers/net/pcmcia/xirc2ps_cs.c | 147 |
1 files changed, 58 insertions, 89 deletions
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index 5e203230144f..925e85096629 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c | |||
@@ -359,7 +359,7 @@ static void xirc_tx_timeout(struct net_device *dev); | |||
359 | static void xirc2ps_tx_timeout_task(struct work_struct *work); | 359 | static void xirc2ps_tx_timeout_task(struct work_struct *work); |
360 | static void set_addresses(struct net_device *dev); | 360 | static void set_addresses(struct net_device *dev); |
361 | static void set_multicast_list(struct net_device *dev); | 361 | static void set_multicast_list(struct net_device *dev); |
362 | static int set_card_type(struct pcmcia_device *link, const void *s); | 362 | static int set_card_type(struct pcmcia_device *link); |
363 | static int do_config(struct net_device *dev, struct ifmap *map); | 363 | static int do_config(struct net_device *dev, struct ifmap *map); |
364 | static int do_open(struct net_device *dev); | 364 | static int do_open(struct net_device *dev); |
365 | static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | 365 | static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); |
@@ -371,28 +371,6 @@ static void do_powerdown(struct net_device *dev); | |||
371 | static int do_stop(struct net_device *dev); | 371 | static int do_stop(struct net_device *dev); |
372 | 372 | ||
373 | /*=============== Helper functions =========================*/ | 373 | /*=============== Helper functions =========================*/ |
374 | static int | ||
375 | first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) | ||
376 | { | ||
377 | int err; | ||
378 | |||
379 | if ((err = pcmcia_get_first_tuple(handle, tuple)) == 0 && | ||
380 | (err = pcmcia_get_tuple_data(handle, tuple)) == 0) | ||
381 | err = pcmcia_parse_tuple(tuple, parse); | ||
382 | return err; | ||
383 | } | ||
384 | |||
385 | static int | ||
386 | next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) | ||
387 | { | ||
388 | int err; | ||
389 | |||
390 | if ((err = pcmcia_get_next_tuple(handle, tuple)) == 0 && | ||
391 | (err = pcmcia_get_tuple_data(handle, tuple)) == 0) | ||
392 | err = pcmcia_parse_tuple(tuple, parse); | ||
393 | return err; | ||
394 | } | ||
395 | |||
396 | #define SelectPage(pgnr) outb((pgnr), ioaddr + XIRCREG_PR) | 374 | #define SelectPage(pgnr) outb((pgnr), ioaddr + XIRCREG_PR) |
397 | #define GetByte(reg) ((unsigned)inb(ioaddr + (reg))) | 375 | #define GetByte(reg) ((unsigned)inb(ioaddr + (reg))) |
398 | #define GetWord(reg) ((unsigned)inw(ioaddr + (reg))) | 376 | #define GetWord(reg) ((unsigned)inw(ioaddr + (reg))) |
@@ -644,15 +622,23 @@ xirc2ps_detach(struct pcmcia_device *link) | |||
644 | * | 622 | * |
645 | */ | 623 | */ |
646 | static int | 624 | static int |
647 | set_card_type(struct pcmcia_device *link, const void *s) | 625 | set_card_type(struct pcmcia_device *link) |
648 | { | 626 | { |
649 | struct net_device *dev = link->priv; | 627 | struct net_device *dev = link->priv; |
650 | local_info_t *local = netdev_priv(dev); | 628 | local_info_t *local = netdev_priv(dev); |
651 | #ifdef PCMCIA_DEBUG | 629 | u8 *buf; |
652 | unsigned cisrev = ((const unsigned char *)s)[2]; | 630 | unsigned int cisrev, mediaid, prodid; |
653 | #endif | 631 | size_t len; |
654 | unsigned mediaid= ((const unsigned char *)s)[3]; | 632 | |
655 | unsigned prodid = ((const unsigned char *)s)[4]; | 633 | len = pcmcia_get_tuple(link, CISTPL_MANFID, &buf); |
634 | if (len < 5) { | ||
635 | dev_err(&link->dev, "invalid CIS -- sorry\n"); | ||
636 | return 0; | ||
637 | } | ||
638 | |||
639 | cisrev = buf[2]; | ||
640 | mediaid = buf[3]; | ||
641 | prodid = buf[4]; | ||
656 | 642 | ||
657 | DEBUG(0, "cisrev=%02x mediaid=%02x prodid=%02x\n", | 643 | DEBUG(0, "cisrev=%02x mediaid=%02x prodid=%02x\n", |
658 | cisrev, mediaid, prodid); | 644 | cisrev, mediaid, prodid); |
@@ -761,6 +747,26 @@ xirc2ps_config_check(struct pcmcia_device *p_dev, | |||
761 | 747 | ||
762 | } | 748 | } |
763 | 749 | ||
750 | |||
751 | static int pcmcia_get_mac_ce(struct pcmcia_device *p_dev, | ||
752 | tuple_t *tuple, | ||
753 | void *priv) | ||
754 | { | ||
755 | struct net_device *dev = priv; | ||
756 | int i; | ||
757 | |||
758 | if (tuple->TupleDataLen != 13) | ||
759 | return -EINVAL; | ||
760 | if ((tuple->TupleData[0] != 2) || (tuple->TupleData[1] != 1) || | ||
761 | (tuple->TupleData[2] != 6)) | ||
762 | return -EINVAL; | ||
763 | /* another try (James Lehmer's CE2 version 4.1)*/ | ||
764 | for (i = 2; i < 6; i++) | ||
765 | dev->dev_addr[i] = tuple->TupleData[i+2]; | ||
766 | return 0; | ||
767 | }; | ||
768 | |||
769 | |||
764 | /**************** | 770 | /**************** |
765 | * xirc2ps_config() is scheduled to run after a CARD_INSERTION event | 771 | * xirc2ps_config() is scheduled to run after a CARD_INSERTION event |
766 | * is received, to configure the PCMCIA socket, and to make the | 772 | * is received, to configure the PCMCIA socket, and to make the |
@@ -772,25 +778,14 @@ xirc2ps_config(struct pcmcia_device * link) | |||
772 | struct net_device *dev = link->priv; | 778 | struct net_device *dev = link->priv; |
773 | local_info_t *local = netdev_priv(dev); | 779 | local_info_t *local = netdev_priv(dev); |
774 | unsigned int ioaddr; | 780 | unsigned int ioaddr; |
775 | tuple_t tuple; | 781 | int err; |
776 | cisparse_t parse; | 782 | u8 *buf; |
777 | int err, i; | 783 | size_t len; |
778 | u_char buf[64]; | ||
779 | cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data; | ||
780 | 784 | ||
781 | local->dingo_ccr = NULL; | 785 | local->dingo_ccr = NULL; |
782 | 786 | ||
783 | DEBUG(0, "config(0x%p)\n", link); | 787 | DEBUG(0, "config(0x%p)\n", link); |
784 | 788 | ||
785 | /* | ||
786 | * This reads the card's CONFIG tuple to find its configuration | ||
787 | * registers. | ||
788 | */ | ||
789 | tuple.Attributes = 0; | ||
790 | tuple.TupleData = buf; | ||
791 | tuple.TupleDataMax = 64; | ||
792 | tuple.TupleOffset = 0; | ||
793 | |||
794 | /* Is this a valid card */ | 789 | /* Is this a valid card */ |
795 | if (link->has_manf_id == 0) { | 790 | if (link->has_manf_id == 0) { |
796 | printk(KNOT_XIRC "manfid not found in CIS\n"); | 791 | printk(KNOT_XIRC "manfid not found in CIS\n"); |
@@ -816,67 +811,41 @@ xirc2ps_config(struct pcmcia_device * link) | |||
816 | break; | 811 | break; |
817 | default: | 812 | default: |
818 | printk(KNOT_XIRC "Unknown Card Manufacturer ID: 0x%04x\n", | 813 | printk(KNOT_XIRC "Unknown Card Manufacturer ID: 0x%04x\n", |
819 | (unsigned)parse.manfid.manf); | 814 | (unsigned)link->manf_id); |
820 | goto failure; | 815 | goto failure; |
821 | } | 816 | } |
822 | DEBUG(0, "found %s card\n", local->manf_str); | 817 | DEBUG(0, "found %s card\n", local->manf_str); |
823 | 818 | ||
824 | /* needed for the additional fields to be parsed by set_card_type() */ | 819 | if (!set_card_type(link)) { |
825 | tuple.DesiredTuple = CISTPL_MANFID; | ||
826 | err = first_tuple(link, &tuple, &parse) | ||
827 | if (err) { | ||
828 | printk(KNOT_XIRC "manfid not found in CIS\n"); | ||
829 | goto failure; | ||
830 | } | ||
831 | if (!set_card_type(link, buf)) { | ||
832 | printk(KNOT_XIRC "this card is not supported\n"); | 820 | printk(KNOT_XIRC "this card is not supported\n"); |
833 | goto failure; | 821 | goto failure; |
834 | } | 822 | } |
835 | 823 | ||
836 | /* get the ethernet address from the CIS */ | 824 | /* get the ethernet address from the CIS */ |
837 | tuple.DesiredTuple = CISTPL_FUNCE; | 825 | err = pcmcia_get_mac_from_cis(link, dev); |
838 | for (err = first_tuple(link, &tuple, &parse); !err; | 826 | |
839 | err = next_tuple(link, &tuple, &parse)) { | 827 | /* not found: try to get the node-id from tuple 0x89 */ |
840 | /* Once I saw two CISTPL_FUNCE_LAN_NODE_ID entries: | 828 | if (err) { |
841 | * the first one with a length of zero the second correct - | 829 | len = pcmcia_get_tuple(link, 0x89, &buf); |
842 | * so I skip all entries with length 0 */ | 830 | /* data layout looks like tuple 0x22 */ |
843 | if (parse.funce.type == CISTPL_FUNCE_LAN_NODE_ID | 831 | if (buf && len == 8) { |
844 | && ((cistpl_lan_node_id_t *)parse.funce.data)->nb) | 832 | if (*buf == CISTPL_FUNCE_LAN_NODE_ID) { |
845 | break; | 833 | int i; |
846 | } | 834 | for (i = 2; i < 6; i++) |
847 | if (err) { /* not found: try to get the node-id from tuple 0x89 */ | 835 | dev->dev_addr[i] = buf[i+2]; |
848 | tuple.DesiredTuple = 0x89; /* data layout looks like tuple 0x22 */ | 836 | } else |
849 | if ((err = pcmcia_get_first_tuple(link, &tuple)) == 0 && | 837 | err = -1; |
850 | (err = pcmcia_get_tuple_data(link, &tuple)) == 0) { | ||
851 | if (tuple.TupleDataLen == 8 && *buf == CISTPL_FUNCE_LAN_NODE_ID) | ||
852 | memcpy(&parse, buf, 8); | ||
853 | else | ||
854 | err = -1; | ||
855 | } | ||
856 | } | ||
857 | if (err) { /* another try (James Lehmer's CE2 version 4.1)*/ | ||
858 | tuple.DesiredTuple = CISTPL_FUNCE; | ||
859 | for (err = first_tuple(link, &tuple, &parse); !err; | ||
860 | err = next_tuple(link, &tuple, &parse)) { | ||
861 | if (parse.funce.type == 0x02 && parse.funce.data[0] == 1 | ||
862 | && parse.funce.data[1] == 6 && tuple.TupleDataLen == 13) { | ||
863 | buf[1] = 4; | ||
864 | memcpy(&parse, buf+1, 8); | ||
865 | break; | ||
866 | } | 838 | } |
867 | } | 839 | kfree(buf); |
868 | } | 840 | } |
841 | |||
842 | if (err) | ||
843 | err = pcmcia_loop_tuple(link, CISTPL_FUNCE, pcmcia_get_mac_ce, dev); | ||
844 | |||
869 | if (err) { | 845 | if (err) { |
870 | printk(KNOT_XIRC "node-id not found in CIS\n"); | 846 | printk(KNOT_XIRC "node-id not found in CIS\n"); |
871 | goto failure; | 847 | goto failure; |
872 | } | 848 | } |
873 | node_id = (cistpl_lan_node_id_t *)parse.funce.data; | ||
874 | if (node_id->nb != 6) { | ||
875 | printk(KNOT_XIRC "malformed node-id in CIS\n"); | ||
876 | goto failure; | ||
877 | } | ||
878 | for (i=0; i < 6; i++) | ||
879 | dev->dev_addr[i] = node_id->id[i]; | ||
880 | 849 | ||
881 | link->io.IOAddrLines =10; | 850 | link->io.IOAddrLines =10; |
882 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; | 851 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; |