Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 198789
b: refs/heads/master
c: 2407d77
h: refs/heads/master
i:
  198787: 268ffc1
v: v3
  • Loading branch information
Matthew Garrett authored and Linus Torvalds committed May 27, 2010
1 parent 9aa6bec commit 64c3e0c
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 47 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5fedc4a282f0c6f5be5e4bebc8840f6022153bb3
refs/heads/master: 2407d77a1a013b88ee3b817f2b934e420e5376f5
130 changes: 84 additions & 46 deletions trunk/drivers/char/ipmi/ipmi_si_intf.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ static int num_max_busy_us;

static int unload_when_empty = 1;

static int add_smi(struct smi_info *smi);
static int try_smi_init(struct smi_info *smi);
static void cleanup_one_si(struct smi_info *to_clean);

Expand Down Expand Up @@ -1785,7 +1786,9 @@ static int hotmod_handler(const char *val, struct kernel_param *kp)
info->irq_setup = std_irq_setup;
info->slave_addr = ipmb;

try_smi_init(info);
if (!add_smi(info))
if (try_smi_init(info))
cleanup_one_si(info);
} else {
/* remove */
struct smi_info *e, *tmp_e;
Expand Down Expand Up @@ -1871,7 +1874,9 @@ static __devinit void hardcode_find_bmc(void)
info->irq_setup = std_irq_setup;
info->slave_addr = slave_addrs[i];

try_smi_init(info);
if (!add_smi(info))
if (try_smi_init(info))
cleanup_one_si(info);
}
}

Expand Down Expand Up @@ -2069,7 +2074,7 @@ static __devinit int try_init_spmi(struct SPMITable *spmi)
}
info->io.addr_data = spmi->addr.address;

try_smi_init(info);
add_smi(info);

return 0;
}
Expand Down Expand Up @@ -2167,7 +2172,7 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev,
info->dev = &acpi_dev->dev;
pnp_set_drvdata(dev, info);

return try_smi_init(info);
return add_smi(info);

err_free:
kfree(info);
Expand Down Expand Up @@ -2326,7 +2331,7 @@ static __devinit void try_init_dmi(struct dmi_ipmi_data *ipmi_data)
if (info->irq)
info->irq_setup = std_irq_setup;

try_smi_init(info);
add_smi(info);
}

static void __devinit dmi_find_bmc(void)
Expand Down Expand Up @@ -2429,7 +2434,7 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev,
info->dev = &pdev->dev;
pci_set_drvdata(pdev, info);

return try_smi_init(info);
return add_smi(info);
}

static void __devexit ipmi_pci_remove(struct pci_dev *pdev)
Expand Down Expand Up @@ -2542,7 +2547,7 @@ static int __devinit ipmi_of_probe(struct of_device *dev,

dev_set_drvdata(&dev->dev, info);

return try_smi_init(info);
return add_smi(info);
}

static int __devexit ipmi_of_remove(struct of_device *dev)
Expand Down Expand Up @@ -2971,14 +2976,16 @@ static __devinit void default_find_bmc(void)
info->io.regsize = DEFAULT_REGSPACING;
info->io.regshift = 0;

if (try_smi_init(info) == 0) {
/* Found one... */
printk(KERN_INFO "ipmi_si: Found default %s state"
" machine at %s address 0x%lx\n",
si_to_str[info->si_type],
addr_space_to_str[info->io.addr_type],
info->io.addr_data);
return;
if (add_smi(info) == 0) {
if ((try_smi_init(info)) == 0) {
/* Found one... */
printk(KERN_INFO "ipmi_si: Found default %s"
" state machine at %s address 0x%lx\n",
si_to_str[info->si_type],
addr_space_to_str[info->io.addr_type],
info->io.addr_data);
} else
cleanup_one_si(info);
}
}
}
Expand All @@ -2997,32 +3004,48 @@ static int is_new_interface(struct smi_info *info)
return 1;
}

static int try_smi_init(struct smi_info *new_smi)
static int add_smi(struct smi_info *new_smi)
{
int rv;
int i;

printk(KERN_INFO "ipmi_si: Trying %s-specified %s state"
" machine at %s address 0x%lx, slave address 0x%x,"
" irq %d\n",
ipmi_addr_src_to_str[new_smi->addr_source],
si_to_str[new_smi->si_type],
addr_space_to_str[new_smi->io.addr_type],
new_smi->io.addr_data,
new_smi->slave_addr, new_smi->irq);
int rv = 0;

printk(KERN_INFO "ipmi_si: Adding %s-specified %s state machine",
ipmi_addr_src_to_str[new_smi->addr_source],
si_to_str[new_smi->si_type]);
mutex_lock(&smi_infos_lock);
if (!is_new_interface(new_smi)) {
printk(KERN_WARNING "ipmi_si: duplicate interface\n");
printk(KERN_CONT ": duplicate interface\n");
rv = -EBUSY;
goto out_err;
}

printk(KERN_CONT "\n");

/* So we know not to free it unless we have allocated one. */
new_smi->intf = NULL;
new_smi->si_sm = NULL;
new_smi->handlers = NULL;

list_add_tail(&new_smi->link, &smi_infos);

out_err:
mutex_unlock(&smi_infos_lock);
return rv;
}

static int try_smi_init(struct smi_info *new_smi)
{
int rv = 0;
int i;

printk(KERN_INFO "ipmi_si: Trying %s-specified %s state"
" machine at %s address 0x%lx, slave address 0x%x,"
" irq %d\n",
ipmi_addr_src_to_str[new_smi->addr_source],
si_to_str[new_smi->si_type],
addr_space_to_str[new_smi->io.addr_type],
new_smi->io.addr_data,
new_smi->slave_addr, new_smi->irq);

switch (new_smi->si_type) {
case SI_KCS:
new_smi->handlers = &kcs_smi_handlers;
Expand Down Expand Up @@ -3183,10 +3206,6 @@ static int try_smi_init(struct smi_info *new_smi)
goto out_err_stop_timer;
}

list_add_tail(&new_smi->link, &smi_infos);

mutex_unlock(&smi_infos_lock);

printk(KERN_INFO "IPMI %s interface initialized\n",
si_to_str[new_smi->si_type]);

Expand All @@ -3197,11 +3216,17 @@ static int try_smi_init(struct smi_info *new_smi)
wait_for_timer_and_thread(new_smi);

out_err:
if (new_smi->intf)
new_smi->interrupt_disabled = 1;

if (new_smi->intf) {
ipmi_unregister_smi(new_smi->intf);
new_smi->intf = NULL;
}

if (new_smi->irq_cleanup)
if (new_smi->irq_cleanup) {
new_smi->irq_cleanup(new_smi);
new_smi->irq_cleanup = NULL;
}

/*
* Wait until we know that we are out of any interrupt
Expand All @@ -3214,18 +3239,21 @@ static int try_smi_init(struct smi_info *new_smi)
if (new_smi->handlers)
new_smi->handlers->cleanup(new_smi->si_sm);
kfree(new_smi->si_sm);
new_smi->si_sm = NULL;
}
if (new_smi->addr_source_cleanup)
if (new_smi->addr_source_cleanup) {
new_smi->addr_source_cleanup(new_smi);
if (new_smi->io_cleanup)
new_smi->addr_source_cleanup = NULL;
}
if (new_smi->io_cleanup) {
new_smi->io_cleanup(new_smi);
new_smi->io_cleanup = NULL;
}

if (new_smi->dev_registered)
if (new_smi->dev_registered) {
platform_device_unregister(new_smi->pdev);

kfree(new_smi);

mutex_unlock(&smi_infos_lock);
new_smi->dev_registered = 0;
}

return rv;
}
Expand All @@ -3235,6 +3263,7 @@ static __devinit int init_ipmi_si(void)
int i;
char *str;
int rv;
struct smi_info *e;

if (initialized)
return 0;
Expand Down Expand Up @@ -3292,15 +3321,21 @@ static __devinit int init_ipmi_si(void)
of_register_platform_driver(&ipmi_of_platform_driver);
#endif

mutex_lock(&smi_infos_lock);
list_for_each_entry(e, &smi_infos, link) {
if (!e->si_sm)
try_smi_init(e);
}
mutex_unlock(&smi_infos_lock);

if (si_trydefaults) {
mutex_lock(&smi_infos_lock);
if (list_empty(&smi_infos)) {
/* No BMC was found, try defaults. */
mutex_unlock(&smi_infos_lock);
default_find_bmc();
} else {
} else
mutex_unlock(&smi_infos_lock);
}
}

mutex_lock(&smi_infos_lock);
Expand All @@ -3326,7 +3361,7 @@ module_init(init_ipmi_si);

static void cleanup_one_si(struct smi_info *to_clean)
{
int rv;
int rv = 0;
unsigned long flags;

if (!to_clean)
Expand Down Expand Up @@ -3370,14 +3405,17 @@ static void cleanup_one_si(struct smi_info *to_clean)
schedule_timeout_uninterruptible(1);
}

rv = ipmi_unregister_smi(to_clean->intf);
if (to_clean->intf)
rv = ipmi_unregister_smi(to_clean->intf);

if (rv) {
printk(KERN_ERR
"ipmi_si: Unable to unregister device: errno=%d\n",
rv);
}

to_clean->handlers->cleanup(to_clean->si_sm);
if (to_clean->handlers)
to_clean->handlers->cleanup(to_clean->si_sm);

kfree(to_clean->si_sm);

Expand Down

0 comments on commit 64c3e0c

Please sign in to comment.