diff options
Diffstat (limited to 'drivers/char/ipmi')
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 65 |
1 files changed, 49 insertions, 16 deletions
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index b532d613fb5b..3822b4f49c84 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -1804,9 +1804,12 @@ static int hotmod_handler(const char *val, struct kernel_param *kp) | |||
1804 | info->irq_setup = std_irq_setup; | 1804 | info->irq_setup = std_irq_setup; |
1805 | info->slave_addr = ipmb; | 1805 | info->slave_addr = ipmb; |
1806 | 1806 | ||
1807 | if (!add_smi(info)) | 1807 | if (!add_smi(info)) { |
1808 | if (try_smi_init(info)) | 1808 | if (try_smi_init(info)) |
1809 | cleanup_one_si(info); | 1809 | cleanup_one_si(info); |
1810 | } else { | ||
1811 | kfree(info); | ||
1812 | } | ||
1810 | } else { | 1813 | } else { |
1811 | /* remove */ | 1814 | /* remove */ |
1812 | struct smi_info *e, *tmp_e; | 1815 | struct smi_info *e, *tmp_e; |
@@ -1890,9 +1893,12 @@ static __devinit void hardcode_find_bmc(void) | |||
1890 | info->irq_setup = std_irq_setup; | 1893 | info->irq_setup = std_irq_setup; |
1891 | info->slave_addr = slave_addrs[i]; | 1894 | info->slave_addr = slave_addrs[i]; |
1892 | 1895 | ||
1893 | if (!add_smi(info)) | 1896 | if (!add_smi(info)) { |
1894 | if (try_smi_init(info)) | 1897 | if (try_smi_init(info)) |
1895 | cleanup_one_si(info); | 1898 | cleanup_one_si(info); |
1899 | } else { | ||
1900 | kfree(info); | ||
1901 | } | ||
1896 | } | 1902 | } |
1897 | } | 1903 | } |
1898 | 1904 | ||
@@ -1965,8 +1971,8 @@ static int acpi_gpe_irq_setup(struct smi_info *info) | |||
1965 | 1971 | ||
1966 | /* | 1972 | /* |
1967 | * Defined at | 1973 | * Defined at |
1968 | * http://h21007.www2.hp.com/dspp/files/unprotected/devresource/ | 1974 | * http://h21007.www2.hp.com/portal/download/files |
1969 | * Docs/TechPapers/IA64/hpspmi.pdf | 1975 | * /unprot/hpspmi.pdf |
1970 | */ | 1976 | */ |
1971 | struct SPMITable { | 1977 | struct SPMITable { |
1972 | s8 Signature[4]; | 1978 | s8 Signature[4]; |
@@ -2013,18 +2019,12 @@ struct SPMITable { | |||
2013 | static __devinit int try_init_spmi(struct SPMITable *spmi) | 2019 | static __devinit int try_init_spmi(struct SPMITable *spmi) |
2014 | { | 2020 | { |
2015 | struct smi_info *info; | 2021 | struct smi_info *info; |
2016 | u8 addr_space; | ||
2017 | 2022 | ||
2018 | if (spmi->IPMIlegacy != 1) { | 2023 | if (spmi->IPMIlegacy != 1) { |
2019 | printk(KERN_INFO PFX "Bad SPMI legacy %d\n", spmi->IPMIlegacy); | 2024 | printk(KERN_INFO PFX "Bad SPMI legacy %d\n", spmi->IPMIlegacy); |
2020 | return -ENODEV; | 2025 | return -ENODEV; |
2021 | } | 2026 | } |
2022 | 2027 | ||
2023 | if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) | ||
2024 | addr_space = IPMI_MEM_ADDR_SPACE; | ||
2025 | else | ||
2026 | addr_space = IPMI_IO_ADDR_SPACE; | ||
2027 | |||
2028 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 2028 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
2029 | if (!info) { | 2029 | if (!info) { |
2030 | printk(KERN_ERR PFX "Could not allocate SI data (3)\n"); | 2030 | printk(KERN_ERR PFX "Could not allocate SI data (3)\n"); |
@@ -2088,7 +2088,13 @@ static __devinit int try_init_spmi(struct SPMITable *spmi) | |||
2088 | } | 2088 | } |
2089 | info->io.addr_data = spmi->addr.address; | 2089 | info->io.addr_data = spmi->addr.address; |
2090 | 2090 | ||
2091 | add_smi(info); | 2091 | pr_info("ipmi_si: SPMI: %s %#lx regsize %d spacing %d irq %d\n", |
2092 | (info->io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem", | ||
2093 | info->io.addr_data, info->io.regsize, info->io.regspacing, | ||
2094 | info->irq); | ||
2095 | |||
2096 | if (add_smi(info)) | ||
2097 | kfree(info); | ||
2092 | 2098 | ||
2093 | return 0; | 2099 | return 0; |
2094 | } | 2100 | } |
@@ -2176,6 +2182,14 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, | |||
2176 | info->io.addr_data = res->start; | 2182 | info->io.addr_data = res->start; |
2177 | 2183 | ||
2178 | info->io.regspacing = DEFAULT_REGSPACING; | 2184 | info->io.regspacing = DEFAULT_REGSPACING; |
2185 | res = pnp_get_resource(dev, | ||
2186 | (info->io.addr_type == IPMI_IO_ADDR_SPACE) ? | ||
2187 | IORESOURCE_IO : IORESOURCE_MEM, | ||
2188 | 1); | ||
2189 | if (res) { | ||
2190 | if (res->start > info->io.addr_data) | ||
2191 | info->io.regspacing = res->start - info->io.addr_data; | ||
2192 | } | ||
2179 | info->io.regsize = DEFAULT_REGSPACING; | 2193 | info->io.regsize = DEFAULT_REGSPACING; |
2180 | info->io.regshift = 0; | 2194 | info->io.regshift = 0; |
2181 | 2195 | ||
@@ -2196,7 +2210,10 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, | |||
2196 | res, info->io.regsize, info->io.regspacing, | 2210 | res, info->io.regsize, info->io.regspacing, |
2197 | info->irq); | 2211 | info->irq); |
2198 | 2212 | ||
2199 | return add_smi(info); | 2213 | if (add_smi(info)) |
2214 | goto err_free; | ||
2215 | |||
2216 | return 0; | ||
2200 | 2217 | ||
2201 | err_free: | 2218 | err_free: |
2202 | kfree(info); | 2219 | kfree(info); |
@@ -2354,7 +2371,13 @@ static __devinit void try_init_dmi(struct dmi_ipmi_data *ipmi_data) | |||
2354 | if (info->irq) | 2371 | if (info->irq) |
2355 | info->irq_setup = std_irq_setup; | 2372 | info->irq_setup = std_irq_setup; |
2356 | 2373 | ||
2357 | add_smi(info); | 2374 | pr_info("ipmi_si: SMBIOS: %s %#lx regsize %d spacing %d irq %d\n", |
2375 | (info->io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem", | ||
2376 | info->io.addr_data, info->io.regsize, info->io.regspacing, | ||
2377 | info->irq); | ||
2378 | |||
2379 | if (add_smi(info)) | ||
2380 | kfree(info); | ||
2358 | } | 2381 | } |
2359 | 2382 | ||
2360 | static void __devinit dmi_find_bmc(void) | 2383 | static void __devinit dmi_find_bmc(void) |
@@ -2460,7 +2483,10 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, | |||
2460 | &pdev->resource[0], info->io.regsize, info->io.regspacing, | 2483 | &pdev->resource[0], info->io.regsize, info->io.regspacing, |
2461 | info->irq); | 2484 | info->irq); |
2462 | 2485 | ||
2463 | return add_smi(info); | 2486 | if (add_smi(info)) |
2487 | kfree(info); | ||
2488 | |||
2489 | return 0; | ||
2464 | } | 2490 | } |
2465 | 2491 | ||
2466 | static void __devexit ipmi_pci_remove(struct pci_dev *pdev) | 2492 | static void __devexit ipmi_pci_remove(struct pci_dev *pdev) |
@@ -2573,7 +2599,12 @@ static int __devinit ipmi_of_probe(struct platform_device *dev, | |||
2573 | 2599 | ||
2574 | dev_set_drvdata(&dev->dev, info); | 2600 | dev_set_drvdata(&dev->dev, info); |
2575 | 2601 | ||
2576 | return add_smi(info); | 2602 | if (add_smi(info)) { |
2603 | kfree(info); | ||
2604 | return -EBUSY; | ||
2605 | } | ||
2606 | |||
2607 | return 0; | ||
2577 | } | 2608 | } |
2578 | 2609 | ||
2579 | static int __devexit ipmi_of_remove(struct platform_device *dev) | 2610 | static int __devexit ipmi_of_remove(struct platform_device *dev) |
@@ -3006,6 +3037,8 @@ static __devinit void default_find_bmc(void) | |||
3006 | info->io.addr_data); | 3037 | info->io.addr_data); |
3007 | } else | 3038 | } else |
3008 | cleanup_one_si(info); | 3039 | cleanup_one_si(info); |
3040 | } else { | ||
3041 | kfree(info); | ||
3009 | } | 3042 | } |
3010 | } | 3043 | } |
3011 | } | 3044 | } |
@@ -3033,7 +3066,7 @@ static int add_smi(struct smi_info *new_smi) | |||
3033 | si_to_str[new_smi->si_type]); | 3066 | si_to_str[new_smi->si_type]); |
3034 | mutex_lock(&smi_infos_lock); | 3067 | mutex_lock(&smi_infos_lock); |
3035 | if (!is_new_interface(new_smi)) { | 3068 | if (!is_new_interface(new_smi)) { |
3036 | printk(KERN_CONT PFX "duplicate interface\n"); | 3069 | printk(KERN_CONT " duplicate interface\n"); |
3037 | rv = -EBUSY; | 3070 | rv = -EBUSY; |
3038 | goto out_err; | 3071 | goto out_err; |
3039 | } | 3072 | } |