aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/ipmi/ipmi_bt_sm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/ipmi/ipmi_bt_sm.c')
-rw-r--r--drivers/char/ipmi/ipmi_bt_sm.c34
1 files changed, 13 insertions, 21 deletions
diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c
index 33862670e285..7c4a195dfc9a 100644
--- a/drivers/char/ipmi/ipmi_bt_sm.c
+++ b/drivers/char/ipmi/ipmi_bt_sm.c
@@ -28,6 +28,8 @@
28 28
29#include <linux/kernel.h> /* For printk. */ 29#include <linux/kernel.h> /* For printk. */
30#include <linux/string.h> 30#include <linux/string.h>
31#include <linux/module.h>
32#include <linux/moduleparam.h>
31#include <linux/ipmi_msgdefs.h> /* for completion codes */ 33#include <linux/ipmi_msgdefs.h> /* for completion codes */
32#include "ipmi_si_sm.h" 34#include "ipmi_si_sm.h"
33 35
@@ -36,6 +38,8 @@ static int bt_debug = 0x00; /* Production value 0, see following flags */
36#define BT_DEBUG_ENABLE 1 38#define BT_DEBUG_ENABLE 1
37#define BT_DEBUG_MSG 2 39#define BT_DEBUG_MSG 2
38#define BT_DEBUG_STATES 4 40#define BT_DEBUG_STATES 4
41module_param(bt_debug, int, 0644);
42MODULE_PARM_DESC(bt_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
39 43
40/* Typical "Get BT Capabilities" values are 2-3 retries, 5-10 seconds, 44/* Typical "Get BT Capabilities" values are 2-3 retries, 5-10 seconds,
41 and 64 byte buffers. However, one HP implementation wants 255 bytes of 45 and 64 byte buffers. However, one HP implementation wants 255 bytes of
@@ -43,7 +47,7 @@ static int bt_debug = 0x00; /* Production value 0, see following flags */
43 Since the Open IPMI architecture is single-message oriented at this 47 Since the Open IPMI architecture is single-message oriented at this
44 stage, the queue depth of BT is of no concern. */ 48 stage, the queue depth of BT is of no concern. */
45 49
46#define BT_NORMAL_TIMEOUT 2000000 /* seconds in microseconds */ 50#define BT_NORMAL_TIMEOUT 5000000 /* seconds in microseconds */
47#define BT_RETRY_LIMIT 2 51#define BT_RETRY_LIMIT 2
48#define BT_RESET_DELAY 6000000 /* 6 seconds after warm reset */ 52#define BT_RESET_DELAY 6000000 /* 6 seconds after warm reset */
49 53
@@ -202,7 +206,7 @@ static int bt_get_result(struct si_sm_data *bt,
202 msg_len = bt->read_count - 2; /* account for length & seq */ 206 msg_len = bt->read_count - 2; /* account for length & seq */
203 /* Always NetFn, Cmd, cCode */ 207 /* Always NetFn, Cmd, cCode */
204 if (msg_len < 3 || msg_len > IPMI_MAX_MSG_LENGTH) { 208 if (msg_len < 3 || msg_len > IPMI_MAX_MSG_LENGTH) {
205 printk(KERN_WARNING "BT results: bad msg_len = %d\n", msg_len); 209 printk(KERN_DEBUG "BT results: bad msg_len = %d\n", msg_len);
206 data[0] = bt->write_data[1] | 0x4; /* Kludge a response */ 210 data[0] = bt->write_data[1] | 0x4; /* Kludge a response */
207 data[1] = bt->write_data[3]; 211 data[1] = bt->write_data[3];
208 data[2] = IPMI_ERR_UNSPECIFIED; 212 data[2] = IPMI_ERR_UNSPECIFIED;
@@ -240,7 +244,7 @@ static void reset_flags(struct si_sm_data *bt)
240 BT_CONTROL(BT_B_BUSY); 244 BT_CONTROL(BT_B_BUSY);
241 BT_CONTROL(BT_CLR_WR_PTR); 245 BT_CONTROL(BT_CLR_WR_PTR);
242 BT_CONTROL(BT_SMS_ATN); 246 BT_CONTROL(BT_SMS_ATN);
243#ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION 247
244 if (BT_STATUS & BT_B2H_ATN) { 248 if (BT_STATUS & BT_B2H_ATN) {
245 int i; 249 int i;
246 BT_CONTROL(BT_H_BUSY); 250 BT_CONTROL(BT_H_BUSY);
@@ -250,7 +254,6 @@ static void reset_flags(struct si_sm_data *bt)
250 BMC2HOST; 254 BMC2HOST;
251 BT_CONTROL(BT_H_BUSY); 255 BT_CONTROL(BT_H_BUSY);
252 } 256 }
253#endif
254} 257}
255 258
256static inline void write_all_bytes(struct si_sm_data *bt) 259static inline void write_all_bytes(struct si_sm_data *bt)
@@ -295,7 +298,7 @@ static inline int read_all_bytes(struct si_sm_data *bt)
295 printk ("\n"); 298 printk ("\n");
296 } 299 }
297 if (bt->seq != bt->write_data[2]) /* idiot check */ 300 if (bt->seq != bt->write_data[2]) /* idiot check */
298 printk(KERN_WARNING "BT: internal error: sequence mismatch\n"); 301 printk(KERN_DEBUG "BT: internal error: sequence mismatch\n");
299 302
300 /* per the spec, the (NetFn, Seq, Cmd) tuples should match */ 303 /* per the spec, the (NetFn, Seq, Cmd) tuples should match */
301 if ((bt->read_data[3] == bt->write_data[3]) && /* Cmd */ 304 if ((bt->read_data[3] == bt->write_data[3]) && /* Cmd */
@@ -321,18 +324,18 @@ static void error_recovery(struct si_sm_data *bt, char *reason)
321 bt->timeout = BT_NORMAL_TIMEOUT; /* various places want to retry */ 324 bt->timeout = BT_NORMAL_TIMEOUT; /* various places want to retry */
322 325
323 status = BT_STATUS; 326 status = BT_STATUS;
324 printk(KERN_WARNING "BT: %s in %s %s ", reason, STATE2TXT, 327 printk(KERN_DEBUG "BT: %s in %s %s\n", reason, STATE2TXT,
325 STATUS2TXT(buf)); 328 STATUS2TXT(buf));
326 329
327 (bt->error_retries)++; 330 (bt->error_retries)++;
328 if (bt->error_retries > BT_RETRY_LIMIT) { 331 if (bt->error_retries > BT_RETRY_LIMIT) {
329 printk("retry limit (%d) exceeded\n", BT_RETRY_LIMIT); 332 printk(KERN_DEBUG "retry limit (%d) exceeded\n", BT_RETRY_LIMIT);
330 bt->state = BT_STATE_HOSED; 333 bt->state = BT_STATE_HOSED;
331 if (!bt->nonzero_status) 334 if (!bt->nonzero_status)
332 printk(KERN_ERR "IPMI: BT stuck, try power cycle\n"); 335 printk(KERN_ERR "IPMI: BT stuck, try power cycle\n");
333 else if (bt->seq == FIRST_SEQ + BT_RETRY_LIMIT) { 336 else if (bt->seq == FIRST_SEQ + BT_RETRY_LIMIT) {
334 /* most likely during insmod */ 337 /* most likely during insmod */
335 printk(KERN_WARNING "IPMI: BT reset (takes 5 secs)\n"); 338 printk(KERN_DEBUG "IPMI: BT reset (takes 5 secs)\n");
336 bt->state = BT_STATE_RESET1; 339 bt->state = BT_STATE_RESET1;
337 } 340 }
338 return; 341 return;
@@ -340,11 +343,11 @@ static void error_recovery(struct si_sm_data *bt, char *reason)
340 343
341 /* Sometimes the BMC queues get in an "off-by-one" state...*/ 344 /* Sometimes the BMC queues get in an "off-by-one" state...*/
342 if ((bt->state == BT_STATE_B2H_WAIT) && (status & BT_B2H_ATN)) { 345 if ((bt->state == BT_STATE_B2H_WAIT) && (status & BT_B2H_ATN)) {
343 printk("retry B2H_WAIT\n"); 346 printk(KERN_DEBUG "retry B2H_WAIT\n");
344 return; 347 return;
345 } 348 }
346 349
347 printk("restart command\n"); 350 printk(KERN_DEBUG "restart command\n");
348 bt->state = BT_STATE_RESTART; 351 bt->state = BT_STATE_RESTART;
349} 352}
350 353
@@ -372,17 +375,6 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
372 return SI_SM_HOSED; 375 return SI_SM_HOSED;
373 376
374 if (bt->state != BT_STATE_IDLE) { /* do timeout test */ 377 if (bt->state != BT_STATE_IDLE) { /* do timeout test */
375
376 /* Certain states, on error conditions, can lock up a CPU
377 because they are effectively in an infinite loop with
378 CALL_WITHOUT_DELAY (right back here with time == 0).
379 Prevent infinite lockup by ALWAYS decrementing timeout. */
380
381 /* FIXME: bt_event is sometimes called with time > BT_NORMAL_TIMEOUT
382 (noticed in ipmi_smic_sm.c January 2004) */
383
384 if ((time <= 0) || (time >= BT_NORMAL_TIMEOUT))
385 time = 100;
386 bt->timeout -= time; 378 bt->timeout -= time;
387 if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1)) { 379 if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1)) {
388 error_recovery(bt, "timed out"); 380 error_recovery(bt, "timed out");