pcmcia: Fix resource leaks in yenta_probe() and _close()
There are some resource leaks in yenta_probe() and _close(). I fixed the following issues with some code cleanups. Thanks to Dominik's suggestions. On the error path in yenta_probe(): - a requested irq is not released - yenta_free_resources() and pci_set_drvdata(dev, NULL) are not called In yenta_close(): - kfree(sock) is not called - sock->base is always set to non-NULL when yenta_close() is called, therefore the check in yenta_close() is not necessary. Signed-off-by: Takeshi Yoshimura <yos@sslab.ics.keio.ac.jp> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
This commit is contained in:
parent
2fb22a8042
commit
d19319affb
|
@ -801,13 +801,13 @@ static void yenta_close(struct pci_dev *dev)
|
||||||
else
|
else
|
||||||
del_timer_sync(&sock->poll_timer);
|
del_timer_sync(&sock->poll_timer);
|
||||||
|
|
||||||
if (sock->base)
|
iounmap(sock->base);
|
||||||
iounmap(sock->base);
|
|
||||||
yenta_free_resources(sock);
|
yenta_free_resources(sock);
|
||||||
|
|
||||||
pci_release_regions(dev);
|
pci_release_regions(dev);
|
||||||
pci_disable_device(dev);
|
pci_disable_device(dev);
|
||||||
pci_set_drvdata(dev, NULL);
|
pci_set_drvdata(dev, NULL);
|
||||||
|
kfree(sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1254,25 +1254,34 @@ static int yenta_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||||
|
|
||||||
/* Register it with the pcmcia layer.. */
|
/* Register it with the pcmcia layer.. */
|
||||||
ret = pcmcia_register_socket(&socket->socket);
|
ret = pcmcia_register_socket(&socket->socket);
|
||||||
if (ret == 0) {
|
if (ret)
|
||||||
/* Add the yenta register attributes */
|
goto free_irq;
|
||||||
ret = device_create_file(&dev->dev, &dev_attr_yenta_registers);
|
|
||||||
if (ret == 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* error path... */
|
/* Add the yenta register attributes */
|
||||||
pcmcia_unregister_socket(&socket->socket);
|
ret = device_create_file(&dev->dev, &dev_attr_yenta_registers);
|
||||||
}
|
if (ret)
|
||||||
|
goto unregister_socket;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* error path... */
|
||||||
|
unregister_socket:
|
||||||
|
pcmcia_unregister_socket(&socket->socket);
|
||||||
|
free_irq:
|
||||||
|
if (socket->cb_irq)
|
||||||
|
free_irq(socket->cb_irq, socket);
|
||||||
|
else
|
||||||
|
del_timer_sync(&socket->poll_timer);
|
||||||
unmap:
|
unmap:
|
||||||
iounmap(socket->base);
|
iounmap(socket->base);
|
||||||
|
yenta_free_resources(socket);
|
||||||
release:
|
release:
|
||||||
pci_release_regions(dev);
|
pci_release_regions(dev);
|
||||||
disable:
|
disable:
|
||||||
pci_disable_device(dev);
|
pci_disable_device(dev);
|
||||||
free:
|
free:
|
||||||
|
pci_set_drvdata(dev, NULL);
|
||||||
kfree(socket);
|
kfree(socket);
|
||||||
out:
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue