diff options
-rw-r--r-- | drivers/net/ibmlana.c | 109 |
1 files changed, 64 insertions, 45 deletions
diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c index 65626d61de46..6969bf17588f 100644 --- a/drivers/net/ibmlana.c +++ b/drivers/net/ibmlana.c | |||
@@ -890,11 +890,14 @@ static void ibmlana_set_multicast_list(struct net_device *dev) | |||
890 | * hardware check | 890 | * hardware check |
891 | * ------------------------------------------------------------------------ */ | 891 | * ------------------------------------------------------------------------ */ |
892 | 892 | ||
893 | static int ibmlana_irq; | ||
894 | static int ibmlana_io; | ||
893 | static int startslot; /* counts through slots when probing multiple devices */ | 895 | static int startslot; /* counts through slots when probing multiple devices */ |
894 | 896 | ||
895 | static int ibmlana_probe(struct net_device *dev) | 897 | static int ibmlana_probe(struct net_device **dev_out) |
896 | { | 898 | { |
897 | int slot, z; | 899 | struct net_device *dev; |
900 | int slot, z, rc; | ||
898 | int base = 0, irq = 0, iobase = 0, memlen = 0; | 901 | int base = 0, irq = 0, iobase = 0, memlen = 0; |
899 | ibmlana_priv *priv; | 902 | ibmlana_priv *priv; |
900 | ibmlana_medium medium; | 903 | ibmlana_medium medium; |
@@ -904,6 +907,13 @@ static int ibmlana_probe(struct net_device *dev) | |||
904 | if (MCA_bus == 0) | 907 | if (MCA_bus == 0) |
905 | return -ENODEV; | 908 | return -ENODEV; |
906 | 909 | ||
910 | dev = alloc_etherdev(sizeof(ibmlana_priv)); | ||
911 | if (!dev) | ||
912 | return -ENOMEM; | ||
913 | |||
914 | dev->irq = ibmlana_irq; | ||
915 | dev->base_addr = ibmlana_io; | ||
916 | |||
907 | base = dev->mem_start; | 917 | base = dev->mem_start; |
908 | irq = dev->irq; | 918 | irq = dev->irq; |
909 | 919 | ||
@@ -924,8 +934,10 @@ static int ibmlana_probe(struct net_device *dev) | |||
924 | } | 934 | } |
925 | 935 | ||
926 | /* nothing found ? */ | 936 | /* nothing found ? */ |
927 | if (slot == -1) | 937 | if (slot == -1) { |
928 | return (base != 0 || irq != 0) ? -ENXIO : -ENODEV; | 938 | rc = (base != 0 || irq != 0) ? -ENXIO : -ENODEV; |
939 | goto err_out; | ||
940 | } | ||
929 | 941 | ||
930 | /* announce success */ | 942 | /* announce success */ |
931 | printk(KERN_INFO "%s: IBM LAN Adapter/A found in slot %d\n", dev->name, slot + 1); | 943 | printk(KERN_INFO "%s: IBM LAN Adapter/A found in slot %d\n", dev->name, slot + 1); |
@@ -934,7 +946,8 @@ static int ibmlana_probe(struct net_device *dev) | |||
934 | if (!request_region(iobase, IBM_LANA_IORANGE, DRV_NAME)) { | 946 | if (!request_region(iobase, IBM_LANA_IORANGE, DRV_NAME)) { |
935 | printk(KERN_ERR "%s: cannot allocate I/O range at %#x!\n", DRV_NAME, iobase); | 947 | printk(KERN_ERR "%s: cannot allocate I/O range at %#x!\n", DRV_NAME, iobase); |
936 | startslot = slot + 1; | 948 | startslot = slot + 1; |
937 | return -EBUSY; | 949 | rc = -EBUSY; |
950 | goto err_out; | ||
938 | } | 951 | } |
939 | 952 | ||
940 | priv = netdev_priv(dev); | 953 | priv = netdev_priv(dev); |
@@ -955,8 +968,8 @@ static int ibmlana_probe(struct net_device *dev) | |||
955 | if (!priv->base) { | 968 | if (!priv->base) { |
956 | printk(KERN_ERR "%s: cannot remap memory!\n", DRV_NAME); | 969 | printk(KERN_ERR "%s: cannot remap memory!\n", DRV_NAME); |
957 | startslot = slot + 1; | 970 | startslot = slot + 1; |
958 | release_region(iobase, IBM_LANA_IORANGE); | 971 | rc = -EBUSY; |
959 | return -EBUSY; | 972 | goto err_out_reg; |
960 | } | 973 | } |
961 | 974 | ||
962 | /* make procfs entries */ | 975 | /* make procfs entries */ |
@@ -996,73 +1009,79 @@ static int ibmlana_probe(struct net_device *dev) | |||
996 | 1009 | ||
997 | startslot = slot + 1; | 1010 | startslot = slot + 1; |
998 | 1011 | ||
1012 | rc = register_netdev(dev); | ||
1013 | if (rc) | ||
1014 | goto err_out_claimed; | ||
1015 | |||
1016 | *dev_out = dev; | ||
999 | return 0; | 1017 | return 0; |
1018 | |||
1019 | err_out_claimed: | ||
1020 | mca_mark_as_unused(priv->slot); | ||
1021 | mca_set_adapter_name(priv->slot, ""); | ||
1022 | mca_set_adapter_procfn(priv->slot, NULL, NULL); | ||
1023 | iounmap(priv->base); | ||
1024 | err_out_reg: | ||
1025 | release_region(iobase, IBM_LANA_IORANGE); | ||
1026 | err_out: | ||
1027 | free_netdev(dev); | ||
1028 | return rc; | ||
1029 | } | ||
1030 | |||
1031 | static void ibmlana_remove_one(struct net_device *_dev) | ||
1032 | { | ||
1033 | struct net_device *dev = _dev; | ||
1034 | ibmlana_priv *priv = netdev_priv(dev); | ||
1035 | |||
1036 | unregister_netdev(dev); | ||
1037 | /*DeinitBoard(dev); */ | ||
1038 | release_region(dev->base_addr, IBM_LANA_IORANGE); | ||
1039 | mca_mark_as_unused(priv->slot); | ||
1040 | mca_set_adapter_name(priv->slot, ""); | ||
1041 | mca_set_adapter_procfn(priv->slot, NULL, NULL); | ||
1042 | iounmap(priv->base); | ||
1043 | free_netdev(dev); | ||
1000 | } | 1044 | } |
1001 | 1045 | ||
1002 | /* ------------------------------------------------------------------------ | 1046 | /* ------------------------------------------------------------------------ |
1003 | * modularization support | 1047 | * modularization support |
1004 | * ------------------------------------------------------------------------ */ | 1048 | * ------------------------------------------------------------------------ */ |
1005 | 1049 | ||
1006 | #ifdef MODULE | ||
1007 | |||
1008 | #define DEVMAX 5 | 1050 | #define DEVMAX 5 |
1009 | 1051 | ||
1010 | static struct net_device *moddevs[DEVMAX]; | 1052 | static struct net_device *moddevs[DEVMAX]; |
1011 | static int irq; | ||
1012 | static int io; | ||
1013 | 1053 | ||
1014 | module_param(irq, int, 0); | 1054 | module_param_named(irq, ibmlana_irq, int, 0); |
1015 | module_param(io, int, 0); | 1055 | module_param_named(io, ibmlana_io, int, 0); |
1016 | MODULE_PARM_DESC(irq, "IBM LAN/A IRQ number"); | 1056 | MODULE_PARM_DESC(irq, "IBM LAN/A IRQ number"); |
1017 | MODULE_PARM_DESC(io, "IBM LAN/A I/O base address"); | 1057 | MODULE_PARM_DESC(io, "IBM LAN/A I/O base address"); |
1018 | MODULE_LICENSE("GPL"); | 1058 | MODULE_LICENSE("GPL"); |
1019 | 1059 | ||
1020 | int init_module(void) | 1060 | static int __init ibmlana_init_module(void) |
1021 | { | 1061 | { |
1022 | int z; | 1062 | int z; |
1023 | 1063 | ||
1024 | startslot = 0; | 1064 | startslot = 0; |
1025 | for (z = 0; z < DEVMAX; z++) { | 1065 | for (z = 0; z < DEVMAX; z++) { |
1026 | struct net_device *dev = alloc_etherdev(sizeof(ibmlana_priv)); | 1066 | struct net_device *dev = NULL; |
1027 | if (!dev) | 1067 | |
1028 | break; | 1068 | if (ibmlana_probe(&dev)) |
1029 | dev->irq = irq; | ||
1030 | dev->base_addr = io; | ||
1031 | if (ibmlana_probe(dev)) { | ||
1032 | free_netdev(dev); | ||
1033 | break; | ||
1034 | } | ||
1035 | if (register_netdev(dev)) { | ||
1036 | ibmlana_priv *priv = netdev_priv(dev); | ||
1037 | release_region(dev->base_addr, IBM_LANA_IORANGE); | ||
1038 | mca_mark_as_unused(priv->slot); | ||
1039 | mca_set_adapter_name(priv->slot, ""); | ||
1040 | mca_set_adapter_procfn(priv->slot, NULL, NULL); | ||
1041 | iounmap(priv->base); | ||
1042 | free_netdev(dev); | ||
1043 | break; | 1069 | break; |
1044 | } | 1070 | |
1045 | moddevs[z] = dev; | 1071 | moddevs[z] = dev; |
1046 | } | 1072 | } |
1047 | return (z > 0) ? 0 : -EIO; | 1073 | return (z > 0) ? 0 : -EIO; |
1048 | } | 1074 | } |
1049 | 1075 | ||
1050 | void cleanup_module(void) | 1076 | static void __exit ibmlana_cleanup_module(void) |
1051 | { | 1077 | { |
1052 | int z; | 1078 | int z; |
1053 | for (z = 0; z < DEVMAX; z++) { | 1079 | for (z = 0; z < DEVMAX; z++) { |
1054 | struct net_device *dev = moddevs[z]; | 1080 | struct net_device *dev = moddevs[z]; |
1055 | if (dev) { | 1081 | if (dev) |
1056 | ibmlana_priv *priv = netdev_priv(dev); | 1082 | ibmlana_remove_one(dev); |
1057 | unregister_netdev(dev); | ||
1058 | /*DeinitBoard(dev); */ | ||
1059 | release_region(dev->base_addr, IBM_LANA_IORANGE); | ||
1060 | mca_mark_as_unused(priv->slot); | ||
1061 | mca_set_adapter_name(priv->slot, ""); | ||
1062 | mca_set_adapter_procfn(priv->slot, NULL, NULL); | ||
1063 | iounmap(priv->base); | ||
1064 | free_netdev(dev); | ||
1065 | } | ||
1066 | } | 1083 | } |
1067 | } | 1084 | } |
1068 | #endif /* MODULE */ | 1085 | |
1086 | module_init(ibmlana_init_module); | ||
1087 | module_exit(ibmlana_cleanup_module); | ||