diff options
author | Corey Minyard <minyard@acm.org> | 2006-12-06 20:41:14 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-07 08:39:47 -0800 |
commit | 4d7cbac7c870ca66d8fb27d68188efbb5de2dffa (patch) | |
tree | 8abf21f9eb42347cfa9d7a071bce9390c6995583 /drivers/char/ipmi/ipmi_si_intf.c | |
parent | 168b35a7f67c5a8189e6b92780dfb5262604057c (diff) | |
download | blackbird-op-linux-4d7cbac7c870ca66d8fb27d68188efbb5de2dffa.tar.gz blackbird-op-linux-4d7cbac7c870ca66d8fb27d68188efbb5de2dffa.zip |
[PATCH] IPMI: Fix BT long busy
The IPMI BT subdriver has been patched to survive "long busy" timeouts seen
during firmware upgrades and resets. The patch never returns the HOSED state,
synthesizes response messages with meaningful completion codes, and recovers
gracefully when the hardware finishes the long busy. The subdriver now issues
a "Get BT Capabilities" command and properly uses those results. More
informative completion codes are returned on error from transaction starts;
this logic was propogated to the KCS and SMIC subdrivers. Finally, indent and
other style quirks were normalized.
Signed-off-by: Rocky Craig <rocky.craig@hp.com>
Signed-off-by: Corey Minyard <minyard@acm.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/char/ipmi/ipmi_si_intf.c')
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index c7de2e86a6dc..81a0c89598e7 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -247,14 +247,18 @@ static void deliver_recv_msg(struct smi_info *smi_info, spin_lock(&(smi_info->si_lock)); } -static void return_hosed_msg(struct smi_info *smi_info) +static void return_hosed_msg(struct smi_info *smi_info, int cCode) { struct ipmi_smi_msg *msg = smi_info->curr_msg; + if (cCode < 0 || cCode > IPMI_ERR_UNSPECIFIED) + cCode = IPMI_ERR_UNSPECIFIED; + /* else use it as is */ + /* Make it a reponse */ msg->rsp[0] = msg->data[0] | 4; msg->rsp[1] = msg->data[1]; - msg->rsp[2] = IPMI_ERR_UNSPECIFIED; + msg->rsp[2] = cCode; msg->rsp_size = 3; smi_info->curr_msg = NULL; @@ -305,7 +309,7 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info) smi_info->curr_msg->data, smi_info->curr_msg->data_size); if (err) { - return_hosed_msg(smi_info); + return_hosed_msg(smi_info, err); } rv = SI_SM_CALL_WITHOUT_DELAY; @@ -647,7 +651,7 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info, /* If we were handling a user message, format a response to send to the upper layer to tell it about the error. */ - return_hosed_msg(smi_info); + return_hosed_msg(smi_info, IPMI_ERR_UNSPECIFIED); } si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0); } |