Commit 6fb41cbd authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-linux-4.12' of git://github.com/cminyard/linux-ipmi

Pull IPMI updates from Corey Minyard:
 "A few fixes of things in the IPMI area, the watchdog would have issues
  at panic time cause by a recently introduced change, a problem with
  device numbering, one possible panic in the I2C driver (destined for
  stable).

  Nothing earth-shattering, but some things that need to go in"

* tag 'for-linux-4.12' of git://github.com/cminyard/linux-ipmi:
  ipmi/watchdog: fix wdog hang on panic waiting for ipmi response
  ipmi_si: use smi_num for init_name
  ipmi: bt-bmc: Add ast2500 compatible string
  ACPI / IPMI: change warning to debug on timeout
  ACPI / IPMI: allow ACPI_IPMI with IPMI_SSIF
  ipmi_ssif: use setup_timer
  ipmi: Fix kernel panic at ipmi_ssif_thread()
parents 5c6ba7d5 2c1175c2
...@@ -6,7 +6,9 @@ perform in-band IPMI communication with their host. ...@@ -6,7 +6,9 @@ perform in-band IPMI communication with their host.
Required properties: Required properties:
- compatible : should be "aspeed,ast2400-ibt-bmc" - compatible : should be one of
"aspeed,ast2400-ibt-bmc"
"aspeed,ast2500-ibt-bmc"
- reg: physical address and size of the registers - reg: physical address and size of the registers
Optional properties: Optional properties:
......
...@@ -256,7 +256,7 @@ config ACPI_PROCESSOR ...@@ -256,7 +256,7 @@ config ACPI_PROCESSOR
config ACPI_IPMI config ACPI_IPMI
tristate "IPMI" tristate "IPMI"
depends on IPMI_SI depends on IPMI_HANDLER
default n default n
help help
This driver enables the ACPI to access the BMC controller. And it This driver enables the ACPI to access the BMC controller. And it
......
...@@ -429,8 +429,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) ...@@ -429,8 +429,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data)
if (msg->recv_type == IPMI_RESPONSE_RECV_TYPE && if (msg->recv_type == IPMI_RESPONSE_RECV_TYPE &&
msg->msg.data_len == 1) { msg->msg.data_len == 1) {
if (msg->msg.data[0] == IPMI_TIMEOUT_COMPLETION_CODE) { if (msg->msg.data[0] == IPMI_TIMEOUT_COMPLETION_CODE) {
dev_WARN_ONCE(dev, true, dev_dbg_once(dev, "Unexpected response (timeout).\n");
"Unexpected response (timeout).\n");
tx_msg->msg_done = ACPI_IPMI_TIMEOUT; tx_msg->msg_done = ACPI_IPMI_TIMEOUT;
} }
goto out_comp; goto out_comp;
......
...@@ -523,6 +523,7 @@ static int bt_bmc_remove(struct platform_device *pdev) ...@@ -523,6 +523,7 @@ static int bt_bmc_remove(struct platform_device *pdev)
static const struct of_device_id bt_bmc_match[] = { static const struct of_device_id bt_bmc_match[] = {
{ .compatible = "aspeed,ast2400-ibt-bmc" }, { .compatible = "aspeed,ast2400-ibt-bmc" },
{ .compatible = "aspeed,ast2500-ibt-bmc" },
{ }, { },
}; };
......
...@@ -1954,7 +1954,9 @@ static int hotmod_handler(const char *val, struct kernel_param *kp) ...@@ -1954,7 +1954,9 @@ static int hotmod_handler(const char *val, struct kernel_param *kp)
kfree(info); kfree(info);
goto out; goto out;
} }
mutex_lock(&smi_infos_lock);
rv = try_smi_init(info); rv = try_smi_init(info);
mutex_unlock(&smi_infos_lock);
if (rv) { if (rv) {
cleanup_one_si(info); cleanup_one_si(info);
goto out; goto out;
...@@ -2042,8 +2044,10 @@ static int hardcode_find_bmc(void) ...@@ -2042,8 +2044,10 @@ static int hardcode_find_bmc(void)
info->slave_addr = slave_addrs[i]; info->slave_addr = slave_addrs[i];
if (!add_smi(info)) { if (!add_smi(info)) {
mutex_lock(&smi_infos_lock);
if (try_smi_init(info)) if (try_smi_init(info))
cleanup_one_si(info); cleanup_one_si(info);
mutex_unlock(&smi_infos_lock);
ret = 0; ret = 0;
} else { } else {
kfree(info); kfree(info);
...@@ -3492,6 +3496,11 @@ static int add_smi(struct smi_info *new_smi) ...@@ -3492,6 +3496,11 @@ static int add_smi(struct smi_info *new_smi)
return rv; return rv;
} }
/*
* Try to start up an interface. Must be called with smi_infos_lock
* held, primarily to keep smi_num consistent, we only one to do these
* one at a time.
*/
static int try_smi_init(struct smi_info *new_smi) static int try_smi_init(struct smi_info *new_smi)
{ {
int rv = 0; int rv = 0;
...@@ -3524,9 +3533,12 @@ static int try_smi_init(struct smi_info *new_smi) ...@@ -3524,9 +3533,12 @@ static int try_smi_init(struct smi_info *new_smi)
goto out_err; goto out_err;
} }
new_smi->intf_num = smi_num;
/* Do this early so it's available for logs. */ /* Do this early so it's available for logs. */
if (!new_smi->dev) { if (!new_smi->dev) {
init_name = kasprintf(GFP_KERNEL, "ipmi_si.%d", 0); init_name = kasprintf(GFP_KERNEL, "ipmi_si.%d",
new_smi->intf_num);
/* /*
* If we don't already have a device from something * If we don't already have a device from something
...@@ -3593,8 +3605,6 @@ static int try_smi_init(struct smi_info *new_smi) ...@@ -3593,8 +3605,6 @@ static int try_smi_init(struct smi_info *new_smi)
new_smi->interrupt_disabled = true; new_smi->interrupt_disabled = true;
atomic_set(&new_smi->need_watch, 0); atomic_set(&new_smi->need_watch, 0);
new_smi->intf_num = smi_num;
smi_num++;
rv = try_enable_event_buffer(new_smi); rv = try_enable_event_buffer(new_smi);
if (rv == 0) if (rv == 0)
...@@ -3661,6 +3671,9 @@ static int try_smi_init(struct smi_info *new_smi) ...@@ -3661,6 +3671,9 @@ static int try_smi_init(struct smi_info *new_smi)
goto out_err_stop_timer; goto out_err_stop_timer;
} }
/* Don't increment till we know we have succeeded. */
smi_num++;
dev_info(new_smi->dev, "IPMI %s interface initialized\n", dev_info(new_smi->dev, "IPMI %s interface initialized\n",
si_to_str[new_smi->si_type]); si_to_str[new_smi->si_type]);
......
...@@ -891,6 +891,7 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result, ...@@ -891,6 +891,7 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result,
* for details on the intricacies of this. * for details on the intricacies of this.
*/ */
int left; int left;
unsigned char *data_to_send;
ssif_inc_stat(ssif_info, sent_messages_parts); ssif_inc_stat(ssif_info, sent_messages_parts);
...@@ -899,6 +900,7 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result, ...@@ -899,6 +900,7 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result,
left = 32; left = 32;
/* Length byte. */ /* Length byte. */
ssif_info->multi_data[ssif_info->multi_pos] = left; ssif_info->multi_data[ssif_info->multi_pos] = left;
data_to_send = ssif_info->multi_data + ssif_info->multi_pos;
ssif_info->multi_pos += left; ssif_info->multi_pos += left;
if (left < 32) if (left < 32)
/* /*
...@@ -912,7 +914,7 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result, ...@@ -912,7 +914,7 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result,
rv = ssif_i2c_send(ssif_info, msg_written_handler, rv = ssif_i2c_send(ssif_info, msg_written_handler,
I2C_SMBUS_WRITE, I2C_SMBUS_WRITE,
SSIF_IPMI_MULTI_PART_REQUEST_MIDDLE, SSIF_IPMI_MULTI_PART_REQUEST_MIDDLE,
ssif_info->multi_data + ssif_info->multi_pos, data_to_send,
I2C_SMBUS_BLOCK_DATA); I2C_SMBUS_BLOCK_DATA);
if (rv < 0) { if (rv < 0) {
/* request failed, just return the error. */ /* request failed, just return the error. */
...@@ -1642,9 +1644,8 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -1642,9 +1644,8 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
spin_lock_init(&ssif_info->lock); spin_lock_init(&ssif_info->lock);
ssif_info->ssif_state = SSIF_NORMAL; ssif_info->ssif_state = SSIF_NORMAL;
init_timer(&ssif_info->retry_timer); setup_timer(&ssif_info->retry_timer, retry_timeout,
ssif_info->retry_timer.data = (unsigned long) ssif_info; (unsigned long)ssif_info);
ssif_info->retry_timer.function = retry_timeout;
for (i = 0; i < SSIF_NUM_STATS; i++) for (i = 0; i < SSIF_NUM_STATS; i++)
atomic_set(&ssif_info->stats[i], 0); atomic_set(&ssif_info->stats[i], 0);
......
...@@ -516,7 +516,7 @@ static void panic_halt_ipmi_heartbeat(void) ...@@ -516,7 +516,7 @@ static void panic_halt_ipmi_heartbeat(void)
msg.cmd = IPMI_WDOG_RESET_TIMER; msg.cmd = IPMI_WDOG_RESET_TIMER;
msg.data = NULL; msg.data = NULL;
msg.data_len = 0; msg.data_len = 0;
atomic_add(2, &panic_done_count); atomic_add(1, &panic_done_count);
rv = ipmi_request_supply_msgs(watchdog_user, rv = ipmi_request_supply_msgs(watchdog_user,
(struct ipmi_addr *) &addr, (struct ipmi_addr *) &addr,
0, 0,
...@@ -526,7 +526,7 @@ static void panic_halt_ipmi_heartbeat(void) ...@@ -526,7 +526,7 @@ static void panic_halt_ipmi_heartbeat(void)
&panic_halt_heartbeat_recv_msg, &panic_halt_heartbeat_recv_msg,
1); 1);
if (rv) if (rv)
atomic_sub(2, &panic_done_count); atomic_sub(1, &panic_done_count);
} }
static struct ipmi_smi_msg panic_halt_smi_msg = { static struct ipmi_smi_msg panic_halt_smi_msg = {
...@@ -550,12 +550,12 @@ static void panic_halt_ipmi_set_timeout(void) ...@@ -550,12 +550,12 @@ static void panic_halt_ipmi_set_timeout(void)
/* Wait for the messages to be free. */ /* Wait for the messages to be free. */
while (atomic_read(&panic_done_count) != 0) while (atomic_read(&panic_done_count) != 0)
ipmi_poll_interface(watchdog_user); ipmi_poll_interface(watchdog_user);
atomic_add(2, &panic_done_count); atomic_add(1, &panic_done_count);
rv = i_ipmi_set_timeout(&panic_halt_smi_msg, rv = i_ipmi_set_timeout(&panic_halt_smi_msg,
&panic_halt_recv_msg, &panic_halt_recv_msg,
&send_heartbeat_now); &send_heartbeat_now);
if (rv) { if (rv) {
atomic_sub(2, &panic_done_count); atomic_sub(1, &panic_done_count);
printk(KERN_WARNING PFX printk(KERN_WARNING PFX
"Unable to extend the watchdog timeout."); "Unable to extend the watchdog timeout.");
} else { } else {
......
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