Commit 2d8f0320 authored by Alexander Viro's avatar Alexander Viro Committed by Jeff Garzik

[PATCH] vlsi_ir leak, allocation and freeing fixes

	* switched to sane allocation
	* fixes race on removal - we unregistered too late
	* contrary to the comment, device had no destructor, so removal
had leaked - unregister_netdev() doesn't trigger freeing in that driver.
	* fixes freeing (kfree -> free_netdev)

Otherwise the same story as with previous patch - irda-related part of NE*
that got lost.
parent fe89aafd
...@@ -1723,8 +1723,6 @@ static int vlsi_irda_init(struct net_device *ndev) ...@@ -1723,8 +1723,6 @@ static int vlsi_irda_init(struct net_device *ndev)
irda_qos_bits_to_value(&idev->qos); irda_qos_bits_to_value(&idev->qos);
irda_device_setup(ndev);
/* currently no public media definitions for IrDA */ /* currently no public media definitions for IrDA */
ndev->flags |= IFF_PORTSEL | IFF_AUTOMEDIA; ndev->flags |= IFF_PORTSEL | IFF_AUTOMEDIA;
...@@ -1748,8 +1746,6 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1748,8 +1746,6 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{ {
struct net_device *ndev; struct net_device *ndev;
vlsi_irda_dev_t *idev; vlsi_irda_dev_t *idev;
int alloc_size;
if (pci_enable_device(pdev)) if (pci_enable_device(pdev))
goto out; goto out;
...@@ -1765,38 +1761,33 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1765,38 +1761,33 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto out_disable; goto out_disable;
} }
alloc_size = sizeof(*ndev) + sizeof(*idev); ndev = alloc_irdadev(sizeof(*idev));
ndev = (struct net_device *) kmalloc (alloc_size, GFP_KERNEL);
if (ndev==NULL) { if (ndev==NULL) {
ERROR("%s: Unable to allocate device memory.\n", __FUNCTION__); ERROR("%s: Unable to allocate device memory.\n", __FUNCTION__);
goto out_disable; goto out_disable;
} }
memset(ndev, 0, alloc_size); idev = ndev->priv;
idev = (vlsi_irda_dev_t *) (ndev + 1);
ndev->priv = (void *) idev;
spin_lock_init(&idev->lock); spin_lock_init(&idev->lock);
init_MUTEX(&idev->sem); init_MUTEX(&idev->sem);
down(&idev->sem); down(&idev->sem);
idev->pdev = pdev; idev->pdev = pdev;
ndev->init = vlsi_irda_init;
strcpy(ndev->name,"irda%d"); if (vlsi_irda_init(ndev) < 0)
if (register_netdev(ndev)) { goto out_freedev;
if (register_netdev(ndev) < 0) {
ERROR("%s: register_netdev failed\n", __FUNCTION__); ERROR("%s: register_netdev failed\n", __FUNCTION__);
goto out_freedev; goto out_freedev;
} }
idev->proc_entry = NULL;
if (vlsi_proc_root != NULL) { if (vlsi_proc_root != NULL) {
struct proc_dir_entry *ent; struct proc_dir_entry *ent;
ent = create_proc_entry(ndev->name, S_IFREG|S_IRUGO, vlsi_proc_root); ent = create_proc_entry(ndev->name, S_IFREG|S_IRUGO, vlsi_proc_root);
if (!ent) { if (!ent) {
WARNING("%s: failed to create proc entry\n", __FUNCTION__); WARNING("%s: failed to create proc entry\n", __FUNCTION__);
idev->proc_entry = NULL;
} }
else { else {
ent->data = ndev; ent->data = ndev;
...@@ -1814,7 +1805,7 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1814,7 +1805,7 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id)
out_freedev: out_freedev:
up(&idev->sem); up(&idev->sem);
kfree(ndev); free_netdev(ndev);
out_disable: out_disable:
pci_disable_device(pdev); pci_disable_device(pdev);
out: out:
...@@ -1832,6 +1823,8 @@ static void __devexit vlsi_irda_remove(struct pci_dev *pdev) ...@@ -1832,6 +1823,8 @@ static void __devexit vlsi_irda_remove(struct pci_dev *pdev)
return; return;
} }
unregister_netdev(ndev);
idev = ndev->priv; idev = ndev->priv;
down(&idev->sem); down(&idev->sem);
if (idev->proc_entry) { if (idev->proc_entry) {
...@@ -1840,10 +1833,7 @@ static void __devexit vlsi_irda_remove(struct pci_dev *pdev) ...@@ -1840,10 +1833,7 @@ static void __devexit vlsi_irda_remove(struct pci_dev *pdev)
} }
up(&idev->sem); up(&idev->sem);
unregister_netdev(ndev); free_netdev(ndev);
/* do not free - async completed by unregister_netdev()
* ndev->destructor called (if present) when going to free
*/
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
......
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