]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] vlsi_ir leak, allocation and freeing fixes
authorAlexander Viro <viro@parcelfarce.linux.theplanet.co.uk>
Tue, 24 Feb 2004 15:17:51 +0000 (10:17 -0500)
committerJeff Garzik <jgarzik@redhat.com>
Tue, 24 Feb 2004 15:17:51 +0000 (10:17 -0500)
* 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.

drivers/net/irda/vlsi_ir.c

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