|
@@ -886,18 +886,17 @@ unsigned int ipmi_addr_length(int addr_type)
|
|
|
}
|
|
|
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) {
|
|
|
- struct ipmi_smi *intf = msg->user_msg_data;
|
|
|
+ int rv = 0;
|
|
|
|
|
|
+ if (!msg->user) {
|
|
|
/* Special handling for NULL users. */
|
|
|
if (intf->null_user_handler) {
|
|
|
intf->null_user_handler(intf, msg);
|
|
|
- ipmi_inc_stat(intf, handled_local_responses);
|
|
|
} else {
|
|
|
/* No handler, so give up. */
|
|
|
- ipmi_inc_stat(intf, unhandled_local_responses);
|
|
|
+ rv = -EINVAL;
|
|
|
}
|
|
|
ipmi_free_recv_msg(msg);
|
|
|
} else if (!oops_in_progress) {
|
|
@@ -910,17 +909,28 @@ static void deliver_response(struct ipmi_recv_msg *msg)
|
|
|
struct ipmi_user *user = msg->user;
|
|
|
user->handler->ipmi_recv_hndl(msg, user->handler_data);
|
|
|
}
|
|
|
+
|
|
|
+ return rv;
|
|
|
}
|
|
|
|
|
|
-static void
|
|
|
-deliver_err_response(struct ipmi_recv_msg *msg, int err)
|
|
|
+static void deliver_local_response(struct ipmi_smi *intf,
|
|
|
+ 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->msg_data[0] = err;
|
|
|
msg->msg.netfn |= 1; /* Convert to a response. */
|
|
|
msg->msg.data_len = 1;
|
|
|
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,
|
|
|
spin_unlock_irqrestore(&intf->seq_lock, flags);
|
|
|
|
|
|
if (msg)
|
|
|
- deliver_err_response(msg, err);
|
|
|
+ deliver_err_response(intf, msg, err);
|
|
|
|
|
|
return rv;
|
|
|
}
|
|
@@ -1443,7 +1453,7 @@ int ipmi_set_gets_events(struct ipmi_user *user, bool val)
|
|
|
list_for_each_entry_safe(msg, msg2, &msgs, link) {
|
|
|
msg->user = user;
|
|
|
kref_get(&user->refcount);
|
|
|
- deliver_response(msg);
|
|
|
+ deliver_local_response(intf, msg);
|
|
|
}
|
|
|
|
|
|
spin_lock_irqsave(&intf->events_lock, flags);
|
|
@@ -3614,7 +3624,7 @@ static void cleanup_smi_msgs(struct ipmi_smi *intf)
|
|
|
ent = &intf->seq_table[i];
|
|
|
if (!ent->inuse)
|
|
|
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,
|
|
|
recv_msg->msg.data = recv_msg->msg_data;
|
|
|
recv_msg->msg.data_len = msg->rsp_size - 10;
|
|
|
recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
|
|
|
- ipmi_inc_stat(intf, handled_ipmb_responses);
|
|
|
- deliver_response(recv_msg);
|
|
|
+ if (deliver_response(intf, recv_msg))
|
|
|
+ ipmi_inc_stat(intf, unhandled_ipmb_responses);
|
|
|
+ else
|
|
|
+ ipmi_inc_stat(intf, handled_ipmb_responses);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -3793,9 +3805,6 @@ static int handle_ipmb_get_msg_cmd(struct ipmi_smi *intf,
|
|
|
}
|
|
|
rcu_read_unlock();
|
|
|
} else {
|
|
|
- /* Deliver the message to the user. */
|
|
|
- ipmi_inc_stat(intf, handled_commands);
|
|
|
-
|
|
|
recv_msg = ipmi_alloc_recv_msg();
|
|
|
if (!recv_msg) {
|
|
|
/*
|
|
@@ -3831,7 +3840,10 @@ static int handle_ipmb_get_msg_cmd(struct ipmi_smi *intf,
|
|
|
recv_msg->msg.data_len = msg->rsp_size - 10;
|
|
|
memcpy(recv_msg->msg_data, &msg->rsp[9],
|
|
|
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,
|
|
|
recv_msg->msg.data = recv_msg->msg_data;
|
|
|
recv_msg->msg.data_len = msg->rsp_size - 12;
|
|
|
recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
|
|
|
- ipmi_inc_stat(intf, handled_lan_responses);
|
|
|
- deliver_response(recv_msg);
|
|
|
+ if (deliver_response(intf, recv_msg))
|
|
|
+ ipmi_inc_stat(intf, unhandled_lan_responses);
|
|
|
+ else
|
|
|
+ ipmi_inc_stat(intf, handled_lan_responses);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -3949,9 +3963,6 @@ static int handle_lan_get_msg_cmd(struct ipmi_smi *intf,
|
|
|
*/
|
|
|
rv = 0;
|
|
|
} else {
|
|
|
- /* Deliver the message to the user. */
|
|
|
- ipmi_inc_stat(intf, handled_commands);
|
|
|
-
|
|
|
recv_msg = ipmi_alloc_recv_msg();
|
|
|
if (!recv_msg) {
|
|
|
/*
|
|
@@ -3989,7 +4000,10 @@ static int handle_lan_get_msg_cmd(struct ipmi_smi *intf,
|
|
|
recv_msg->msg.data_len = msg->rsp_size - 12;
|
|
|
memcpy(recv_msg->msg_data, &msg->rsp[11],
|
|
|
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,
|
|
|
|
|
|
rv = 0;
|
|
|
} else {
|
|
|
- /* Deliver the message to the user. */
|
|
|
- ipmi_inc_stat(intf, handled_commands);
|
|
|
-
|
|
|
recv_msg = ipmi_alloc_recv_msg();
|
|
|
if (!recv_msg) {
|
|
|
/*
|
|
@@ -4096,7 +4107,10 @@ static int handle_oem_get_msg_cmd(struct ipmi_smi *intf,
|
|
|
recv_msg->msg.data_len = msg->rsp_size - 4;
|
|
|
memcpy(recv_msg->msg_data, &msg->rsp[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,
|
|
|
/* Now deliver all the messages. */
|
|
|
list_for_each_entry_safe(recv_msg, recv_msg2, &msgs, 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) {
|
|
|
/*
|
|
@@ -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);
|
|
|
recv_msg->msg.data = recv_msg->msg_data;
|
|
|
recv_msg->msg.data_len = msg->rsp_size - 2;
|
|
|
- deliver_response(recv_msg);
|
|
|
+ deliver_local_response(intf, recv_msg);
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
@@ -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_len = 1;
|
|
|
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))
|
|
|
&& (msg->rsp[1] == IPMI_GET_MSG_CMD)) {
|
|
|
struct ipmi_channel *chans;
|
|
@@ -4761,7 +4775,7 @@ static unsigned int ipmi_timeout_handler(struct ipmi_smi *intf,
|
|
|
spin_unlock_irqrestore(&intf->seq_lock, flags);
|
|
|
|
|
|
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
|