Commit ac93bd0c authored by Corey Minyard's avatar Corey Minyard

ipmi: Fix some counter issues

Counters would not be pegged properly on some errors.  Have
deliver_response() return an error so the counters can be
incremented properly.
Signed-off-by: default avatarCorey Minyard <cminyard@mvista.com>
parent a567b623
...@@ -886,18 +886,17 @@ unsigned int ipmi_addr_length(int addr_type) ...@@ -886,18 +886,17 @@ unsigned int ipmi_addr_length(int addr_type)
} }
EXPORT_SYMBOL(ipmi_addr_length); EXPORT_SYMBOL(ipmi_addr_length);
static void deliver_response(struct ipmi_recv_msg *msg) static int deliver_response(struct ipmi_smi *intf, struct ipmi_recv_msg *msg)
{ {
if (!msg->user) { int rv = 0;
struct ipmi_smi *intf = msg->user_msg_data;
if (!msg->user) {
/* Special handling for NULL users. */ /* Special handling for NULL users. */
if (intf->null_user_handler) { if (intf->null_user_handler) {
intf->null_user_handler(intf, msg); intf->null_user_handler(intf, msg);
ipmi_inc_stat(intf, handled_local_responses);
} else { } else {
/* No handler, so give up. */ /* No handler, so give up. */
ipmi_inc_stat(intf, unhandled_local_responses); rv = -EINVAL;
} }
ipmi_free_recv_msg(msg); ipmi_free_recv_msg(msg);
} else if (!oops_in_progress) { } else if (!oops_in_progress) {
...@@ -910,17 +909,28 @@ static void deliver_response(struct ipmi_recv_msg *msg) ...@@ -910,17 +909,28 @@ static void deliver_response(struct ipmi_recv_msg *msg)
struct ipmi_user *user = msg->user; struct ipmi_user *user = msg->user;
user->handler->ipmi_recv_hndl(msg, user->handler_data); user->handler->ipmi_recv_hndl(msg, user->handler_data);
} }
return rv;
} }
static void static void deliver_local_response(struct ipmi_smi *intf,
deliver_err_response(struct ipmi_recv_msg *msg, int err) struct ipmi_recv_msg *msg)
{
if (deliver_response(intf, msg))
ipmi_inc_stat(intf, unhandled_local_responses);
else
ipmi_inc_stat(intf, handled_local_responses);
}
static void deliver_err_response(struct ipmi_smi *intf,
struct ipmi_recv_msg *msg, int err)
{ {
msg->recv_type = IPMI_RESPONSE_RECV_TYPE; msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
msg->msg_data[0] = err; msg->msg_data[0] = err;
msg->msg.netfn |= 1; /* Convert to a response. */ msg->msg.netfn |= 1; /* Convert to a response. */
msg->msg.data_len = 1; msg->msg.data_len = 1;
msg->msg.data = msg->msg_data; msg->msg.data = msg->msg_data;
deliver_response(msg); deliver_local_response(intf, msg);
} }
/* /*
...@@ -1071,7 +1081,7 @@ static int intf_err_seq(struct ipmi_smi *intf, ...@@ -1071,7 +1081,7 @@ static int intf_err_seq(struct ipmi_smi *intf,
spin_unlock_irqrestore(&intf->seq_lock, flags); spin_unlock_irqrestore(&intf->seq_lock, flags);
if (msg) if (msg)
deliver_err_response(msg, err); deliver_err_response(intf, msg, err);
return rv; return rv;
} }
...@@ -1443,7 +1453,7 @@ int ipmi_set_gets_events(struct ipmi_user *user, bool val) ...@@ -1443,7 +1453,7 @@ int ipmi_set_gets_events(struct ipmi_user *user, bool val)
list_for_each_entry_safe(msg, msg2, &msgs, link) { list_for_each_entry_safe(msg, msg2, &msgs, link) {
msg->user = user; msg->user = user;
kref_get(&user->refcount); kref_get(&user->refcount);
deliver_response(msg); deliver_local_response(intf, msg);
} }
spin_lock_irqsave(&intf->events_lock, flags); spin_lock_irqsave(&intf->events_lock, flags);
...@@ -3614,7 +3624,7 @@ static void cleanup_smi_msgs(struct ipmi_smi *intf) ...@@ -3614,7 +3624,7 @@ static void cleanup_smi_msgs(struct ipmi_smi *intf)
ent = &intf->seq_table[i]; ent = &intf->seq_table[i];
if (!ent->inuse) if (!ent->inuse)
continue; continue;
deliver_err_response(ent->recv_msg, IPMI_ERR_UNSPECIFIED); deliver_err_response(intf, ent->recv_msg, IPMI_ERR_UNSPECIFIED);
} }
} }
...@@ -3719,8 +3729,10 @@ static int handle_ipmb_get_msg_rsp(struct ipmi_smi *intf, ...@@ -3719,8 +3729,10 @@ static int handle_ipmb_get_msg_rsp(struct ipmi_smi *intf,
recv_msg->msg.data = recv_msg->msg_data; recv_msg->msg.data = recv_msg->msg_data;
recv_msg->msg.data_len = msg->rsp_size - 10; recv_msg->msg.data_len = msg->rsp_size - 10;
recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE; recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
ipmi_inc_stat(intf, handled_ipmb_responses); if (deliver_response(intf, recv_msg))
deliver_response(recv_msg); ipmi_inc_stat(intf, unhandled_ipmb_responses);
else
ipmi_inc_stat(intf, handled_ipmb_responses);
return 0; return 0;
} }
...@@ -3793,9 +3805,6 @@ static int handle_ipmb_get_msg_cmd(struct ipmi_smi *intf, ...@@ -3793,9 +3805,6 @@ static int handle_ipmb_get_msg_cmd(struct ipmi_smi *intf,
} }
rcu_read_unlock(); rcu_read_unlock();
} else { } else {
/* Deliver the message to the user. */
ipmi_inc_stat(intf, handled_commands);
recv_msg = ipmi_alloc_recv_msg(); recv_msg = ipmi_alloc_recv_msg();
if (!recv_msg) { if (!recv_msg) {
/* /*
...@@ -3831,7 +3840,10 @@ static int handle_ipmb_get_msg_cmd(struct ipmi_smi *intf, ...@@ -3831,7 +3840,10 @@ static int handle_ipmb_get_msg_cmd(struct ipmi_smi *intf,
recv_msg->msg.data_len = msg->rsp_size - 10; recv_msg->msg.data_len = msg->rsp_size - 10;
memcpy(recv_msg->msg_data, &msg->rsp[9], memcpy(recv_msg->msg_data, &msg->rsp[9],
msg->rsp_size - 10); msg->rsp_size - 10);
deliver_response(recv_msg); if (deliver_response(intf, recv_msg))
ipmi_inc_stat(intf, unhandled_commands);
else
ipmi_inc_stat(intf, handled_commands);
} }
} }
...@@ -3897,8 +3909,10 @@ static int handle_lan_get_msg_rsp(struct ipmi_smi *intf, ...@@ -3897,8 +3909,10 @@ static int handle_lan_get_msg_rsp(struct ipmi_smi *intf,
recv_msg->msg.data = recv_msg->msg_data; recv_msg->msg.data = recv_msg->msg_data;
recv_msg->msg.data_len = msg->rsp_size - 12; recv_msg->msg.data_len = msg->rsp_size - 12;
recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE; recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
ipmi_inc_stat(intf, handled_lan_responses); if (deliver_response(intf, recv_msg))
deliver_response(recv_msg); ipmi_inc_stat(intf, unhandled_lan_responses);
else
ipmi_inc_stat(intf, handled_lan_responses);
return 0; return 0;
} }
...@@ -3949,9 +3963,6 @@ static int handle_lan_get_msg_cmd(struct ipmi_smi *intf, ...@@ -3949,9 +3963,6 @@ static int handle_lan_get_msg_cmd(struct ipmi_smi *intf,
*/ */
rv = 0; rv = 0;
} else { } else {
/* Deliver the message to the user. */
ipmi_inc_stat(intf, handled_commands);
recv_msg = ipmi_alloc_recv_msg(); recv_msg = ipmi_alloc_recv_msg();
if (!recv_msg) { if (!recv_msg) {
/* /*
...@@ -3989,7 +4000,10 @@ static int handle_lan_get_msg_cmd(struct ipmi_smi *intf, ...@@ -3989,7 +4000,10 @@ static int handle_lan_get_msg_cmd(struct ipmi_smi *intf,
recv_msg->msg.data_len = msg->rsp_size - 12; recv_msg->msg.data_len = msg->rsp_size - 12;
memcpy(recv_msg->msg_data, &msg->rsp[11], memcpy(recv_msg->msg_data, &msg->rsp[11],
msg->rsp_size - 12); msg->rsp_size - 12);
deliver_response(recv_msg); if (deliver_response(intf, recv_msg))
ipmi_inc_stat(intf, unhandled_commands);
else
ipmi_inc_stat(intf, handled_commands);
} }
} }
...@@ -4057,9 +4071,6 @@ static int handle_oem_get_msg_cmd(struct ipmi_smi *intf, ...@@ -4057,9 +4071,6 @@ static int handle_oem_get_msg_cmd(struct ipmi_smi *intf,
rv = 0; rv = 0;
} else { } else {
/* Deliver the message to the user. */
ipmi_inc_stat(intf, handled_commands);
recv_msg = ipmi_alloc_recv_msg(); recv_msg = ipmi_alloc_recv_msg();
if (!recv_msg) { if (!recv_msg) {
/* /*
...@@ -4096,7 +4107,10 @@ static int handle_oem_get_msg_cmd(struct ipmi_smi *intf, ...@@ -4096,7 +4107,10 @@ static int handle_oem_get_msg_cmd(struct ipmi_smi *intf,
recv_msg->msg.data_len = msg->rsp_size - 4; recv_msg->msg.data_len = msg->rsp_size - 4;
memcpy(recv_msg->msg_data, &msg->rsp[4], memcpy(recv_msg->msg_data, &msg->rsp[4],
msg->rsp_size - 4); msg->rsp_size - 4);
deliver_response(recv_msg); if (deliver_response(intf, recv_msg))
ipmi_inc_stat(intf, unhandled_commands);
else
ipmi_inc_stat(intf, handled_commands);
} }
} }
...@@ -4187,7 +4201,7 @@ static int handle_read_event_rsp(struct ipmi_smi *intf, ...@@ -4187,7 +4201,7 @@ static int handle_read_event_rsp(struct ipmi_smi *intf,
/* Now deliver all the messages. */ /* Now deliver all the messages. */
list_for_each_entry_safe(recv_msg, recv_msg2, &msgs, link) { list_for_each_entry_safe(recv_msg, recv_msg2, &msgs, link) {
list_del(&recv_msg->link); list_del(&recv_msg->link);
deliver_response(recv_msg); deliver_local_response(intf, recv_msg);
} }
} else if (intf->waiting_events_count < MAX_EVENTS_IN_QUEUE) { } else if (intf->waiting_events_count < MAX_EVENTS_IN_QUEUE) {
/* /*
...@@ -4259,7 +4273,7 @@ static int handle_bmc_rsp(struct ipmi_smi *intf, ...@@ -4259,7 +4273,7 @@ static int handle_bmc_rsp(struct ipmi_smi *intf,
memcpy(recv_msg->msg_data, &msg->rsp[2], msg->rsp_size - 2); memcpy(recv_msg->msg_data, &msg->rsp[2], msg->rsp_size - 2);
recv_msg->msg.data = recv_msg->msg_data; recv_msg->msg.data = recv_msg->msg_data;
recv_msg->msg.data_len = msg->rsp_size - 2; recv_msg->msg.data_len = msg->rsp_size - 2;
deliver_response(recv_msg); deliver_local_response(intf, recv_msg);
} }
return 0; return 0;
...@@ -4336,7 +4350,7 @@ static int handle_one_recv_msg(struct ipmi_smi *intf, ...@@ -4336,7 +4350,7 @@ static int handle_one_recv_msg(struct ipmi_smi *intf,
recv_msg->msg.data = recv_msg->msg_data; recv_msg->msg.data = recv_msg->msg_data;
recv_msg->msg.data_len = 1; recv_msg->msg.data_len = 1;
recv_msg->msg_data[0] = msg->rsp[2]; recv_msg->msg_data[0] = msg->rsp[2];
deliver_response(recv_msg); deliver_local_response(intf, recv_msg);
} else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2)) } else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2))
&& (msg->rsp[1] == IPMI_GET_MSG_CMD)) { && (msg->rsp[1] == IPMI_GET_MSG_CMD)) {
struct ipmi_channel *chans; struct ipmi_channel *chans;
...@@ -4761,7 +4775,7 @@ static unsigned int ipmi_timeout_handler(struct ipmi_smi *intf, ...@@ -4761,7 +4775,7 @@ static unsigned int ipmi_timeout_handler(struct ipmi_smi *intf,
spin_unlock_irqrestore(&intf->seq_lock, flags); spin_unlock_irqrestore(&intf->seq_lock, flags);
list_for_each_entry_safe(msg, msg2, &timeouts, link) list_for_each_entry_safe(msg, msg2, &timeouts, link)
deliver_err_response(msg, IPMI_TIMEOUT_COMPLETION_CODE); deliver_err_response(intf, msg, IPMI_TIMEOUT_COMPLETION_CODE);
/* /*
* Maintenance mode handling. Check the timeout * Maintenance mode handling. Check the timeout
......
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