}
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) {
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);
}
/*
spin_unlock_irqrestore(&intf->seq_lock, flags);
if (msg)
- deliver_err_response(msg, err);
+ deliver_err_response(intf, msg, err);
return rv;
}
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);
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);
}
}
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;
}
}
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) {
/*
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);
}
}
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;
}
*/
rv = 0;
} else {
- /* Deliver the message to the user. */
- ipmi_inc_stat(intf, handled_commands);
-
recv_msg = ipmi_alloc_recv_msg();
if (!recv_msg) {
/*
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);
}
}
rv = 0;
} else {
- /* Deliver the message to the user. */
- ipmi_inc_stat(intf, handled_commands);
-
recv_msg = ipmi_alloc_recv_msg();
if (!recv_msg) {
/*
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);
}
}
/* 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) {
/*
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;
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;
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