aboutsummaryrefslogtreecommitdiff
path: root/hw/fsp
diff options
context:
space:
mode:
authorVasant Hegde <hegdevasant@linux.vnet.ibm.com>2019-11-25 20:49:14 +0530
committerVasant Hegde <hegdevasant@linux.vnet.ibm.com>2019-11-30 12:39:28 +0530
commite2a26c9ee49c00be5e767e5f8669b22738040fdc (patch)
tree94025e828b3776bd6ebdfe8dfdf6fe3bfcc9901d /hw/fsp
parentaaa3e159cb2ce6baa3d4ca1a283c5f918944c18b (diff)
downloadskiboot-e2a26c9ee49c00be5e767e5f8669b22738040fdc.zip
skiboot-e2a26c9ee49c00be5e767e5f8669b22738040fdc.tar.gz
skiboot-e2a26c9ee49c00be5e767e5f8669b22738040fdc.tar.bz2
FSP/IPMI: Handle FSP reset reload
[ Upstream commit 2a63db6511b63a75efe820f90bb7972afc2fcdef ] FSP IPMI driver serializes ipmi messages. It sends message to FSP and waits for response before sending new message. It works fine as long as we get response from FSP on time. If we have inflight ipmi message during FSP R/R, we will not get resonse from FSP. So if we initiate inband FSP R/R then all subsequent inband ipmi message gets blocked. Sequence: - ipmitool mc reset cold - <FSP R/R complete> - ipmitool <any command> <-- gets blocked This patch clears inflight ipmi messages after FSP R/R complete. Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com> Cc: skiboot-stable@lists.ozlabs.org Signed-off-by: Oliver O'Halloran <oohall@gmail.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Diffstat (limited to 'hw/fsp')
-rw-r--r--hw/fsp/fsp-ipmi.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/hw/fsp/fsp-ipmi.c b/hw/fsp/fsp-ipmi.c
index d262cee..3fe2a82 100644
--- a/hw/fsp/fsp-ipmi.c
+++ b/hw/fsp/fsp-ipmi.c
@@ -79,6 +79,10 @@ static void fsp_ipmi_cmd_done(uint8_t cmd, uint8_t netfn, uint8_t cc)
struct fsp_ipmi_msg *fsp_ipmi_msg = fsp_ipmi.cur_msg;
lock(&fsp_ipmi.lock);
+ if (fsp_ipmi.cur_msg == NULL) {
+ unlock(&fsp_ipmi.lock);
+ return;
+ }
list_del(&fsp_ipmi_msg->link);
fsp_ipmi.cur_msg = NULL;
unlock(&fsp_ipmi.lock);
@@ -256,6 +260,35 @@ static struct ipmi_backend fsp_ipmi_backend = {
.dequeue_msg = fsp_ipmi_dequeue_msg,
};
+static bool fsp_ipmi_rr_notify(uint32_t cmd_sub_mod,
+ struct fsp_msg *msg __unused)
+{
+ struct ipmi_msg *ipmi_msg;
+
+ switch (cmd_sub_mod) {
+ case FSP_RESET_START:
+ return true;
+ case FSP_RELOAD_COMPLETE:
+ /*
+ * We will not get response for outstanding request. Send error
+ * message to caller and start sending new ipmi messages.
+ */
+ if (fsp_ipmi.cur_msg) {
+ ipmi_msg = &fsp_ipmi.cur_msg->ipmi_msg;
+ fsp_ipmi_cmd_done(ipmi_msg->cmd,
+ IPMI_NETFN_RETURN_CODE(ipmi_msg->netfn),
+ IPMI_ERR_UNSPECIFIED);
+ }
+ fsp_ipmi_send_request();
+ return true;
+ }
+ return false;
+}
+
+static struct fsp_client fsp_ipmi_client_rr = {
+ .message = fsp_ipmi_rr_notify,
+};
+
static bool fsp_ipmi_send_response(uint32_t cmd)
{
struct fsp_msg *resp;
@@ -369,5 +402,6 @@ void fsp_ipmi_init(void)
init_lock(&fsp_ipmi.lock);
fsp_register_client(&fsp_ipmi_client, FSP_MCLASS_FETCH_SPDATA);
+ fsp_register_client(&fsp_ipmi_client_rr, FSP_MCLASS_RR_EVENT);
ipmi_register_backend(&fsp_ipmi_backend);
}