1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <linux/netdevice.h>
27#include <linux/etherdevice.h>
28#include <linux/errno.h>
29#include <linux/init.h>
30#include <linux/netlink.h>
31#include <net/Space.h>
32
33
34
35
36
37struct netdev_boot_setup {
38 char name[IFNAMSIZ];
39 struct ifmap map;
40};
41#define NETDEV_BOOT_SETUP_MAX 8
42
43
44
45
46
47
48
49
50
51static struct netdev_boot_setup dev_boot_setup[NETDEV_BOOT_SETUP_MAX];
52
53
54
55
56
57
58
59
60
61
62static int netdev_boot_setup_add(char *name, struct ifmap *map)
63{
64 struct netdev_boot_setup *s;
65 int i;
66
67 s = dev_boot_setup;
68 for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) {
69 if (s[i].name[0] == '\0' || s[i].name[0] == ' ') {
70 memset(s[i].name, 0, sizeof(s[i].name));
71 strlcpy(s[i].name, name, IFNAMSIZ);
72 memcpy(&s[i].map, map, sizeof(s[i].map));
73 break;
74 }
75 }
76
77 return i >= NETDEV_BOOT_SETUP_MAX ? 0 : 1;
78}
79
80
81
82
83
84
85
86
87
88
89int netdev_boot_setup_check(struct net_device *dev)
90{
91 struct netdev_boot_setup *s = dev_boot_setup;
92 int i;
93
94 for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) {
95 if (s[i].name[0] != '\0' && s[i].name[0] != ' ' &&
96 !strcmp(dev->name, s[i].name)) {
97 dev->irq = s[i].map.irq;
98 dev->base_addr = s[i].map.base_addr;
99 dev->mem_start = s[i].map.mem_start;
100 dev->mem_end = s[i].map.mem_end;
101 return 1;
102 }
103 }
104 return 0;
105}
106EXPORT_SYMBOL(netdev_boot_setup_check);
107
108
109
110
111
112
113
114
115
116
117
118static unsigned long netdev_boot_base(const char *prefix, int unit)
119{
120 const struct netdev_boot_setup *s = dev_boot_setup;
121 char name[IFNAMSIZ];
122 int i;
123
124 sprintf(name, "%s%d", prefix, unit);
125
126
127
128
129
130 if (__dev_get_by_name(&init_net, name))
131 return 1;
132
133 for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++)
134 if (!strcmp(name, s[i].name))
135 return s[i].map.base_addr;
136 return 0;
137}
138
139
140
141
142static int __init netdev_boot_setup(char *str)
143{
144 int ints[5];
145 struct ifmap map;
146
147 str = get_options(str, ARRAY_SIZE(ints), ints);
148 if (!str || !*str)
149 return 0;
150
151
152 memset(&map, 0, sizeof(map));
153 if (ints[0] > 0)
154 map.irq = ints[1];
155 if (ints[0] > 1)
156 map.base_addr = ints[2];
157 if (ints[0] > 2)
158 map.mem_start = ints[3];
159 if (ints[0] > 3)
160 map.mem_end = ints[4];
161
162
163 return netdev_boot_setup_add(str, &map);
164}
165
166__setup("netdev=", netdev_boot_setup);
167
168static int __init ether_boot_setup(char *str)
169{
170 return netdev_boot_setup(str);
171}
172__setup("ether=", ether_boot_setup);
173
174
175
176
177
178
179struct devprobe2 {
180 struct net_device *(*probe)(int unit);
181 int status;
182};
183
184static int __init probe_list2(int unit, struct devprobe2 *p, int autoprobe)
185{
186 struct net_device *dev;
187
188 for (; p->probe; p++) {
189 if (autoprobe && p->status)
190 continue;
191 dev = p->probe(unit);
192 if (!IS_ERR(dev))
193 return 0;
194 if (autoprobe)
195 p->status = PTR_ERR(dev);
196 }
197 return -ENODEV;
198}
199
200
201
202
203static struct devprobe2 isa_probes[] __initdata = {
204#ifdef CONFIG_3C515
205 {tc515_probe, 0},
206#endif
207#ifdef CONFIG_ULTRA
208 {ultra_probe, 0},
209#endif
210#ifdef CONFIG_WD80x3
211 {wd_probe, 0},
212#endif
213#if defined(CONFIG_NE2000)
214 {ne_probe, 0},
215#endif
216#ifdef CONFIG_LANCE
217 {lance_probe, 0},
218#endif
219#ifdef CONFIG_SMC9194
220 {smc_init, 0},
221#endif
222#ifdef CONFIG_CS89x0_ISA
223 {cs89x0_probe, 0},
224#endif
225 {NULL, 0},
226};
227
228
229
230
231
232static void __init ethif_probe2(int unit)
233{
234 unsigned long base_addr = netdev_boot_base("eth", unit);
235
236 if (base_addr == 1)
237 return;
238
239 probe_list2(unit, isa_probes, base_addr == 0);
240}
241
242
243static int __init net_olddevs_init(void)
244{
245 int num;
246
247 for (num = 0; num < 8; ++num)
248 ethif_probe2(num);
249
250#ifdef CONFIG_COPS
251 cops_probe(0);
252 cops_probe(1);
253 cops_probe(2);
254#endif
255
256 return 0;
257}
258
259device_initcall(net_olddevs_init);
260