diff options
author | Corey Minyard <cminyard@mvista.com> | 2014-01-24 15:00:53 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-25 18:31:58 -0500 |
commit | d02b3709ff8efebfca0612d0ac2a6e31a91c13f4 (patch) | |
tree | b052ce0e547d884b9b86ef26f28d9e3355822462 | |
parent | e21404dc0ac7ac971c1e36274b48bb460463f4e5 (diff) |
ipmi: Cleanup error return
Return proper errors for a lot of IPMI failure cases. Also call
pci_disable_device when IPMI PCI devices are removed.
Signed-off-by: Corey Minyard <cminyard@mvista.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index a5e048fb8b38..671c3852d359 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -1849,11 +1849,15 @@ static int hotmod_handler(const char *val, struct kernel_param *kp) | |||
1849 | info->irq_setup = std_irq_setup; | 1849 | info->irq_setup = std_irq_setup; |
1850 | info->slave_addr = ipmb; | 1850 | info->slave_addr = ipmb; |
1851 | 1851 | ||
1852 | if (!add_smi(info)) { | 1852 | rv = add_smi(info); |
1853 | if (try_smi_init(info)) | 1853 | if (rv) { |
1854 | cleanup_one_si(info); | ||
1855 | } else { | ||
1856 | kfree(info); | 1854 | kfree(info); |
1855 | goto out; | ||
1856 | } | ||
1857 | rv = try_smi_init(info); | ||
1858 | if (rv) { | ||
1859 | cleanup_one_si(info); | ||
1860 | goto out; | ||
1857 | } | 1861 | } |
1858 | } else { | 1862 | } else { |
1859 | /* remove */ | 1863 | /* remove */ |
@@ -2067,6 +2071,7 @@ struct SPMITable { | |||
2067 | static int try_init_spmi(struct SPMITable *spmi) | 2071 | static int try_init_spmi(struct SPMITable *spmi) |
2068 | { | 2072 | { |
2069 | struct smi_info *info; | 2073 | struct smi_info *info; |
2074 | int rv; | ||
2070 | 2075 | ||
2071 | if (spmi->IPMIlegacy != 1) { | 2076 | if (spmi->IPMIlegacy != 1) { |
2072 | printk(KERN_INFO PFX "Bad SPMI legacy %d\n", spmi->IPMIlegacy); | 2077 | printk(KERN_INFO PFX "Bad SPMI legacy %d\n", spmi->IPMIlegacy); |
@@ -2141,10 +2146,11 @@ static int try_init_spmi(struct SPMITable *spmi) | |||
2141 | info->io.addr_data, info->io.regsize, info->io.regspacing, | 2146 | info->io.addr_data, info->io.regsize, info->io.regspacing, |
2142 | info->irq); | 2147 | info->irq); |
2143 | 2148 | ||
2144 | if (add_smi(info)) | 2149 | rv = add_smi(info); |
2150 | if (rv) | ||
2145 | kfree(info); | 2151 | kfree(info); |
2146 | 2152 | ||
2147 | return 0; | 2153 | return rv; |
2148 | } | 2154 | } |
2149 | 2155 | ||
2150 | static void spmi_find_bmc(void) | 2156 | static void spmi_find_bmc(void) |
@@ -2178,6 +2184,7 @@ static int ipmi_pnp_probe(struct pnp_dev *dev, | |||
2178 | acpi_handle handle; | 2184 | acpi_handle handle; |
2179 | acpi_status status; | 2185 | acpi_status status; |
2180 | unsigned long long tmp; | 2186 | unsigned long long tmp; |
2187 | int rv; | ||
2181 | 2188 | ||
2182 | acpi_dev = pnp_acpi_device(dev); | 2189 | acpi_dev = pnp_acpi_device(dev); |
2183 | if (!acpi_dev) | 2190 | if (!acpi_dev) |
@@ -2259,10 +2266,11 @@ static int ipmi_pnp_probe(struct pnp_dev *dev, | |||
2259 | res, info->io.regsize, info->io.regspacing, | 2266 | res, info->io.regsize, info->io.regspacing, |
2260 | info->irq); | 2267 | info->irq); |
2261 | 2268 | ||
2262 | if (add_smi(info)) | 2269 | rv = add_smi(info); |
2263 | goto err_free; | 2270 | if (rv) |
2271 | kfree(info); | ||
2264 | 2272 | ||
2265 | return 0; | 2273 | return rv; |
2266 | 2274 | ||
2267 | err_free: | 2275 | err_free: |
2268 | kfree(info); | 2276 | kfree(info); |
@@ -2566,16 +2574,20 @@ static int ipmi_pci_probe(struct pci_dev *pdev, | |||
2566 | &pdev->resource[0], info->io.regsize, info->io.regspacing, | 2574 | &pdev->resource[0], info->io.regsize, info->io.regspacing, |
2567 | info->irq); | 2575 | info->irq); |
2568 | 2576 | ||
2569 | if (add_smi(info)) | 2577 | rv = add_smi(info); |
2578 | if (rv) { | ||
2570 | kfree(info); | 2579 | kfree(info); |
2580 | pci_disable_device(pdev); | ||
2581 | } | ||
2571 | 2582 | ||
2572 | return 0; | 2583 | return rv; |
2573 | } | 2584 | } |
2574 | 2585 | ||
2575 | static void ipmi_pci_remove(struct pci_dev *pdev) | 2586 | static void ipmi_pci_remove(struct pci_dev *pdev) |
2576 | { | 2587 | { |
2577 | struct smi_info *info = pci_get_drvdata(pdev); | 2588 | struct smi_info *info = pci_get_drvdata(pdev); |
2578 | cleanup_one_si(info); | 2589 | cleanup_one_si(info); |
2590 | pci_disable_device(pdev); | ||
2579 | } | 2591 | } |
2580 | 2592 | ||
2581 | static struct pci_device_id ipmi_pci_devices[] = { | 2593 | static struct pci_device_id ipmi_pci_devices[] = { |
@@ -2670,9 +2682,10 @@ static int ipmi_probe(struct platform_device *dev) | |||
2670 | 2682 | ||
2671 | dev_set_drvdata(&dev->dev, info); | 2683 | dev_set_drvdata(&dev->dev, info); |
2672 | 2684 | ||
2673 | if (add_smi(info)) { | 2685 | ret = add_smi(info); |
2686 | if (ret) { | ||
2674 | kfree(info); | 2687 | kfree(info); |
2675 | return -EBUSY; | 2688 | return ret; |
2676 | } | 2689 | } |
2677 | #endif | 2690 | #endif |
2678 | return 0; | 2691 | return 0; |
@@ -2736,9 +2749,10 @@ static int ipmi_parisc_probe(struct parisc_device *dev) | |||
2736 | 2749 | ||
2737 | dev_set_drvdata(&dev->dev, info); | 2750 | dev_set_drvdata(&dev->dev, info); |
2738 | 2751 | ||
2739 | if (add_smi(info)) { | 2752 | rv = add_smi(info); |
2753 | if (rv) { | ||
2740 | kfree(info); | 2754 | kfree(info); |
2741 | return -EBUSY; | 2755 | return rv; |
2742 | } | 2756 | } |
2743 | 2757 | ||
2744 | return 0; | 2758 | return 0; |