aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sunhme.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sunhme.c')
-rw-r--r--drivers/net/sunhme.c417
1 files changed, 210 insertions, 207 deletions
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index bd5d2668a362..c33ead3470db 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>
@@ -40,15 +40,13 @@
40#include <asm/dma.h> 40#include <asm/dma.h>
41#include <asm/byteorder.h> 41#include <asm/byteorder.h>
42 42
43#ifdef __sparc__ 43#ifdef CONFIG_SPARC
44#include <asm/idprom.h> 44#include <asm/idprom.h>
45#include <asm/sbus.h> 45#include <asm/sbus.h>
46#include <asm/openprom.h> 46#include <asm/openprom.h>
47#include <asm/oplib.h> 47#include <asm/oplib.h>
48#include <asm/prom.h>
48#include <asm/auxio.h> 49#include <asm/auxio.h>
49#ifndef __sparc_v9__
50#include <asm/io-unit.h>
51#endif
52#endif 50#endif
53#include <asm/uaccess.h> 51#include <asm/uaccess.h>
54 52
@@ -57,7 +55,7 @@
57 55
58#ifdef CONFIG_PCI 56#ifdef CONFIG_PCI
59#include <linux/pci.h> 57#include <linux/pci.h>
60#ifdef __sparc__ 58#ifdef CONFIG_SPARC
61#include <asm/pbm.h> 59#include <asm/pbm.h>
62#endif 60#endif
63#endif 61#endif
@@ -65,9 +63,9 @@
65#include "sunhme.h" 63#include "sunhme.h"
66 64
67#define DRV_NAME "sunhme" 65#define DRV_NAME "sunhme"
68#define DRV_VERSION "2.02" 66#define DRV_VERSION "3.00"
69#define DRV_RELDATE "8/24/03" 67#define DRV_RELDATE "June 23, 2006"
70#define DRV_AUTHOR "David S. Miller (davem@redhat.com)" 68#define DRV_AUTHOR "David S. Miller (davem@davemloft.net)"
71 69
72static char version[] = 70static char version[] =
73 DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n"; 71 DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n";
@@ -83,8 +81,6 @@ static int macaddr[6];
83module_param_array(macaddr, int, NULL, 0); 81module_param_array(macaddr, int, NULL, 0);
84MODULE_PARM_DESC(macaddr, "Happy Meal MAC address to set"); 82MODULE_PARM_DESC(macaddr, "Happy Meal MAC address to set");
85 83
86static struct happy_meal *root_happy_dev;
87
88#ifdef CONFIG_SBUS 84#ifdef CONFIG_SBUS
89static struct quattro *qfe_sbus_list; 85static struct quattro *qfe_sbus_list;
90#endif 86#endif
@@ -181,26 +177,6 @@ static __inline__ void tx_dump_ring(struct happy_meal *hp)
181#define DEFAULT_IPG2 4 /* For all modes */ 177#define DEFAULT_IPG2 4 /* For all modes */
182#define DEFAULT_JAMSIZE 4 /* Toe jam */ 178#define DEFAULT_JAMSIZE 4 /* Toe jam */
183 179
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
190static 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
200MODULE_DEVICE_TABLE(pci, happymeal_pci_ids);
201
202#endif
203
204/* NOTE: In the descriptor writes one _must_ write the address 180/* NOTE: In the descriptor writes one _must_ write the address
205 * member _first_. The card must not be allowed to see 181 * member _first_. The card must not be allowed to see
206 * the updated descriptor flags until the address is 182 * the updated descriptor flags until the address is
@@ -1610,7 +1586,7 @@ static int happy_meal_init(struct happy_meal *hp)
1610 HMD(("happy_meal_init: old[%08x] bursts<", 1586 HMD(("happy_meal_init: old[%08x] bursts<",
1611 hme_read32(hp, gregs + GREG_CFG))); 1587 hme_read32(hp, gregs + GREG_CFG)));
1612 1588
1613#ifndef __sparc__ 1589#ifndef CONFIG_SPARC
1614 /* It is always PCI and can handle 64byte bursts. */ 1590 /* It is always PCI and can handle 64byte bursts. */
1615 hme_write32(hp, gregs + GREG_CFG, GREG_CFG_BURST64); 1591 hme_write32(hp, gregs + GREG_CFG, GREG_CFG_BURST64);
1616#else 1592#else
@@ -1647,7 +1623,7 @@ static int happy_meal_init(struct happy_meal *hp)
1647 HMD(("XXX>")); 1623 HMD(("XXX>"));
1648 hme_write32(hp, gregs + GREG_CFG, 0); 1624 hme_write32(hp, gregs + GREG_CFG, 0);
1649 } 1625 }
1650#endif /* __sparc__ */ 1626#endif /* CONFIG_SPARC */
1651 1627
1652 /* Turn off interrupts we do not want to hear. */ 1628 /* Turn off interrupts we do not want to hear. */
1653 HMD((", enable global interrupts, ")); 1629 HMD((", enable global interrupts, "));
@@ -2592,14 +2568,10 @@ static void __init quattro_apply_ranges(struct quattro *qp, struct happy_meal *h
2592 */ 2568 */
2593static struct quattro * __init quattro_sbus_find(struct sbus_dev *goal_sdev) 2569static struct quattro * __init quattro_sbus_find(struct sbus_dev *goal_sdev)
2594{ 2570{
2595 struct sbus_bus *sbus;
2596 struct sbus_dev *sdev; 2571 struct sbus_dev *sdev;
2597 struct quattro *qp; 2572 struct quattro *qp;
2598 int i; 2573 int i;
2599 2574
2600 if (qfe_sbus_list == NULL)
2601 goto found;
2602
2603 for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) { 2575 for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
2604 for (i = 0, sdev = qp->quattro_dev; 2576 for (i = 0, sdev = qp->quattro_dev;
2605 (sdev != NULL) && (i < 4); 2577 (sdev != NULL) && (i < 4);
@@ -2608,17 +2580,7 @@ static struct quattro * __init quattro_sbus_find(struct sbus_dev *goal_sdev)
2608 return qp; 2580 return qp;
2609 } 2581 }
2610 } 2582 }
2611 for_each_sbus(sbus) {
2612 for_each_sbusdev(sdev, sbus) {
2613 if (sdev == goal_sdev)
2614 goto found;
2615 }
2616 }
2617
2618 /* Cannot find quattro parent, fail. */
2619 return NULL;
2620 2583
2621found:
2622 qp = kmalloc(sizeof(struct quattro), GFP_KERNEL); 2584 qp = kmalloc(sizeof(struct quattro), GFP_KERNEL);
2623 if (qp != NULL) { 2585 if (qp != NULL) {
2624 int i; 2586 int i;
@@ -2655,6 +2617,17 @@ static void __init quattro_sbus_register_irqs(void)
2655 } 2617 }
2656 } 2618 }
2657} 2619}
2620
2621static void __devexit quattro_sbus_free_irqs(void)
2622{
2623 struct quattro *qp;
2624
2625 for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
2626 struct sbus_dev *sdev = qp->quattro_dev;
2627
2628 free_irq(sdev->irqs[0], qp);
2629 }
2630}
2658#endif /* CONFIG_SBUS */ 2631#endif /* CONFIG_SBUS */
2659 2632
2660#ifdef CONFIG_PCI 2633#ifdef CONFIG_PCI
@@ -2689,8 +2662,9 @@ static struct quattro * __init quattro_pci_find(struct pci_dev *pdev)
2689#endif /* CONFIG_PCI */ 2662#endif /* CONFIG_PCI */
2690 2663
2691#ifdef CONFIG_SBUS 2664#ifdef CONFIG_SBUS
2692static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) 2665static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe)
2693{ 2666{
2667 struct device_node *dp = sdev->ofdev.node;
2694 struct quattro *qp = NULL; 2668 struct quattro *qp = NULL;
2695 struct happy_meal *hp; 2669 struct happy_meal *hp;
2696 struct net_device *dev; 2670 struct net_device *dev;
@@ -2713,6 +2687,7 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2713 if (!dev) 2687 if (!dev)
2714 goto err_out; 2688 goto err_out;
2715 SET_MODULE_OWNER(dev); 2689 SET_MODULE_OWNER(dev);
2690 SET_NETDEV_DEV(dev, &sdev->ofdev.dev);
2716 2691
2717 if (hme_version_printed++ == 0) 2692 if (hme_version_printed++ == 0)
2718 printk(KERN_INFO "%s", version); 2693 printk(KERN_INFO "%s", version);
@@ -2728,13 +2703,16 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2728 for (i = 0; i < 6; i++) 2703 for (i = 0; i < 6; i++)
2729 dev->dev_addr[i] = macaddr[i]; 2704 dev->dev_addr[i] = macaddr[i];
2730 macaddr[5]++; 2705 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 { 2706 } else {
2737 memcpy(dev->dev_addr, idprom->id_ethaddr, 6); 2707 unsigned char *addr;
2708 int len;
2709
2710 addr = of_get_property(dp, "local-mac-address", &len);
2711
2712 if (qfe_slot != -1 && addr && len == 6)
2713 memcpy(dev->dev_addr, addr, 6);
2714 else
2715 memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
2738 } 2716 }
2739 2717
2740 hp = dev->priv; 2718 hp = dev->priv;
@@ -2745,9 +2723,8 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2745 2723
2746 err = -ENODEV; 2724 err = -ENODEV;
2747 if (sdev->num_registers != 5) { 2725 if (sdev->num_registers != 5) {
2748 printk(KERN_ERR "happymeal: Device does not have 5 regs, it has %d.\n", 2726 printk(KERN_ERR "happymeal: Device needs 5 regs, has %d.\n",
2749 sdev->num_registers); 2727 sdev->num_registers);
2750 printk(KERN_ERR "happymeal: Would you like that for here or to go?\n");
2751 goto err_out_free_netdev; 2728 goto err_out_free_netdev;
2752 } 2729 }
2753 2730
@@ -2761,39 +2738,39 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2761 hp->gregs = sbus_ioremap(&sdev->resource[0], 0, 2738 hp->gregs = sbus_ioremap(&sdev->resource[0], 0,
2762 GREG_REG_SIZE, "HME Global Regs"); 2739 GREG_REG_SIZE, "HME Global Regs");
2763 if (!hp->gregs) { 2740 if (!hp->gregs) {
2764 printk(KERN_ERR "happymeal: Cannot map Happy Meal global registers.\n"); 2741 printk(KERN_ERR "happymeal: Cannot map global registers.\n");
2765 goto err_out_free_netdev; 2742 goto err_out_free_netdev;
2766 } 2743 }
2767 2744
2768 hp->etxregs = sbus_ioremap(&sdev->resource[1], 0, 2745 hp->etxregs = sbus_ioremap(&sdev->resource[1], 0,
2769 ETX_REG_SIZE, "HME TX Regs"); 2746 ETX_REG_SIZE, "HME TX Regs");
2770 if (!hp->etxregs) { 2747 if (!hp->etxregs) {
2771 printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Transmit registers.\n"); 2748 printk(KERN_ERR "happymeal: Cannot map MAC TX registers.\n");
2772 goto err_out_iounmap; 2749 goto err_out_iounmap;
2773 } 2750 }
2774 2751
2775 hp->erxregs = sbus_ioremap(&sdev->resource[2], 0, 2752 hp->erxregs = sbus_ioremap(&sdev->resource[2], 0,
2776 ERX_REG_SIZE, "HME RX Regs"); 2753 ERX_REG_SIZE, "HME RX Regs");
2777 if (!hp->erxregs) { 2754 if (!hp->erxregs) {
2778 printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Receive registers.\n"); 2755 printk(KERN_ERR "happymeal: Cannot map MAC RX registers.\n");
2779 goto err_out_iounmap; 2756 goto err_out_iounmap;
2780 } 2757 }
2781 2758
2782 hp->bigmacregs = sbus_ioremap(&sdev->resource[3], 0, 2759 hp->bigmacregs = sbus_ioremap(&sdev->resource[3], 0,
2783 BMAC_REG_SIZE, "HME BIGMAC Regs"); 2760 BMAC_REG_SIZE, "HME BIGMAC Regs");
2784 if (!hp->bigmacregs) { 2761 if (!hp->bigmacregs) {
2785 printk(KERN_ERR "happymeal: Cannot map Happy Meal BIGMAC registers.\n"); 2762 printk(KERN_ERR "happymeal: Cannot map BIGMAC registers.\n");
2786 goto err_out_iounmap; 2763 goto err_out_iounmap;
2787 } 2764 }
2788 2765
2789 hp->tcvregs = sbus_ioremap(&sdev->resource[4], 0, 2766 hp->tcvregs = sbus_ioremap(&sdev->resource[4], 0,
2790 TCVR_REG_SIZE, "HME Tranceiver Regs"); 2767 TCVR_REG_SIZE, "HME Tranceiver Regs");
2791 if (!hp->tcvregs) { 2768 if (!hp->tcvregs) {
2792 printk(KERN_ERR "happymeal: Cannot map Happy Meal Tranceiver registers.\n"); 2769 printk(KERN_ERR "happymeal: Cannot map TCVR registers.\n");
2793 goto err_out_iounmap; 2770 goto err_out_iounmap;
2794 } 2771 }
2795 2772
2796 hp->hm_revision = prom_getintdefault(sdev->prom_node, "hm-rev", 0xff); 2773 hp->hm_revision = of_getintprop_default(dp, "hm-rev", 0xff);
2797 if (hp->hm_revision == 0xff) 2774 if (hp->hm_revision == 0xff)
2798 hp->hm_revision = 0xa0; 2775 hp->hm_revision = 0xa0;
2799 2776
@@ -2807,8 +2784,8 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2807 hp->happy_flags |= HFLAG_QUATTRO; 2784 hp->happy_flags |= HFLAG_QUATTRO;
2808 2785
2809 /* Get the supported DVMA burst sizes from our Happy SBUS. */ 2786 /* Get the supported DVMA burst sizes from our Happy SBUS. */
2810 hp->happy_bursts = prom_getintdefault(sdev->bus->prom_node, 2787 hp->happy_bursts = of_getintprop_default(sdev->bus->ofdev.node,
2811 "burst-sizes", 0x00); 2788 "burst-sizes", 0x00);
2812 2789
2813 hp->happy_block = sbus_alloc_consistent(hp->happy_dev, 2790 hp->happy_block = sbus_alloc_consistent(hp->happy_dev,
2814 PAGE_SIZE, 2791 PAGE_SIZE,
@@ -2871,6 +2848,8 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2871 goto err_out_free_consistent; 2848 goto err_out_free_consistent;
2872 } 2849 }
2873 2850
2851 dev_set_drvdata(&sdev->ofdev.dev, hp);
2852
2874 if (qfe_slot != -1) 2853 if (qfe_slot != -1)
2875 printk(KERN_INFO "%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet ", 2854 printk(KERN_INFO "%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet ",
2876 dev->name, qfe_slot); 2855 dev->name, qfe_slot);
@@ -2883,12 +2862,6 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2883 dev->dev_addr[i], i == 5 ? ' ' : ':'); 2862 dev->dev_addr[i], i == 5 ? ' ' : ':');
2884 printk("\n"); 2863 printk("\n");
2885 2864
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; 2865 return 0;
2893 2866
2894err_out_free_consistent: 2867err_out_free_consistent:
@@ -2918,7 +2891,7 @@ err_out:
2918#endif 2891#endif
2919 2892
2920#ifdef CONFIG_PCI 2893#ifdef CONFIG_PCI
2921#ifndef __sparc__ 2894#ifndef CONFIG_SPARC
2922static int is_quattro_p(struct pci_dev *pdev) 2895static int is_quattro_p(struct pci_dev *pdev)
2923{ 2896{
2924 struct pci_dev *busdev = pdev->bus->self; 2897 struct pci_dev *busdev = pdev->bus->self;
@@ -3006,14 +2979,14 @@ static void get_hme_mac_nonsparc(struct pci_dev *pdev, unsigned char *dev_addr)
3006 get_random_bytes(&dev_addr[3], 3); 2979 get_random_bytes(&dev_addr[3], 3);
3007 return; 2980 return;
3008} 2981}
3009#endif /* !(__sparc__) */ 2982#endif /* !(CONFIG_SPARC) */
3010 2983
3011static int __init happy_meal_pci_init(struct pci_dev *pdev) 2984static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
2985 const struct pci_device_id *ent)
3012{ 2986{
3013 struct quattro *qp = NULL; 2987 struct quattro *qp = NULL;
3014#ifdef __sparc__ 2988#ifdef CONFIG_SPARC
3015 struct pcidev_cookie *pcp; 2989 struct pcidev_cookie *pcp;
3016 int node;
3017#endif 2990#endif
3018 struct happy_meal *hp; 2991 struct happy_meal *hp;
3019 struct net_device *dev; 2992 struct net_device *dev;
@@ -3024,15 +2997,14 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3024 int err; 2997 int err;
3025 2998
3026 /* Now make sure pci_dev cookie is there. */ 2999 /* Now make sure pci_dev cookie is there. */
3027#ifdef __sparc__ 3000#ifdef CONFIG_SPARC
3028 pcp = pdev->sysdata; 3001 pcp = pdev->sysdata;
3029 if (pcp == NULL || pcp->prom_node == -1) { 3002 if (pcp == NULL) {
3030 printk(KERN_ERR "happymeal(PCI): Some PCI device info missing\n"); 3003 printk(KERN_ERR "happymeal(PCI): Some PCI device info missing\n");
3031 return -ENODEV; 3004 return -ENODEV;
3032 } 3005 }
3033 node = pcp->prom_node;
3034 3006
3035 prom_getstring(node, "name", prom_name, sizeof(prom_name)); 3007 strcpy(prom_name, pcp->prom_node->name);
3036#else 3008#else
3037 if (is_quattro_p(pdev)) 3009 if (is_quattro_p(pdev))
3038 strcpy(prom_name, "SUNW,qfe"); 3010 strcpy(prom_name, "SUNW,qfe");
@@ -3103,11 +3075,15 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3103 dev->dev_addr[i] = macaddr[i]; 3075 dev->dev_addr[i] = macaddr[i];
3104 macaddr[5]++; 3076 macaddr[5]++;
3105 } else { 3077 } else {
3106#ifdef __sparc__ 3078#ifdef CONFIG_SPARC
3079 unsigned char *addr;
3080 int len;
3081
3107 if (qfe_slot != -1 && 3082 if (qfe_slot != -1 &&
3108 prom_getproplen(node, "local-mac-address") == 6) { 3083 (addr = of_get_property(pcp->prom_node,
3109 prom_getproperty(node, "local-mac-address", 3084 "local-mac-address", &len)) != NULL
3110 dev->dev_addr, 6); 3085 && len == 6) {
3086 memcpy(dev->dev_addr, addr, 6);
3111 } else { 3087 } else {
3112 memcpy(dev->dev_addr, idprom->id_ethaddr, 6); 3088 memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
3113 } 3089 }
@@ -3123,8 +3099,8 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3123 hp->bigmacregs = (hpreg_base + 0x6000UL); 3099 hp->bigmacregs = (hpreg_base + 0x6000UL);
3124 hp->tcvregs = (hpreg_base + 0x7000UL); 3100 hp->tcvregs = (hpreg_base + 0x7000UL);
3125 3101
3126#ifdef __sparc__ 3102#ifdef CONFIG_SPARC
3127 hp->hm_revision = prom_getintdefault(node, "hm-rev", 0xff); 3103 hp->hm_revision = of_getintprop_default(pcp->prom_node, "hm-rev", 0xff);
3128 if (hp->hm_revision == 0xff) { 3104 if (hp->hm_revision == 0xff) {
3129 unsigned char prev; 3105 unsigned char prev;
3130 3106
@@ -3148,7 +3124,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3148 /* And of course, indicate this is PCI. */ 3124 /* And of course, indicate this is PCI. */
3149 hp->happy_flags |= HFLAG_PCI; 3125 hp->happy_flags |= HFLAG_PCI;
3150 3126
3151#ifdef __sparc__ 3127#ifdef CONFIG_SPARC
3152 /* Assume PCI happy meals can handle all burst sizes. */ 3128 /* Assume PCI happy meals can handle all burst sizes. */
3153 hp->happy_bursts = DMA_BURSTBITS; 3129 hp->happy_bursts = DMA_BURSTBITS;
3154#endif 3130#endif
@@ -3211,6 +3187,8 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3211 goto err_out_iounmap; 3187 goto err_out_iounmap;
3212 } 3188 }
3213 3189
3190 dev_set_drvdata(&pdev->dev, hp);
3191
3214 if (!qfe_slot) { 3192 if (!qfe_slot) {
3215 struct pci_dev *qpdev = qp->quattro_dev; 3193 struct pci_dev *qpdev = qp->quattro_dev;
3216 3194
@@ -3240,12 +3218,6 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3240 3218
3241 printk("\n"); 3219 printk("\n");
3242 3220
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; 3221 return 0;
3250 3222
3251err_out_iounmap: 3223err_out_iounmap:
@@ -3263,136 +3235,146 @@ err_out_clear_quattro:
3263err_out: 3235err_out:
3264 return err; 3236 return err;
3265} 3237}
3266#endif
3267 3238
3268#ifdef CONFIG_SBUS 3239static void __devexit happy_meal_pci_remove(struct pci_dev *pdev)
3269static int __init happy_meal_sbus_probe(void)
3270{ 3240{
3271 struct sbus_bus *sbus; 3241 struct happy_meal *hp = dev_get_drvdata(&pdev->dev);
3272 struct sbus_dev *sdev; 3242 struct net_device *net_dev = hp->dev;
3273 int cards = 0; 3243
3274 char model[128]; 3244 unregister_netdev(net_dev);
3275 3245
3276 for_each_sbus(sbus) { 3246 pci_free_consistent(hp->happy_dev,
3277 for_each_sbusdev(sdev, sbus) { 3247 PAGE_SIZE,
3278 char *name = sdev->prom_name; 3248 hp->happy_block,
3279 3249 hp->hblock_dvma);
3280 if (!strcmp(name, "SUNW,hme")) { 3250 iounmap(hp->gregs);
3281 cards++; 3251 pci_release_regions(hp->happy_dev);
3282 prom_getstring(sdev->prom_node, "model", 3252
3283 model, sizeof(model)); 3253 free_netdev(net_dev);
3284 if (!strcmp(model, "SUNW,sbus-qfe")) 3254
3285 happy_meal_sbus_init(sdev, 1); 3255 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} 3256}
3299#endif
3300 3257
3301#ifdef CONFIG_PCI 3258static struct pci_device_id happymeal_pci_ids[] = {
3302static int __init happy_meal_pci_probe(void) 3259 {
3260 .vendor = PCI_VENDOR_ID_SUN,
3261 .device = PCI_DEVICE_ID_SUN_HAPPYMEAL,
3262 .subvendor = PCI_ANY_ID,
3263 .subdevice = PCI_ANY_ID,
3264 },
3265 { } /* Terminating entry */
3266};
3267
3268MODULE_DEVICE_TABLE(pci, happymeal_pci_ids);
3269
3270static struct pci_driver hme_pci_driver = {
3271 .name = "hme",
3272 .id_table = happymeal_pci_ids,
3273 .probe = happy_meal_pci_probe,
3274 .remove = __devexit_p(happy_meal_pci_remove),
3275};
3276
3277static int __init happy_meal_pci_init(void)
3303{ 3278{
3304 struct pci_dev *pdev = NULL; 3279 return pci_module_init(&hme_pci_driver);
3305 int cards = 0; 3280}
3306 3281
3307 while ((pdev = pci_find_device(PCI_VENDOR_ID_SUN, 3282static void happy_meal_pci_exit(void)
3308 PCI_DEVICE_ID_SUN_HAPPYMEAL, pdev)) != NULL) { 3283{
3309 if (pci_enable_device(pdev)) 3284 pci_unregister_driver(&hme_pci_driver);
3310 continue; 3285
3311 pci_set_master(pdev); 3286 while (qfe_pci_list) {
3312 cards++; 3287 struct quattro *qfe = qfe_pci_list;
3313 happy_meal_pci_init(pdev); 3288 struct quattro *next = qfe->next;
3289
3290 kfree(qfe);
3291
3292 qfe_pci_list = next;
3314 } 3293 }
3315 return cards;
3316} 3294}
3295
3317#endif 3296#endif
3318 3297
3319static int __init happy_meal_probe(void) 3298#ifdef CONFIG_SBUS
3299static int __devinit hme_sbus_probe(struct of_device *dev, const struct of_device_id *match)
3320{ 3300{
3321 static int called = 0; 3301 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
3322 int cards; 3302 struct device_node *dp = dev->node;
3303 char *model = of_get_property(dp, "model", NULL);
3304 int is_qfe = (match->data != NULL);
3323 3305
3324 root_happy_dev = NULL; 3306 if (!is_qfe && model && !strcmp(model, "SUNW,sbus-qfe"))
3307 is_qfe = 1;
3325 3308
3326 if (called) 3309 return happy_meal_sbus_probe_one(sdev, is_qfe);
3327 return -ENODEV; 3310}
3328 called++; 3311
3312static int __devexit hme_sbus_remove(struct of_device *dev)
3313{
3314 struct happy_meal *hp = dev_get_drvdata(&dev->dev);
3315 struct net_device *net_dev = hp->dev;
3316
3317 unregister_netdevice(net_dev);
3318
3319 /* XXX qfe parent interrupt... */
3320
3321 sbus_iounmap(hp->gregs, GREG_REG_SIZE);
3322 sbus_iounmap(hp->etxregs, ETX_REG_SIZE);
3323 sbus_iounmap(hp->erxregs, ERX_REG_SIZE);
3324 sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE);
3325 sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE);
3326 sbus_free_consistent(hp->happy_dev,
3327 PAGE_SIZE,
3328 hp->happy_block,
3329 hp->hblock_dvma);
3330
3331 free_netdev(net_dev);
3332
3333 dev_set_drvdata(&dev->dev, NULL);
3329 3334
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; 3335 return 0;
3340} 3336}
3341 3337
3338static struct of_device_id hme_sbus_match[] = {
3339 {
3340 .name = "SUNW,hme",
3341 },
3342 {
3343 .name = "SUNW,qfe",
3344 .data = (void *) 1,
3345 },
3346 {
3347 .name = "qfe",
3348 .data = (void *) 1,
3349 },
3350 {},
3351};
3342 3352
3343static void __exit happy_meal_cleanup_module(void) 3353MODULE_DEVICE_TABLE(of, hme_sbus_match);
3344{
3345#ifdef CONFIG_SBUS
3346 struct quattro *last_seen_qfe = NULL;
3347#endif
3348 3354
3349 while (root_happy_dev) { 3355static struct of_platform_driver hme_sbus_driver = {
3350 struct happy_meal *hp = root_happy_dev; 3356 .name = "hme",
3351 struct happy_meal *next = root_happy_dev->next_module; 3357 .match_table = hme_sbus_match,
3352 struct net_device *dev = hp->dev; 3358 .probe = hme_sbus_probe,
3359 .remove = __devexit_p(hme_sbus_remove),
3360};
3353 3361
3354 /* Unregister netdev before unmapping registers as this 3362static int __init happy_meal_sbus_init(void)
3355 * call can end up trying to access those registers. 3363{
3356 */ 3364 int err;
3357 unregister_netdev(dev);
3358 3365
3359#ifdef CONFIG_SBUS 3366 err = of_register_driver(&hme_sbus_driver, &sbus_bus_type);
3360 if (!(hp->happy_flags & HFLAG_PCI)) { 3367 if (!err)
3361 if (hp->happy_flags & HFLAG_QUATTRO) { 3368 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 3369
3368 sbus_iounmap(hp->gregs, GREG_REG_SIZE); 3370 return err;
3369 sbus_iounmap(hp->etxregs, ETX_REG_SIZE); 3371}
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 3372
3391 root_happy_dev = next; 3373static void happy_meal_sbus_exit(void)
3392 } 3374{
3375 of_unregister_driver(&hme_sbus_driver);
3376 quattro_sbus_free_irqs();
3393 3377
3394 /* Now cleanup the quattro lists. */
3395#ifdef CONFIG_SBUS
3396 while (qfe_sbus_list) { 3378 while (qfe_sbus_list) {
3397 struct quattro *qfe = qfe_sbus_list; 3379 struct quattro *qfe = qfe_sbus_list;
3398 struct quattro *next = qfe->next; 3380 struct quattro *next = qfe->next;
@@ -3401,18 +3383,39 @@ static void __exit happy_meal_cleanup_module(void)
3401 3383
3402 qfe_sbus_list = next; 3384 qfe_sbus_list = next;
3403 } 3385 }
3386}
3404#endif 3387#endif
3405#ifdef CONFIG_PCI
3406 while (qfe_pci_list) {
3407 struct quattro *qfe = qfe_pci_list;
3408 struct quattro *next = qfe->next;
3409 3388
3410 kfree(qfe); 3389static int __init happy_meal_probe(void)
3390{
3391 int err = 0;
3411 3392
3412 qfe_pci_list = next; 3393#ifdef CONFIG_SBUS
3394 err = happy_meal_sbus_init();
3395#endif
3396#ifdef CONFIG_PCI
3397 if (!err) {
3398 err = happy_meal_pci_init();
3399#ifdef CONFIG_SBUS
3400 if (err)
3401 happy_meal_sbus_exit();
3402#endif
3413 } 3403 }
3414#endif 3404#endif
3405
3406 return err;
3407}
3408
3409
3410static void __exit happy_meal_exit(void)
3411{
3412#ifdef CONFIG_SBUS
3413 happy_meal_sbus_exit();
3414#endif
3415#ifdef CONFIG_PCI
3416 happy_meal_pci_exit();
3417#endif
3415} 3418}
3416 3419
3417module_init(happy_meal_probe); 3420module_init(happy_meal_probe);
3418module_exit(happy_meal_cleanup_module); 3421module_exit(happy_meal_exit);