diff options
-rw-r--r-- | drivers/net/myri_sbus.c | 116 |
1 files changed, 61 insertions, 55 deletions
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index 6c86dca62e2a..d9f616fea3d9 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c | |||
@@ -1,10 +1,10 @@ | |||
1 | /* myri_sbus.h: MyriCOM MyriNET SBUS card driver. | 1 | /* myri_sbus.c: MyriCOM MyriNET SBUS card driver. |
2 | * | 2 | * |
3 | * Copyright (C) 1996, 1999 David S. Miller (davem@redhat.com) | 3 | * Copyright (C) 1996, 1999, 2006 David S. Miller (davem@davemloft.net) |
4 | */ | 4 | */ |
5 | 5 | ||
6 | static char version[] = | 6 | static char version[] = |
7 | "myri_sbus.c:v1.9 12/Sep/99 David S. Miller (davem@redhat.com)\n"; | 7 | "myri_sbus.c:v2.0 June 23, 2006 David S. Miller (davem@davemloft.net)\n"; |
8 | 8 | ||
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/config.h> | 10 | #include <linux/config.h> |
@@ -81,10 +81,6 @@ static char version[] = | |||
81 | #define DHDR(x) | 81 | #define DHDR(x) |
82 | #endif | 82 | #endif |
83 | 83 | ||
84 | #ifdef MODULE | ||
85 | static struct myri_eth *root_myri_dev; | ||
86 | #endif | ||
87 | |||
88 | static void myri_reset_off(void __iomem *lp, void __iomem *cregs) | 84 | static void myri_reset_off(void __iomem *lp, void __iomem *cregs) |
89 | { | 85 | { |
90 | /* Clear IRQ mask. */ | 86 | /* Clear IRQ mask. */ |
@@ -896,8 +892,9 @@ static void dump_eeprom(struct myri_eth *mp) | |||
896 | } | 892 | } |
897 | #endif | 893 | #endif |
898 | 894 | ||
899 | static int __init myri_ether_init(struct sbus_dev *sdev, int num) | 895 | static int __init myri_ether_init(struct sbus_dev *sdev) |
900 | { | 896 | { |
897 | static int num; | ||
901 | static unsigned version_printed; | 898 | static unsigned version_printed; |
902 | struct net_device *dev; | 899 | struct net_device *dev; |
903 | struct myri_eth *mp; | 900 | struct myri_eth *mp; |
@@ -913,6 +910,9 @@ static int __init myri_ether_init(struct sbus_dev *sdev, int num) | |||
913 | if (version_printed++ == 0) | 910 | if (version_printed++ == 0) |
914 | printk(version); | 911 | printk(version); |
915 | 912 | ||
913 | SET_MODULE_OWNER(dev); | ||
914 | SET_NETDEV_DEV(dev, &sdev->ofdev.dev); | ||
915 | |||
916 | mp = (struct myri_eth *) dev->priv; | 916 | mp = (struct myri_eth *) dev->priv; |
917 | spin_lock_init(&mp->irq_lock); | 917 | spin_lock_init(&mp->irq_lock); |
918 | mp->myri_sdev = sdev; | 918 | mp->myri_sdev = sdev; |
@@ -1092,10 +1092,9 @@ static int __init myri_ether_init(struct sbus_dev *sdev, int num) | |||
1092 | goto err_free_irq; | 1092 | goto err_free_irq; |
1093 | } | 1093 | } |
1094 | 1094 | ||
1095 | #ifdef MODULE | 1095 | dev_set_drvdata(&sdev->ofdev.dev, mp); |
1096 | mp->next_module = root_myri_dev; | 1096 | |
1097 | root_myri_dev = mp; | 1097 | num++; |
1098 | #endif | ||
1099 | 1098 | ||
1100 | printk("%s: MyriCOM MyriNET Ethernet ", dev->name); | 1099 | printk("%s: MyriCOM MyriNET Ethernet ", dev->name); |
1101 | 1100 | ||
@@ -1114,61 +1113,68 @@ err: | |||
1114 | return -ENODEV; | 1113 | return -ENODEV; |
1115 | } | 1114 | } |
1116 | 1115 | ||
1117 | static int __init myri_sbus_match(struct sbus_dev *sdev) | ||
1118 | { | ||
1119 | char *name = sdev->prom_name; | ||
1120 | 1116 | ||
1121 | if (!strcmp(name, "MYRICOM,mlanai") || | 1117 | static int __devinit myri_sbus_probe(struct of_device *dev, const struct of_device_id *match) |
1122 | !strcmp(name, "myri")) | 1118 | { |
1123 | return 1; | 1119 | struct sbus_dev *sdev = to_sbus_device(&dev->dev); |
1124 | 1120 | ||
1125 | return 0; | 1121 | return myri_ether_init(sdev); |
1126 | } | 1122 | } |
1127 | 1123 | ||
1128 | static int __init myri_sbus_probe(void) | 1124 | static int __devexit myri_sbus_remove(struct of_device *dev) |
1129 | { | 1125 | { |
1130 | struct sbus_bus *bus; | 1126 | struct myri_eth *mp = dev_get_drvdata(&dev->dev); |
1131 | struct sbus_dev *sdev = NULL; | 1127 | struct net_device *net_dev = mp->dev; |
1132 | static int called; | ||
1133 | int cards = 0, v; | ||
1134 | 1128 | ||
1135 | #ifdef MODULE | 1129 | unregister_netdevice(net_dev); |
1136 | root_myri_dev = NULL; | ||
1137 | #endif | ||
1138 | 1130 | ||
1139 | if (called) | 1131 | free_irq(net_dev->irq, net_dev); |
1140 | return -ENODEV; | 1132 | |
1141 | called++; | 1133 | if (mp->eeprom.cpuvers < CPUVERS_4_0) { |
1142 | 1134 | sbus_iounmap(mp->regs, mp->reg_size); | |
1143 | for_each_sbus(bus) { | 1135 | } else { |
1144 | for_each_sbusdev(sdev, bus) { | 1136 | sbus_iounmap(mp->cregs, PAGE_SIZE); |
1145 | if (myri_sbus_match(sdev)) { | 1137 | sbus_iounmap(mp->lregs, (256 * 1024)); |
1146 | cards++; | 1138 | sbus_iounmap(mp->lanai, (512 * 1024)); |
1147 | DET(("Found myricom myrinet as %s\n", sdev->prom_name)); | ||
1148 | if ((v = myri_ether_init(sdev, (cards - 1)))) | ||
1149 | return v; | ||
1150 | } | ||
1151 | } | ||
1152 | } | 1139 | } |
1153 | if (!cards) | 1140 | |
1154 | return -ENODEV; | 1141 | free_netdev(net_dev); |
1142 | |||
1143 | dev_set_drvdata(&dev->dev, NULL); | ||
1144 | |||
1155 | return 0; | 1145 | return 0; |
1156 | } | 1146 | } |
1157 | 1147 | ||
1158 | static void __exit myri_sbus_cleanup(void) | 1148 | static struct of_device_id myri_sbus_match[] = { |
1149 | { | ||
1150 | .name = "MYRICOM,mlanai", | ||
1151 | }, | ||
1152 | { | ||
1153 | .name = "myri", | ||
1154 | }, | ||
1155 | {}, | ||
1156 | }; | ||
1157 | |||
1158 | MODULE_DEVICE_TABLE(of, myri_sbus_match); | ||
1159 | |||
1160 | static struct of_platform_driver myri_sbus_driver = { | ||
1161 | .name = "myri", | ||
1162 | .match_table = myri_sbus_match, | ||
1163 | .probe = myri_sbus_probe, | ||
1164 | .remove = __devexit_p(myri_sbus_remove), | ||
1165 | }; | ||
1166 | |||
1167 | static int __init myri_sbus_init(void) | ||
1168 | { | ||
1169 | return of_register_driver(&myri_sbus_driver, &sbus_bus_type); | ||
1170 | } | ||
1171 | |||
1172 | static void __exit myri_sbus_exit(void) | ||
1159 | { | 1173 | { |
1160 | #ifdef MODULE | 1174 | of_unregister_driver(&myri_sbus_driver); |
1161 | while (root_myri_dev) { | ||
1162 | struct myri_eth *next = root_myri_dev->next_module; | ||
1163 | |||
1164 | unregister_netdev(root_myri_dev->dev); | ||
1165 | /* this will also free the co-allocated 'root_myri_dev' */ | ||
1166 | free_netdev(root_myri_dev->dev); | ||
1167 | root_myri_dev = next; | ||
1168 | } | ||
1169 | #endif /* MODULE */ | ||
1170 | } | 1175 | } |
1171 | 1176 | ||
1172 | module_init(myri_sbus_probe); | 1177 | module_init(myri_sbus_init); |
1173 | module_exit(myri_sbus_cleanup); | 1178 | module_exit(myri_sbus_exit); |
1179 | |||
1174 | MODULE_LICENSE("GPL"); | 1180 | MODULE_LICENSE("GPL"); |