Commit 0b7fab69 authored by Angelo Dell\'Aera's avatar Angelo Dell\'Aera Committed by Jeff Garzik

[PATCH] saa9730 (minor revision)

Don't know if the patch I released few days ago was still
applied. This is a minor revision of that patch which converts
saa9730 to spinlocks thus removing save_and_cli() and
restore_flags() calls.

Regards,
Angelo Dell'Aera
parent 8e4b3625
...@@ -21,6 +21,11 @@ ...@@ -21,6 +21,11 @@
* *
* SAA9730 ethernet driver. * SAA9730 ethernet driver.
* *
* Changes:
* Angelo Dell'Aera <buffer@antifork.org> : Conversion to the new PCI API (pci_driver).
* Conversion to spinlocks.
* Error handling fixes.
*
*/ */
#include <linux/init.h> #include <linux/init.h>
...@@ -30,6 +35,7 @@ ...@@ -30,6 +35,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/spinlock.h>
#include <asm/addrspace.h> #include <asm/addrspace.h>
#include <asm/mips-boards/prom.h> #include <asm/mips-boards/prom.h>
...@@ -42,6 +48,15 @@ int lan_saa9730_debug = LAN_SAA9730_DEBUG; ...@@ -42,6 +48,15 @@ int lan_saa9730_debug = LAN_SAA9730_DEBUG;
int lan_saa9730_debug; int lan_saa9730_debug;
#endif #endif
#define DRV_MODULE_NAME "saa9730"
static struct pci_device_id saa9730_pci_tbl[] = {
{ PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA9370,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, saa9730_pci_tbl);
/* Non-zero only if the current card is a PCI with BIOS-set IRQ. */ /* Non-zero only if the current card is a PCI with BIOS-set IRQ. */
static unsigned int pci_irq_line; static unsigned int pci_irq_line;
...@@ -216,6 +231,9 @@ static int lan_saa9730_allocate_buffers(struct lan_saa9730_private *lp) ...@@ -216,6 +231,9 @@ static int lan_saa9730_allocate_buffers(struct lan_saa9730_private *lp)
buffer_start = buffer_start =
(unsigned int) kmalloc(mem_size, GFP_DMA | GFP_KERNEL); (unsigned int) kmalloc(mem_size, GFP_DMA | GFP_KERNEL);
if (!buffer_start)
return -ENOMEM;
/* /*
* Set DMA buffer to kseg1 (uncached). * Set DMA buffer to kseg1 (uncached).
* Make sure to flush before using it uncached. * Make sure to flush before using it uncached.
...@@ -887,13 +905,14 @@ static int lan_saa9730_start_xmit(struct sk_buff *skb, ...@@ -887,13 +905,14 @@ static int lan_saa9730_start_xmit(struct sk_buff *skb,
printk("Send packet: skb=%08x\n", (unsigned int) skb); printk("Send packet: skb=%08x\n", (unsigned int) skb);
skblen = skb->len; skblen = skb->len;
save_and_cli(flags);
spin_lock_irqsave(&lp->lock, flags);
len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen; len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen;
if (lan_saa9730_write(lp, skb, skblen)) { if (lan_saa9730_write(lp, skb, skblen)) {
restore_flags(flags); spin_unlock_irqrestore(&lp->lock, flags);
printk printk("Error when writing packet to controller: skb=%08x\n",
("Error when writing packet to controller: skb=%08x\n",
(unsigned int) skb); (unsigned int) skb);
netif_stop_queue(dev); netif_stop_queue(dev);
return -1; return -1;
...@@ -906,7 +925,7 @@ static int lan_saa9730_start_xmit(struct sk_buff *skb, ...@@ -906,7 +925,7 @@ static int lan_saa9730_start_xmit(struct sk_buff *skb,
netif_start_queue(dev); netif_start_queue(dev);
dev_kfree_skb(skb); dev_kfree_skb(skb);
restore_flags(flags); spin_unlock_irqrestore(&lp->lock, flags);
return 0; return 0;
} }
...@@ -971,21 +990,47 @@ static void lan_saa9730_set_multicast(struct net_device *dev) ...@@ -971,21 +990,47 @@ static void lan_saa9730_set_multicast(struct net_device *dev)
lan_saa9730_restart(lp); lan_saa9730_restart(lp);
} }
static void __devexit saa9730_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
if (dev) {
if (dev->priv)
kfree(dev->priv);
unregister_netdev(dev);
free_netdev(dev);
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
}
}
static int lan_saa9730_init(struct net_device *dev, int ioaddr, int irq) static int lan_saa9730_init(struct net_device *dev, int ioaddr, int irq)
{ {
struct lan_saa9730_private *lp; struct lan_saa9730_private *lp;
unsigned char ethernet_addr[6]; unsigned char ethernet_addr[6];
int ret = 0;
dev = init_etherdev(dev, 0); dev = init_etherdev(dev, 0);
if (!dev)
return -ENOMEM;
dev->open = lan_saa9730_open_fail; dev->open = lan_saa9730_open_fail;
if (get_ethernet_addr(ethernet_addr))
return -1;
if (get_ethernet_addr(ethernet_addr)) {
ret = -ENODEV;
goto out;
}
memcpy(dev->dev_addr, ethernet_addr, 6); memcpy(dev->dev_addr, ethernet_addr, 6);
dev->base_addr = ioaddr; dev->base_addr = ioaddr;
dev->irq = irq; dev->irq = irq;
/* /*
* Make certain the data structures used by the controller are aligned * Make certain the data structures used by the controller are aligned
* and DMAble. * and DMAble.
...@@ -995,6 +1040,11 @@ static int lan_saa9730_init(struct net_device *dev, int ioaddr, int irq) ...@@ -995,6 +1040,11 @@ static int lan_saa9730_init(struct net_device *dev, int ioaddr, int irq)
GFP_DMA | GFP_KERNEL) GFP_DMA | GFP_KERNEL)
+ 7) & ~7); + 7) & ~7);
if (!lp) {
ret = -ENOMEM;
goto out;
}
dev->priv = lp; dev->priv = lp;
memset(lp, 0, sizeof(*lp)); memset(lp, 0, sizeof(*lp));
...@@ -1007,33 +1057,35 @@ static int lan_saa9730_init(struct net_device *dev, int ioaddr, int irq) ...@@ -1007,33 +1057,35 @@ static int lan_saa9730_init(struct net_device *dev, int ioaddr, int irq)
SAA9730_EVM_REGS_ADDR); SAA9730_EVM_REGS_ADDR);
/* Allocate LAN RX/TX frame buffer space. */ /* Allocate LAN RX/TX frame buffer space. */
if (lan_saa9730_allocate_buffers(lp)) if ((ret = lan_saa9730_allocate_buffers(lp)))
return -1; goto out;
/* Stop LAN controller. */ /* Stop LAN controller. */
if (lan_saa9730_stop(lp)) if ((ret = lan_saa9730_stop(lp)))
return -1; goto out;
/* Initialize CAM registers. */ /* Initialize CAM registers. */
if (lan_saa9730_cam_init(dev)) if ((ret = lan_saa9730_cam_init(dev)))
return -1; goto out;
/* Initialize MII registers. */ /* Initialize MII registers. */
if (lan_saa9730_mii_init(lp)) if ((ret = lan_saa9730_mii_init(lp)))
return -1; goto out;
/* Initialize control registers. */ /* Initialize control registers. */
if (lan_saa9730_control_init(lp)) if ((ret = lan_saa9730_control_init(lp)))
return -1; goto out;
/* Load CAM registers. */ /* Load CAM registers. */
if (lan_saa9730_cam_load(lp)) if ((ret = lan_saa9730_cam_load(lp)))
return -1; goto out;
/* Initialize DMA context registers. */ /* Initialize DMA context registers. */
if (lan_saa9730_dma_init(lp)) if ((ret = lan_saa9730_dma_init(lp)))
return -1; goto out;
spin_lock_init(&lp->lock);
dev->open = lan_saa9730_open; dev->open = lan_saa9730_open;
dev->hard_start_xmit = lan_saa9730_start_xmit; dev->hard_start_xmit = lan_saa9730_start_xmit;
dev->stop = lan_saa9730_close; dev->stop = lan_saa9730_close;
...@@ -1042,42 +1094,89 @@ static int lan_saa9730_init(struct net_device *dev, int ioaddr, int irq) ...@@ -1042,42 +1094,89 @@ static int lan_saa9730_init(struct net_device *dev, int ioaddr, int irq)
dev->tx_timeout = lan_saa9730_tx_timeout; dev->tx_timeout = lan_saa9730_tx_timeout;
dev->watchdog_timeo = (HZ >> 1); dev->watchdog_timeo = (HZ >> 1);
dev->dma = 0; dev->dma = 0;
return 0; return 0;
out:
if (dev) {
if (dev->priv)
kfree(dev->priv);
unregister_netdevice(dev);
free_netdev(dev);
}
return ret;
} }
static int __init saa9730_probe(void) static int __devinit saa9730_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{ {
struct net_device *dev = NULL; struct net_device *dev = NULL;
struct pci_dev *pdev = NULL; unsigned int pci_ioaddr;
int err;
if (lan_saa9730_debug > 1) if (lan_saa9730_debug > 1)
printk printk("saa9730.c: PCI bios is present, checking for devices...\n");
("saa9730.c: PCI bios is present, checking for devices...\n");
err = pci_enable_device(pdev);
if (err) {
printk(KERN_ERR "Cannot enable PCI device, aborting.\n");
goto out;
}
err = pci_request_regions(pdev, DRV_MODULE_NAME);
if (err) {
printk(KERN_ERR "Cannot obtain PCI resources, aborting.\n");
goto out_disable_pdev;
}
while ((pdev = pci_find_device(PCI_VENDOR_ID_PHILIPS, pci_irq_line = pdev->irq;
PCI_DEVICE_ID_PHILIPS_SAA9730, /* LAN base address in located at BAR 1. */
pdev))) {
unsigned int pci_ioaddr; pci_ioaddr = pci_resource_start(pdev, 1);
pci_set_master(pdev);
printk("Found SAA9730 (PCI) at %#x, irq %d.\n",
pci_ioaddr, pci_irq_line);
err = lan_saa9730_init(dev, pci_ioaddr, pci_irq_line);
if (err) {
printk("Lan init failed");
goto out_disable_pdev;
}
pci_set_drvdata(pdev, dev);
return 0;
out_disable_pdev:
pci_disable_device(pdev);
out:
pci_set_drvdata(pdev, NULL);
return err;
}
pci_irq_line = pdev->irq;
/* LAN base address in located at BAR 1. */
pci_ioaddr = pci_resource_start(pdev, 1); static struct pci_driver saa9730_driver = {
pci_set_master(pdev); .name = DRV_MODULE_NAME,
.id_table = saa9730_pci_tbl,
.probe = saa9730_init_one,
.remove = __devexit_p(saa9730_remove_one),
};
printk("Found SAA9730 (PCI) at %#x, irq %d.\n",
pci_ioaddr, pci_irq_line);
if (!lan_saa9730_init
(dev, pci_ioaddr, pci_irq_line))
return 0;
else
printk("Lan init failed.\n");
}
return -ENODEV; static int __init saa9730_init(void)
{
return pci_module_init(&saa9730_driver);
}
static void __exit saa9730_cleanup(void)
{
pci_unregister_driver(&saa9730_driver);
} }
module_init(saa9730_probe); module_init(saa9730_init);
module_exit(saa9730_cleanup);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -365,6 +365,7 @@ struct lan_saa9730_private { ...@@ -365,6 +365,7 @@ struct lan_saa9730_private {
unsigned char PhysicalAddress[LAN_SAA9730_CAM_ENTRIES][6]; unsigned char PhysicalAddress[LAN_SAA9730_CAM_ENTRIES][6];
struct net_device_stats stats; struct net_device_stats stats;
spinlock_t lock;
}; };
#endif /* _SAA9730_H */ #endif /* _SAA9730_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment