aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-06-23 21:21:02 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-24 02:15:58 -0400
commit050bbb196392b9c178f82b1205a23dd2f915ee93 (patch)
tree7558fc040ea5cfedefd56f0e5412b15ee23d8228
parent9e326acf567b605cf4177081cc7367c24ec10a66 (diff)
[NET] sunhme: Convert to new SBUS driver framework.
And make it a real PCI driver too. Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/sunhme.c360
-rw-r--r--drivers/net/sunhme.h1
2 files changed, 187 insertions, 174 deletions
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index 9f4367e2aa0d..ec51f397e1ed 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>
@@ -47,9 +47,6 @@
47#include <asm/oplib.h> 47#include <asm/oplib.h>
48#include <asm/prom.h> 48#include <asm/prom.h>
49#include <asm/auxio.h> 49#include <asm/auxio.h>
50#ifndef CONFIG_SPARC64
51#include <asm/io-unit.h>
52#endif
53#endif 50#endif
54#include <asm/uaccess.h> 51#include <asm/uaccess.h>
55 52
@@ -66,9 +63,9 @@
66#include "sunhme.h" 63#include "sunhme.h"
67 64
68#define DRV_NAME "sunhme" 65#define DRV_NAME "sunhme"
69#define DRV_VERSION "2.02" 66#define DRV_VERSION "3.00"
70#define DRV_RELDATE "8/24/03" 67#define DRV_RELDATE "June 23, 2006"
71#define DRV_AUTHOR "David S. Miller (davem@redhat.com)" 68#define DRV_AUTHOR "David S. Miller (davem@davemloft.net)"
72 69
73static char version[] = 70static char version[] =
74 DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n"; 71 DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n";
@@ -84,8 +81,6 @@ static int macaddr[6];
84module_param_array(macaddr, int, NULL, 0); 81module_param_array(macaddr, int, NULL, 0);
85MODULE_PARM_DESC(macaddr, "Happy Meal MAC address to set"); 82MODULE_PARM_DESC(macaddr, "Happy Meal MAC address to set");
86 83
87static struct happy_meal *root_happy_dev;
88
89#ifdef CONFIG_SBUS 84#ifdef CONFIG_SBUS
90static struct quattro *qfe_sbus_list; 85static struct quattro *qfe_sbus_list;
91#endif 86#endif
@@ -182,26 +177,6 @@ static __inline__ void tx_dump_ring(struct happy_meal *hp)
182#define DEFAULT_IPG2 4 /* For all modes */ 177#define DEFAULT_IPG2 4 /* For all modes */
183#define DEFAULT_JAMSIZE 4 /* Toe jam */ 178#define DEFAULT_JAMSIZE 4 /* Toe jam */
184 179
185#if defined(CONFIG_PCI) && defined(MODULE)
186/* This happy_pci_ids is declared __initdata because it is only used
187 as an advisory to depmod. If this is ported to the new PCI interface
188 where it could be referenced at any time due to hot plugging,
189 the __initdata reference should be removed. */
190
191static struct pci_device_id happymeal_pci_ids[] = {
192 {
193 .vendor = PCI_VENDOR_ID_SUN,
194 .device = PCI_DEVICE_ID_SUN_HAPPYMEAL,
195 .subvendor = PCI_ANY_ID,
196 .subdevice = PCI_ANY_ID,
197 },
198 { } /* Terminating entry */
199};
200
201MODULE_DEVICE_TABLE(pci, happymeal_pci_ids);
202
203#endif
204
205/* NOTE: In the descriptor writes one _must_ write the address 180/* NOTE: In the descriptor writes one _must_ write the address
206 * member _first_. The card must not be allowed to see 181 * member _first_. The card must not be allowed to see
207 * the updated descriptor flags until the address is 182 * the updated descriptor flags until the address is
@@ -2656,6 +2631,17 @@ static void __init quattro_sbus_register_irqs(void)
2656 } 2631 }
2657 } 2632 }
2658} 2633}
2634
2635static void __devexit quattro_sbus_free_irqs(void)
2636{
2637 struct quattro *qp;
2638
2639 for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
2640 struct sbus_dev *sdev = qp->quattro_dev;
2641
2642 free_irq(sdev->irqs[0], qp);
2643 }
2644}
2659#endif /* CONFIG_SBUS */ 2645#endif /* CONFIG_SBUS */
2660 2646
2661#ifdef CONFIG_PCI 2647#ifdef CONFIG_PCI
@@ -2690,8 +2676,9 @@ static struct quattro * __init quattro_pci_find(struct pci_dev *pdev)
2690#endif /* CONFIG_PCI */ 2676#endif /* CONFIG_PCI */
2691 2677
2692#ifdef CONFIG_SBUS 2678#ifdef CONFIG_SBUS
2693static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) 2679static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe)
2694{ 2680{
2681 struct device_node *dp = sdev->ofdev.node;
2695 struct quattro *qp = NULL; 2682 struct quattro *qp = NULL;
2696 struct happy_meal *hp; 2683 struct happy_meal *hp;
2697 struct net_device *dev; 2684 struct net_device *dev;
@@ -2714,6 +2701,7 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2714 if (!dev) 2701 if (!dev)
2715 goto err_out; 2702 goto err_out;
2716 SET_MODULE_OWNER(dev); 2703 SET_MODULE_OWNER(dev);
2704 SET_NETDEV_DEV(dev, &sdev->ofdev.dev);
2717 2705
2718 if (hme_version_printed++ == 0) 2706 if (hme_version_printed++ == 0)
2719 printk(KERN_INFO "%s", version); 2707 printk(KERN_INFO "%s", version);
@@ -2729,13 +2717,16 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2729 for (i = 0; i < 6; i++) 2717 for (i = 0; i < 6; i++)
2730 dev->dev_addr[i] = macaddr[i]; 2718 dev->dev_addr[i] = macaddr[i];
2731 macaddr[5]++; 2719 macaddr[5]++;
2732 } else if (qfe_slot != -1 &&
2733 prom_getproplen(sdev->prom_node,
2734 "local-mac-address") == 6) {
2735 prom_getproperty(sdev->prom_node, "local-mac-address",
2736 dev->dev_addr, 6);
2737 } else { 2720 } else {
2738 memcpy(dev->dev_addr, idprom->id_ethaddr, 6); 2721 unsigned char *addr;
2722 int len;
2723
2724 addr = of_get_property(dp, "local-mac-address", &len);
2725
2726 if (qfe_slot != -1 && addr && len == 6)
2727 memcpy(dev->dev_addr, addr, 6);
2728 else
2729 memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
2739 } 2730 }
2740 2731
2741 hp = dev->priv; 2732 hp = dev->priv;
@@ -2746,9 +2737,8 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2746 2737
2747 err = -ENODEV; 2738 err = -ENODEV;
2748 if (sdev->num_registers != 5) { 2739 if (sdev->num_registers != 5) {
2749 printk(KERN_ERR "happymeal: Device does not have 5 regs, it has %d.\n", 2740 printk(KERN_ERR "happymeal: Device needs 5 regs, has %d.\n",
2750 sdev->num_registers); 2741 sdev->num_registers);
2751 printk(KERN_ERR "happymeal: Would you like that for here or to go?\n");
2752 goto err_out_free_netdev; 2742 goto err_out_free_netdev;
2753 } 2743 }
2754 2744
@@ -2762,39 +2752,39 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2762 hp->gregs = sbus_ioremap(&sdev->resource[0], 0, 2752 hp->gregs = sbus_ioremap(&sdev->resource[0], 0,
2763 GREG_REG_SIZE, "HME Global Regs"); 2753 GREG_REG_SIZE, "HME Global Regs");
2764 if (!hp->gregs) { 2754 if (!hp->gregs) {
2765 printk(KERN_ERR "happymeal: Cannot map Happy Meal global registers.\n"); 2755 printk(KERN_ERR "happymeal: Cannot map global registers.\n");
2766 goto err_out_free_netdev; 2756 goto err_out_free_netdev;
2767 } 2757 }
2768 2758
2769 hp->etxregs = sbus_ioremap(&sdev->resource[1], 0, 2759 hp->etxregs = sbus_ioremap(&sdev->resource[1], 0,
2770 ETX_REG_SIZE, "HME TX Regs"); 2760 ETX_REG_SIZE, "HME TX Regs");
2771 if (!hp->etxregs) { 2761 if (!hp->etxregs) {
2772 printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Transmit registers.\n"); 2762 printk(KERN_ERR "happymeal: Cannot map MAC TX registers.\n");
2773 goto err_out_iounmap; 2763 goto err_out_iounmap;
2774 } 2764 }
2775 2765
2776 hp->erxregs = sbus_ioremap(&sdev->resource[2], 0, 2766 hp->erxregs = sbus_ioremap(&sdev->resource[2], 0,
2777 ERX_REG_SIZE, "HME RX Regs"); 2767 ERX_REG_SIZE, "HME RX Regs");
2778 if (!hp->erxregs) { 2768 if (!hp->erxregs) {
2779 printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Receive registers.\n"); 2769 printk(KERN_ERR "happymeal: Cannot map MAC RX registers.\n");
2780 goto err_out_iounmap; 2770 goto err_out_iounmap;
2781 } 2771 }
2782 2772
2783 hp->bigmacregs = sbus_ioremap(&sdev->resource[3], 0, 2773 hp->bigmacregs = sbus_ioremap(&sdev->resource[3], 0,
2784 BMAC_REG_SIZE, "HME BIGMAC Regs"); 2774 BMAC_REG_SIZE, "HME BIGMAC Regs");
2785 if (!hp->bigmacregs) { 2775 if (!hp->bigmacregs) {
2786 printk(KERN_ERR "happymeal: Cannot map Happy Meal BIGMAC registers.\n"); 2776 printk(KERN_ERR "happymeal: Cannot map BIGMAC registers.\n");
2787 goto err_out_iounmap; 2777 goto err_out_iounmap;
2788 } 2778 }
2789 2779
2790 hp->tcvregs = sbus_ioremap(&sdev->resource[4], 0, 2780 hp->tcvregs = sbus_ioremap(&sdev->resource[4], 0,
2791 TCVR_REG_SIZE, "HME Tranceiver Regs"); 2781 TCVR_REG_SIZE, "HME Tranceiver Regs");
2792 if (!hp->tcvregs) { 2782 if (!hp->tcvregs) {
2793 printk(KERN_ERR "happymeal: Cannot map Happy Meal Tranceiver registers.\n"); 2783 printk(KERN_ERR "happymeal: Cannot map TCVR registers.\n");
2794 goto err_out_iounmap; 2784 goto err_out_iounmap;
2795 } 2785 }
2796 2786
2797 hp->hm_revision = prom_getintdefault(sdev->prom_node, "hm-rev", 0xff); 2787 hp->hm_revision = of_getintprop_default(dp, "hm-rev", 0xff);
2798 if (hp->hm_revision == 0xff) 2788 if (hp->hm_revision == 0xff)
2799 hp->hm_revision = 0xa0; 2789 hp->hm_revision = 0xa0;
2800 2790
@@ -2808,8 +2798,8 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2808 hp->happy_flags |= HFLAG_QUATTRO; 2798 hp->happy_flags |= HFLAG_QUATTRO;
2809 2799
2810 /* Get the supported DVMA burst sizes from our Happy SBUS. */ 2800 /* Get the supported DVMA burst sizes from our Happy SBUS. */
2811 hp->happy_bursts = prom_getintdefault(sdev->bus->prom_node, 2801 hp->happy_bursts = of_getintprop_default(sdev->bus->ofdev.node,
2812 "burst-sizes", 0x00); 2802 "burst-sizes", 0x00);
2813 2803
2814 hp->happy_block = sbus_alloc_consistent(hp->happy_dev, 2804 hp->happy_block = sbus_alloc_consistent(hp->happy_dev,
2815 PAGE_SIZE, 2805 PAGE_SIZE,
@@ -2872,6 +2862,8 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2872 goto err_out_free_consistent; 2862 goto err_out_free_consistent;
2873 } 2863 }
2874 2864
2865 dev_set_drvdata(&sdev->ofdev.dev, hp);
2866
2875 if (qfe_slot != -1) 2867 if (qfe_slot != -1)
2876 printk(KERN_INFO "%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet ", 2868 printk(KERN_INFO "%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet ",
2877 dev->name, qfe_slot); 2869 dev->name, qfe_slot);
@@ -2884,12 +2876,6 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2884 dev->dev_addr[i], i == 5 ? ' ' : ':'); 2876 dev->dev_addr[i], i == 5 ? ' ' : ':');
2885 printk("\n"); 2877 printk("\n");
2886 2878
2887 /* We are home free at this point, link us in to the happy
2888 * device list.
2889 */
2890 hp->next_module = root_happy_dev;
2891 root_happy_dev = hp;
2892
2893 return 0; 2879 return 0;
2894 2880
2895err_out_free_consistent: 2881err_out_free_consistent:
@@ -3009,7 +2995,8 @@ static void get_hme_mac_nonsparc(struct pci_dev *pdev, unsigned char *dev_addr)
3009} 2995}
3010#endif /* !(CONFIG_SPARC) */ 2996#endif /* !(CONFIG_SPARC) */
3011 2997
3012static int __init happy_meal_pci_init(struct pci_dev *pdev) 2998static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
2999 const struct pci_device_id *ent)
3013{ 3000{
3014 struct quattro *qp = NULL; 3001 struct quattro *qp = NULL;
3015#ifdef CONFIG_SPARC 3002#ifdef CONFIG_SPARC
@@ -3214,6 +3201,8 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3214 goto err_out_iounmap; 3201 goto err_out_iounmap;
3215 } 3202 }
3216 3203
3204 dev_set_drvdata(&pdev->dev, hp);
3205
3217 if (!qfe_slot) { 3206 if (!qfe_slot) {
3218 struct pci_dev *qpdev = qp->quattro_dev; 3207 struct pci_dev *qpdev = qp->quattro_dev;
3219 3208
@@ -3243,12 +3232,6 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3243 3232
3244 printk("\n"); 3233 printk("\n");
3245 3234
3246 /* We are home free at this point, link us in to the happy
3247 * device list.
3248 */
3249 hp->next_module = root_happy_dev;
3250 root_happy_dev = hp;
3251
3252 return 0; 3235 return 0;
3253 3236
3254err_out_iounmap: 3237err_out_iounmap:
@@ -3266,136 +3249,146 @@ err_out_clear_quattro:
3266err_out: 3249err_out:
3267 return err; 3250 return err;
3268} 3251}
3269#endif
3270 3252
3271#ifdef CONFIG_SBUS 3253static void __devexit happy_meal_pci_remove(struct pci_dev *pdev)
3272static int __init happy_meal_sbus_probe(void)
3273{ 3254{
3274 struct sbus_bus *sbus; 3255 struct happy_meal *hp = dev_get_drvdata(&pdev->dev);
3275 struct sbus_dev *sdev; 3256 struct net_device *net_dev = hp->dev;
3276 int cards = 0;
3277 char model[128];
3278 3257
3279 for_each_sbus(sbus) { 3258 unregister_netdev(net_dev);
3280 for_each_sbusdev(sdev, sbus) { 3259
3281 char *name = sdev->prom_name; 3260 pci_free_consistent(hp->happy_dev,
3282 3261 PAGE_SIZE,
3283 if (!strcmp(name, "SUNW,hme")) { 3262 hp->happy_block,
3284 cards++; 3263 hp->hblock_dvma);
3285 prom_getstring(sdev->prom_node, "model", 3264 iounmap(hp->gregs);
3286 model, sizeof(model)); 3265 pci_release_regions(hp->happy_dev);
3287 if (!strcmp(model, "SUNW,sbus-qfe")) 3266
3288 happy_meal_sbus_init(sdev, 1); 3267 free_netdev(net_dev);
3289 else 3268
3290 happy_meal_sbus_init(sdev, 0); 3269 dev_set_drvdata(&pdev->dev, NULL);
3291 } else if (!strcmp(name, "qfe") ||
3292 !strcmp(name, "SUNW,qfe")) {
3293 cards++;
3294 happy_meal_sbus_init(sdev, 1);
3295 }
3296 }
3297 }
3298 if (cards != 0)
3299 quattro_sbus_register_irqs();
3300 return cards;
3301} 3270}
3302#endif
3303 3271
3304#ifdef CONFIG_PCI 3272static struct pci_device_id happymeal_pci_ids[] = {
3305static int __init happy_meal_pci_probe(void) 3273 {
3274 .vendor = PCI_VENDOR_ID_SUN,
3275 .device = PCI_DEVICE_ID_SUN_HAPPYMEAL,
3276 .subvendor = PCI_ANY_ID,
3277 .subdevice = PCI_ANY_ID,
3278 },
3279 { } /* Terminating entry */
3280};
3281
3282MODULE_DEVICE_TABLE(pci, happymeal_pci_ids);
3283
3284static struct pci_driver hme_pci_driver = {
3285 .name = "hme",
3286 .id_table = happymeal_pci_ids,
3287 .probe = happy_meal_pci_probe,
3288 .remove = __devexit_p(happy_meal_pci_remove),
3289};
3290
3291static int __init happy_meal_pci_init(void)
3306{ 3292{
3307 struct pci_dev *pdev = NULL; 3293 return pci_module_init(&hme_pci_driver);
3308 int cards = 0; 3294}
3309 3295
3310 while ((pdev = pci_find_device(PCI_VENDOR_ID_SUN, 3296static void happy_meal_pci_exit(void)
3311 PCI_DEVICE_ID_SUN_HAPPYMEAL, pdev)) != NULL) { 3297{
3312 if (pci_enable_device(pdev)) 3298 pci_unregister_driver(&hme_pci_driver);
3313 continue; 3299
3314 pci_set_master(pdev); 3300 while (qfe_pci_list) {
3315 cards++; 3301 struct quattro *qfe = qfe_pci_list;
3316 happy_meal_pci_init(pdev); 3302 struct quattro *next = qfe->next;
3303
3304 kfree(qfe);
3305
3306 qfe_pci_list = next;
3317 } 3307 }
3318 return cards;
3319} 3308}
3309
3320#endif 3310#endif
3321 3311
3322static int __init happy_meal_probe(void) 3312#ifdef CONFIG_SBUS
3313static int __devinit hme_sbus_probe(struct of_device *dev, const struct of_device_id *match)
3323{ 3314{
3324 static int called = 0; 3315 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
3325 int cards; 3316 struct device_node *dp = dev->node;
3317 char *model = of_get_property(dp, "model", NULL);
3318 int is_qfe = (match->data != NULL);
3326 3319
3327 root_happy_dev = NULL; 3320 if (!is_qfe && model && !strcmp(model, "SUNW,sbus-qfe"))
3321 is_qfe = 1;
3328 3322
3329 if (called) 3323 return happy_meal_sbus_probe_one(sdev, is_qfe);
3330 return -ENODEV; 3324}
3331 called++; 3325
3326static int __devexit hme_sbus_remove(struct of_device *dev)
3327{
3328 struct happy_meal *hp = dev_get_drvdata(&dev->dev);
3329 struct net_device *net_dev = hp->dev;
3330
3331 unregister_netdevice(net_dev);
3332
3333 /* XXX qfe parent interrupt... */
3334
3335 sbus_iounmap(hp->gregs, GREG_REG_SIZE);
3336 sbus_iounmap(hp->etxregs, ETX_REG_SIZE);
3337 sbus_iounmap(hp->erxregs, ERX_REG_SIZE);
3338 sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE);
3339 sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE);
3340 sbus_free_consistent(hp->happy_dev,
3341 PAGE_SIZE,
3342 hp->happy_block,
3343 hp->hblock_dvma);
3344
3345 free_netdev(net_dev);
3346
3347 dev_set_drvdata(&dev->dev, NULL);
3332 3348
3333 cards = 0;
3334#ifdef CONFIG_SBUS
3335 cards += happy_meal_sbus_probe();
3336#endif
3337#ifdef CONFIG_PCI
3338 cards += happy_meal_pci_probe();
3339#endif
3340 if (!cards)
3341 return -ENODEV;
3342 return 0; 3349 return 0;
3343} 3350}
3344 3351
3352static struct of_device_id hme_sbus_match[] = {
3353 {
3354 .name = "SUNW,hme",
3355 },
3356 {
3357 .name = "SUNW,qfe",
3358 .data = (void *) 1,
3359 },
3360 {
3361 .name = "qfe",
3362 .data = (void *) 1,
3363 },
3364 {},
3365};
3345 3366
3346static void __exit happy_meal_cleanup_module(void) 3367MODULE_DEVICE_TABLE(of, hme_sbus_match);
3347{
3348#ifdef CONFIG_SBUS
3349 struct quattro *last_seen_qfe = NULL;
3350#endif
3351 3368
3352 while (root_happy_dev) { 3369static struct of_platform_driver hme_sbus_driver = {
3353 struct happy_meal *hp = root_happy_dev; 3370 .name = "hme",
3354 struct happy_meal *next = root_happy_dev->next_module; 3371 .match_table = hme_sbus_match,
3355 struct net_device *dev = hp->dev; 3372 .probe = hme_sbus_probe,
3373 .remove = __devexit_p(hme_sbus_remove),
3374};
3356 3375
3357 /* Unregister netdev before unmapping registers as this 3376static int __init happy_meal_sbus_init(void)
3358 * call can end up trying to access those registers. 3377{
3359 */ 3378 int err;
3360 unregister_netdev(dev);
3361 3379
3362#ifdef CONFIG_SBUS 3380 err = of_register_driver(&hme_sbus_driver, &sbus_bus_type);
3363 if (!(hp->happy_flags & HFLAG_PCI)) { 3381 if (!err)
3364 if (hp->happy_flags & HFLAG_QUATTRO) { 3382 quattro_sbus_register_irqs();
3365 if (hp->qfe_parent != last_seen_qfe) {
3366 free_irq(dev->irq, hp->qfe_parent);
3367 last_seen_qfe = hp->qfe_parent;
3368 }
3369 }
3370 3383
3371 sbus_iounmap(hp->gregs, GREG_REG_SIZE); 3384 return err;
3372 sbus_iounmap(hp->etxregs, ETX_REG_SIZE); 3385}
3373 sbus_iounmap(hp->erxregs, ERX_REG_SIZE);
3374 sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE);
3375 sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE);
3376 sbus_free_consistent(hp->happy_dev,
3377 PAGE_SIZE,
3378 hp->happy_block,
3379 hp->hblock_dvma);
3380 }
3381#endif
3382#ifdef CONFIG_PCI
3383 if ((hp->happy_flags & HFLAG_PCI)) {
3384 pci_free_consistent(hp->happy_dev,
3385 PAGE_SIZE,
3386 hp->happy_block,
3387 hp->hblock_dvma);
3388 iounmap(hp->gregs);
3389 pci_release_regions(hp->happy_dev);
3390 }
3391#endif
3392 free_netdev(dev);
3393 3386
3394 root_happy_dev = next; 3387static void happy_meal_sbus_exit(void)
3395 } 3388{
3389 of_unregister_driver(&hme_sbus_driver);
3390 quattro_sbus_free_irqs();
3396 3391
3397 /* Now cleanup the quattro lists. */
3398#ifdef CONFIG_SBUS
3399 while (qfe_sbus_list) { 3392 while (qfe_sbus_list) {
3400 struct quattro *qfe = qfe_sbus_list; 3393 struct quattro *qfe = qfe_sbus_list;
3401 struct quattro *next = qfe->next; 3394 struct quattro *next = qfe->next;
@@ -3404,18 +3397,39 @@ static void __exit happy_meal_cleanup_module(void)
3404 3397
3405 qfe_sbus_list = next; 3398 qfe_sbus_list = next;
3406 } 3399 }
3400}
3407#endif 3401#endif
3408#ifdef CONFIG_PCI
3409 while (qfe_pci_list) {
3410 struct quattro *qfe = qfe_pci_list;
3411 struct quattro *next = qfe->next;
3412 3402
3413 kfree(qfe); 3403static int __init happy_meal_probe(void)
3404{
3405 int err = 0;
3414 3406
3415 qfe_pci_list = next; 3407#ifdef CONFIG_SBUS
3408 err = happy_meal_sbus_init();
3409#endif
3410#ifdef CONFIG_PCI
3411 if (!err) {
3412 err = happy_meal_pci_init();
3413#ifdef CONFIG_SBUS
3414 if (err)
3415 happy_meal_sbus_exit();
3416#endif
3416 } 3417 }
3417#endif 3418#endif
3419
3420 return err;
3421}
3422
3423
3424static void __exit happy_meal_exit(void)
3425{
3426#ifdef CONFIG_SBUS
3427 happy_meal_sbus_exit();
3428#endif
3429#ifdef CONFIG_PCI
3430 happy_meal_pci_exit();
3431#endif
3418} 3432}
3419 3433
3420module_init(happy_meal_probe); 3434module_init(happy_meal_probe);
3421module_exit(happy_meal_cleanup_module); 3435module_exit(happy_meal_exit);
diff --git a/drivers/net/sunhme.h b/drivers/net/sunhme.h
index 34e9f953cea4..9b7ccaeeee89 100644
--- a/drivers/net/sunhme.h
+++ b/drivers/net/sunhme.h
@@ -461,7 +461,6 @@ struct happy_meal {
461 struct net_device *dev; /* Backpointer */ 461 struct net_device *dev; /* Backpointer */
462 struct quattro *qfe_parent; /* For Quattro cards */ 462 struct quattro *qfe_parent; /* For Quattro cards */
463 int qfe_ent; /* Which instance on quattro */ 463 int qfe_ent; /* Which instance on quattro */
464 struct happy_meal *next_module;
465}; 464};
466 465
467/* Here are the happy flags. */ 466/* Here are the happy flags. */