Commit 5576fb86 authored by Jean Delvare's avatar Jean Delvare Committed by Borislav Petkov

amd8111_edac: Fix leaks in probe error paths

Both probe error paths are incomplete and leak memory and device
references. Add the missing cleanups.
Signed-off-by: default avatarJean Delvare <jdelvare@suse.de>
Link: http://lkml.kernel.org/r/20140224154534.5a3b797a@endymion.delvare
Cc: Mauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
parent 0e089c18
...@@ -350,6 +350,7 @@ static int amd8111_dev_probe(struct pci_dev *dev, ...@@ -350,6 +350,7 @@ static int amd8111_dev_probe(struct pci_dev *dev,
const struct pci_device_id *id) const struct pci_device_id *id)
{ {
struct amd8111_dev_info *dev_info = &amd8111_devices[id->driver_data]; struct amd8111_dev_info *dev_info = &amd8111_devices[id->driver_data];
int ret = -ENODEV;
dev_info->dev = pci_get_device(PCI_VENDOR_ID_AMD, dev_info->dev = pci_get_device(PCI_VENDOR_ID_AMD,
dev_info->err_dev, NULL); dev_info->err_dev, NULL);
...@@ -359,16 +360,15 @@ static int amd8111_dev_probe(struct pci_dev *dev, ...@@ -359,16 +360,15 @@ static int amd8111_dev_probe(struct pci_dev *dev,
"vendor %x, device %x, name %s\n", "vendor %x, device %x, name %s\n",
PCI_VENDOR_ID_AMD, dev_info->err_dev, PCI_VENDOR_ID_AMD, dev_info->err_dev,
dev_info->ctl_name); dev_info->ctl_name);
return -ENODEV; goto err;
} }
if (pci_enable_device(dev_info->dev)) { if (pci_enable_device(dev_info->dev)) {
pci_dev_put(dev_info->dev);
printk(KERN_ERR "failed to enable:" printk(KERN_ERR "failed to enable:"
"vendor %x, device %x, name %s\n", "vendor %x, device %x, name %s\n",
PCI_VENDOR_ID_AMD, dev_info->err_dev, PCI_VENDOR_ID_AMD, dev_info->err_dev,
dev_info->ctl_name); dev_info->ctl_name);
return -ENODEV; goto err_dev_put;
} }
/* /*
...@@ -381,8 +381,10 @@ static int amd8111_dev_probe(struct pci_dev *dev, ...@@ -381,8 +381,10 @@ static int amd8111_dev_probe(struct pci_dev *dev,
edac_device_alloc_ctl_info(0, dev_info->ctl_name, 1, edac_device_alloc_ctl_info(0, dev_info->ctl_name, 1,
NULL, 0, 0, NULL, 0, 0,
NULL, 0, dev_info->edac_idx); NULL, 0, dev_info->edac_idx);
if (!dev_info->edac_dev) if (!dev_info->edac_dev) {
return -ENOMEM; ret = -ENOMEM;
goto err_dev_put;
}
dev_info->edac_dev->pvt_info = dev_info; dev_info->edac_dev->pvt_info = dev_info;
dev_info->edac_dev->dev = &dev_info->dev->dev; dev_info->edac_dev->dev = &dev_info->dev->dev;
...@@ -399,8 +401,7 @@ static int amd8111_dev_probe(struct pci_dev *dev, ...@@ -399,8 +401,7 @@ static int amd8111_dev_probe(struct pci_dev *dev,
if (edac_device_add_device(dev_info->edac_dev) > 0) { if (edac_device_add_device(dev_info->edac_dev) > 0) {
printk(KERN_ERR "failed to add edac_dev for %s\n", printk(KERN_ERR "failed to add edac_dev for %s\n",
dev_info->ctl_name); dev_info->ctl_name);
edac_device_free_ctl_info(dev_info->edac_dev); goto err_edac_free_ctl;
return -ENODEV;
} }
printk(KERN_INFO "added one edac_dev on AMD8111 " printk(KERN_INFO "added one edac_dev on AMD8111 "
...@@ -409,6 +410,13 @@ static int amd8111_dev_probe(struct pci_dev *dev, ...@@ -409,6 +410,13 @@ static int amd8111_dev_probe(struct pci_dev *dev,
dev_info->ctl_name); dev_info->ctl_name);
return 0; return 0;
err_edac_free_ctl:
edac_device_free_ctl_info(dev_info->edac_dev);
err_dev_put:
pci_dev_put(dev_info->dev);
err:
return ret;
} }
static void amd8111_dev_remove(struct pci_dev *dev) static void amd8111_dev_remove(struct pci_dev *dev)
...@@ -437,6 +445,7 @@ static int amd8111_pci_probe(struct pci_dev *dev, ...@@ -437,6 +445,7 @@ static int amd8111_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id) const struct pci_device_id *id)
{ {
struct amd8111_pci_info *pci_info = &amd8111_pcis[id->driver_data]; struct amd8111_pci_info *pci_info = &amd8111_pcis[id->driver_data];
int ret = -ENODEV;
pci_info->dev = pci_get_device(PCI_VENDOR_ID_AMD, pci_info->dev = pci_get_device(PCI_VENDOR_ID_AMD,
pci_info->err_dev, NULL); pci_info->err_dev, NULL);
...@@ -446,16 +455,15 @@ static int amd8111_pci_probe(struct pci_dev *dev, ...@@ -446,16 +455,15 @@ static int amd8111_pci_probe(struct pci_dev *dev,
"vendor %x, device %x, name %s\n", "vendor %x, device %x, name %s\n",
PCI_VENDOR_ID_AMD, pci_info->err_dev, PCI_VENDOR_ID_AMD, pci_info->err_dev,
pci_info->ctl_name); pci_info->ctl_name);
return -ENODEV; goto err;
} }
if (pci_enable_device(pci_info->dev)) { if (pci_enable_device(pci_info->dev)) {
pci_dev_put(pci_info->dev);
printk(KERN_ERR "failed to enable:" printk(KERN_ERR "failed to enable:"
"vendor %x, device %x, name %s\n", "vendor %x, device %x, name %s\n",
PCI_VENDOR_ID_AMD, pci_info->err_dev, PCI_VENDOR_ID_AMD, pci_info->err_dev,
pci_info->ctl_name); pci_info->ctl_name);
return -ENODEV; goto err_dev_put;
} }
/* /*
...@@ -465,8 +473,10 @@ static int amd8111_pci_probe(struct pci_dev *dev, ...@@ -465,8 +473,10 @@ static int amd8111_pci_probe(struct pci_dev *dev,
*/ */
pci_info->edac_idx = edac_pci_alloc_index(); pci_info->edac_idx = edac_pci_alloc_index();
pci_info->edac_dev = edac_pci_alloc_ctl_info(0, pci_info->ctl_name); pci_info->edac_dev = edac_pci_alloc_ctl_info(0, pci_info->ctl_name);
if (!pci_info->edac_dev) if (!pci_info->edac_dev) {
return -ENOMEM; ret = -ENOMEM;
goto err_dev_put;
}
pci_info->edac_dev->pvt_info = pci_info; pci_info->edac_dev->pvt_info = pci_info;
pci_info->edac_dev->dev = &pci_info->dev->dev; pci_info->edac_dev->dev = &pci_info->dev->dev;
...@@ -483,8 +493,7 @@ static int amd8111_pci_probe(struct pci_dev *dev, ...@@ -483,8 +493,7 @@ static int amd8111_pci_probe(struct pci_dev *dev,
if (edac_pci_add_device(pci_info->edac_dev, pci_info->edac_idx) > 0) { if (edac_pci_add_device(pci_info->edac_dev, pci_info->edac_idx) > 0) {
printk(KERN_ERR "failed to add edac_pci for %s\n", printk(KERN_ERR "failed to add edac_pci for %s\n",
pci_info->ctl_name); pci_info->ctl_name);
edac_pci_free_ctl_info(pci_info->edac_dev); goto err_edac_free_ctl;
return -ENODEV;
} }
printk(KERN_INFO "added one edac_pci on AMD8111 " printk(KERN_INFO "added one edac_pci on AMD8111 "
...@@ -493,6 +502,13 @@ static int amd8111_pci_probe(struct pci_dev *dev, ...@@ -493,6 +502,13 @@ static int amd8111_pci_probe(struct pci_dev *dev,
pci_info->ctl_name); pci_info->ctl_name);
return 0; return 0;
err_edac_free_ctl:
edac_pci_free_ctl_info(pci_info->edac_dev);
err_dev_put:
pci_dev_put(pci_info->dev);
err:
return ret;
} }
static void amd8111_pci_remove(struct pci_dev *dev) static void amd8111_pci_remove(struct pci_dev *dev)
......
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