aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ibmlana.c109
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
893static int ibmlana_irq;
894static int ibmlana_io;
893static int startslot; /* counts through slots when probing multiple devices */ 895static int startslot; /* counts through slots when probing multiple devices */
894 896
895static int ibmlana_probe(struct net_device *dev) 897static 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
1019err_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);
1024err_out_reg:
1025 release_region(iobase, IBM_LANA_IORANGE);
1026err_out:
1027 free_netdev(dev);
1028 return rc;
1029}
1030
1031static 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
1010static struct net_device *moddevs[DEVMAX]; 1052static struct net_device *moddevs[DEVMAX];
1011static int irq;
1012static int io;
1013 1053
1014module_param(irq, int, 0); 1054module_param_named(irq, ibmlana_irq, int, 0);
1015module_param(io, int, 0); 1055module_param_named(io, ibmlana_io, int, 0);
1016MODULE_PARM_DESC(irq, "IBM LAN/A IRQ number"); 1056MODULE_PARM_DESC(irq, "IBM LAN/A IRQ number");
1017MODULE_PARM_DESC(io, "IBM LAN/A I/O base address"); 1057MODULE_PARM_DESC(io, "IBM LAN/A I/O base address");
1018MODULE_LICENSE("GPL"); 1058MODULE_LICENSE("GPL");
1019 1059
1020int init_module(void) 1060static 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
1050void cleanup_module(void) 1076static 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
1086module_init(ibmlana_init_module);
1087module_exit(ibmlana_cleanup_module);