diff options
| author | Ralf Bächle <ralf@linux-mips.org> | 2005-01-27 14:12:28 -0500 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2005-01-27 14:12:28 -0500 |
| commit | 1f6d24c68dd9726ea83ebef94f4e8c74eb4657bc (patch) | |
| tree | 6e79de755f1b077f71b82fa407042b705a947f08 | |
| parent | 427a4804db4e131909b39ef69956305ab436e6e6 (diff) | |
[PATCH] Jazzsonic driver updates
o Resurrect the Jazz SONIC driver after years of it not having been tested
o Convert from Space.c initialization to module_init / platform device.
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
| -rw-r--r-- | drivers/net/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/net/Space.c | 8 | ||||
| -rw-r--r-- | drivers/net/jazzsonic.c | 217 | ||||
| -rw-r--r-- | drivers/net/sonic.c | 4 |
4 files changed, 149 insertions, 82 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index d9a7c9a1fc22..b15c797f8cef 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -445,7 +445,7 @@ config LASI_82596 config MIPS_JAZZ_SONIC tristate "MIPS JAZZ onboard SONIC Ethernet support" - depends on NET_ETHERNET && MIPS_JAZZ + depends on NET_ETHERNET && MACH_JAZZ help This is the driver for the onboard card of MIPS Magnum 4000, Acer PICA, Olivetti M700-10 and a few other identical OEM systems. diff --git a/drivers/net/Space.c b/drivers/net/Space.c index 4158b44c54fd..fc519377b5aa 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c @@ -302,13 +302,6 @@ static struct devprobe2 m68k_probes[] __initdata = { {NULL, 0}, }; -static struct devprobe2 mips_probes[] __initdata = { -#ifdef CONFIG_MIPS_JAZZ_SONIC - {sonic_probe, 0}, -#endif - {NULL, 0}, -}; - /* * Unified ethernet device probe, segmented per architecture and * per bus interface. This drives the legacy devices only for now. @@ -322,7 +315,6 @@ static void __init ethif_probe2(int unit) return; (void)( probe_list2(unit, m68k_probes, base_addr == 0) && - probe_list2(unit, mips_probes, base_addr == 0) && probe_list2(unit, eisa_probes, base_addr == 0) && probe_list2(unit, mca_probes, base_addr == 0) && probe_list2(unit, isa_probes, base_addr == 0) && diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c index 7046c4395266..7fec613e1675 100644 --- a/drivers/net/jazzsonic.c +++ b/drivers/net/jazzsonic.c @@ -14,6 +14,7 @@ */ #include <linux/kernel.h> +#include <linux/module.h> #include <linux/types.h> #include <linux/fcntl.h> #include <linux/interrupt.h> @@ -28,6 +29,7 @@ #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/bitops.h> +#include <linux/device.h> #include <asm/bootinfo.h> #include <asm/system.h> @@ -37,7 +39,10 @@ #include <asm/jazz.h> #include <asm/jazzdma.h> -#define DRV_NAME "jazzsonic" +static char jazz_sonic_string[] = "jazzsonic"; +static struct platform_device *jazz_sonic_device; + +#define SONIC_MEM_SIZE 0x100 #define SREGS_PAD(n) u16 n; @@ -50,8 +55,8 @@ #define SONIC_WRITE(reg,val) \ do { \ - *((volatile unsigned int *)base_addr+reg) = val; \ -} + *((volatile unsigned int *)base_addr+(reg)) = (val); \ +} while (0) /* use 0 for production, 1 for verification, >2 for debug */ @@ -80,70 +85,7 @@ static unsigned short known_revisions[] = 0xffff /* end of list */ }; -/* Index to functions, as function prototypes. */ - -static int sonic_probe1(struct net_device *dev, unsigned int base_addr, - unsigned int irq); - - -/* - * Probe for a SONIC ethernet controller on a Mips Jazz board. - * Actually probing is superfluous but we're paranoid. - */ -struct net_device * __init sonic_probe(int unit) -{ - struct net_device *dev; - struct sonic_local *lp; - unsigned int base_addr; - int err = 0; - int i; - - /* - * Don't probe if we're not running on a Jazz board. - */ - if (mips_machgroup != MACH_GROUP_JAZZ) - return ERR_PTR(-ENODEV); - - dev = alloc_etherdev(0); - if (!dev) - return ERR_PTR(-ENOMEM); - - sprintf(dev->name, "eth%d", unit); - netdev_boot_setup_check(dev); - base_addr = dev->base_addr; - - if (base_addr >= KSEG0) { /* Check a single specified location. */ - err = sonic_probe1(dev, base_addr, dev->irq); - } else if (base_addr != 0) { /* Don't probe at all. */ - err = -ENXIO; - } else { - for (i = 0; sonic_portlist[i].port; i++) { - int io = sonic_portlist[i].port; - if (sonic_probe1(dev, io, sonic_portlist[i].irq) == 0) - break; - } - if (!sonic_portlist[i].port) - err = -ENODEV; - } - if (err) - goto out; - err = register_netdev(dev); - if (err) - goto out1; - return dev; -out1: - lp = dev->priv; - vdma_free(lp->rba_laddr); - kfree(lp->rba); - vdma_free(lp->cda_laddr); - kfree(lp); - release_region(dev->base_addr, 0x100); -out: - free_netdev(dev); - return ERR_PTR(err); -} - -static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr, +static int __init sonic_probe1(struct net_device *dev, unsigned long base_addr, unsigned int irq) { static unsigned version_printed; @@ -153,7 +95,7 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr, int err = -ENODEV; int i; - if (!request_region(base_addr, 0x100, DRV_NAME)) + if (!request_mem_region(base_addr, SONIC_MEM_SIZE, jazz_sonic_string)) return -EBUSY; /* * get the Silicon Revision ID. If this is one of the known @@ -233,7 +175,7 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr, memset(lp, 0, sizeof(struct sonic_local)); /* get the virtual dma address */ - lp->cda_laddr = vdma_alloc(PHYSADDR(lp),sizeof(*lp)); + lp->cda_laddr = vdma_alloc(CPHYSADDR(lp),sizeof(*lp)); if (lp->cda_laddr == ~0UL) { printk("%s: couldn't get DMA page entry for " "descriptors\n", dev->name); @@ -254,7 +196,7 @@ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr, } /* get virtual dma address */ - lp->rba_laddr = vdma_alloc(PHYSADDR(lp->rba), + lp->rba_laddr = vdma_alloc(CPHYSADDR(lp->rba), SONIC_NUM_RRS * SONIC_RBSIZE); if (lp->rba_laddr == ~0UL) { printk("%s: couldn't get DMA page entry for receive " @@ -291,7 +233,66 @@ out2: out1: kfree(lp); out: - release_region(base_addr, 0x100); + release_region(base_addr, SONIC_MEM_SIZE); + return err; +} + +/* + * Probe for a SONIC ethernet controller on a Mips Jazz board. + * Actually probing is superfluous but we're paranoid. + */ +static int __init jazz_sonic_probe(struct device *device) +{ + struct net_device *dev; + struct sonic_local *lp; + unsigned long base_addr; + int err = 0; + int i; + + /* + * Don't probe if we're not running on a Jazz board. + */ + if (mips_machgroup != MACH_GROUP_JAZZ) + return -ENODEV; + + dev = alloc_etherdev(0); + if (!dev) + return -ENOMEM; + + netdev_boot_setup_check(dev); + base_addr = dev->base_addr; + + if (base_addr >= KSEG0) { /* Check a single specified location. */ + err = sonic_probe1(dev, base_addr, dev->irq); + } else if (base_addr != 0) { /* Don't probe at all. */ + err = -ENXIO; + } else { + for (i = 0; sonic_portlist[i].port; i++) { + int io = sonic_portlist[i].port; + if (sonic_probe1(dev, io, sonic_portlist[i].irq) == 0) + break; + } + if (!sonic_portlist[i].port) + err = -ENODEV; + } + if (err) + goto out; + err = register_netdev(dev); + if (err) + goto out1; + + return 0; + +out1: + lp = dev->priv; + vdma_free(lp->rba_laddr); + kfree(lp->rba); + vdma_free(lp->cda_laddr); + kfree(lp); + release_region(dev->base_addr, SONIC_MEM_SIZE); +out: + free_netdev(dev); + return err; } @@ -304,3 +305,77 @@ out: #define sonic_chiptomem(x) KSEG1ADDR(vdma_log2phys(x)) #include "sonic.c" + +static int __devexit jazz_sonic_device_remove (struct device *device) +{ + struct net_device *dev = device->driver_data; + + unregister_netdev (dev); + release_region (dev->base_addr, SONIC_MEM_SIZE); + free_netdev (dev); + + return 0; +} + +static struct device_driver jazz_sonic_driver = { + .name = jazz_sonic_string, + .bus = &platform_bus_type, + .probe = jazz_sonic_probe, + .remove = __devexit_p(jazz_sonic_device_remove), +}; + +static void jazz_sonic_platform_release (struct device *device) +{ + struct platform_device *pldev; + + /* free device */ + pldev = to_platform_device (device); + kfree (pldev); +} + +static int __init jazz_sonic_init_module(void) +{ + struct platform_device *pldev; + + if (driver_register(&jazz_sonic_driver)) { + printk(KERN_ERR "Driver registration failed\n"); + return -ENOMEM; + } + + jazz_sonic_device = NULL; + + if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) { + goto out_unregister; + } + + memset(pldev, 0, sizeof (*pldev)); + pldev->name = jazz_sonic_string; + pldev->id = 0; + pldev->dev.release = jazz_sonic_platform_release; + jazz_sonic_device = pldev; + + if (platform_device_register (pldev)) { + kfree(pldev); + jazz_sonic_device = NULL; + } + + return 0; + +out_unregister: + platform_device_unregister(pldev); + + return -ENOMEM; +} + +static void __exit jazz_sonic_cleanup_module(void) +{ + driver_unregister(&jazz_sonic_driver); + + if (jazz_sonic_device) { + platform_device_unregister(jazz_sonic_device); + jazz_sonic_device = NULL; + } +} + +module_init(jazz_sonic_init_module); +module_exit(jazz_sonic_cleanup_module); diff --git a/drivers/net/sonic.c b/drivers/net/sonic.c index 2f6e30984134..cdc9cc873e06 100644 --- a/drivers/net/sonic.c +++ b/drivers/net/sonic.c @@ -116,7 +116,7 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev) /* * Map the packet data into the logical DMA address space */ - if ((laddr = vdma_alloc(PHYSADDR(skb->data), skb->len)) == ~0UL) { + if ((laddr = vdma_alloc(CPHYSADDR(skb->data), skb->len)) == ~0UL) { printk("%s: no VDMA entry for transmit available.\n", dev->name); dev_kfree_skb(skb); @@ -223,7 +223,7 @@ static irqreturn_t sonic_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* We must free the original skb */ if (lp->tx_skb[entry]) { - dev_kfree_skb(lp->tx_skb[entry]); + dev_kfree_skb_irq(lp->tx_skb[entry]); lp->tx_skb[entry] = 0; } /* and the VDMA address */ |
