diff options
author | Ondrej Zary <linux@rainbow-software.org> | 2008-03-28 17:41:23 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-03-28 22:14:07 -0400 |
commit | ac4bed1375c06af7c76b4615ae661791b62e93ef (patch) | |
tree | eeb3fb1733b0ed791d199a9b40e7731ed29d5701 /drivers | |
parent | a0f55e0e833009c6a4eeb2626b807e3c21b128c8 (diff) |
3c509: convert to isa_driver and pnp_driver
Convert 3c509 driver to isa_driver and pnp_driver. The result is that
autoloading using udev and hibernation works with ISA PnP cards. It also adds
hibernation support for non-PnP ISA cards.
xcvr module parameter was removed as its value was not used.
Tested using 3 ISA cards in various combinations of PnP and non-PnP modes.
EISA and MCA only compile-tested.
Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/3c509.c | 729 |
1 files changed, 372 insertions, 357 deletions
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index 8fafac987e0b..54dac0696d91 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c | |||
@@ -54,25 +54,24 @@ | |||
54 | v1.19a 28Oct2002 Davud Ruggiero <jdr@farfalle.com> | 54 | v1.19a 28Oct2002 Davud Ruggiero <jdr@farfalle.com> |
55 | - Increase *read_eeprom udelay to workaround oops with 2 cards. | 55 | - Increase *read_eeprom udelay to workaround oops with 2 cards. |
56 | v1.19b 08Nov2002 Marc Zyngier <maz@wild-wind.fr.eu.org> | 56 | v1.19b 08Nov2002 Marc Zyngier <maz@wild-wind.fr.eu.org> |
57 | - Introduce driver model for EISA cards. | 57 | - Introduce driver model for EISA cards. |
58 | v1.20 04Feb2008 Ondrej Zary <linux@rainbow-software.org> | ||
59 | - convert to isa_driver and pnp_driver and some cleanups | ||
58 | */ | 60 | */ |
59 | 61 | ||
60 | #define DRV_NAME "3c509" | 62 | #define DRV_NAME "3c509" |
61 | #define DRV_VERSION "1.19b" | 63 | #define DRV_VERSION "1.20" |
62 | #define DRV_RELDATE "08Nov2002" | 64 | #define DRV_RELDATE "04Feb2008" |
63 | 65 | ||
64 | /* A few values that may be tweaked. */ | 66 | /* A few values that may be tweaked. */ |
65 | 67 | ||
66 | /* Time in jiffies before concluding the transmitter is hung. */ | 68 | /* Time in jiffies before concluding the transmitter is hung. */ |
67 | #define TX_TIMEOUT (400*HZ/1000) | 69 | #define TX_TIMEOUT (400*HZ/1000) |
68 | /* Maximum events (Rx packets, etc.) to handle at each interrupt. */ | ||
69 | static int max_interrupt_work = 10; | ||
70 | 70 | ||
71 | #include <linux/module.h> | 71 | #include <linux/module.h> |
72 | #ifdef CONFIG_MCA | ||
73 | #include <linux/mca.h> | 72 | #include <linux/mca.h> |
74 | #endif | 73 | #include <linux/isa.h> |
75 | #include <linux/isapnp.h> | 74 | #include <linux/pnp.h> |
76 | #include <linux/string.h> | 75 | #include <linux/string.h> |
77 | #include <linux/interrupt.h> | 76 | #include <linux/interrupt.h> |
78 | #include <linux/errno.h> | 77 | #include <linux/errno.h> |
@@ -97,10 +96,6 @@ static int max_interrupt_work = 10; | |||
97 | 96 | ||
98 | static char version[] __initdata = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE " becker@scyld.com\n"; | 97 | static char version[] __initdata = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE " becker@scyld.com\n"; |
99 | 98 | ||
100 | #if defined(CONFIG_PM) && (defined(CONFIG_MCA) || defined(CONFIG_EISA)) | ||
101 | #define EL3_SUSPEND | ||
102 | #endif | ||
103 | |||
104 | #ifdef EL3_DEBUG | 99 | #ifdef EL3_DEBUG |
105 | static int el3_debug = EL3_DEBUG; | 100 | static int el3_debug = EL3_DEBUG; |
106 | #else | 101 | #else |
@@ -111,6 +106,7 @@ static int el3_debug = 2; | |||
111 | * a global variable so that the mca/eisa probe routines can increment | 106 | * a global variable so that the mca/eisa probe routines can increment |
112 | * it */ | 107 | * it */ |
113 | static int el3_cards = 0; | 108 | static int el3_cards = 0; |
109 | #define EL3_MAX_CARDS 8 | ||
114 | 110 | ||
115 | /* To minimize the size of the driver source I only define operating | 111 | /* To minimize the size of the driver source I only define operating |
116 | constants if they are used several times. You'll need the manual | 112 | constants if they are used several times. You'll need the manual |
@@ -119,7 +115,7 @@ static int el3_cards = 0; | |||
119 | #define EL3_DATA 0x00 | 115 | #define EL3_DATA 0x00 |
120 | #define EL3_CMD 0x0e | 116 | #define EL3_CMD 0x0e |
121 | #define EL3_STATUS 0x0e | 117 | #define EL3_STATUS 0x0e |
122 | #define EEPROM_READ 0x80 | 118 | #define EEPROM_READ 0x80 |
123 | 119 | ||
124 | #define EL3_IO_EXTENT 16 | 120 | #define EL3_IO_EXTENT 16 |
125 | 121 | ||
@@ -168,23 +164,31 @@ enum RxFilter { | |||
168 | */ | 164 | */ |
169 | #define SKB_QUEUE_SIZE 64 | 165 | #define SKB_QUEUE_SIZE 64 |
170 | 166 | ||
167 | enum el3_cardtype { EL3_ISA, EL3_PNP, EL3_MCA, EL3_EISA }; | ||
168 | |||
171 | struct el3_private { | 169 | struct el3_private { |
172 | struct net_device_stats stats; | 170 | struct net_device_stats stats; |
173 | struct net_device *next_dev; | ||
174 | spinlock_t lock; | 171 | spinlock_t lock; |
175 | /* skb send-queue */ | 172 | /* skb send-queue */ |
176 | int head, size; | 173 | int head, size; |
177 | struct sk_buff *queue[SKB_QUEUE_SIZE]; | 174 | struct sk_buff *queue[SKB_QUEUE_SIZE]; |
178 | enum { | 175 | enum el3_cardtype type; |
179 | EL3_MCA, | ||
180 | EL3_PNP, | ||
181 | EL3_EISA, | ||
182 | } type; /* type of device */ | ||
183 | struct device *dev; | ||
184 | }; | 176 | }; |
185 | static int id_port __initdata = 0x110; /* Start with 0x110 to avoid new sound cards.*/ | 177 | static int id_port; |
186 | static struct net_device *el3_root_dev; | 178 | static int current_tag; |
179 | static struct net_device *el3_devs[EL3_MAX_CARDS]; | ||
180 | |||
181 | /* Parameters that may be passed into the module. */ | ||
182 | static int debug = -1; | ||
183 | static int irq[] = {-1, -1, -1, -1, -1, -1, -1, -1}; | ||
184 | /* Maximum events (Rx packets, etc.) to handle at each interrupt. */ | ||
185 | static int max_interrupt_work = 10; | ||
186 | #ifdef CONFIG_PNP | ||
187 | static int nopnp; | ||
188 | #endif | ||
187 | 189 | ||
190 | static int __init el3_common_init(struct net_device *dev); | ||
191 | static void el3_common_remove(struct net_device *dev); | ||
188 | static ushort id_read_eeprom(int index); | 192 | static ushort id_read_eeprom(int index); |
189 | static ushort read_eeprom(int ioaddr, int index); | 193 | static ushort read_eeprom(int ioaddr, int index); |
190 | static int el3_open(struct net_device *dev); | 194 | static int el3_open(struct net_device *dev); |
@@ -199,7 +203,7 @@ static void el3_tx_timeout (struct net_device *dev); | |||
199 | static void el3_down(struct net_device *dev); | 203 | static void el3_down(struct net_device *dev); |
200 | static void el3_up(struct net_device *dev); | 204 | static void el3_up(struct net_device *dev); |
201 | static const struct ethtool_ops ethtool_ops; | 205 | static const struct ethtool_ops ethtool_ops; |
202 | #ifdef EL3_SUSPEND | 206 | #ifdef CONFIG_PM |
203 | static int el3_suspend(struct device *, pm_message_t); | 207 | static int el3_suspend(struct device *, pm_message_t); |
204 | static int el3_resume(struct device *); | 208 | static int el3_resume(struct device *); |
205 | #else | 209 | #else |
@@ -209,13 +213,272 @@ static int el3_resume(struct device *); | |||
209 | 213 | ||
210 | 214 | ||
211 | /* generic device remove for all device types */ | 215 | /* generic device remove for all device types */ |
212 | #if defined(CONFIG_EISA) || defined(CONFIG_MCA) | ||
213 | static int el3_device_remove (struct device *device); | 216 | static int el3_device_remove (struct device *device); |
214 | #endif | ||
215 | #ifdef CONFIG_NET_POLL_CONTROLLER | 217 | #ifdef CONFIG_NET_POLL_CONTROLLER |
216 | static void el3_poll_controller(struct net_device *dev); | 218 | static void el3_poll_controller(struct net_device *dev); |
217 | #endif | 219 | #endif |
218 | 220 | ||
221 | /* Return 0 on success, 1 on error, 2 when found already detected PnP card */ | ||
222 | static int el3_isa_id_sequence(__be16 *phys_addr) | ||
223 | { | ||
224 | short lrs_state = 0xff; | ||
225 | int i; | ||
226 | |||
227 | /* ISA boards are detected by sending the ID sequence to the | ||
228 | ID_PORT. We find cards past the first by setting the 'current_tag' | ||
229 | on cards as they are found. Cards with their tag set will not | ||
230 | respond to subsequent ID sequences. */ | ||
231 | |||
232 | outb(0x00, id_port); | ||
233 | outb(0x00, id_port); | ||
234 | for (i = 0; i < 255; i++) { | ||
235 | outb(lrs_state, id_port); | ||
236 | lrs_state <<= 1; | ||
237 | lrs_state = lrs_state & 0x100 ? lrs_state ^ 0xcf : lrs_state; | ||
238 | } | ||
239 | /* For the first probe, clear all board's tag registers. */ | ||
240 | if (current_tag == 0) | ||
241 | outb(0xd0, id_port); | ||
242 | else /* Otherwise kill off already-found boards. */ | ||
243 | outb(0xd8, id_port); | ||
244 | if (id_read_eeprom(7) != 0x6d50) | ||
245 | return 1; | ||
246 | /* Read in EEPROM data, which does contention-select. | ||
247 | Only the lowest address board will stay "on-line". | ||
248 | 3Com got the byte order backwards. */ | ||
249 | for (i = 0; i < 3; i++) | ||
250 | phys_addr[i] = htons(id_read_eeprom(i)); | ||
251 | #ifdef CONFIG_PNP | ||
252 | if (!nopnp) { | ||
253 | /* The ISA PnP 3c509 cards respond to the ID sequence too. | ||
254 | This check is needed in order not to register them twice. */ | ||
255 | for (i = 0; i < el3_cards; i++) { | ||
256 | struct el3_private *lp = netdev_priv(el3_devs[i]); | ||
257 | if (lp->type == EL3_PNP | ||
258 | && !memcmp(phys_addr, el3_devs[i]->dev_addr, | ||
259 | ETH_ALEN)) { | ||
260 | if (el3_debug > 3) | ||
261 | printk(KERN_DEBUG "3c509 with address %02x %02x %02x %02x %02x %02x was found by ISAPnP\n", | ||
262 | phys_addr[0] & 0xff, phys_addr[0] >> 8, | ||
263 | phys_addr[1] & 0xff, phys_addr[1] >> 8, | ||
264 | phys_addr[2] & 0xff, phys_addr[2] >> 8); | ||
265 | /* Set the adaptor tag so that the next card can be found. */ | ||
266 | outb(0xd0 + ++current_tag, id_port); | ||
267 | return 2; | ||
268 | } | ||
269 | } | ||
270 | } | ||
271 | #endif /* CONFIG_PNP */ | ||
272 | return 0; | ||
273 | |||
274 | } | ||
275 | |||
276 | static void __devinit el3_dev_fill(struct net_device *dev, __be16 *phys_addr, | ||
277 | int ioaddr, int irq, int if_port, | ||
278 | enum el3_cardtype type) | ||
279 | { | ||
280 | struct el3_private *lp = netdev_priv(dev); | ||
281 | |||
282 | memcpy(dev->dev_addr, phys_addr, ETH_ALEN); | ||
283 | dev->base_addr = ioaddr; | ||
284 | dev->irq = irq; | ||
285 | dev->if_port = if_port; | ||
286 | lp->type = type; | ||
287 | } | ||
288 | |||
289 | static int __devinit el3_isa_match(struct device *pdev, | ||
290 | unsigned int ndev) | ||
291 | { | ||
292 | struct net_device *dev; | ||
293 | int ioaddr, isa_irq, if_port, err; | ||
294 | unsigned int iobase; | ||
295 | __be16 phys_addr[3]; | ||
296 | |||
297 | while ((err = el3_isa_id_sequence(phys_addr)) == 2) | ||
298 | ; /* Skip to next card when PnP card found */ | ||
299 | if (err == 1) | ||
300 | return 0; | ||
301 | |||
302 | iobase = id_read_eeprom(8); | ||
303 | if_port = iobase >> 14; | ||
304 | ioaddr = 0x200 + ((iobase & 0x1f) << 4); | ||
305 | if (irq[el3_cards] > 1 && irq[el3_cards] < 16) | ||
306 | isa_irq = irq[el3_cards]; | ||
307 | else | ||
308 | isa_irq = id_read_eeprom(9) >> 12; | ||
309 | |||
310 | dev = alloc_etherdev(sizeof(struct el3_private)); | ||
311 | if (!dev) | ||
312 | return -ENOMEM; | ||
313 | |||
314 | netdev_boot_setup_check(dev); | ||
315 | |||
316 | if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509-isa")) { | ||
317 | free_netdev(dev); | ||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | /* Set the adaptor tag so that the next card can be found. */ | ||
322 | outb(0xd0 + ++current_tag, id_port); | ||
323 | |||
324 | /* Activate the adaptor at the EEPROM location. */ | ||
325 | outb((ioaddr >> 4) | 0xe0, id_port); | ||
326 | |||
327 | EL3WINDOW(0); | ||
328 | if (inw(ioaddr) != 0x6d50) { | ||
329 | free_netdev(dev); | ||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | /* Free the interrupt so that some other card can use it. */ | ||
334 | outw(0x0f00, ioaddr + WN0_IRQ); | ||
335 | |||
336 | el3_dev_fill(dev, phys_addr, ioaddr, isa_irq, if_port, EL3_ISA); | ||
337 | dev_set_drvdata(pdev, dev); | ||
338 | if (el3_common_init(dev)) { | ||
339 | free_netdev(dev); | ||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | el3_devs[el3_cards++] = dev; | ||
344 | return 1; | ||
345 | } | ||
346 | |||
347 | static int __devexit el3_isa_remove(struct device *pdev, | ||
348 | unsigned int ndev) | ||
349 | { | ||
350 | el3_device_remove(pdev); | ||
351 | dev_set_drvdata(pdev, NULL); | ||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | #ifdef CONFIG_PM | ||
356 | static int el3_isa_suspend(struct device *dev, unsigned int n, | ||
357 | pm_message_t state) | ||
358 | { | ||
359 | current_tag = 0; | ||
360 | return el3_suspend(dev, state); | ||
361 | } | ||
362 | |||
363 | static int el3_isa_resume(struct device *dev, unsigned int n) | ||
364 | { | ||
365 | struct net_device *ndev = dev_get_drvdata(dev); | ||
366 | int ioaddr = ndev->base_addr, err; | ||
367 | __be16 phys_addr[3]; | ||
368 | |||
369 | while ((err = el3_isa_id_sequence(phys_addr)) == 2) | ||
370 | ; /* Skip to next card when PnP card found */ | ||
371 | if (err == 1) | ||
372 | return 0; | ||
373 | /* Set the adaptor tag so that the next card can be found. */ | ||
374 | outb(0xd0 + ++current_tag, id_port); | ||
375 | /* Enable the card */ | ||
376 | outb((ioaddr >> 4) | 0xe0, id_port); | ||
377 | EL3WINDOW(0); | ||
378 | if (inw(ioaddr) != 0x6d50) | ||
379 | return 1; | ||
380 | /* Free the interrupt so that some other card can use it. */ | ||
381 | outw(0x0f00, ioaddr + WN0_IRQ); | ||
382 | return el3_resume(dev); | ||
383 | } | ||
384 | #endif | ||
385 | |||
386 | static struct isa_driver el3_isa_driver = { | ||
387 | .match = el3_isa_match, | ||
388 | .remove = __devexit_p(el3_isa_remove), | ||
389 | #ifdef CONFIG_PM | ||
390 | .suspend = el3_isa_suspend, | ||
391 | .resume = el3_isa_resume, | ||
392 | #endif | ||
393 | .driver = { | ||
394 | .name = "3c509" | ||
395 | }, | ||
396 | }; | ||
397 | static int isa_registered; | ||
398 | |||
399 | #ifdef CONFIG_PNP | ||
400 | static struct pnp_device_id el3_pnp_ids[] = { | ||
401 | { .id = "TCM5090" }, /* 3Com Etherlink III (TP) */ | ||
402 | { .id = "TCM5091" }, /* 3Com Etherlink III */ | ||
403 | { .id = "TCM5094" }, /* 3Com Etherlink III (combo) */ | ||
404 | { .id = "TCM5095" }, /* 3Com Etherlink III (TPO) */ | ||
405 | { .id = "TCM5098" }, /* 3Com Etherlink III (TPC) */ | ||
406 | { .id = "PNP80f7" }, /* 3Com Etherlink III compatible */ | ||
407 | { .id = "PNP80f8" }, /* 3Com Etherlink III compatible */ | ||
408 | { .id = "" } | ||
409 | }; | ||
410 | MODULE_DEVICE_TABLE(pnp, el3_pnp_ids); | ||
411 | |||
412 | static int __devinit el3_pnp_probe(struct pnp_dev *pdev, | ||
413 | const struct pnp_device_id *id) | ||
414 | { | ||
415 | short i; | ||
416 | int ioaddr, irq, if_port; | ||
417 | u16 phys_addr[3]; | ||
418 | struct net_device *dev = NULL; | ||
419 | int err; | ||
420 | |||
421 | ioaddr = pnp_port_start(pdev, 0); | ||
422 | if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509-pnp")) | ||
423 | return -EBUSY; | ||
424 | irq = pnp_irq(pdev, 0); | ||
425 | EL3WINDOW(0); | ||
426 | for (i = 0; i < 3; i++) | ||
427 | phys_addr[i] = htons(read_eeprom(ioaddr, i)); | ||
428 | if_port = read_eeprom(ioaddr, 8) >> 14; | ||
429 | dev = alloc_etherdev(sizeof(struct el3_private)); | ||
430 | if (!dev) { | ||
431 | release_region(ioaddr, EL3_IO_EXTENT); | ||
432 | return -ENOMEM; | ||
433 | } | ||
434 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
435 | netdev_boot_setup_check(dev); | ||
436 | |||
437 | el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_PNP); | ||
438 | pnp_set_drvdata(pdev, dev); | ||
439 | err = el3_common_init(dev); | ||
440 | |||
441 | if (err) { | ||
442 | pnp_set_drvdata(pdev, NULL); | ||
443 | free_netdev(dev); | ||
444 | return err; | ||
445 | } | ||
446 | |||
447 | el3_devs[el3_cards++] = dev; | ||
448 | return 0; | ||
449 | } | ||
450 | |||
451 | static void __devexit el3_pnp_remove(struct pnp_dev *pdev) | ||
452 | { | ||
453 | el3_common_remove(pnp_get_drvdata(pdev)); | ||
454 | pnp_set_drvdata(pdev, NULL); | ||
455 | } | ||
456 | |||
457 | #ifdef CONFIG_PM | ||
458 | static int el3_pnp_suspend(struct pnp_dev *pdev, pm_message_t state) | ||
459 | { | ||
460 | return el3_suspend(&pdev->dev, state); | ||
461 | } | ||
462 | |||
463 | static int el3_pnp_resume(struct pnp_dev *pdev) | ||
464 | { | ||
465 | return el3_resume(&pdev->dev); | ||
466 | } | ||
467 | #endif | ||
468 | |||
469 | static struct pnp_driver el3_pnp_driver = { | ||
470 | .name = "3c509", | ||
471 | .id_table = el3_pnp_ids, | ||
472 | .probe = el3_pnp_probe, | ||
473 | .remove = __devexit_p(el3_pnp_remove), | ||
474 | #ifdef CONFIG_PM | ||
475 | .suspend = el3_pnp_suspend, | ||
476 | .resume = el3_pnp_resume, | ||
477 | #endif | ||
478 | }; | ||
479 | static int pnp_registered; | ||
480 | #endif /* CONFIG_PNP */ | ||
481 | |||
219 | #ifdef CONFIG_EISA | 482 | #ifdef CONFIG_EISA |
220 | static struct eisa_device_id el3_eisa_ids[] = { | 483 | static struct eisa_device_id el3_eisa_ids[] = { |
221 | { "TCM5092" }, | 484 | { "TCM5092" }, |
@@ -230,13 +493,14 @@ static int el3_eisa_probe (struct device *device); | |||
230 | static struct eisa_driver el3_eisa_driver = { | 493 | static struct eisa_driver el3_eisa_driver = { |
231 | .id_table = el3_eisa_ids, | 494 | .id_table = el3_eisa_ids, |
232 | .driver = { | 495 | .driver = { |
233 | .name = "3c509", | 496 | .name = "3c579", |
234 | .probe = el3_eisa_probe, | 497 | .probe = el3_eisa_probe, |
235 | .remove = __devexit_p (el3_device_remove), | 498 | .remove = __devexit_p (el3_device_remove), |
236 | .suspend = el3_suspend, | 499 | .suspend = el3_suspend, |
237 | .resume = el3_resume, | 500 | .resume = el3_resume, |
238 | } | 501 | } |
239 | }; | 502 | }; |
503 | static int eisa_registered; | ||
240 | #endif | 504 | #endif |
241 | 505 | ||
242 | #ifdef CONFIG_MCA | 506 | #ifdef CONFIG_MCA |
@@ -271,45 +535,9 @@ static struct mca_driver el3_mca_driver = { | |||
271 | .resume = el3_resume, | 535 | .resume = el3_resume, |
272 | }, | 536 | }, |
273 | }; | 537 | }; |
538 | static int mca_registered; | ||
274 | #endif /* CONFIG_MCA */ | 539 | #endif /* CONFIG_MCA */ |
275 | 540 | ||
276 | #if defined(__ISAPNP__) | ||
277 | static struct isapnp_device_id el3_isapnp_adapters[] __initdata = { | ||
278 | { ISAPNP_ANY_ID, ISAPNP_ANY_ID, | ||
279 | ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5090), | ||
280 | (long) "3Com Etherlink III (TP)" }, | ||
281 | { ISAPNP_ANY_ID, ISAPNP_ANY_ID, | ||
282 | ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5091), | ||
283 | (long) "3Com Etherlink III" }, | ||
284 | { ISAPNP_ANY_ID, ISAPNP_ANY_ID, | ||
285 | ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5094), | ||
286 | (long) "3Com Etherlink III (combo)" }, | ||
287 | { ISAPNP_ANY_ID, ISAPNP_ANY_ID, | ||
288 | ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5095), | ||
289 | (long) "3Com Etherlink III (TPO)" }, | ||
290 | { ISAPNP_ANY_ID, ISAPNP_ANY_ID, | ||
291 | ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5098), | ||
292 | (long) "3Com Etherlink III (TPC)" }, | ||
293 | { ISAPNP_ANY_ID, ISAPNP_ANY_ID, | ||
294 | ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_FUNCTION(0x80f7), | ||
295 | (long) "3Com Etherlink III compatible" }, | ||
296 | { ISAPNP_ANY_ID, ISAPNP_ANY_ID, | ||
297 | ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_FUNCTION(0x80f8), | ||
298 | (long) "3Com Etherlink III compatible" }, | ||
299 | { } /* terminate list */ | ||
300 | }; | ||
301 | |||
302 | static __be16 el3_isapnp_phys_addr[8][3]; | ||
303 | static int nopnp; | ||
304 | #endif /* __ISAPNP__ */ | ||
305 | |||
306 | /* With the driver model introduction for EISA devices, both init | ||
307 | * and cleanup have been split : | ||
308 | * - EISA devices probe/remove starts in el3_eisa_probe/el3_device_remove | ||
309 | * - MCA/ISA still use el3_probe | ||
310 | * | ||
311 | * Both call el3_common_init/el3_common_remove. */ | ||
312 | |||
313 | static int __init el3_common_init(struct net_device *dev) | 541 | static int __init el3_common_init(struct net_device *dev) |
314 | { | 542 | { |
315 | struct el3_private *lp = netdev_priv(dev); | 543 | struct el3_private *lp = netdev_priv(dev); |
@@ -360,231 +588,11 @@ static int __init el3_common_init(struct net_device *dev) | |||
360 | 588 | ||
361 | static void el3_common_remove (struct net_device *dev) | 589 | static void el3_common_remove (struct net_device *dev) |
362 | { | 590 | { |
363 | struct el3_private *lp = netdev_priv(dev); | ||
364 | |||
365 | (void) lp; /* Keep gcc quiet... */ | ||
366 | #if defined(__ISAPNP__) | ||
367 | if (lp->type == EL3_PNP) | ||
368 | pnp_device_detach(to_pnp_dev(lp->dev)); | ||
369 | #endif | ||
370 | |||
371 | unregister_netdev (dev); | 591 | unregister_netdev (dev); |
372 | release_region(dev->base_addr, EL3_IO_EXTENT); | 592 | release_region(dev->base_addr, EL3_IO_EXTENT); |
373 | free_netdev (dev); | 593 | free_netdev (dev); |
374 | } | 594 | } |
375 | 595 | ||
376 | static int __init el3_probe(int card_idx) | ||
377 | { | ||
378 | struct net_device *dev; | ||
379 | struct el3_private *lp; | ||
380 | short lrs_state = 0xff, i; | ||
381 | int ioaddr, irq, if_port; | ||
382 | __be16 phys_addr[3]; | ||
383 | static int current_tag; | ||
384 | int err = -ENODEV; | ||
385 | #if defined(__ISAPNP__) | ||
386 | static int pnp_cards; | ||
387 | struct pnp_dev *idev = NULL; | ||
388 | int pnp_found = 0; | ||
389 | |||
390 | if (nopnp == 1) | ||
391 | goto no_pnp; | ||
392 | |||
393 | for (i=0; el3_isapnp_adapters[i].vendor != 0; i++) { | ||
394 | int j; | ||
395 | while ((idev = pnp_find_dev(NULL, | ||
396 | el3_isapnp_adapters[i].vendor, | ||
397 | el3_isapnp_adapters[i].function, | ||
398 | idev))) { | ||
399 | if (pnp_device_attach(idev) < 0) | ||
400 | continue; | ||
401 | if (pnp_activate_dev(idev) < 0) { | ||
402 | __again: | ||
403 | pnp_device_detach(idev); | ||
404 | continue; | ||
405 | } | ||
406 | if (!pnp_port_valid(idev, 0) || !pnp_irq_valid(idev, 0)) | ||
407 | goto __again; | ||
408 | ioaddr = pnp_port_start(idev, 0); | ||
409 | if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509 PnP")) { | ||
410 | pnp_device_detach(idev); | ||
411 | return -EBUSY; | ||
412 | } | ||
413 | irq = pnp_irq(idev, 0); | ||
414 | if (el3_debug > 3) | ||
415 | printk ("ISAPnP reports %s at i/o 0x%x, irq %d\n", | ||
416 | (char*) el3_isapnp_adapters[i].driver_data, ioaddr, irq); | ||
417 | EL3WINDOW(0); | ||
418 | for (j = 0; j < 3; j++) | ||
419 | el3_isapnp_phys_addr[pnp_cards][j] = | ||
420 | phys_addr[j] = | ||
421 | htons(read_eeprom(ioaddr, j)); | ||
422 | if_port = read_eeprom(ioaddr, 8) >> 14; | ||
423 | dev = alloc_etherdev(sizeof (struct el3_private)); | ||
424 | if (!dev) { | ||
425 | release_region(ioaddr, EL3_IO_EXTENT); | ||
426 | pnp_device_detach(idev); | ||
427 | return -ENOMEM; | ||
428 | } | ||
429 | |||
430 | SET_NETDEV_DEV(dev, &idev->dev); | ||
431 | pnp_cards++; | ||
432 | |||
433 | netdev_boot_setup_check(dev); | ||
434 | pnp_found = 1; | ||
435 | goto found; | ||
436 | } | ||
437 | } | ||
438 | no_pnp: | ||
439 | #endif /* __ISAPNP__ */ | ||
440 | |||
441 | /* Select an open I/O location at 0x1*0 to do contention select. */ | ||
442 | for ( ; id_port < 0x200; id_port += 0x10) { | ||
443 | if (!request_region(id_port, 1, "3c509")) | ||
444 | continue; | ||
445 | outb(0x00, id_port); | ||
446 | outb(0xff, id_port); | ||
447 | if (inb(id_port) & 0x01){ | ||
448 | release_region(id_port, 1); | ||
449 | break; | ||
450 | } else | ||
451 | release_region(id_port, 1); | ||
452 | } | ||
453 | if (id_port >= 0x200) { | ||
454 | /* Rare -- do we really need a warning? */ | ||
455 | printk(" WARNING: No I/O port available for 3c509 activation.\n"); | ||
456 | return -ENODEV; | ||
457 | } | ||
458 | |||
459 | /* Next check for all ISA bus boards by sending the ID sequence to the | ||
460 | ID_PORT. We find cards past the first by setting the 'current_tag' | ||
461 | on cards as they are found. Cards with their tag set will not | ||
462 | respond to subsequent ID sequences. */ | ||
463 | |||
464 | outb(0x00, id_port); | ||
465 | outb(0x00, id_port); | ||
466 | for(i = 0; i < 255; i++) { | ||
467 | outb(lrs_state, id_port); | ||
468 | lrs_state <<= 1; | ||
469 | lrs_state = lrs_state & 0x100 ? lrs_state ^ 0xcf : lrs_state; | ||
470 | } | ||
471 | |||
472 | /* For the first probe, clear all board's tag registers. */ | ||
473 | if (current_tag == 0) | ||
474 | outb(0xd0, id_port); | ||
475 | else /* Otherwise kill off already-found boards. */ | ||
476 | outb(0xd8, id_port); | ||
477 | |||
478 | if (id_read_eeprom(7) != 0x6d50) { | ||
479 | return -ENODEV; | ||
480 | } | ||
481 | |||
482 | /* Read in EEPROM data, which does contention-select. | ||
483 | Only the lowest address board will stay "on-line". | ||
484 | 3Com got the byte order backwards. */ | ||
485 | for (i = 0; i < 3; i++) { | ||
486 | phys_addr[i] = htons(id_read_eeprom(i)); | ||
487 | } | ||
488 | |||
489 | #if defined(__ISAPNP__) | ||
490 | if (nopnp == 0) { | ||
491 | /* The ISA PnP 3c509 cards respond to the ID sequence. | ||
492 | This check is needed in order not to register them twice. */ | ||
493 | for (i = 0; i < pnp_cards; i++) { | ||
494 | if (phys_addr[0] == el3_isapnp_phys_addr[i][0] && | ||
495 | phys_addr[1] == el3_isapnp_phys_addr[i][1] && | ||
496 | phys_addr[2] == el3_isapnp_phys_addr[i][2]) | ||
497 | { | ||
498 | if (el3_debug > 3) | ||
499 | printk("3c509 with address %02x %02x %02x %02x %02x %02x was found by ISAPnP\n", | ||
500 | phys_addr[0] & 0xff, phys_addr[0] >> 8, | ||
501 | phys_addr[1] & 0xff, phys_addr[1] >> 8, | ||
502 | phys_addr[2] & 0xff, phys_addr[2] >> 8); | ||
503 | /* Set the adaptor tag so that the next card can be found. */ | ||
504 | outb(0xd0 + ++current_tag, id_port); | ||
505 | goto no_pnp; | ||
506 | } | ||
507 | } | ||
508 | } | ||
509 | #endif /* __ISAPNP__ */ | ||
510 | |||
511 | { | ||
512 | unsigned int iobase = id_read_eeprom(8); | ||
513 | if_port = iobase >> 14; | ||
514 | ioaddr = 0x200 + ((iobase & 0x1f) << 4); | ||
515 | } | ||
516 | irq = id_read_eeprom(9) >> 12; | ||
517 | |||
518 | dev = alloc_etherdev(sizeof (struct el3_private)); | ||
519 | if (!dev) | ||
520 | return -ENOMEM; | ||
521 | |||
522 | netdev_boot_setup_check(dev); | ||
523 | |||
524 | /* Set passed-in IRQ or I/O Addr. */ | ||
525 | if (dev->irq > 1 && dev->irq < 16) | ||
526 | irq = dev->irq; | ||
527 | |||
528 | if (dev->base_addr) { | ||
529 | if (dev->mem_end == 0x3c509 /* Magic key */ | ||
530 | && dev->base_addr >= 0x200 && dev->base_addr <= 0x3e0) | ||
531 | ioaddr = dev->base_addr & 0x3f0; | ||
532 | else if (dev->base_addr != ioaddr) | ||
533 | goto out; | ||
534 | } | ||
535 | |||
536 | if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509")) { | ||
537 | err = -EBUSY; | ||
538 | goto out; | ||
539 | } | ||
540 | |||
541 | /* Set the adaptor tag so that the next card can be found. */ | ||
542 | outb(0xd0 + ++current_tag, id_port); | ||
543 | |||
544 | /* Activate the adaptor at the EEPROM location. */ | ||
545 | outb((ioaddr >> 4) | 0xe0, id_port); | ||
546 | |||
547 | EL3WINDOW(0); | ||
548 | if (inw(ioaddr) != 0x6d50) | ||
549 | goto out1; | ||
550 | |||
551 | /* Free the interrupt so that some other card can use it. */ | ||
552 | outw(0x0f00, ioaddr + WN0_IRQ); | ||
553 | |||
554 | #if defined(__ISAPNP__) | ||
555 | found: /* PNP jumps here... */ | ||
556 | #endif /* __ISAPNP__ */ | ||
557 | |||
558 | memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr)); | ||
559 | dev->base_addr = ioaddr; | ||
560 | dev->irq = irq; | ||
561 | dev->if_port = if_port; | ||
562 | lp = netdev_priv(dev); | ||
563 | #if defined(__ISAPNP__) | ||
564 | lp->dev = &idev->dev; | ||
565 | if (pnp_found) | ||
566 | lp->type = EL3_PNP; | ||
567 | #endif | ||
568 | err = el3_common_init(dev); | ||
569 | |||
570 | if (err) | ||
571 | goto out1; | ||
572 | |||
573 | el3_cards++; | ||
574 | lp->next_dev = el3_root_dev; | ||
575 | el3_root_dev = dev; | ||
576 | return 0; | ||
577 | |||
578 | out1: | ||
579 | #if defined(__ISAPNP__) | ||
580 | if (idev) | ||
581 | pnp_device_detach(idev); | ||
582 | #endif | ||
583 | out: | ||
584 | free_netdev(dev); | ||
585 | return err; | ||
586 | } | ||
587 | |||
588 | #ifdef CONFIG_MCA | 596 | #ifdef CONFIG_MCA |
589 | static int __init el3_mca_probe(struct device *device) | 597 | static int __init el3_mca_probe(struct device *device) |
590 | { | 598 | { |
@@ -596,7 +604,6 @@ static int __init el3_mca_probe(struct device *device) | |||
596 | * redone for multi-card detection by ZP Gu (zpg@castle.net) | 604 | * redone for multi-card detection by ZP Gu (zpg@castle.net) |
597 | * now works as a module */ | 605 | * now works as a module */ |
598 | 606 | ||
599 | struct el3_private *lp; | ||
600 | short i; | 607 | short i; |
601 | int ioaddr, irq, if_port; | 608 | int ioaddr, irq, if_port; |
602 | u16 phys_addr[3]; | 609 | u16 phys_addr[3]; |
@@ -613,7 +620,7 @@ static int __init el3_mca_probe(struct device *device) | |||
613 | irq = pos5 & 0x0f; | 620 | irq = pos5 & 0x0f; |
614 | 621 | ||
615 | 622 | ||
616 | printk("3c529: found %s at slot %d\n", | 623 | printk(KERN_INFO "3c529: found %s at slot %d\n", |
617 | el3_mca_adapter_names[mdev->index], slot + 1); | 624 | el3_mca_adapter_names[mdev->index], slot + 1); |
618 | 625 | ||
619 | /* claim the slot */ | 626 | /* claim the slot */ |
@@ -626,7 +633,7 @@ static int __init el3_mca_probe(struct device *device) | |||
626 | irq = mca_device_transform_irq(mdev, irq); | 633 | irq = mca_device_transform_irq(mdev, irq); |
627 | ioaddr = mca_device_transform_ioport(mdev, ioaddr); | 634 | ioaddr = mca_device_transform_ioport(mdev, ioaddr); |
628 | if (el3_debug > 2) { | 635 | if (el3_debug > 2) { |
629 | printk("3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port); | 636 | printk(KERN_DEBUG "3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port); |
630 | } | 637 | } |
631 | EL3WINDOW(0); | 638 | EL3WINDOW(0); |
632 | for (i = 0; i < 3; i++) { | 639 | for (i = 0; i < 3; i++) { |
@@ -641,13 +648,7 @@ static int __init el3_mca_probe(struct device *device) | |||
641 | 648 | ||
642 | netdev_boot_setup_check(dev); | 649 | netdev_boot_setup_check(dev); |
643 | 650 | ||
644 | memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr)); | 651 | el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_MCA); |
645 | dev->base_addr = ioaddr; | ||
646 | dev->irq = irq; | ||
647 | dev->if_port = if_port; | ||
648 | lp = netdev_priv(dev); | ||
649 | lp->dev = device; | ||
650 | lp->type = EL3_MCA; | ||
651 | device->driver_data = dev; | 652 | device->driver_data = dev; |
652 | err = el3_common_init(dev); | 653 | err = el3_common_init(dev); |
653 | 654 | ||
@@ -657,7 +658,7 @@ static int __init el3_mca_probe(struct device *device) | |||
657 | return -ENOMEM; | 658 | return -ENOMEM; |
658 | } | 659 | } |
659 | 660 | ||
660 | el3_cards++; | 661 | el3_devs[el3_cards++] = dev; |
661 | return 0; | 662 | return 0; |
662 | } | 663 | } |
663 | 664 | ||
@@ -666,7 +667,6 @@ static int __init el3_mca_probe(struct device *device) | |||
666 | #ifdef CONFIG_EISA | 667 | #ifdef CONFIG_EISA |
667 | static int __init el3_eisa_probe (struct device *device) | 668 | static int __init el3_eisa_probe (struct device *device) |
668 | { | 669 | { |
669 | struct el3_private *lp; | ||
670 | short i; | 670 | short i; |
671 | int ioaddr, irq, if_port; | 671 | int ioaddr, irq, if_port; |
672 | u16 phys_addr[3]; | 672 | u16 phys_addr[3]; |
@@ -678,7 +678,7 @@ static int __init el3_eisa_probe (struct device *device) | |||
678 | edev = to_eisa_device (device); | 678 | edev = to_eisa_device (device); |
679 | ioaddr = edev->base_addr; | 679 | ioaddr = edev->base_addr; |
680 | 680 | ||
681 | if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509")) | 681 | if (!request_region(ioaddr, EL3_IO_EXTENT, "3c579-eisa")) |
682 | return -EBUSY; | 682 | return -EBUSY; |
683 | 683 | ||
684 | /* Change the register set to the configuration window 0. */ | 684 | /* Change the register set to the configuration window 0. */ |
@@ -700,13 +700,7 @@ static int __init el3_eisa_probe (struct device *device) | |||
700 | 700 | ||
701 | netdev_boot_setup_check(dev); | 701 | netdev_boot_setup_check(dev); |
702 | 702 | ||
703 | memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr)); | 703 | el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_EISA); |
704 | dev->base_addr = ioaddr; | ||
705 | dev->irq = irq; | ||
706 | dev->if_port = if_port; | ||
707 | lp = netdev_priv(dev); | ||
708 | lp->dev = device; | ||
709 | lp->type = EL3_EISA; | ||
710 | eisa_set_drvdata (edev, dev); | 704 | eisa_set_drvdata (edev, dev); |
711 | err = el3_common_init(dev); | 705 | err = el3_common_init(dev); |
712 | 706 | ||
@@ -716,12 +710,11 @@ static int __init el3_eisa_probe (struct device *device) | |||
716 | return err; | 710 | return err; |
717 | } | 711 | } |
718 | 712 | ||
719 | el3_cards++; | 713 | el3_devs[el3_cards++] = dev; |
720 | return 0; | 714 | return 0; |
721 | } | 715 | } |
722 | #endif | 716 | #endif |
723 | 717 | ||
724 | #if defined(CONFIG_EISA) || defined(CONFIG_MCA) | ||
725 | /* This remove works for all device types. | 718 | /* This remove works for all device types. |
726 | * | 719 | * |
727 | * The net dev must be stored in the driver_data field */ | 720 | * The net dev must be stored in the driver_data field */ |
@@ -734,7 +727,6 @@ static int __devexit el3_device_remove (struct device *device) | |||
734 | el3_common_remove (dev); | 727 | el3_common_remove (dev); |
735 | return 0; | 728 | return 0; |
736 | } | 729 | } |
737 | #endif | ||
738 | 730 | ||
739 | /* Read a word from the EEPROM using the regular EEPROM access register. | 731 | /* Read a word from the EEPROM using the regular EEPROM access register. |
740 | Assume that we are in register window zero. | 732 | Assume that we are in register window zero. |
@@ -749,7 +741,7 @@ static ushort read_eeprom(int ioaddr, int index) | |||
749 | } | 741 | } |
750 | 742 | ||
751 | /* Read a word from the EEPROM when in the ISA ID probe state. */ | 743 | /* Read a word from the EEPROM when in the ISA ID probe state. */ |
752 | static ushort __init id_read_eeprom(int index) | 744 | static ushort id_read_eeprom(int index) |
753 | { | 745 | { |
754 | int bit, word = 0; | 746 | int bit, word = 0; |
755 | 747 | ||
@@ -765,7 +757,7 @@ static ushort __init id_read_eeprom(int index) | |||
765 | word = (word << 1) + (inb(id_port) & 0x01); | 757 | word = (word << 1) + (inb(id_port) & 0x01); |
766 | 758 | ||
767 | if (el3_debug > 3) | 759 | if (el3_debug > 3) |
768 | printk(" 3c509 EEPROM word %d %#4.4x.\n", index, word); | 760 | printk(KERN_DEBUG " 3c509 EEPROM word %d %#4.4x.\n", index, word); |
769 | 761 | ||
770 | return word; | 762 | return word; |
771 | } | 763 | } |
@@ -787,13 +779,13 @@ el3_open(struct net_device *dev) | |||
787 | 779 | ||
788 | EL3WINDOW(0); | 780 | EL3WINDOW(0); |
789 | if (el3_debug > 3) | 781 | if (el3_debug > 3) |
790 | printk("%s: Opening, IRQ %d status@%x %4.4x.\n", dev->name, | 782 | printk(KERN_DEBUG "%s: Opening, IRQ %d status@%x %4.4x.\n", dev->name, |
791 | dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS)); | 783 | dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS)); |
792 | 784 | ||
793 | el3_up(dev); | 785 | el3_up(dev); |
794 | 786 | ||
795 | if (el3_debug > 3) | 787 | if (el3_debug > 3) |
796 | printk("%s: Opened 3c509 IRQ %d status %4.4x.\n", | 788 | printk(KERN_DEBUG "%s: Opened 3c509 IRQ %d status %4.4x.\n", |
797 | dev->name, dev->irq, inw(ioaddr + EL3_STATUS)); | 789 | dev->name, dev->irq, inw(ioaddr + EL3_STATUS)); |
798 | 790 | ||
799 | return 0; | 791 | return 0; |
@@ -806,7 +798,7 @@ el3_tx_timeout (struct net_device *dev) | |||
806 | int ioaddr = dev->base_addr; | 798 | int ioaddr = dev->base_addr; |
807 | 799 | ||
808 | /* Transmitter timeout, serious problems. */ | 800 | /* Transmitter timeout, serious problems. */ |
809 | printk("%s: transmit timed out, Tx_status %2.2x status %4.4x " | 801 | printk(KERN_WARNING "%s: transmit timed out, Tx_status %2.2x status %4.4x " |
810 | "Tx FIFO room %d.\n", | 802 | "Tx FIFO room %d.\n", |
811 | dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS), | 803 | dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS), |
812 | inw(ioaddr + TX_FREE)); | 804 | inw(ioaddr + TX_FREE)); |
@@ -831,7 +823,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
831 | lp->stats.tx_bytes += skb->len; | 823 | lp->stats.tx_bytes += skb->len; |
832 | 824 | ||
833 | if (el3_debug > 4) { | 825 | if (el3_debug > 4) { |
834 | printk("%s: el3_start_xmit(length = %u) called, status %4.4x.\n", | 826 | printk(KERN_DEBUG "%s: el3_start_xmit(length = %u) called, status %4.4x.\n", |
835 | dev->name, skb->len, inw(ioaddr + EL3_STATUS)); | 827 | dev->name, skb->len, inw(ioaddr + EL3_STATUS)); |
836 | } | 828 | } |
837 | #if 0 | 829 | #if 0 |
@@ -840,7 +832,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
840 | ushort status = inw(ioaddr + EL3_STATUS); | 832 | ushort status = inw(ioaddr + EL3_STATUS); |
841 | if (status & 0x0001 /* IRQ line active, missed one. */ | 833 | if (status & 0x0001 /* IRQ line active, missed one. */ |
842 | && inw(ioaddr + EL3_STATUS) & 1) { /* Make sure. */ | 834 | && inw(ioaddr + EL3_STATUS) & 1) { /* Make sure. */ |
843 | printk("%s: Missed interrupt, status then %04x now %04x" | 835 | printk(KERN_DEBUG "%s: Missed interrupt, status then %04x now %04x" |
844 | " Tx %2.2x Rx %4.4x.\n", dev->name, status, | 836 | " Tx %2.2x Rx %4.4x.\n", dev->name, status, |
845 | inw(ioaddr + EL3_STATUS), inb(ioaddr + TX_STATUS), | 837 | inw(ioaddr + EL3_STATUS), inb(ioaddr + TX_STATUS), |
846 | inw(ioaddr + RX_STATUS)); | 838 | inw(ioaddr + RX_STATUS)); |
@@ -914,7 +906,7 @@ el3_interrupt(int irq, void *dev_id) | |||
914 | 906 | ||
915 | if (el3_debug > 4) { | 907 | if (el3_debug > 4) { |
916 | status = inw(ioaddr + EL3_STATUS); | 908 | status = inw(ioaddr + EL3_STATUS); |
917 | printk("%s: interrupt, status %4.4x.\n", dev->name, status); | 909 | printk(KERN_DEBUG "%s: interrupt, status %4.4x.\n", dev->name, status); |
918 | } | 910 | } |
919 | 911 | ||
920 | while ((status = inw(ioaddr + EL3_STATUS)) & | 912 | while ((status = inw(ioaddr + EL3_STATUS)) & |
@@ -925,7 +917,7 @@ el3_interrupt(int irq, void *dev_id) | |||
925 | 917 | ||
926 | if (status & TxAvailable) { | 918 | if (status & TxAvailable) { |
927 | if (el3_debug > 5) | 919 | if (el3_debug > 5) |
928 | printk(" TX room bit was handled.\n"); | 920 | printk(KERN_DEBUG " TX room bit was handled.\n"); |
929 | /* There's room in the FIFO for a full-sized packet. */ | 921 | /* There's room in the FIFO for a full-sized packet. */ |
930 | outw(AckIntr | TxAvailable, ioaddr + EL3_CMD); | 922 | outw(AckIntr | TxAvailable, ioaddr + EL3_CMD); |
931 | netif_wake_queue (dev); | 923 | netif_wake_queue (dev); |
@@ -964,7 +956,7 @@ el3_interrupt(int irq, void *dev_id) | |||
964 | } | 956 | } |
965 | 957 | ||
966 | if (--i < 0) { | 958 | if (--i < 0) { |
967 | printk("%s: Infinite loop in interrupt, status %4.4x.\n", | 959 | printk(KERN_ERR "%s: Infinite loop in interrupt, status %4.4x.\n", |
968 | dev->name, status); | 960 | dev->name, status); |
969 | /* Clear all interrupts. */ | 961 | /* Clear all interrupts. */ |
970 | outw(AckIntr | 0xFF, ioaddr + EL3_CMD); | 962 | outw(AckIntr | 0xFF, ioaddr + EL3_CMD); |
@@ -975,7 +967,7 @@ el3_interrupt(int irq, void *dev_id) | |||
975 | } | 967 | } |
976 | 968 | ||
977 | if (el3_debug > 4) { | 969 | if (el3_debug > 4) { |
978 | printk("%s: exiting interrupt, status %4.4x.\n", dev->name, | 970 | printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n", dev->name, |
979 | inw(ioaddr + EL3_STATUS)); | 971 | inw(ioaddr + EL3_STATUS)); |
980 | } | 972 | } |
981 | spin_unlock(&lp->lock); | 973 | spin_unlock(&lp->lock); |
@@ -1450,7 +1442,7 @@ el3_up(struct net_device *dev) | |||
1450 | } | 1442 | } |
1451 | 1443 | ||
1452 | /* Power Management support functions */ | 1444 | /* Power Management support functions */ |
1453 | #ifdef EL3_SUSPEND | 1445 | #ifdef CONFIG_PM |
1454 | 1446 | ||
1455 | static int | 1447 | static int |
1456 | el3_suspend(struct device *pdev, pm_message_t state) | 1448 | el3_suspend(struct device *pdev, pm_message_t state) |
@@ -1500,79 +1492,102 @@ el3_resume(struct device *pdev) | |||
1500 | return 0; | 1492 | return 0; |
1501 | } | 1493 | } |
1502 | 1494 | ||
1503 | #endif /* EL3_SUSPEND */ | 1495 | #endif /* CONFIG_PM */ |
1504 | |||
1505 | /* Parameters that may be passed into the module. */ | ||
1506 | static int debug = -1; | ||
1507 | static int irq[] = {-1, -1, -1, -1, -1, -1, -1, -1}; | ||
1508 | static int xcvr[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; | ||
1509 | 1496 | ||
1510 | module_param(debug,int, 0); | 1497 | module_param(debug,int, 0); |
1511 | module_param_array(irq, int, NULL, 0); | 1498 | module_param_array(irq, int, NULL, 0); |
1512 | module_param_array(xcvr, int, NULL, 0); | ||
1513 | module_param(max_interrupt_work, int, 0); | 1499 | module_param(max_interrupt_work, int, 0); |
1514 | MODULE_PARM_DESC(debug, "debug level (0-6)"); | 1500 | MODULE_PARM_DESC(debug, "debug level (0-6)"); |
1515 | MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)"); | 1501 | MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)"); |
1516 | MODULE_PARM_DESC(xcvr,"transceiver(s) (0=internal, 1=external)"); | ||
1517 | MODULE_PARM_DESC(max_interrupt_work, "maximum events handled per interrupt"); | 1502 | MODULE_PARM_DESC(max_interrupt_work, "maximum events handled per interrupt"); |
1518 | #if defined(__ISAPNP__) | 1503 | #ifdef CONFIG_PNP |
1519 | module_param(nopnp, int, 0); | 1504 | module_param(nopnp, int, 0); |
1520 | MODULE_PARM_DESC(nopnp, "disable ISA PnP support (0-1)"); | 1505 | MODULE_PARM_DESC(nopnp, "disable ISA PnP support (0-1)"); |
1521 | MODULE_DEVICE_TABLE(isapnp, el3_isapnp_adapters); | 1506 | #endif /* CONFIG_PNP */ |
1522 | #endif /* __ISAPNP__ */ | 1507 | MODULE_DESCRIPTION("3Com Etherlink III (3c509, 3c509B, 3c529, 3c579) ethernet driver"); |
1523 | MODULE_DESCRIPTION("3Com Etherlink III (3c509, 3c509B) ISA/PnP ethernet driver"); | ||
1524 | MODULE_LICENSE("GPL"); | 1508 | MODULE_LICENSE("GPL"); |
1525 | 1509 | ||
1526 | static int __init el3_init_module(void) | 1510 | static int __init el3_init_module(void) |
1527 | { | 1511 | { |
1528 | int ret = 0; | 1512 | int ret = 0; |
1529 | el3_cards = 0; | ||
1530 | 1513 | ||
1531 | if (debug >= 0) | 1514 | if (debug >= 0) |
1532 | el3_debug = debug; | 1515 | el3_debug = debug; |
1533 | 1516 | ||
1534 | el3_root_dev = NULL; | 1517 | #ifdef CONFIG_PNP |
1535 | while (el3_probe(el3_cards) == 0) { | 1518 | if (!nopnp) { |
1536 | if (irq[el3_cards] > 1) | 1519 | ret = pnp_register_driver(&el3_pnp_driver); |
1537 | el3_root_dev->irq = irq[el3_cards]; | 1520 | if (!ret) |
1538 | if (xcvr[el3_cards] >= 0) | 1521 | pnp_registered = 1; |
1539 | el3_root_dev->if_port = xcvr[el3_cards]; | 1522 | } |
1540 | el3_cards++; | 1523 | #endif |
1524 | /* Select an open I/O location at 0x1*0 to do ISA contention select. */ | ||
1525 | /* Start with 0x110 to avoid some sound cards.*/ | ||
1526 | for (id_port = 0x110 ; id_port < 0x200; id_port += 0x10) { | ||
1527 | if (!request_region(id_port, 1, "3c509-control")) | ||
1528 | continue; | ||
1529 | outb(0x00, id_port); | ||
1530 | outb(0xff, id_port); | ||
1531 | if (inb(id_port) & 0x01) | ||
1532 | break; | ||
1533 | else | ||
1534 | release_region(id_port, 1); | ||
1535 | } | ||
1536 | if (id_port >= 0x200) { | ||
1537 | id_port = 0; | ||
1538 | printk(KERN_ERR "No I/O port available for 3c509 activation.\n"); | ||
1539 | } else { | ||
1540 | ret = isa_register_driver(&el3_isa_driver, EL3_MAX_CARDS); | ||
1541 | if (!ret) | ||
1542 | isa_registered = 1; | ||
1541 | } | 1543 | } |
1542 | |||
1543 | #ifdef CONFIG_EISA | 1544 | #ifdef CONFIG_EISA |
1544 | ret = eisa_driver_register(&el3_eisa_driver); | 1545 | ret = eisa_driver_register(&el3_eisa_driver); |
1546 | if (!ret) | ||
1547 | eisa_registered = 1; | ||
1545 | #endif | 1548 | #endif |
1546 | #ifdef CONFIG_MCA | 1549 | #ifdef CONFIG_MCA |
1547 | { | 1550 | ret = mca_register_driver(&el3_mca_driver); |
1548 | int err = mca_register_driver(&el3_mca_driver); | 1551 | if (!ret) |
1549 | if (ret == 0) | 1552 | mca_registered = 1; |
1550 | ret = err; | 1553 | #endif |
1551 | } | 1554 | |
1555 | #ifdef CONFIG_PNP | ||
1556 | if (pnp_registered) | ||
1557 | ret = 0; | ||
1558 | #endif | ||
1559 | if (isa_registered) | ||
1560 | ret = 0; | ||
1561 | #ifdef CONFIG_EISA | ||
1562 | if (eisa_registered) | ||
1563 | ret = 0; | ||
1564 | #endif | ||
1565 | #ifdef CONFIG_MCA | ||
1566 | if (mca_registered) | ||
1567 | ret = 0; | ||
1552 | #endif | 1568 | #endif |
1553 | return ret; | 1569 | return ret; |
1554 | } | 1570 | } |
1555 | 1571 | ||
1556 | static void __exit el3_cleanup_module(void) | 1572 | static void __exit el3_cleanup_module(void) |
1557 | { | 1573 | { |
1558 | struct net_device *next_dev; | 1574 | #ifdef CONFIG_PNP |
1559 | 1575 | if (pnp_registered) | |
1560 | while (el3_root_dev) { | 1576 | pnp_unregister_driver(&el3_pnp_driver); |
1561 | struct el3_private *lp = netdev_priv(el3_root_dev); | 1577 | #endif |
1562 | 1578 | if (isa_registered) | |
1563 | next_dev = lp->next_dev; | 1579 | isa_unregister_driver(&el3_isa_driver); |
1564 | el3_common_remove (el3_root_dev); | 1580 | if (id_port) |
1565 | el3_root_dev = next_dev; | 1581 | release_region(id_port, 1); |
1566 | } | ||
1567 | |||
1568 | #ifdef CONFIG_EISA | 1582 | #ifdef CONFIG_EISA |
1569 | eisa_driver_unregister (&el3_eisa_driver); | 1583 | if (eisa_registered) |
1584 | eisa_driver_unregister(&el3_eisa_driver); | ||
1570 | #endif | 1585 | #endif |
1571 | #ifdef CONFIG_MCA | 1586 | #ifdef CONFIG_MCA |
1572 | mca_unregister_driver(&el3_mca_driver); | 1587 | if (mca_registered) |
1588 | mca_unregister_driver(&el3_mca_driver); | ||
1573 | #endif | 1589 | #endif |
1574 | } | 1590 | } |
1575 | 1591 | ||
1576 | module_init (el3_init_module); | 1592 | module_init (el3_init_module); |
1577 | module_exit (el3_cleanup_module); | 1593 | module_exit (el3_cleanup_module); |
1578 | |||