Commit a4e1e020 authored by Stephen Hemminger's avatar Stephen Hemminger

[netdrvr xircom_cb] fix race in statistics pointer setting

by converting to use alloc_etherdev.
parent 5b84ad19
...@@ -230,7 +230,8 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_ ...@@ -230,7 +230,8 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
This way, we can fail gracefully if not enough memory This way, we can fail gracefully if not enough memory
is available. is available.
*/ */
if ((dev = init_etherdev(NULL, sizeof(struct xircom_private))) == NULL) { dev = alloc_etherdev(sizeof(struct xircom_private));
if (!dev) {
printk(KERN_ERR "xircom_probe: failed to allocate etherdev\n"); printk(KERN_ERR "xircom_probe: failed to allocate etherdev\n");
goto device_fail; goto device_fail;
} }
...@@ -250,7 +251,7 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_ ...@@ -250,7 +251,7 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev); SET_NETDEV_DEV(dev, &pdev->dev);
printk(KERN_INFO "%s: Xircom cardbus revision %i at irq %i \n", dev->name, chip_rev, pdev->irq);
private->dev = dev; private->dev = dev;
private->pdev = pdev; private->pdev = pdev;
...@@ -259,7 +260,6 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_ ...@@ -259,7 +260,6 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
dev->irq = pdev->irq; dev->irq = pdev->irq;
dev->base_addr = private->io_port; dev->base_addr = private->io_port;
initialize_card(private); initialize_card(private);
read_mac_address(private); read_mac_address(private);
setup_descriptors(private); setup_descriptors(private);
...@@ -272,7 +272,12 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_ ...@@ -272,7 +272,12 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
pci_set_drvdata(pdev, dev); pci_set_drvdata(pdev, dev);
if (register_netdev(dev)) {
printk(KERN_ERR "xircom_probe: netdevice registration failed.\n");
goto reg_fail;
}
printk(KERN_INFO "%s: Xircom cardbus revision %i at irq %i \n", dev->name, chip_rev, pdev->irq);
/* start the transmitter to get a heartbeat */ /* start the transmitter to get a heartbeat */
/* TODO: send 2 dummy packets here */ /* TODO: send 2 dummy packets here */
transceiver_voodoo(private); transceiver_voodoo(private);
...@@ -287,10 +292,12 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_ ...@@ -287,10 +292,12 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
leave("xircom_probe"); leave("xircom_probe");
return 0; return 0;
reg_fail:
kfree(private->tx_buffer);
tx_buf_fail: tx_buf_fail:
kfree(private->rx_buffer); kfree(private->rx_buffer);
rx_buf_fail: rx_buf_fail:
kfree(dev); free_netdev(dev);
device_fail: device_fail:
return -ENODEV; return -ENODEV;
} }
...@@ -305,22 +312,16 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_ ...@@ -305,22 +312,16 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
static void __devexit xircom_remove(struct pci_dev *pdev) static void __devexit xircom_remove(struct pci_dev *pdev)
{ {
struct net_device *dev = pci_get_drvdata(pdev); struct net_device *dev = pci_get_drvdata(pdev);
struct xircom_private *card; struct xircom_private *card = dev->priv;
enter("xircom_remove"); enter("xircom_remove");
if (dev!=NULL) {
card=dev->priv;
if (card!=NULL) {
if (card->rx_buffer!=NULL)
pci_free_consistent(pdev,8192,card->rx_buffer,card->rx_dma_handle); pci_free_consistent(pdev,8192,card->rx_buffer,card->rx_dma_handle);
card->rx_buffer = NULL;
if (card->tx_buffer!=NULL)
pci_free_consistent(pdev,8192,card->tx_buffer,card->tx_dma_handle); pci_free_consistent(pdev,8192,card->tx_buffer,card->tx_dma_handle);
card->tx_buffer = NULL;
}
}
release_region(dev->base_addr, 128); release_region(dev->base_addr, 128);
unregister_netdev(dev); unregister_netdev(dev);
free_netdev(dev); free_netdev(dev);
pci_set_drvdata(pdev, NULL);
leave("xircom_remove"); leave("xircom_remove");
} }
......
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