ia64/linux-2.6.18-xen.hg

view drivers/net/macsonic.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
line source
1 /*
2 * macsonic.c
3 *
4 * (C) 2005 Finn Thain
5 *
6 * Converted to DMA API, converted to unified driver model, made it work as
7 * a module again, and from the mac68k project, introduced more 32-bit cards
8 * and dhd's support for 16-bit cards.
9 *
10 * (C) 1998 Alan Cox
11 *
12 * Debugging Andreas Ehliar, Michael Schmitz
13 *
14 * Based on code
15 * (C) 1996 by Thomas Bogendoerfer (tsbogend@bigbug.franken.de)
16 *
17 * This driver is based on work from Andreas Busse, but most of
18 * the code is rewritten.
19 *
20 * (C) 1995 by Andreas Busse (andy@waldorf-gmbh.de)
21 *
22 * A driver for the Mac onboard Sonic ethernet chip.
23 *
24 * 98/12/21 MSch: judged from tests on Q800, it's basically working,
25 * but eating up both receive and transmit resources
26 * and duplicating packets. Needs more testing.
27 *
28 * 99/01/03 MSch: upgraded to version 0.92 of the core driver, fixed.
29 *
30 * 00/10/31 sammy@oh.verio.com: Updated driver for 2.4 kernels, fixed problems
31 * on centris.
32 */
34 #include <linux/kernel.h>
35 #include <linux/module.h>
36 #include <linux/types.h>
37 #include <linux/fcntl.h>
38 #include <linux/interrupt.h>
39 #include <linux/init.h>
40 #include <linux/ioport.h>
41 #include <linux/in.h>
42 #include <linux/slab.h>
43 #include <linux/string.h>
44 #include <linux/delay.h>
45 #include <linux/nubus.h>
46 #include <linux/errno.h>
47 #include <linux/netdevice.h>
48 #include <linux/etherdevice.h>
49 #include <linux/skbuff.h>
50 #include <linux/platform_device.h>
51 #include <linux/dma-mapping.h>
53 #include <asm/bootinfo.h>
54 #include <asm/system.h>
55 #include <asm/pgtable.h>
56 #include <asm/io.h>
57 #include <asm/hwtest.h>
58 #include <asm/dma.h>
59 #include <asm/macintosh.h>
60 #include <asm/macints.h>
61 #include <asm/mac_via.h>
63 static char mac_sonic_string[] = "macsonic";
64 static struct platform_device *mac_sonic_device;
66 #include "sonic.h"
68 /* These should basically be bus-size and endian independent (since
69 the SONIC is at least smart enough that it uses the same endianness
70 as the host, unlike certain less enlightened Macintosh NICs) */
71 #define SONIC_READ(reg) (nubus_readw(dev->base_addr + (reg * 4) \
72 + lp->reg_offset))
73 #define SONIC_WRITE(reg,val) (nubus_writew(val, dev->base_addr + (reg * 4) \
74 + lp->reg_offset))
76 /* use 0 for production, 1 for verification, >1 for debug */
77 #ifdef SONIC_DEBUG
78 static unsigned int sonic_debug = SONIC_DEBUG;
79 #else
80 static unsigned int sonic_debug = 1;
81 #endif
83 static int sonic_version_printed;
85 extern int mac_onboard_sonic_probe(struct net_device* dev);
86 extern int mac_nubus_sonic_probe(struct net_device* dev);
88 /* For onboard SONIC */
89 #define ONBOARD_SONIC_REGISTERS 0x50F0A000
90 #define ONBOARD_SONIC_PROM_BASE 0x50f08000
92 enum macsonic_type {
93 MACSONIC_DUODOCK,
94 MACSONIC_APPLE,
95 MACSONIC_APPLE16,
96 MACSONIC_DAYNA,
97 MACSONIC_DAYNALINK
98 };
100 /* For the built-in SONIC in the Duo Dock */
101 #define DUODOCK_SONIC_REGISTERS 0xe10000
102 #define DUODOCK_SONIC_PROM_BASE 0xe12000
104 /* For Apple-style NuBus SONIC */
105 #define APPLE_SONIC_REGISTERS 0
106 #define APPLE_SONIC_PROM_BASE 0x40000
108 /* Daynalink LC SONIC */
109 #define DAYNALINK_PROM_BASE 0x400000
111 /* For Dayna-style NuBus SONIC (haven't seen one yet) */
112 #define DAYNA_SONIC_REGISTERS 0x180000
113 /* This is what OpenBSD says. However, this is definitely in NuBus
114 ROM space so we should be able to get it by walking the NuBus
115 resource directories */
116 #define DAYNA_SONIC_MAC_ADDR 0xffe004
118 #define SONIC_READ_PROM(addr) nubus_readb(prom_addr+addr)
120 /*
121 * For reversing the PROM address
122 */
124 static unsigned char nibbletab[] = {0, 8, 4, 12, 2, 10, 6, 14,
125 1, 9, 5, 13, 3, 11, 7, 15};
127 static inline void bit_reverse_addr(unsigned char addr[6])
128 {
129 int i;
131 for(i = 0; i < 6; i++)
132 addr[i] = ((nibbletab[addr[i] & 0xf] << 4) |
133 nibbletab[(addr[i] >> 4) &0xf]);
134 }
136 int __init macsonic_init(struct net_device* dev)
137 {
138 struct sonic_local* lp = netdev_priv(dev);
140 /* Allocate the entire chunk of memory for the descriptors.
141 Note that this cannot cross a 64K boundary. */
142 if ((lp->descriptors = dma_alloc_coherent(lp->device,
143 SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
144 &lp->descriptors_laddr, GFP_KERNEL)) == NULL) {
145 printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", lp->device->bus_id);
146 return -ENOMEM;
147 }
149 /* Now set up the pointers to point to the appropriate places */
150 lp->cda = lp->descriptors;
151 lp->tda = lp->cda + (SIZEOF_SONIC_CDA
152 * SONIC_BUS_SCALE(lp->dma_bitmode));
153 lp->rda = lp->tda + (SIZEOF_SONIC_TD * SONIC_NUM_TDS
154 * SONIC_BUS_SCALE(lp->dma_bitmode));
155 lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
156 * SONIC_BUS_SCALE(lp->dma_bitmode));
158 lp->cda_laddr = lp->descriptors_laddr;
159 lp->tda_laddr = lp->cda_laddr + (SIZEOF_SONIC_CDA
160 * SONIC_BUS_SCALE(lp->dma_bitmode));
161 lp->rda_laddr = lp->tda_laddr + (SIZEOF_SONIC_TD * SONIC_NUM_TDS
162 * SONIC_BUS_SCALE(lp->dma_bitmode));
163 lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
164 * SONIC_BUS_SCALE(lp->dma_bitmode));
166 dev->open = sonic_open;
167 dev->stop = sonic_close;
168 dev->hard_start_xmit = sonic_send_packet;
169 dev->get_stats = sonic_get_stats;
170 dev->set_multicast_list = &sonic_multicast_list;
171 dev->tx_timeout = sonic_tx_timeout;
172 dev->watchdog_timeo = TX_TIMEOUT;
174 /*
175 * clear tally counter
176 */
177 SONIC_WRITE(SONIC_CRCT, 0xffff);
178 SONIC_WRITE(SONIC_FAET, 0xffff);
179 SONIC_WRITE(SONIC_MPT, 0xffff);
181 return 0;
182 }
184 int __init mac_onboard_sonic_ethernet_addr(struct net_device* dev)
185 {
186 struct sonic_local *lp = netdev_priv(dev);
187 const int prom_addr = ONBOARD_SONIC_PROM_BASE;
188 int i;
190 /* On NuBus boards we can sometimes look in the ROM resources.
191 No such luck for comm-slot/onboard. */
192 for(i = 0; i < 6; i++)
193 dev->dev_addr[i] = SONIC_READ_PROM(i);
195 /* Most of the time, the address is bit-reversed. The NetBSD
196 source has a rather long and detailed historical account of
197 why this is so. */
198 if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) &&
199 memcmp(dev->dev_addr, "\x00\xA0\x40", 3) &&
200 memcmp(dev->dev_addr, "\x00\x80\x19", 3) &&
201 memcmp(dev->dev_addr, "\x00\x05\x02", 3))
202 bit_reverse_addr(dev->dev_addr);
203 else
204 return 0;
206 /* If we still have what seems to be a bogus address, we'll
207 look in the CAM. The top entry should be ours. */
208 /* Danger! This only works if MacOS has already initialized
209 the card... */
210 if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) &&
211 memcmp(dev->dev_addr, "\x00\xA0\x40", 3) &&
212 memcmp(dev->dev_addr, "\x00\x80\x19", 3) &&
213 memcmp(dev->dev_addr, "\x00\x05\x02", 3))
214 {
215 unsigned short val;
217 printk(KERN_INFO "macsonic: PROM seems to be wrong, trying CAM entry 15\n");
219 SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
220 SONIC_WRITE(SONIC_CEP, 15);
222 val = SONIC_READ(SONIC_CAP2);
223 dev->dev_addr[5] = val >> 8;
224 dev->dev_addr[4] = val & 0xff;
225 val = SONIC_READ(SONIC_CAP1);
226 dev->dev_addr[3] = val >> 8;
227 dev->dev_addr[2] = val & 0xff;
228 val = SONIC_READ(SONIC_CAP0);
229 dev->dev_addr[1] = val >> 8;
230 dev->dev_addr[0] = val & 0xff;
232 printk(KERN_INFO "HW Address from CAM 15: ");
233 for (i = 0; i < 6; i++) {
234 printk("%2.2x", dev->dev_addr[i]);
235 if (i < 5)
236 printk(":");
237 }
238 printk("\n");
239 } else return 0;
241 if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) &&
242 memcmp(dev->dev_addr, "\x00\xA0\x40", 3) &&
243 memcmp(dev->dev_addr, "\x00\x80\x19", 3) &&
244 memcmp(dev->dev_addr, "\x00\x05\x02", 3))
245 {
246 /*
247 * Still nonsense ... messed up someplace!
248 */
249 printk(KERN_ERR "macsonic: ERROR (INVALID MAC)\n");
250 return -EIO;
251 } else return 0;
252 }
254 int __init mac_onboard_sonic_probe(struct net_device* dev)
255 {
256 /* Bwahahaha */
257 static int once_is_more_than_enough;
258 struct sonic_local* lp = netdev_priv(dev);
259 int sr;
260 int commslot = 0;
262 if (once_is_more_than_enough)
263 return -ENODEV;
264 once_is_more_than_enough = 1;
266 if (!MACH_IS_MAC)
267 return -ENODEV;
269 if (macintosh_config->ether_type != MAC_ETHER_SONIC)
270 return -ENODEV;
272 printk(KERN_INFO "Checking for internal Macintosh ethernet (SONIC).. ");
274 /* Bogus probing, on the models which may or may not have
275 Ethernet (BTW, the Ethernet *is* always at the same
276 address, and nothing else lives there, at least if Apple's
277 documentation is to be believed) */
278 if (macintosh_config->ident == MAC_MODEL_Q630 ||
279 macintosh_config->ident == MAC_MODEL_P588 ||
280 macintosh_config->ident == MAC_MODEL_P575 ||
281 macintosh_config->ident == MAC_MODEL_C610) {
282 unsigned long flags;
283 int card_present;
285 local_irq_save(flags);
286 card_present = hwreg_present((void*)ONBOARD_SONIC_REGISTERS);
287 local_irq_restore(flags);
289 if (!card_present) {
290 printk("none.\n");
291 return -ENODEV;
292 }
293 commslot = 1;
294 }
296 printk("yes\n");
298 /* Danger! My arms are flailing wildly! You *must* set lp->reg_offset
299 * and dev->base_addr before using SONIC_READ() or SONIC_WRITE() */
300 dev->base_addr = ONBOARD_SONIC_REGISTERS;
301 if (via_alt_mapping)
302 dev->irq = IRQ_AUTO_3;
303 else
304 dev->irq = IRQ_NUBUS_9;
306 if (!sonic_version_printed) {
307 printk(KERN_INFO "%s", version);
308 sonic_version_printed = 1;
309 }
310 printk(KERN_INFO "%s: onboard / comm-slot SONIC at 0x%08lx\n",
311 lp->device->bus_id, dev->base_addr);
313 /* The PowerBook's SONIC is 16 bit always. */
314 if (macintosh_config->ident == MAC_MODEL_PB520) {
315 lp->reg_offset = 0;
316 lp->dma_bitmode = SONIC_BITMODE16;
317 sr = SONIC_READ(SONIC_SR);
318 } else if (commslot) {
319 /* Some of the comm-slot cards are 16 bit. But some
320 of them are not. The 32-bit cards use offset 2 and
321 have known revisions, we try reading the revision
322 register at offset 2, if we don't get a known revision
323 we assume 16 bit at offset 0. */
324 lp->reg_offset = 2;
325 lp->dma_bitmode = SONIC_BITMODE16;
327 sr = SONIC_READ(SONIC_SR);
328 if (sr == 0x0004 || sr == 0x0006 || sr == 0x0100 || sr == 0x0101)
329 /* 83932 is 0x0004 or 0x0006, 83934 is 0x0100 or 0x0101 */
330 lp->dma_bitmode = SONIC_BITMODE32;
331 else {
332 lp->dma_bitmode = SONIC_BITMODE16;
333 lp->reg_offset = 0;
334 sr = SONIC_READ(SONIC_SR);
335 }
336 } else {
337 /* All onboard cards are at offset 2 with 32 bit DMA. */
338 lp->reg_offset = 2;
339 lp->dma_bitmode = SONIC_BITMODE32;
340 sr = SONIC_READ(SONIC_SR);
341 }
342 printk(KERN_INFO
343 "%s: revision 0x%04x, using %d bit DMA and register offset %d\n",
344 lp->device->bus_id, sr, lp->dma_bitmode?32:16, lp->reg_offset);
346 #if 0 /* This is sometimes useful to find out how MacOS configured the card. */
347 printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", lp->device->bus_id,
348 SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff);
349 #endif
351 /* Software reset, then initialize control registers. */
352 SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
354 SONIC_WRITE(SONIC_DCR, SONIC_DCR_EXBUS | SONIC_DCR_BMS |
355 SONIC_DCR_RFT1 | SONIC_DCR_TFT0 |
356 (lp->dma_bitmode ? SONIC_DCR_DW : 0));
358 /* This *must* be written back to in order to restore the
359 * extended programmable output bits, as it may not have been
360 * initialised since the hardware reset. */
361 SONIC_WRITE(SONIC_DCR2, 0);
363 /* Clear *and* disable interrupts to be on the safe side */
364 SONIC_WRITE(SONIC_IMR, 0);
365 SONIC_WRITE(SONIC_ISR, 0x7fff);
367 /* Now look for the MAC address. */
368 if (mac_onboard_sonic_ethernet_addr(dev) != 0)
369 return -ENODEV;
371 /* Shared init code */
372 return macsonic_init(dev);
373 }
375 int __init mac_nubus_sonic_ethernet_addr(struct net_device* dev,
376 unsigned long prom_addr,
377 int id)
378 {
379 int i;
380 for(i = 0; i < 6; i++)
381 dev->dev_addr[i] = SONIC_READ_PROM(i);
383 /* Some of the addresses are bit-reversed */
384 if (id != MACSONIC_DAYNA)
385 bit_reverse_addr(dev->dev_addr);
387 return 0;
388 }
390 int __init macsonic_ident(struct nubus_dev* ndev)
391 {
392 if (ndev->dr_hw == NUBUS_DRHW_ASANTE_LC &&
393 ndev->dr_sw == NUBUS_DRSW_SONIC_LC)
394 return MACSONIC_DAYNALINK;
395 if (ndev->dr_hw == NUBUS_DRHW_SONIC &&
396 ndev->dr_sw == NUBUS_DRSW_APPLE) {
397 /* There has to be a better way to do this... */
398 if (strstr(ndev->board->name, "DuoDock"))
399 return MACSONIC_DUODOCK;
400 else
401 return MACSONIC_APPLE;
402 }
404 if (ndev->dr_hw == NUBUS_DRHW_SMC9194 &&
405 ndev->dr_sw == NUBUS_DRSW_DAYNA)
406 return MACSONIC_DAYNA;
408 if (ndev->dr_hw == NUBUS_DRHW_SONIC_LC &&
409 ndev->dr_sw == 0) { /* huh? */
410 return MACSONIC_APPLE16;
411 }
412 return -1;
413 }
415 int __init mac_nubus_sonic_probe(struct net_device* dev)
416 {
417 static int slots;
418 struct nubus_dev* ndev = NULL;
419 struct sonic_local* lp = netdev_priv(dev);
420 unsigned long base_addr, prom_addr;
421 u16 sonic_dcr;
422 int id = -1;
423 int reg_offset, dma_bitmode;
425 /* Find the first SONIC that hasn't been initialized already */
426 while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK,
427 NUBUS_TYPE_ETHERNET, ndev)) != NULL)
428 {
429 /* Have we seen it already? */
430 if (slots & (1<<ndev->board->slot))
431 continue;
432 slots |= 1<<ndev->board->slot;
434 /* Is it one of ours? */
435 if ((id = macsonic_ident(ndev)) != -1)
436 break;
437 }
439 if (ndev == NULL)
440 return -ENODEV;
442 switch (id) {
443 case MACSONIC_DUODOCK:
444 base_addr = ndev->board->slot_addr + DUODOCK_SONIC_REGISTERS;
445 prom_addr = ndev->board->slot_addr + DUODOCK_SONIC_PROM_BASE;
446 sonic_dcr = SONIC_DCR_EXBUS | SONIC_DCR_RFT0 | SONIC_DCR_RFT1 |
447 SONIC_DCR_TFT0;
448 reg_offset = 2;
449 dma_bitmode = SONIC_BITMODE32;
450 break;
451 case MACSONIC_APPLE:
452 base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS;
453 prom_addr = ndev->board->slot_addr + APPLE_SONIC_PROM_BASE;
454 sonic_dcr = SONIC_DCR_BMS | SONIC_DCR_RFT1 | SONIC_DCR_TFT0;
455 reg_offset = 0;
456 dma_bitmode = SONIC_BITMODE32;
457 break;
458 case MACSONIC_APPLE16:
459 base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS;
460 prom_addr = ndev->board->slot_addr + APPLE_SONIC_PROM_BASE;
461 sonic_dcr = SONIC_DCR_EXBUS | SONIC_DCR_RFT1 | SONIC_DCR_TFT0 |
462 SONIC_DCR_PO1 | SONIC_DCR_BMS;
463 reg_offset = 0;
464 dma_bitmode = SONIC_BITMODE16;
465 break;
466 case MACSONIC_DAYNALINK:
467 base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS;
468 prom_addr = ndev->board->slot_addr + DAYNALINK_PROM_BASE;
469 sonic_dcr = SONIC_DCR_RFT1 | SONIC_DCR_TFT0 |
470 SONIC_DCR_PO1 | SONIC_DCR_BMS;
471 reg_offset = 0;
472 dma_bitmode = SONIC_BITMODE16;
473 break;
474 case MACSONIC_DAYNA:
475 base_addr = ndev->board->slot_addr + DAYNA_SONIC_REGISTERS;
476 prom_addr = ndev->board->slot_addr + DAYNA_SONIC_MAC_ADDR;
477 sonic_dcr = SONIC_DCR_BMS |
478 SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | SONIC_DCR_PO1;
479 reg_offset = 0;
480 dma_bitmode = SONIC_BITMODE16;
481 break;
482 default:
483 printk(KERN_ERR "macsonic: WTF, id is %d\n", id);
484 return -ENODEV;
485 }
487 /* Danger! My arms are flailing wildly! You *must* set lp->reg_offset
488 * and dev->base_addr before using SONIC_READ() or SONIC_WRITE() */
489 dev->base_addr = base_addr;
490 lp->reg_offset = reg_offset;
491 lp->dma_bitmode = dma_bitmode;
492 dev->irq = SLOT2IRQ(ndev->board->slot);
494 if (!sonic_version_printed) {
495 printk(KERN_INFO "%s", version);
496 sonic_version_printed = 1;
497 }
498 printk(KERN_INFO "%s: %s in slot %X\n",
499 lp->device->bus_id, ndev->board->name, ndev->board->slot);
500 printk(KERN_INFO "%s: revision 0x%04x, using %d bit DMA and register offset %d\n",
501 lp->device->bus_id, SONIC_READ(SONIC_SR), dma_bitmode?32:16, reg_offset);
503 #if 0 /* This is sometimes useful to find out how MacOS configured the card. */
504 printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", lp->device->bus_id,
505 SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff);
506 #endif
508 /* Software reset, then initialize control registers. */
509 SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
510 SONIC_WRITE(SONIC_DCR, sonic_dcr | (dma_bitmode ? SONIC_DCR_DW : 0));
511 /* This *must* be written back to in order to restore the
512 * extended programmable output bits, since it may not have been
513 * initialised since the hardware reset. */
514 SONIC_WRITE(SONIC_DCR2, 0);
516 /* Clear *and* disable interrupts to be on the safe side */
517 SONIC_WRITE(SONIC_IMR, 0);
518 SONIC_WRITE(SONIC_ISR, 0x7fff);
520 /* Now look for the MAC address. */
521 if (mac_nubus_sonic_ethernet_addr(dev, prom_addr, id) != 0)
522 return -ENODEV;
524 /* Shared init code */
525 return macsonic_init(dev);
526 }
528 static int __init mac_sonic_probe(struct platform_device *device)
529 {
530 struct net_device *dev;
531 struct sonic_local *lp;
532 int err;
533 int i;
535 dev = alloc_etherdev(sizeof(struct sonic_local));
536 if (!dev)
537 return -ENOMEM;
539 lp = netdev_priv(dev);
540 lp->device = &device->dev;
541 SET_NETDEV_DEV(dev, &device->dev);
542 SET_MODULE_OWNER(dev);
544 /* This will catch fatal stuff like -ENOMEM as well as success */
545 err = mac_onboard_sonic_probe(dev);
546 if (err == 0)
547 goto found;
548 if (err != -ENODEV)
549 goto out;
550 err = mac_nubus_sonic_probe(dev);
551 if (err)
552 goto out;
553 found:
554 err = register_netdev(dev);
555 if (err)
556 goto out;
558 printk("%s: MAC ", dev->name);
559 for (i = 0; i < 6; i++) {
560 printk("%2.2x", dev->dev_addr[i]);
561 if (i < 5)
562 printk(":");
563 }
564 printk(" IRQ %d\n", dev->irq);
566 return 0;
568 out:
569 free_netdev(dev);
571 return err;
572 }
574 MODULE_DESCRIPTION("Macintosh SONIC ethernet driver");
575 module_param(sonic_debug, int, 0);
576 MODULE_PARM_DESC(sonic_debug, "macsonic debug level (1-4)");
578 #define SONIC_IRQ_FLAG IRQ_FLG_FAST
580 #include "sonic.c"
582 static int __devexit mac_sonic_device_remove (struct platform_device *device)
583 {
584 struct net_device *dev = platform_get_drvdata(device);
585 struct sonic_local* lp = netdev_priv(dev);
587 unregister_netdev (dev);
588 dma_free_coherent(lp->device, SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
589 lp->descriptors, lp->descriptors_laddr);
590 free_netdev (dev);
592 return 0;
593 }
595 static struct platform_driver mac_sonic_driver = {
596 .probe = mac_sonic_probe,
597 .remove = __devexit_p(mac_sonic_device_remove),
598 .driver = {
599 .name = mac_sonic_string,
600 },
601 };
603 static int __init mac_sonic_init_module(void)
604 {
605 int err;
607 if ((err = platform_driver_register(&mac_sonic_driver))) {
608 printk(KERN_ERR "Driver registration failed\n");
609 return err;
610 }
612 mac_sonic_device = platform_device_alloc(mac_sonic_string, 0);
613 if (!mac_sonic_device) {
614 goto out_unregister;
615 }
617 if (platform_device_add(mac_sonic_device)) {
618 platform_device_put(mac_sonic_device);
619 mac_sonic_device = NULL;
620 }
622 return 0;
624 out_unregister:
625 platform_driver_unregister(&mac_sonic_driver);
627 return -ENOMEM;
628 }
630 static void __exit mac_sonic_cleanup_module(void)
631 {
632 platform_driver_unregister(&mac_sonic_driver);
634 if (mac_sonic_device) {
635 platform_device_unregister(mac_sonic_device);
636 mac_sonic_device = NULL;
637 }
638 }
640 module_init(mac_sonic_init_module);
641 module_exit(mac_sonic_cleanup_module);