aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/ipmi/ipmi_kcs_sm.c
diff options
context:
space:
mode:
authorCorey Minyard <minyard@acm.org>2005-11-07 03:59:56 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-07 10:53:44 -0500
commitc4edff1c19ef23e15aae64ca03f32c6719822d54 (patch)
tree06858fc7330b433b629827347c63ad890c715b3e /drivers/char/ipmi/ipmi_kcs_sm.c
parent393d2cc354d150b8b4bb888a9da7db4c935e12bd (diff)
[PATCH] ipmi: various si cleanup
A number of small changes for the various system interface drivers, consolidated from a number of patches from Matt Domsch. Clear B2H_ATN and drain the BMC message buffer on command timeout. This prevents further commands from failing after a timeout. Add bt_debug and smic_debug module parameters, expose them in sysfs. This lets you enable and disable debugging messages at runtime. Unsigned jiffies math in ipmi_si_intf.c causes a too-large value to be passed to ->event() after jiffies wrap-around. The BT driver had caught this, but didn't know how to fix it. Now all calls to ->event() use a sane value for time. Increase timeout for commands handed to the BT driver from 2 seconds to 5 seconds. This is necessary particularly when the previous command was a "Clear SEL", as that command completes, yet the BMC isn't really ready to handle another command yet. Silence BT debugging messages which were being printed on the console. Increase SMIC timeout form 1/10s to 2s. This is needed on Dell PowerEdge 2650 and PowerEdge 750 with ERA/O cards to allow commands to complete without timing out. Adds kcs_debug module param, to match behavior of BT and SMIC. This also prevents messages from being sent to the console unless explicitly requested. Signed-off-by: Matt Domsch <Matt_Domsch@dell.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_kcs_sm.c')
-rw-r--r--drivers/char/ipmi/ipmi_kcs_sm.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c
index d21853a594a3..dc83365ede4a 100644
--- a/drivers/char/ipmi/ipmi_kcs_sm.c
+++ b/drivers/char/ipmi/ipmi_kcs_sm.c
@@ -38,16 +38,24 @@
38 */ 38 */
39 39
40#include <linux/kernel.h> /* For printk. */ 40#include <linux/kernel.h> /* For printk. */
41#include <linux/module.h>
42#include <linux/moduleparam.h>
41#include <linux/string.h> 43#include <linux/string.h>
42#include <linux/ipmi_msgdefs.h> /* for completion codes */ 44#include <linux/ipmi_msgdefs.h> /* for completion codes */
43#include "ipmi_si_sm.h" 45#include "ipmi_si_sm.h"
44 46
45/* Set this if you want a printout of why the state machine was hosed 47/* kcs_debug is a bit-field
46 when it gets hosed. */ 48 * KCS_DEBUG_ENABLE - turned on for now
47#define DEBUG_HOSED_REASON 49 * KCS_DEBUG_MSG - commands and their responses
50 * KCS_DEBUG_STATES - state machine
51 */
52#define KCS_DEBUG_STATES 4
53#define KCS_DEBUG_MSG 2
54#define KCS_DEBUG_ENABLE 1
48 55
49/* Print the state machine state on entry every time. */ 56static int kcs_debug;
50#undef DEBUG_STATE 57module_param(kcs_debug, int, 0644);
58MODULE_PARM_DESC(kcs_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
51 59
52/* The states the KCS driver may be in. */ 60/* The states the KCS driver may be in. */
53enum kcs_states { 61enum kcs_states {
@@ -175,9 +183,8 @@ static inline void start_error_recovery(struct si_sm_data *kcs, char *reason)
175{ 183{
176 (kcs->error_retries)++; 184 (kcs->error_retries)++;
177 if (kcs->error_retries > MAX_ERROR_RETRIES) { 185 if (kcs->error_retries > MAX_ERROR_RETRIES) {
178#ifdef DEBUG_HOSED_REASON 186 if (kcs_debug & KCS_DEBUG_ENABLE)
179 printk("ipmi_kcs_sm: kcs hosed: %s\n", reason); 187 printk(KERN_DEBUG "ipmi_kcs_sm: kcs hosed: %s\n", reason);
180#endif
181 kcs->state = KCS_HOSED; 188 kcs->state = KCS_HOSED;
182 } else { 189 } else {
183 kcs->state = KCS_ERROR0; 190 kcs->state = KCS_ERROR0;
@@ -248,14 +255,21 @@ static void restart_kcs_transaction(struct si_sm_data *kcs)
248static int start_kcs_transaction(struct si_sm_data *kcs, unsigned char *data, 255static int start_kcs_transaction(struct si_sm_data *kcs, unsigned char *data,
249 unsigned int size) 256 unsigned int size)
250{ 257{
258 unsigned int i;
259
251 if ((size < 2) || (size > MAX_KCS_WRITE_SIZE)) { 260 if ((size < 2) || (size > MAX_KCS_WRITE_SIZE)) {
252 return -1; 261 return -1;
253 } 262 }
254
255 if ((kcs->state != KCS_IDLE) && (kcs->state != KCS_HOSED)) { 263 if ((kcs->state != KCS_IDLE) && (kcs->state != KCS_HOSED)) {
256 return -2; 264 return -2;
257 } 265 }
258 266 if (kcs_debug & KCS_DEBUG_MSG) {
267 printk(KERN_DEBUG "start_kcs_transaction -");
268 for (i = 0; i < size; i ++) {
269 printk(" %02x", (unsigned char) (data [i]));
270 }
271 printk ("\n");
272 }
259 kcs->error_retries = 0; 273 kcs->error_retries = 0;
260 memcpy(kcs->write_data, data, size); 274 memcpy(kcs->write_data, data, size);
261 kcs->write_count = size; 275 kcs->write_count = size;
@@ -305,9 +319,9 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
305 319
306 status = read_status(kcs); 320 status = read_status(kcs);
307 321
308#ifdef DEBUG_STATE 322 if (kcs_debug & KCS_DEBUG_STATES)
309 printk(" State = %d, %x\n", kcs->state, status); 323 printk(KERN_DEBUG "KCS: State = %d, %x\n", kcs->state, status);
310#endif 324
311 /* All states wait for ibf, so just do it here. */ 325 /* All states wait for ibf, so just do it here. */
312 if (!check_ibf(kcs, status, time)) 326 if (!check_ibf(kcs, status, time))
313 return SI_SM_CALL_WITH_DELAY; 327 return SI_SM_CALL_WITH_DELAY;