diff options
Diffstat (limited to 'drivers/char/ipmi/ipmi_bt_sm.c')
-rw-r--r-- | drivers/char/ipmi/ipmi_bt_sm.c | 34 |
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 |
41 | module_param(bt_debug, int, 0644); | ||
42 | MODULE_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 | ||
256 | static inline void write_all_bytes(struct si_sm_data *bt) | 259 | static 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"); |