From a8df150c5de4b2a542660e7b3727fddfce2e015b Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Wed, 19 Nov 2014 11:47:17 -0600 Subject: ipmi: Fix attention handling for system interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If an attention came in while handling a message response, it could cause the state machine to go into the wrong mode and lock things up if the state machine wasn't in normal mode. So if the state machine is not in normal mode, save the attention flag for later. Signed-off-by: Corey Minyard Tested-by: Tony Rex Tested-by: Magnus Johansson E Cc: Per Fogelström diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 2952d2d..4a894af 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -262,6 +262,11 @@ struct smi_info { */ bool supports_event_msg_buff; + /* + * Did we get an attention that we did not handle? + */ + bool got_attn; + /* From the get device id response... */ struct ipmi_device_id device_id; @@ -813,25 +818,35 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info, * We prefer handling attn over new messages. But don't do * this if there is not yet an upper layer to handle anything. */ - if (likely(smi_info->intf) && si_sm_result == SI_SM_ATTN) { + if (likely(smi_info->intf) && + (si_sm_result == SI_SM_ATTN || smi_info->got_attn)) { unsigned char msg[2]; - smi_inc_stat(smi_info, attentions); + if (smi_info->si_state != SI_NORMAL) { + /* + * We got an ATTN, but we are doing something else. + * Handle the ATTN later. + */ + smi_info->got_attn = true; + } else { + smi_info->got_attn = false; + smi_inc_stat(smi_info, attentions); - /* - * Got a attn, send down a get message flags to see - * what's causing it. It would be better to handle - * this in the upper layer, but due to the way - * interrupts work with the SMI, that's not really - * possible. - */ - msg[0] = (IPMI_NETFN_APP_REQUEST << 2); - msg[1] = IPMI_GET_MSG_FLAGS_CMD; + /* + * Got a attn, send down a get message flags to see + * what's causing it. It would be better to handle + * this in the upper layer, but due to the way + * interrupts work with the SMI, that's not really + * possible. + */ + msg[0] = (IPMI_NETFN_APP_REQUEST << 2); + msg[1] = IPMI_GET_MSG_FLAGS_CMD; - smi_info->handlers->start_transaction( - smi_info->si_sm, msg, 2); - smi_info->si_state = SI_GETTING_FLAGS; - goto restart; + smi_info->handlers->start_transaction( + smi_info->si_sm, msg, 2); + smi_info->si_state = SI_GETTING_FLAGS; + goto restart; + } } /* If we are currently idle, try to start the next message. */ -- cgit v0.10.2