diff options
Diffstat (limited to 'drivers/net/sunhme.c')
-rw-r--r-- | drivers/net/sunhme.c | 443 |
1 files changed, 220 insertions, 223 deletions
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index bd5d2668a36..f05eea53623 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* $Id: sunhme.c,v 1.124 2002/01/15 06:25:51 davem Exp $ | 1 | /* sunhme.c: Sparc HME/BigMac 10/100baseT half/full duplex auto switching, |
2 | * sunhme.c: Sparc HME/BigMac 10/100baseT half/full duplex auto switching, | ||
3 | * auto carrier detecting ethernet driver. Also known as the | 2 | * auto carrier detecting ethernet driver. Also known as the |
4 | * "Happy Meal Ethernet" found on SunSwift SBUS cards. | 3 | * "Happy Meal Ethernet" found on SunSwift SBUS cards. |
5 | * | 4 | * |
6 | * Copyright (C) 1996, 1998, 1999, 2002, 2003 David S. Miller (davem@redhat.com) | 5 | * Copyright (C) 1996, 1998, 1999, 2002, 2003, |
6 | 2006 David S. Miller (davem@davemloft.net) | ||
7 | * | 7 | * |
8 | * Changes : | 8 | * Changes : |
9 | * 2000/11/11 Willy Tarreau <willy AT meta-x.org> | 9 | * 2000/11/11 Willy Tarreau <willy AT meta-x.org> |
@@ -13,7 +13,6 @@ | |||
13 | * argument : macaddr=0x00,0x10,0x20,0x30,0x40,0x50 | 13 | * argument : macaddr=0x00,0x10,0x20,0x30,0x40,0x50 |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/config.h> | ||
17 | #include <linux/module.h> | 16 | #include <linux/module.h> |
18 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
19 | #include <linux/types.h> | 18 | #include <linux/types.h> |
@@ -40,15 +39,13 @@ | |||
40 | #include <asm/dma.h> | 39 | #include <asm/dma.h> |
41 | #include <asm/byteorder.h> | 40 | #include <asm/byteorder.h> |
42 | 41 | ||
43 | #ifdef __sparc__ | 42 | #ifdef CONFIG_SPARC |
44 | #include <asm/idprom.h> | 43 | #include <asm/idprom.h> |
45 | #include <asm/sbus.h> | 44 | #include <asm/sbus.h> |
46 | #include <asm/openprom.h> | 45 | #include <asm/openprom.h> |
47 | #include <asm/oplib.h> | 46 | #include <asm/oplib.h> |
47 | #include <asm/prom.h> | ||
48 | #include <asm/auxio.h> | 48 | #include <asm/auxio.h> |
49 | #ifndef __sparc_v9__ | ||
50 | #include <asm/io-unit.h> | ||
51 | #endif | ||
52 | #endif | 49 | #endif |
53 | #include <asm/uaccess.h> | 50 | #include <asm/uaccess.h> |
54 | 51 | ||
@@ -57,7 +54,7 @@ | |||
57 | 54 | ||
58 | #ifdef CONFIG_PCI | 55 | #ifdef CONFIG_PCI |
59 | #include <linux/pci.h> | 56 | #include <linux/pci.h> |
60 | #ifdef __sparc__ | 57 | #ifdef CONFIG_SPARC |
61 | #include <asm/pbm.h> | 58 | #include <asm/pbm.h> |
62 | #endif | 59 | #endif |
63 | #endif | 60 | #endif |
@@ -65,9 +62,9 @@ | |||
65 | #include "sunhme.h" | 62 | #include "sunhme.h" |
66 | 63 | ||
67 | #define DRV_NAME "sunhme" | 64 | #define DRV_NAME "sunhme" |
68 | #define DRV_VERSION "2.02" | 65 | #define DRV_VERSION "3.00" |
69 | #define DRV_RELDATE "8/24/03" | 66 | #define DRV_RELDATE "June 23, 2006" |
70 | #define DRV_AUTHOR "David S. Miller (davem@redhat.com)" | 67 | #define DRV_AUTHOR "David S. Miller (davem@davemloft.net)" |
71 | 68 | ||
72 | static char version[] = | 69 | static char version[] = |
73 | DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n"; | 70 | DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n"; |
@@ -83,8 +80,6 @@ static int macaddr[6]; | |||
83 | module_param_array(macaddr, int, NULL, 0); | 80 | module_param_array(macaddr, int, NULL, 0); |
84 | MODULE_PARM_DESC(macaddr, "Happy Meal MAC address to set"); | 81 | MODULE_PARM_DESC(macaddr, "Happy Meal MAC address to set"); |
85 | 82 | ||
86 | static struct happy_meal *root_happy_dev; | ||
87 | |||
88 | #ifdef CONFIG_SBUS | 83 | #ifdef CONFIG_SBUS |
89 | static struct quattro *qfe_sbus_list; | 84 | static struct quattro *qfe_sbus_list; |
90 | #endif | 85 | #endif |
@@ -181,26 +176,6 @@ static __inline__ void tx_dump_ring(struct happy_meal *hp) | |||
181 | #define DEFAULT_IPG2 4 /* For all modes */ | 176 | #define DEFAULT_IPG2 4 /* For all modes */ |
182 | #define DEFAULT_JAMSIZE 4 /* Toe jam */ | 177 | #define DEFAULT_JAMSIZE 4 /* Toe jam */ |
183 | 178 | ||
184 | #if defined(CONFIG_PCI) && defined(MODULE) | ||
185 | /* This happy_pci_ids is declared __initdata because it is only used | ||
186 | as an advisory to depmod. If this is ported to the new PCI interface | ||
187 | where it could be referenced at any time due to hot plugging, | ||
188 | the __initdata reference should be removed. */ | ||
189 | |||
190 | static struct pci_device_id happymeal_pci_ids[] = { | ||
191 | { | ||
192 | .vendor = PCI_VENDOR_ID_SUN, | ||
193 | .device = PCI_DEVICE_ID_SUN_HAPPYMEAL, | ||
194 | .subvendor = PCI_ANY_ID, | ||
195 | .subdevice = PCI_ANY_ID, | ||
196 | }, | ||
197 | { } /* Terminating entry */ | ||
198 | }; | ||
199 | |||
200 | MODULE_DEVICE_TABLE(pci, happymeal_pci_ids); | ||
201 | |||
202 | #endif | ||
203 | |||
204 | /* NOTE: In the descriptor writes one _must_ write the address | 179 | /* NOTE: In the descriptor writes one _must_ write the address |
205 | * member _first_. The card must not be allowed to see | 180 | * member _first_. The card must not be allowed to see |
206 | * the updated descriptor flags until the address is | 181 | * the updated descriptor flags until the address is |
@@ -530,7 +505,7 @@ static void happy_meal_tcvr_write(struct happy_meal *hp, | |||
530 | unsigned short value) | 505 | unsigned short value) |
531 | { | 506 | { |
532 | int tries = TCVR_WRITE_TRIES; | 507 | int tries = TCVR_WRITE_TRIES; |
533 | 508 | ||
534 | ASD(("happy_meal_tcvr_write: reg=0x%02x value=%04x\n", reg, value)); | 509 | ASD(("happy_meal_tcvr_write: reg=0x%02x value=%04x\n", reg, value)); |
535 | 510 | ||
536 | /* Welcome to Sun Microsystems, can I take your order please? */ | 511 | /* Welcome to Sun Microsystems, can I take your order please? */ |
@@ -1232,7 +1207,7 @@ static void happy_meal_transceiver_check(struct happy_meal *hp, void __iomem *tr | |||
1232 | * flags, thus: | 1207 | * flags, thus: |
1233 | * | 1208 | * |
1234 | * skb->csum = rxd->rx_flags & 0xffff; | 1209 | * skb->csum = rxd->rx_flags & 0xffff; |
1235 | * skb->ip_summed = CHECKSUM_HW; | 1210 | * skb->ip_summed = CHECKSUM_COMPLETE; |
1236 | * | 1211 | * |
1237 | * before sending off the skb to the protocols, and we are good as gold. | 1212 | * before sending off the skb to the protocols, and we are good as gold. |
1238 | */ | 1213 | */ |
@@ -1610,7 +1585,7 @@ static int happy_meal_init(struct happy_meal *hp) | |||
1610 | HMD(("happy_meal_init: old[%08x] bursts<", | 1585 | HMD(("happy_meal_init: old[%08x] bursts<", |
1611 | hme_read32(hp, gregs + GREG_CFG))); | 1586 | hme_read32(hp, gregs + GREG_CFG))); |
1612 | 1587 | ||
1613 | #ifndef __sparc__ | 1588 | #ifndef CONFIG_SPARC |
1614 | /* It is always PCI and can handle 64byte bursts. */ | 1589 | /* It is always PCI and can handle 64byte bursts. */ |
1615 | hme_write32(hp, gregs + GREG_CFG, GREG_CFG_BURST64); | 1590 | hme_write32(hp, gregs + GREG_CFG, GREG_CFG_BURST64); |
1616 | #else | 1591 | #else |
@@ -1647,7 +1622,7 @@ static int happy_meal_init(struct happy_meal *hp) | |||
1647 | HMD(("XXX>")); | 1622 | HMD(("XXX>")); |
1648 | hme_write32(hp, gregs + GREG_CFG, 0); | 1623 | hme_write32(hp, gregs + GREG_CFG, 0); |
1649 | } | 1624 | } |
1650 | #endif /* __sparc__ */ | 1625 | #endif /* CONFIG_SPARC */ |
1651 | 1626 | ||
1652 | /* Turn off interrupts we do not want to hear. */ | 1627 | /* Turn off interrupts we do not want to hear. */ |
1653 | HMD((", enable global interrupts, ")); | 1628 | HMD((", enable global interrupts, ")); |
@@ -1803,7 +1778,7 @@ static void happy_meal_set_initial_advertisement(struct happy_meal *hp) | |||
1803 | static int happy_meal_is_not_so_happy(struct happy_meal *hp, u32 status) | 1778 | static int happy_meal_is_not_so_happy(struct happy_meal *hp, u32 status) |
1804 | { | 1779 | { |
1805 | int reset = 0; | 1780 | int reset = 0; |
1806 | 1781 | ||
1807 | /* Only print messages for non-counter related interrupts. */ | 1782 | /* Only print messages for non-counter related interrupts. */ |
1808 | if (status & (GREG_STAT_STSTERR | GREG_STAT_TFIFO_UND | | 1783 | if (status & (GREG_STAT_STSTERR | GREG_STAT_TFIFO_UND | |
1809 | GREG_STAT_MAXPKTERR | GREG_STAT_RXERR | | 1784 | GREG_STAT_MAXPKTERR | GREG_STAT_RXERR | |
@@ -2099,7 +2074,7 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev) | |||
2099 | 2074 | ||
2100 | /* This card is _fucking_ hot... */ | 2075 | /* This card is _fucking_ hot... */ |
2101 | skb->csum = ntohs(csum ^ 0xffff); | 2076 | skb->csum = ntohs(csum ^ 0xffff); |
2102 | skb->ip_summed = CHECKSUM_HW; | 2077 | skb->ip_summed = CHECKSUM_COMPLETE; |
2103 | 2078 | ||
2104 | RXD(("len=%d csum=%4x]", len, csum)); | 2079 | RXD(("len=%d csum=%4x]", len, csum)); |
2105 | skb->protocol = eth_type_trans(skb, dev); | 2080 | skb->protocol = eth_type_trans(skb, dev); |
@@ -2219,7 +2194,7 @@ static int happy_meal_open(struct net_device *dev) | |||
2219 | */ | 2194 | */ |
2220 | if ((hp->happy_flags & (HFLAG_QUATTRO|HFLAG_PCI)) != HFLAG_QUATTRO) { | 2195 | if ((hp->happy_flags & (HFLAG_QUATTRO|HFLAG_PCI)) != HFLAG_QUATTRO) { |
2221 | if (request_irq(dev->irq, &happy_meal_interrupt, | 2196 | if (request_irq(dev->irq, &happy_meal_interrupt, |
2222 | SA_SHIRQ, dev->name, (void *)dev)) { | 2197 | IRQF_SHARED, dev->name, (void *)dev)) { |
2223 | HMD(("EAGAIN\n")); | 2198 | HMD(("EAGAIN\n")); |
2224 | printk(KERN_ERR "happy_meal(SBUS): Can't order irq %d to go.\n", | 2199 | printk(KERN_ERR "happy_meal(SBUS): Can't order irq %d to go.\n", |
2225 | dev->irq); | 2200 | dev->irq); |
@@ -2293,7 +2268,7 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2293 | u32 tx_flags; | 2268 | u32 tx_flags; |
2294 | 2269 | ||
2295 | tx_flags = TXFLAG_OWN; | 2270 | tx_flags = TXFLAG_OWN; |
2296 | if (skb->ip_summed == CHECKSUM_HW) { | 2271 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
2297 | u32 csum_start_off, csum_stuff_off; | 2272 | u32 csum_start_off, csum_stuff_off; |
2298 | 2273 | ||
2299 | csum_start_off = (u32) (skb->h.raw - skb->data); | 2274 | csum_start_off = (u32) (skb->h.raw - skb->data); |
@@ -2537,7 +2512,7 @@ static u32 hme_get_link(struct net_device *dev) | |||
2537 | return (hp->sw_bmsr & BMSR_LSTATUS); | 2512 | return (hp->sw_bmsr & BMSR_LSTATUS); |
2538 | } | 2513 | } |
2539 | 2514 | ||
2540 | static struct ethtool_ops hme_ethtool_ops = { | 2515 | static const struct ethtool_ops hme_ethtool_ops = { |
2541 | .get_settings = hme_get_settings, | 2516 | .get_settings = hme_get_settings, |
2542 | .set_settings = hme_set_settings, | 2517 | .set_settings = hme_set_settings, |
2543 | .get_drvinfo = hme_get_drvinfo, | 2518 | .get_drvinfo = hme_get_drvinfo, |
@@ -2547,7 +2522,7 @@ static struct ethtool_ops hme_ethtool_ops = { | |||
2547 | static int hme_version_printed; | 2522 | static int hme_version_printed; |
2548 | 2523 | ||
2549 | #ifdef CONFIG_SBUS | 2524 | #ifdef CONFIG_SBUS |
2550 | void __init quattro_get_ranges(struct quattro *qp) | 2525 | void __devinit quattro_get_ranges(struct quattro *qp) |
2551 | { | 2526 | { |
2552 | struct sbus_dev *sdev = qp->quattro_dev; | 2527 | struct sbus_dev *sdev = qp->quattro_dev; |
2553 | int err; | 2528 | int err; |
@@ -2563,7 +2538,7 @@ void __init quattro_get_ranges(struct quattro *qp) | |||
2563 | qp->nranges = (err / sizeof(struct linux_prom_ranges)); | 2538 | qp->nranges = (err / sizeof(struct linux_prom_ranges)); |
2564 | } | 2539 | } |
2565 | 2540 | ||
2566 | static void __init quattro_apply_ranges(struct quattro *qp, struct happy_meal *hp) | 2541 | static void __devinit quattro_apply_ranges(struct quattro *qp, struct happy_meal *hp) |
2567 | { | 2542 | { |
2568 | struct sbus_dev *sdev = hp->happy_dev; | 2543 | struct sbus_dev *sdev = hp->happy_dev; |
2569 | int rng; | 2544 | int rng; |
@@ -2590,16 +2565,12 @@ static void __init quattro_apply_ranges(struct quattro *qp, struct happy_meal *h | |||
2590 | * | 2565 | * |
2591 | * Return NULL on failure. | 2566 | * Return NULL on failure. |
2592 | */ | 2567 | */ |
2593 | static struct quattro * __init quattro_sbus_find(struct sbus_dev *goal_sdev) | 2568 | static struct quattro * __devinit quattro_sbus_find(struct sbus_dev *goal_sdev) |
2594 | { | 2569 | { |
2595 | struct sbus_bus *sbus; | ||
2596 | struct sbus_dev *sdev; | 2570 | struct sbus_dev *sdev; |
2597 | struct quattro *qp; | 2571 | struct quattro *qp; |
2598 | int i; | 2572 | int i; |
2599 | 2573 | ||
2600 | if (qfe_sbus_list == NULL) | ||
2601 | goto found; | ||
2602 | |||
2603 | for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) { | 2574 | for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) { |
2604 | for (i = 0, sdev = qp->quattro_dev; | 2575 | for (i = 0, sdev = qp->quattro_dev; |
2605 | (sdev != NULL) && (i < 4); | 2576 | (sdev != NULL) && (i < 4); |
@@ -2608,17 +2579,7 @@ static struct quattro * __init quattro_sbus_find(struct sbus_dev *goal_sdev) | |||
2608 | return qp; | 2579 | return qp; |
2609 | } | 2580 | } |
2610 | } | 2581 | } |
2611 | for_each_sbus(sbus) { | ||
2612 | for_each_sbusdev(sdev, sbus) { | ||
2613 | if (sdev == goal_sdev) | ||
2614 | goto found; | ||
2615 | } | ||
2616 | } | ||
2617 | 2582 | ||
2618 | /* Cannot find quattro parent, fail. */ | ||
2619 | return NULL; | ||
2620 | |||
2621 | found: | ||
2622 | qp = kmalloc(sizeof(struct quattro), GFP_KERNEL); | 2583 | qp = kmalloc(sizeof(struct quattro), GFP_KERNEL); |
2623 | if (qp != NULL) { | 2584 | if (qp != NULL) { |
2624 | int i; | 2585 | int i; |
@@ -2647,7 +2608,7 @@ static void __init quattro_sbus_register_irqs(void) | |||
2647 | 2608 | ||
2648 | err = request_irq(sdev->irqs[0], | 2609 | err = request_irq(sdev->irqs[0], |
2649 | quattro_sbus_interrupt, | 2610 | quattro_sbus_interrupt, |
2650 | SA_SHIRQ, "Quattro", | 2611 | IRQF_SHARED, "Quattro", |
2651 | qp); | 2612 | qp); |
2652 | if (err != 0) { | 2613 | if (err != 0) { |
2653 | printk(KERN_ERR "Quattro: Fatal IRQ registery error %d.\n", err); | 2614 | printk(KERN_ERR "Quattro: Fatal IRQ registery error %d.\n", err); |
@@ -2655,6 +2616,17 @@ static void __init quattro_sbus_register_irqs(void) | |||
2655 | } | 2616 | } |
2656 | } | 2617 | } |
2657 | } | 2618 | } |
2619 | |||
2620 | static void quattro_sbus_free_irqs(void) | ||
2621 | { | ||
2622 | struct quattro *qp; | ||
2623 | |||
2624 | for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) { | ||
2625 | struct sbus_dev *sdev = qp->quattro_dev; | ||
2626 | |||
2627 | free_irq(sdev->irqs[0], qp); | ||
2628 | } | ||
2629 | } | ||
2658 | #endif /* CONFIG_SBUS */ | 2630 | #endif /* CONFIG_SBUS */ |
2659 | 2631 | ||
2660 | #ifdef CONFIG_PCI | 2632 | #ifdef CONFIG_PCI |
@@ -2689,8 +2661,9 @@ static struct quattro * __init quattro_pci_find(struct pci_dev *pdev) | |||
2689 | #endif /* CONFIG_PCI */ | 2661 | #endif /* CONFIG_PCI */ |
2690 | 2662 | ||
2691 | #ifdef CONFIG_SBUS | 2663 | #ifdef CONFIG_SBUS |
2692 | static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) | 2664 | static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe) |
2693 | { | 2665 | { |
2666 | struct device_node *dp = sdev->ofdev.node; | ||
2694 | struct quattro *qp = NULL; | 2667 | struct quattro *qp = NULL; |
2695 | struct happy_meal *hp; | 2668 | struct happy_meal *hp; |
2696 | struct net_device *dev; | 2669 | struct net_device *dev; |
@@ -2713,6 +2686,7 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) | |||
2713 | if (!dev) | 2686 | if (!dev) |
2714 | goto err_out; | 2687 | goto err_out; |
2715 | SET_MODULE_OWNER(dev); | 2688 | SET_MODULE_OWNER(dev); |
2689 | SET_NETDEV_DEV(dev, &sdev->ofdev.dev); | ||
2716 | 2690 | ||
2717 | if (hme_version_printed++ == 0) | 2691 | if (hme_version_printed++ == 0) |
2718 | printk(KERN_INFO "%s", version); | 2692 | printk(KERN_INFO "%s", version); |
@@ -2728,13 +2702,16 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) | |||
2728 | for (i = 0; i < 6; i++) | 2702 | for (i = 0; i < 6; i++) |
2729 | dev->dev_addr[i] = macaddr[i]; | 2703 | dev->dev_addr[i] = macaddr[i]; |
2730 | macaddr[5]++; | 2704 | macaddr[5]++; |
2731 | } else if (qfe_slot != -1 && | ||
2732 | prom_getproplen(sdev->prom_node, | ||
2733 | "local-mac-address") == 6) { | ||
2734 | prom_getproperty(sdev->prom_node, "local-mac-address", | ||
2735 | dev->dev_addr, 6); | ||
2736 | } else { | 2705 | } else { |
2737 | memcpy(dev->dev_addr, idprom->id_ethaddr, 6); | 2706 | unsigned char *addr; |
2707 | int len; | ||
2708 | |||
2709 | addr = of_get_property(dp, "local-mac-address", &len); | ||
2710 | |||
2711 | if (qfe_slot != -1 && addr && len == 6) | ||
2712 | memcpy(dev->dev_addr, addr, 6); | ||
2713 | else | ||
2714 | memcpy(dev->dev_addr, idprom->id_ethaddr, 6); | ||
2738 | } | 2715 | } |
2739 | 2716 | ||
2740 | hp = dev->priv; | 2717 | hp = dev->priv; |
@@ -2745,9 +2722,8 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) | |||
2745 | 2722 | ||
2746 | err = -ENODEV; | 2723 | err = -ENODEV; |
2747 | if (sdev->num_registers != 5) { | 2724 | if (sdev->num_registers != 5) { |
2748 | printk(KERN_ERR "happymeal: Device does not have 5 regs, it has %d.\n", | 2725 | printk(KERN_ERR "happymeal: Device needs 5 regs, has %d.\n", |
2749 | sdev->num_registers); | 2726 | sdev->num_registers); |
2750 | printk(KERN_ERR "happymeal: Would you like that for here or to go?\n"); | ||
2751 | goto err_out_free_netdev; | 2727 | goto err_out_free_netdev; |
2752 | } | 2728 | } |
2753 | 2729 | ||
@@ -2761,39 +2737,39 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) | |||
2761 | hp->gregs = sbus_ioremap(&sdev->resource[0], 0, | 2737 | hp->gregs = sbus_ioremap(&sdev->resource[0], 0, |
2762 | GREG_REG_SIZE, "HME Global Regs"); | 2738 | GREG_REG_SIZE, "HME Global Regs"); |
2763 | if (!hp->gregs) { | 2739 | if (!hp->gregs) { |
2764 | printk(KERN_ERR "happymeal: Cannot map Happy Meal global registers.\n"); | 2740 | printk(KERN_ERR "happymeal: Cannot map global registers.\n"); |
2765 | goto err_out_free_netdev; | 2741 | goto err_out_free_netdev; |
2766 | } | 2742 | } |
2767 | 2743 | ||
2768 | hp->etxregs = sbus_ioremap(&sdev->resource[1], 0, | 2744 | hp->etxregs = sbus_ioremap(&sdev->resource[1], 0, |
2769 | ETX_REG_SIZE, "HME TX Regs"); | 2745 | ETX_REG_SIZE, "HME TX Regs"); |
2770 | if (!hp->etxregs) { | 2746 | if (!hp->etxregs) { |
2771 | printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Transmit registers.\n"); | 2747 | printk(KERN_ERR "happymeal: Cannot map MAC TX registers.\n"); |
2772 | goto err_out_iounmap; | 2748 | goto err_out_iounmap; |
2773 | } | 2749 | } |
2774 | 2750 | ||
2775 | hp->erxregs = sbus_ioremap(&sdev->resource[2], 0, | 2751 | hp->erxregs = sbus_ioremap(&sdev->resource[2], 0, |
2776 | ERX_REG_SIZE, "HME RX Regs"); | 2752 | ERX_REG_SIZE, "HME RX Regs"); |
2777 | if (!hp->erxregs) { | 2753 | if (!hp->erxregs) { |
2778 | printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Receive registers.\n"); | 2754 | printk(KERN_ERR "happymeal: Cannot map MAC RX registers.\n"); |
2779 | goto err_out_iounmap; | 2755 | goto err_out_iounmap; |
2780 | } | 2756 | } |
2781 | 2757 | ||
2782 | hp->bigmacregs = sbus_ioremap(&sdev->resource[3], 0, | 2758 | hp->bigmacregs = sbus_ioremap(&sdev->resource[3], 0, |
2783 | BMAC_REG_SIZE, "HME BIGMAC Regs"); | 2759 | BMAC_REG_SIZE, "HME BIGMAC Regs"); |
2784 | if (!hp->bigmacregs) { | 2760 | if (!hp->bigmacregs) { |
2785 | printk(KERN_ERR "happymeal: Cannot map Happy Meal BIGMAC registers.\n"); | 2761 | printk(KERN_ERR "happymeal: Cannot map BIGMAC registers.\n"); |
2786 | goto err_out_iounmap; | 2762 | goto err_out_iounmap; |
2787 | } | 2763 | } |
2788 | 2764 | ||
2789 | hp->tcvregs = sbus_ioremap(&sdev->resource[4], 0, | 2765 | hp->tcvregs = sbus_ioremap(&sdev->resource[4], 0, |
2790 | TCVR_REG_SIZE, "HME Tranceiver Regs"); | 2766 | TCVR_REG_SIZE, "HME Tranceiver Regs"); |
2791 | if (!hp->tcvregs) { | 2767 | if (!hp->tcvregs) { |
2792 | printk(KERN_ERR "happymeal: Cannot map Happy Meal Tranceiver registers.\n"); | 2768 | printk(KERN_ERR "happymeal: Cannot map TCVR registers.\n"); |
2793 | goto err_out_iounmap; | 2769 | goto err_out_iounmap; |
2794 | } | 2770 | } |
2795 | 2771 | ||
2796 | hp->hm_revision = prom_getintdefault(sdev->prom_node, "hm-rev", 0xff); | 2772 | hp->hm_revision = of_getintprop_default(dp, "hm-rev", 0xff); |
2797 | if (hp->hm_revision == 0xff) | 2773 | if (hp->hm_revision == 0xff) |
2798 | hp->hm_revision = 0xa0; | 2774 | hp->hm_revision = 0xa0; |
2799 | 2775 | ||
@@ -2807,8 +2783,8 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) | |||
2807 | hp->happy_flags |= HFLAG_QUATTRO; | 2783 | hp->happy_flags |= HFLAG_QUATTRO; |
2808 | 2784 | ||
2809 | /* Get the supported DVMA burst sizes from our Happy SBUS. */ | 2785 | /* Get the supported DVMA burst sizes from our Happy SBUS. */ |
2810 | hp->happy_bursts = prom_getintdefault(sdev->bus->prom_node, | 2786 | hp->happy_bursts = of_getintprop_default(sdev->bus->ofdev.node, |
2811 | "burst-sizes", 0x00); | 2787 | "burst-sizes", 0x00); |
2812 | 2788 | ||
2813 | hp->happy_block = sbus_alloc_consistent(hp->happy_dev, | 2789 | hp->happy_block = sbus_alloc_consistent(hp->happy_dev, |
2814 | PAGE_SIZE, | 2790 | PAGE_SIZE, |
@@ -2871,6 +2847,8 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) | |||
2871 | goto err_out_free_consistent; | 2847 | goto err_out_free_consistent; |
2872 | } | 2848 | } |
2873 | 2849 | ||
2850 | dev_set_drvdata(&sdev->ofdev.dev, hp); | ||
2851 | |||
2874 | if (qfe_slot != -1) | 2852 | if (qfe_slot != -1) |
2875 | printk(KERN_INFO "%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet ", | 2853 | printk(KERN_INFO "%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet ", |
2876 | dev->name, qfe_slot); | 2854 | dev->name, qfe_slot); |
@@ -2883,12 +2861,6 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) | |||
2883 | dev->dev_addr[i], i == 5 ? ' ' : ':'); | 2861 | dev->dev_addr[i], i == 5 ? ' ' : ':'); |
2884 | printk("\n"); | 2862 | printk("\n"); |
2885 | 2863 | ||
2886 | /* We are home free at this point, link us in to the happy | ||
2887 | * device list. | ||
2888 | */ | ||
2889 | hp->next_module = root_happy_dev; | ||
2890 | root_happy_dev = hp; | ||
2891 | |||
2892 | return 0; | 2864 | return 0; |
2893 | 2865 | ||
2894 | err_out_free_consistent: | 2866 | err_out_free_consistent: |
@@ -2918,7 +2890,7 @@ err_out: | |||
2918 | #endif | 2890 | #endif |
2919 | 2891 | ||
2920 | #ifdef CONFIG_PCI | 2892 | #ifdef CONFIG_PCI |
2921 | #ifndef __sparc__ | 2893 | #ifndef CONFIG_SPARC |
2922 | static int is_quattro_p(struct pci_dev *pdev) | 2894 | static int is_quattro_p(struct pci_dev *pdev) |
2923 | { | 2895 | { |
2924 | struct pci_dev *busdev = pdev->bus->self; | 2896 | struct pci_dev *busdev = pdev->bus->self; |
@@ -3006,14 +2978,14 @@ static void get_hme_mac_nonsparc(struct pci_dev *pdev, unsigned char *dev_addr) | |||
3006 | get_random_bytes(&dev_addr[3], 3); | 2978 | get_random_bytes(&dev_addr[3], 3); |
3007 | return; | 2979 | return; |
3008 | } | 2980 | } |
3009 | #endif /* !(__sparc__) */ | 2981 | #endif /* !(CONFIG_SPARC) */ |
3010 | 2982 | ||
3011 | static int __init happy_meal_pci_init(struct pci_dev *pdev) | 2983 | static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, |
2984 | const struct pci_device_id *ent) | ||
3012 | { | 2985 | { |
3013 | struct quattro *qp = NULL; | 2986 | struct quattro *qp = NULL; |
3014 | #ifdef __sparc__ | 2987 | #ifdef CONFIG_SPARC |
3015 | struct pcidev_cookie *pcp; | 2988 | struct pcidev_cookie *pcp; |
3016 | int node; | ||
3017 | #endif | 2989 | #endif |
3018 | struct happy_meal *hp; | 2990 | struct happy_meal *hp; |
3019 | struct net_device *dev; | 2991 | struct net_device *dev; |
@@ -3024,15 +2996,14 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) | |||
3024 | int err; | 2996 | int err; |
3025 | 2997 | ||
3026 | /* Now make sure pci_dev cookie is there. */ | 2998 | /* Now make sure pci_dev cookie is there. */ |
3027 | #ifdef __sparc__ | 2999 | #ifdef CONFIG_SPARC |
3028 | pcp = pdev->sysdata; | 3000 | pcp = pdev->sysdata; |
3029 | if (pcp == NULL || pcp->prom_node == -1) { | 3001 | if (pcp == NULL) { |
3030 | printk(KERN_ERR "happymeal(PCI): Some PCI device info missing\n"); | 3002 | printk(KERN_ERR "happymeal(PCI): Some PCI device info missing\n"); |
3031 | return -ENODEV; | 3003 | return -ENODEV; |
3032 | } | 3004 | } |
3033 | node = pcp->prom_node; | 3005 | |
3034 | 3006 | strcpy(prom_name, pcp->prom_node->name); | |
3035 | prom_getstring(node, "name", prom_name, sizeof(prom_name)); | ||
3036 | #else | 3007 | #else |
3037 | if (is_quattro_p(pdev)) | 3008 | if (is_quattro_p(pdev)) |
3038 | strcpy(prom_name, "SUNW,qfe"); | 3009 | strcpy(prom_name, "SUNW,qfe"); |
@@ -3075,7 +3046,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) | |||
3075 | hp->qfe_parent = qp; | 3046 | hp->qfe_parent = qp; |
3076 | hp->qfe_ent = qfe_slot; | 3047 | hp->qfe_ent = qfe_slot; |
3077 | qp->happy_meals[qfe_slot] = dev; | 3048 | qp->happy_meals[qfe_slot] = dev; |
3078 | } | 3049 | } |
3079 | 3050 | ||
3080 | hpreg_res = pci_resource_start(pdev, 0); | 3051 | hpreg_res = pci_resource_start(pdev, 0); |
3081 | err = -ENODEV; | 3052 | err = -ENODEV; |
@@ -3103,11 +3074,15 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) | |||
3103 | dev->dev_addr[i] = macaddr[i]; | 3074 | dev->dev_addr[i] = macaddr[i]; |
3104 | macaddr[5]++; | 3075 | macaddr[5]++; |
3105 | } else { | 3076 | } else { |
3106 | #ifdef __sparc__ | 3077 | #ifdef CONFIG_SPARC |
3078 | unsigned char *addr; | ||
3079 | int len; | ||
3080 | |||
3107 | if (qfe_slot != -1 && | 3081 | if (qfe_slot != -1 && |
3108 | prom_getproplen(node, "local-mac-address") == 6) { | 3082 | (addr = of_get_property(pcp->prom_node, |
3109 | prom_getproperty(node, "local-mac-address", | 3083 | "local-mac-address", &len)) != NULL |
3110 | dev->dev_addr, 6); | 3084 | && len == 6) { |
3085 | memcpy(dev->dev_addr, addr, 6); | ||
3111 | } else { | 3086 | } else { |
3112 | memcpy(dev->dev_addr, idprom->id_ethaddr, 6); | 3087 | memcpy(dev->dev_addr, idprom->id_ethaddr, 6); |
3113 | } | 3088 | } |
@@ -3115,7 +3090,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) | |||
3115 | get_hme_mac_nonsparc(pdev, &dev->dev_addr[0]); | 3090 | get_hme_mac_nonsparc(pdev, &dev->dev_addr[0]); |
3116 | #endif | 3091 | #endif |
3117 | } | 3092 | } |
3118 | 3093 | ||
3119 | /* Layout registers. */ | 3094 | /* Layout registers. */ |
3120 | hp->gregs = (hpreg_base + 0x0000UL); | 3095 | hp->gregs = (hpreg_base + 0x0000UL); |
3121 | hp->etxregs = (hpreg_base + 0x2000UL); | 3096 | hp->etxregs = (hpreg_base + 0x2000UL); |
@@ -3123,8 +3098,8 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) | |||
3123 | hp->bigmacregs = (hpreg_base + 0x6000UL); | 3098 | hp->bigmacregs = (hpreg_base + 0x6000UL); |
3124 | hp->tcvregs = (hpreg_base + 0x7000UL); | 3099 | hp->tcvregs = (hpreg_base + 0x7000UL); |
3125 | 3100 | ||
3126 | #ifdef __sparc__ | 3101 | #ifdef CONFIG_SPARC |
3127 | hp->hm_revision = prom_getintdefault(node, "hm-rev", 0xff); | 3102 | hp->hm_revision = of_getintprop_default(pcp->prom_node, "hm-rev", 0xff); |
3128 | if (hp->hm_revision == 0xff) { | 3103 | if (hp->hm_revision == 0xff) { |
3129 | unsigned char prev; | 3104 | unsigned char prev; |
3130 | 3105 | ||
@@ -3148,7 +3123,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) | |||
3148 | /* And of course, indicate this is PCI. */ | 3123 | /* And of course, indicate this is PCI. */ |
3149 | hp->happy_flags |= HFLAG_PCI; | 3124 | hp->happy_flags |= HFLAG_PCI; |
3150 | 3125 | ||
3151 | #ifdef __sparc__ | 3126 | #ifdef CONFIG_SPARC |
3152 | /* Assume PCI happy meals can handle all burst sizes. */ | 3127 | /* Assume PCI happy meals can handle all burst sizes. */ |
3153 | hp->happy_bursts = DMA_BURSTBITS; | 3128 | hp->happy_bursts = DMA_BURSTBITS; |
3154 | #endif | 3129 | #endif |
@@ -3211,6 +3186,8 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) | |||
3211 | goto err_out_iounmap; | 3186 | goto err_out_iounmap; |
3212 | } | 3187 | } |
3213 | 3188 | ||
3189 | dev_set_drvdata(&pdev->dev, hp); | ||
3190 | |||
3214 | if (!qfe_slot) { | 3191 | if (!qfe_slot) { |
3215 | struct pci_dev *qpdev = qp->quattro_dev; | 3192 | struct pci_dev *qpdev = qp->quattro_dev; |
3216 | 3193 | ||
@@ -3224,7 +3201,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) | |||
3224 | qpdev->device == PCI_DEVICE_ID_DEC_21153) | 3201 | qpdev->device == PCI_DEVICE_ID_DEC_21153) |
3225 | printk("DEC 21153 PCI Bridge\n"); | 3202 | printk("DEC 21153 PCI Bridge\n"); |
3226 | else | 3203 | else |
3227 | printk("unknown bridge %04x.%04x\n", | 3204 | printk("unknown bridge %04x.%04x\n", |
3228 | qpdev->vendor, qpdev->device); | 3205 | qpdev->vendor, qpdev->device); |
3229 | } | 3206 | } |
3230 | 3207 | ||
@@ -3240,12 +3217,6 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) | |||
3240 | 3217 | ||
3241 | printk("\n"); | 3218 | printk("\n"); |
3242 | 3219 | ||
3243 | /* We are home free at this point, link us in to the happy | ||
3244 | * device list. | ||
3245 | */ | ||
3246 | hp->next_module = root_happy_dev; | ||
3247 | root_happy_dev = hp; | ||
3248 | |||
3249 | return 0; | 3220 | return 0; |
3250 | 3221 | ||
3251 | err_out_iounmap: | 3222 | err_out_iounmap: |
@@ -3263,136 +3234,141 @@ err_out_clear_quattro: | |||
3263 | err_out: | 3234 | err_out: |
3264 | return err; | 3235 | return err; |
3265 | } | 3236 | } |
3266 | #endif | ||
3267 | 3237 | ||
3268 | #ifdef CONFIG_SBUS | 3238 | static void __devexit happy_meal_pci_remove(struct pci_dev *pdev) |
3269 | static int __init happy_meal_sbus_probe(void) | ||
3270 | { | 3239 | { |
3271 | struct sbus_bus *sbus; | 3240 | struct happy_meal *hp = dev_get_drvdata(&pdev->dev); |
3272 | struct sbus_dev *sdev; | 3241 | struct net_device *net_dev = hp->dev; |
3273 | int cards = 0; | 3242 | |
3274 | char model[128]; | 3243 | unregister_netdev(net_dev); |
3275 | 3244 | ||
3276 | for_each_sbus(sbus) { | 3245 | pci_free_consistent(hp->happy_dev, |
3277 | for_each_sbusdev(sdev, sbus) { | 3246 | PAGE_SIZE, |
3278 | char *name = sdev->prom_name; | 3247 | hp->happy_block, |
3279 | 3248 | hp->hblock_dvma); | |
3280 | if (!strcmp(name, "SUNW,hme")) { | 3249 | iounmap(hp->gregs); |
3281 | cards++; | 3250 | pci_release_regions(hp->happy_dev); |
3282 | prom_getstring(sdev->prom_node, "model", | 3251 | |
3283 | model, sizeof(model)); | 3252 | free_netdev(net_dev); |
3284 | if (!strcmp(model, "SUNW,sbus-qfe")) | 3253 | |
3285 | happy_meal_sbus_init(sdev, 1); | 3254 | dev_set_drvdata(&pdev->dev, NULL); |
3286 | else | ||
3287 | happy_meal_sbus_init(sdev, 0); | ||
3288 | } else if (!strcmp(name, "qfe") || | ||
3289 | !strcmp(name, "SUNW,qfe")) { | ||
3290 | cards++; | ||
3291 | happy_meal_sbus_init(sdev, 1); | ||
3292 | } | ||
3293 | } | ||
3294 | } | ||
3295 | if (cards != 0) | ||
3296 | quattro_sbus_register_irqs(); | ||
3297 | return cards; | ||
3298 | } | 3255 | } |
3299 | #endif | ||
3300 | 3256 | ||
3301 | #ifdef CONFIG_PCI | 3257 | static struct pci_device_id happymeal_pci_ids[] = { |
3302 | static int __init happy_meal_pci_probe(void) | 3258 | { PCI_DEVICE(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_HAPPYMEAL) }, |
3259 | { } /* Terminating entry */ | ||
3260 | }; | ||
3261 | |||
3262 | MODULE_DEVICE_TABLE(pci, happymeal_pci_ids); | ||
3263 | |||
3264 | static struct pci_driver hme_pci_driver = { | ||
3265 | .name = "hme", | ||
3266 | .id_table = happymeal_pci_ids, | ||
3267 | .probe = happy_meal_pci_probe, | ||
3268 | .remove = __devexit_p(happy_meal_pci_remove), | ||
3269 | }; | ||
3270 | |||
3271 | static int __init happy_meal_pci_init(void) | ||
3272 | { | ||
3273 | return pci_register_driver(&hme_pci_driver); | ||
3274 | } | ||
3275 | |||
3276 | static void happy_meal_pci_exit(void) | ||
3303 | { | 3277 | { |
3304 | struct pci_dev *pdev = NULL; | 3278 | pci_unregister_driver(&hme_pci_driver); |
3305 | int cards = 0; | ||
3306 | 3279 | ||
3307 | while ((pdev = pci_find_device(PCI_VENDOR_ID_SUN, | 3280 | while (qfe_pci_list) { |
3308 | PCI_DEVICE_ID_SUN_HAPPYMEAL, pdev)) != NULL) { | 3281 | struct quattro *qfe = qfe_pci_list; |
3309 | if (pci_enable_device(pdev)) | 3282 | struct quattro *next = qfe->next; |
3310 | continue; | 3283 | |
3311 | pci_set_master(pdev); | 3284 | kfree(qfe); |
3312 | cards++; | 3285 | |
3313 | happy_meal_pci_init(pdev); | 3286 | qfe_pci_list = next; |
3314 | } | 3287 | } |
3315 | return cards; | ||
3316 | } | 3288 | } |
3289 | |||
3317 | #endif | 3290 | #endif |
3318 | 3291 | ||
3319 | static int __init happy_meal_probe(void) | 3292 | #ifdef CONFIG_SBUS |
3293 | static int __devinit hme_sbus_probe(struct of_device *dev, const struct of_device_id *match) | ||
3320 | { | 3294 | { |
3321 | static int called = 0; | 3295 | struct sbus_dev *sdev = to_sbus_device(&dev->dev); |
3322 | int cards; | 3296 | struct device_node *dp = dev->node; |
3297 | char *model = of_get_property(dp, "model", NULL); | ||
3298 | int is_qfe = (match->data != NULL); | ||
3323 | 3299 | ||
3324 | root_happy_dev = NULL; | 3300 | if (!is_qfe && model && !strcmp(model, "SUNW,sbus-qfe")) |
3301 | is_qfe = 1; | ||
3325 | 3302 | ||
3326 | if (called) | 3303 | return happy_meal_sbus_probe_one(sdev, is_qfe); |
3327 | return -ENODEV; | 3304 | } |
3328 | called++; | 3305 | |
3306 | static int __devexit hme_sbus_remove(struct of_device *dev) | ||
3307 | { | ||
3308 | struct happy_meal *hp = dev_get_drvdata(&dev->dev); | ||
3309 | struct net_device *net_dev = hp->dev; | ||
3310 | |||
3311 | unregister_netdevice(net_dev); | ||
3312 | |||
3313 | /* XXX qfe parent interrupt... */ | ||
3314 | |||
3315 | sbus_iounmap(hp->gregs, GREG_REG_SIZE); | ||
3316 | sbus_iounmap(hp->etxregs, ETX_REG_SIZE); | ||
3317 | sbus_iounmap(hp->erxregs, ERX_REG_SIZE); | ||
3318 | sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE); | ||
3319 | sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE); | ||
3320 | sbus_free_consistent(hp->happy_dev, | ||
3321 | PAGE_SIZE, | ||
3322 | hp->happy_block, | ||
3323 | hp->hblock_dvma); | ||
3324 | |||
3325 | free_netdev(net_dev); | ||
3326 | |||
3327 | dev_set_drvdata(&dev->dev, NULL); | ||
3329 | 3328 | ||
3330 | cards = 0; | ||
3331 | #ifdef CONFIG_SBUS | ||
3332 | cards += happy_meal_sbus_probe(); | ||
3333 | #endif | ||
3334 | #ifdef CONFIG_PCI | ||
3335 | cards += happy_meal_pci_probe(); | ||
3336 | #endif | ||
3337 | if (!cards) | ||
3338 | return -ENODEV; | ||
3339 | return 0; | 3329 | return 0; |
3340 | } | 3330 | } |
3341 | 3331 | ||
3332 | static struct of_device_id hme_sbus_match[] = { | ||
3333 | { | ||
3334 | .name = "SUNW,hme", | ||
3335 | }, | ||
3336 | { | ||
3337 | .name = "SUNW,qfe", | ||
3338 | .data = (void *) 1, | ||
3339 | }, | ||
3340 | { | ||
3341 | .name = "qfe", | ||
3342 | .data = (void *) 1, | ||
3343 | }, | ||
3344 | {}, | ||
3345 | }; | ||
3342 | 3346 | ||
3343 | static void __exit happy_meal_cleanup_module(void) | 3347 | MODULE_DEVICE_TABLE(of, hme_sbus_match); |
3344 | { | ||
3345 | #ifdef CONFIG_SBUS | ||
3346 | struct quattro *last_seen_qfe = NULL; | ||
3347 | #endif | ||
3348 | 3348 | ||
3349 | while (root_happy_dev) { | 3349 | static struct of_platform_driver hme_sbus_driver = { |
3350 | struct happy_meal *hp = root_happy_dev; | 3350 | .name = "hme", |
3351 | struct happy_meal *next = root_happy_dev->next_module; | 3351 | .match_table = hme_sbus_match, |
3352 | struct net_device *dev = hp->dev; | 3352 | .probe = hme_sbus_probe, |
3353 | .remove = __devexit_p(hme_sbus_remove), | ||
3354 | }; | ||
3353 | 3355 | ||
3354 | /* Unregister netdev before unmapping registers as this | 3356 | static int __init happy_meal_sbus_init(void) |
3355 | * call can end up trying to access those registers. | 3357 | { |
3356 | */ | 3358 | int err; |
3357 | unregister_netdev(dev); | ||
3358 | 3359 | ||
3359 | #ifdef CONFIG_SBUS | 3360 | err = of_register_driver(&hme_sbus_driver, &sbus_bus_type); |
3360 | if (!(hp->happy_flags & HFLAG_PCI)) { | 3361 | if (!err) |
3361 | if (hp->happy_flags & HFLAG_QUATTRO) { | 3362 | quattro_sbus_register_irqs(); |
3362 | if (hp->qfe_parent != last_seen_qfe) { | ||
3363 | free_irq(dev->irq, hp->qfe_parent); | ||
3364 | last_seen_qfe = hp->qfe_parent; | ||
3365 | } | ||
3366 | } | ||
3367 | 3363 | ||
3368 | sbus_iounmap(hp->gregs, GREG_REG_SIZE); | 3364 | return err; |
3369 | sbus_iounmap(hp->etxregs, ETX_REG_SIZE); | 3365 | } |
3370 | sbus_iounmap(hp->erxregs, ERX_REG_SIZE); | ||
3371 | sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE); | ||
3372 | sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE); | ||
3373 | sbus_free_consistent(hp->happy_dev, | ||
3374 | PAGE_SIZE, | ||
3375 | hp->happy_block, | ||
3376 | hp->hblock_dvma); | ||
3377 | } | ||
3378 | #endif | ||
3379 | #ifdef CONFIG_PCI | ||
3380 | if ((hp->happy_flags & HFLAG_PCI)) { | ||
3381 | pci_free_consistent(hp->happy_dev, | ||
3382 | PAGE_SIZE, | ||
3383 | hp->happy_block, | ||
3384 | hp->hblock_dvma); | ||
3385 | iounmap(hp->gregs); | ||
3386 | pci_release_regions(hp->happy_dev); | ||
3387 | } | ||
3388 | #endif | ||
3389 | free_netdev(dev); | ||
3390 | 3366 | ||
3391 | root_happy_dev = next; | 3367 | static void happy_meal_sbus_exit(void) |
3392 | } | 3368 | { |
3369 | of_unregister_driver(&hme_sbus_driver); | ||
3370 | quattro_sbus_free_irqs(); | ||
3393 | 3371 | ||
3394 | /* Now cleanup the quattro lists. */ | ||
3395 | #ifdef CONFIG_SBUS | ||
3396 | while (qfe_sbus_list) { | 3372 | while (qfe_sbus_list) { |
3397 | struct quattro *qfe = qfe_sbus_list; | 3373 | struct quattro *qfe = qfe_sbus_list; |
3398 | struct quattro *next = qfe->next; | 3374 | struct quattro *next = qfe->next; |
@@ -3401,18 +3377,39 @@ static void __exit happy_meal_cleanup_module(void) | |||
3401 | 3377 | ||
3402 | qfe_sbus_list = next; | 3378 | qfe_sbus_list = next; |
3403 | } | 3379 | } |
3380 | } | ||
3404 | #endif | 3381 | #endif |
3405 | #ifdef CONFIG_PCI | ||
3406 | while (qfe_pci_list) { | ||
3407 | struct quattro *qfe = qfe_pci_list; | ||
3408 | struct quattro *next = qfe->next; | ||
3409 | 3382 | ||
3410 | kfree(qfe); | 3383 | static int __init happy_meal_probe(void) |
3384 | { | ||
3385 | int err = 0; | ||
3411 | 3386 | ||
3412 | qfe_pci_list = next; | 3387 | #ifdef CONFIG_SBUS |
3388 | err = happy_meal_sbus_init(); | ||
3389 | #endif | ||
3390 | #ifdef CONFIG_PCI | ||
3391 | if (!err) { | ||
3392 | err = happy_meal_pci_init(); | ||
3393 | #ifdef CONFIG_SBUS | ||
3394 | if (err) | ||
3395 | happy_meal_sbus_exit(); | ||
3396 | #endif | ||
3413 | } | 3397 | } |
3414 | #endif | 3398 | #endif |
3399 | |||
3400 | return err; | ||
3401 | } | ||
3402 | |||
3403 | |||
3404 | static void __exit happy_meal_exit(void) | ||
3405 | { | ||
3406 | #ifdef CONFIG_SBUS | ||
3407 | happy_meal_sbus_exit(); | ||
3408 | #endif | ||
3409 | #ifdef CONFIG_PCI | ||
3410 | happy_meal_pci_exit(); | ||
3411 | #endif | ||
3415 | } | 3412 | } |
3416 | 3413 | ||
3417 | module_init(happy_meal_probe); | 3414 | module_init(happy_meal_probe); |
3418 | module_exit(happy_meal_cleanup_module); | 3415 | module_exit(happy_meal_exit); |