4 * The state machine for an Open IPMI BT sub-driver under ipmi_si.c, part
5 * of the driver architecture at http://sourceforge.net/project/openipmi
7 * Author: Rocky Craig <first.last@hp.com>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
20 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
22 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
23 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 675 Mass Ave, Cambridge, MA 02139, USA. */
29 #include <linux/kernel.h> /* For printk. */
30 #include <linux/string.h>
31 #include <linux/ipmi_msgdefs.h> /* for completion codes */
32 #include "ipmi_si_sm.h"
34 #define IPMI_BT_VERSION "v33"
36 static int bt_debug
= 0x00; /* Production value 0, see following flags */
38 #define BT_DEBUG_ENABLE 1
39 #define BT_DEBUG_MSG 2
40 #define BT_DEBUG_STATES 4
42 /* Typical "Get BT Capabilities" values are 2-3 retries, 5-10 seconds,
43 and 64 byte buffers. However, one HP implementation wants 255 bytes of
44 buffer (with a documented message of 160 bytes) so go for the max.
45 Since the Open IPMI architecture is single-message oriented at this
46 stage, the queue depth of BT is of no concern. */
48 #define BT_NORMAL_TIMEOUT 2000000 /* seconds in microseconds */
49 #define BT_RETRY_LIMIT 2
50 #define BT_RESET_DELAY 6000000 /* 6 seconds after warm reset */
54 BT_STATE_XACTION_START
,
57 BT_STATE_WRITE_CONSUME
,
60 BT_STATE_RESET1
, /* These must come last */
69 enum bt_states last_state
; /* assist printing and resets */
70 unsigned char seq
; /* BT sequence number */
72 unsigned char write_data
[IPMI_MAX_MSG_LENGTH
];
74 unsigned char read_data
[IPMI_MAX_MSG_LENGTH
];
78 unsigned int error_retries
; /* end of "common" fields */
79 int nonzero_status
; /* hung BMCs stay all 0 */
82 #define BT_CLR_WR_PTR 0x01 /* See IPMI 1.5 table 11.6.4 */
83 #define BT_CLR_RD_PTR 0x02
84 #define BT_H2B_ATN 0x04
85 #define BT_B2H_ATN 0x08
86 #define BT_SMS_ATN 0x10
88 #define BT_H_BUSY 0x40
89 #define BT_B_BUSY 0x80
91 /* Some bits are toggled on each write: write once to set it, once
92 more to clear it; writing a zero does nothing. To absolutely
93 clear it, check its state and write if set. This avoids the "get
94 current then use as mask" scheme to modify one bit. Note that the
95 variable "bt" is hardcoded into these macros. */
97 #define BT_STATUS bt->io->inputb(bt->io, 0)
98 #define BT_CONTROL(x) bt->io->outputb(bt->io, 0, x)
100 #define BMC2HOST bt->io->inputb(bt->io, 1)
101 #define HOST2BMC(x) bt->io->outputb(bt->io, 1, x)
103 #define BT_INTMASK_R bt->io->inputb(bt->io, 2)
104 #define BT_INTMASK_W(x) bt->io->outputb(bt->io, 2, x)
106 /* Convenience routines for debugging. These are not multi-open safe!
107 Note the macros have hardcoded variables in them. */
109 static char *state2txt(unsigned char state
)
112 case BT_STATE_IDLE
: return("IDLE");
113 case BT_STATE_XACTION_START
: return("XACTION");
114 case BT_STATE_WRITE_BYTES
: return("WR_BYTES");
115 case BT_STATE_WRITE_END
: return("WR_END");
116 case BT_STATE_WRITE_CONSUME
: return("WR_CONSUME");
117 case BT_STATE_B2H_WAIT
: return("B2H_WAIT");
118 case BT_STATE_READ_END
: return("RD_END");
119 case BT_STATE_RESET1
: return("RESET1");
120 case BT_STATE_RESET2
: return("RESET2");
121 case BT_STATE_RESET3
: return("RESET3");
122 case BT_STATE_RESTART
: return("RESTART");
123 case BT_STATE_HOSED
: return("HOSED");
127 #define STATE2TXT state2txt(bt->state)
129 static char *status2txt(unsigned char status
, char *buf
)
132 if (status
& BT_B_BUSY
) strcat(buf
, "B_BUSY ");
133 if (status
& BT_H_BUSY
) strcat(buf
, "H_BUSY ");
134 if (status
& BT_OEM0
) strcat(buf
, "OEM0 ");
135 if (status
& BT_SMS_ATN
) strcat(buf
, "SMS ");
136 if (status
& BT_B2H_ATN
) strcat(buf
, "B2H ");
137 if (status
& BT_H2B_ATN
) strcat(buf
, "H2B ");
141 #define STATUS2TXT(buf) status2txt(status, buf)
143 /* This will be called from within this module on a hosed condition */
145 static unsigned int bt_init_data(struct si_sm_data
*bt
, struct si_sm_io
*io
)
147 bt
->state
= BT_STATE_IDLE
;
148 bt
->last_state
= BT_STATE_IDLE
;
153 bt
->error_retries
= 0;
154 bt
->nonzero_status
= 0;
156 bt
->timeout
= BT_NORMAL_TIMEOUT
;
157 return 3; /* We claim 3 bytes of space; ought to check SPMI table */
160 static int bt_start_transaction(struct si_sm_data
*bt
,
166 if ((size
< 2) || (size
> IPMI_MAX_MSG_LENGTH
)) return -1;
168 if ((bt
->state
!= BT_STATE_IDLE
) && (bt
->state
!= BT_STATE_HOSED
))
171 if (bt_debug
& BT_DEBUG_MSG
) {
172 printk(KERN_WARNING
"+++++++++++++++++++++++++++++++++++++\n");
173 printk(KERN_WARNING
"BT: write seq=0x%02X:", bt
->seq
);
174 for (i
= 0; i
< size
; i
++) printk (" %02x", data
[i
]);
177 bt
->write_data
[0] = size
+ 1; /* all data plus seq byte */
178 bt
->write_data
[1] = *data
; /* NetFn/LUN */
179 bt
->write_data
[2] = bt
->seq
;
180 memcpy(bt
->write_data
+ 3, data
+ 1, size
- 1);
181 bt
->write_count
= size
+ 2;
183 bt
->error_retries
= 0;
184 bt
->nonzero_status
= 0;
187 bt
->state
= BT_STATE_XACTION_START
;
188 bt
->last_state
= BT_STATE_IDLE
;
189 bt
->timeout
= BT_NORMAL_TIMEOUT
;
193 /* After the upper state machine has been told SI_SM_TRANSACTION_COMPLETE
194 it calls this. Strip out the length and seq bytes. */
196 static int bt_get_result(struct si_sm_data
*bt
,
202 msg_len
= bt
->read_count
- 2; /* account for length & seq */
203 /* Always NetFn, Cmd, cCode */
204 if (msg_len
< 3 || msg_len
> IPMI_MAX_MSG_LENGTH
) {
205 printk(KERN_WARNING
"BT results: bad msg_len = %d\n", msg_len
);
206 data
[0] = bt
->write_data
[1] | 0x4; /* Kludge a response */
207 data
[1] = bt
->write_data
[3];
208 data
[2] = IPMI_ERR_UNSPECIFIED
;
211 data
[0] = bt
->read_data
[1];
212 data
[1] = bt
->read_data
[3];
213 if (length
< msg_len
) bt
->truncated
= 1;
214 if (bt
->truncated
) { /* can be set in read_all_bytes() */
215 data
[2] = IPMI_ERR_MSG_TRUNCATED
;
217 } else memcpy(data
+ 2, bt
->read_data
+ 4, msg_len
- 2);
219 if (bt_debug
& BT_DEBUG_MSG
) {
220 printk (KERN_WARNING
"BT: res (raw)");
221 for (i
= 0; i
< msg_len
; i
++) printk(" %02x", data
[i
]);
225 bt
->read_count
= 0; /* paranoia */
229 /* This bit's functionality is optional */
230 #define BT_BMC_HWRST 0x80
232 static void reset_flags(struct si_sm_data
*bt
)
234 if (BT_STATUS
& BT_H_BUSY
) BT_CONTROL(BT_H_BUSY
);
235 if (BT_STATUS
& BT_B_BUSY
) BT_CONTROL(BT_B_BUSY
);
236 BT_CONTROL(BT_CLR_WR_PTR
);
237 BT_CONTROL(BT_SMS_ATN
);
238 #ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION
239 if (BT_STATUS
& BT_B2H_ATN
) {
241 BT_CONTROL(BT_H_BUSY
);
242 BT_CONTROL(BT_B2H_ATN
);
243 BT_CONTROL(BT_CLR_RD_PTR
);
244 for (i
= 0; i
< IPMI_MAX_MSG_LENGTH
+ 2; i
++) BMC2HOST
;
245 BT_CONTROL(BT_H_BUSY
);
250 static inline void write_all_bytes(struct si_sm_data
*bt
)
254 if (bt_debug
& BT_DEBUG_MSG
) {
255 printk(KERN_WARNING
"BT: write %d bytes seq=0x%02X",
256 bt
->write_count
, bt
->seq
);
257 for (i
= 0; i
< bt
->write_count
; i
++)
258 printk (" %02x", bt
->write_data
[i
]);
261 for (i
= 0; i
< bt
->write_count
; i
++) HOST2BMC(bt
->write_data
[i
]);
264 static inline int read_all_bytes(struct si_sm_data
*bt
)
268 bt
->read_data
[0] = BMC2HOST
;
269 bt
->read_count
= bt
->read_data
[0];
270 if (bt_debug
& BT_DEBUG_MSG
)
271 printk(KERN_WARNING
"BT: read %d bytes:", bt
->read_count
);
273 /* minimum: length, NetFn, Seq, Cmd, cCode == 5 total, or 4 more
274 following the length byte. */
275 if (bt
->read_count
< 4 || bt
->read_count
>= IPMI_MAX_MSG_LENGTH
) {
276 if (bt_debug
& BT_DEBUG_MSG
)
277 printk("bad length %d\n", bt
->read_count
);
279 return 1; /* let next XACTION START clean it up */
281 for (i
= 1; i
<= bt
->read_count
; i
++) bt
->read_data
[i
] = BMC2HOST
;
282 bt
->read_count
++; /* account for the length byte */
284 if (bt_debug
& BT_DEBUG_MSG
) {
285 for (i
= 0; i
< bt
->read_count
; i
++)
286 printk (" %02x", bt
->read_data
[i
]);
289 if (bt
->seq
!= bt
->write_data
[2]) /* idiot check */
290 printk(KERN_WARNING
"BT: internal error: sequence mismatch\n");
292 /* per the spec, the (NetFn, Seq, Cmd) tuples should match */
293 if ((bt
->read_data
[3] == bt
->write_data
[3]) && /* Cmd */
294 (bt
->read_data
[2] == bt
->write_data
[2]) && /* Sequence */
295 ((bt
->read_data
[1] & 0xF8) == (bt
->write_data
[1] & 0xF8)))
298 if (bt_debug
& BT_DEBUG_MSG
) printk(KERN_WARNING
"BT: bad packet: "
299 "want 0x(%02X, %02X, %02X) got (%02X, %02X, %02X)\n",
300 bt
->write_data
[1], bt
->write_data
[2], bt
->write_data
[3],
301 bt
->read_data
[1], bt
->read_data
[2], bt
->read_data
[3]);
305 /* Modifies bt->state appropriately, need to get into the bt_event() switch */
307 static void error_recovery(struct si_sm_data
*bt
, char *reason
)
309 unsigned char status
;
310 char buf
[40]; /* For getting status */
312 bt
->timeout
= BT_NORMAL_TIMEOUT
; /* various places want to retry */
315 printk(KERN_WARNING
"BT: %s in %s %s ", reason
, STATE2TXT
,
318 (bt
->error_retries
)++;
319 if (bt
->error_retries
> BT_RETRY_LIMIT
) {
320 printk("retry limit (%d) exceeded\n", BT_RETRY_LIMIT
);
321 bt
->state
= BT_STATE_HOSED
;
322 if (!bt
->nonzero_status
)
323 printk(KERN_ERR
"IPMI: BT stuck, try power cycle\n");
324 else if (bt
->seq
== FIRST_SEQ
+ BT_RETRY_LIMIT
) {
325 /* most likely during insmod */
326 printk(KERN_WARNING
"IPMI: BT reset (takes 5 secs)\n");
327 bt
->state
= BT_STATE_RESET1
;
332 /* Sometimes the BMC queues get in an "off-by-one" state...*/
333 if ((bt
->state
== BT_STATE_B2H_WAIT
) && (status
& BT_B2H_ATN
)) {
334 printk("retry B2H_WAIT\n");
338 printk("restart command\n");
339 bt
->state
= BT_STATE_RESTART
;
342 /* Check the status and (possibly) advance the BT state machine. The
343 default return is SI_SM_CALL_WITH_DELAY. */
345 static enum si_sm_result
bt_event(struct si_sm_data
*bt
, long time
)
347 unsigned char status
;
348 char buf
[40]; /* For getting status */
352 bt
->nonzero_status
|= status
;
354 if ((bt_debug
& BT_DEBUG_STATES
) && (bt
->state
!= bt
->last_state
))
355 printk(KERN_WARNING
"BT: %s %s TO=%ld - %ld \n",
360 bt
->last_state
= bt
->state
;
362 if (bt
->state
== BT_STATE_HOSED
) return SI_SM_HOSED
;
364 if (bt
->state
!= BT_STATE_IDLE
) { /* do timeout test */
366 /* Certain states, on error conditions, can lock up a CPU
367 because they are effectively in an infinite loop with
368 CALL_WITHOUT_DELAY (right back here with time == 0).
369 Prevent infinite lockup by ALWAYS decrementing timeout. */
371 /* FIXME: bt_event is sometimes called with time > BT_NORMAL_TIMEOUT
372 (noticed in ipmi_smic_sm.c January 2004) */
374 if ((time
<= 0) || (time
>= BT_NORMAL_TIMEOUT
)) time
= 100;
376 if ((bt
->timeout
< 0) && (bt
->state
< BT_STATE_RESET1
)) {
377 error_recovery(bt
, "timed out");
378 return SI_SM_CALL_WITHOUT_DELAY
;
384 case BT_STATE_IDLE
: /* check for asynchronous messages */
385 if (status
& BT_SMS_ATN
) {
386 BT_CONTROL(BT_SMS_ATN
); /* clear it */
391 case BT_STATE_XACTION_START
:
392 if (status
& BT_H_BUSY
) {
393 BT_CONTROL(BT_H_BUSY
);
396 if (status
& BT_B2H_ATN
) break;
397 bt
->state
= BT_STATE_WRITE_BYTES
;
398 return SI_SM_CALL_WITHOUT_DELAY
; /* for logging */
400 case BT_STATE_WRITE_BYTES
:
401 if (status
& (BT_B_BUSY
| BT_H2B_ATN
)) break;
402 BT_CONTROL(BT_CLR_WR_PTR
);
404 BT_CONTROL(BT_H2B_ATN
); /* clears too fast to catch? */
405 bt
->state
= BT_STATE_WRITE_CONSUME
;
406 return SI_SM_CALL_WITHOUT_DELAY
; /* it MIGHT sail through */
408 case BT_STATE_WRITE_CONSUME
: /* BMCs usually blow right thru here */
409 if (status
& (BT_H2B_ATN
| BT_B_BUSY
)) break;
410 bt
->state
= BT_STATE_B2H_WAIT
;
411 /* fall through with status */
413 /* Stay in BT_STATE_B2H_WAIT until a packet matches. However, spinning
414 hard here, constantly reading status, seems to hold off the
415 generation of B2H_ATN so ALWAYS return CALL_WITH_DELAY. */
417 case BT_STATE_B2H_WAIT
:
418 if (!(status
& BT_B2H_ATN
)) break;
420 /* Assume ordered, uncached writes: no need to wait */
421 if (!(status
& BT_H_BUSY
)) BT_CONTROL(BT_H_BUSY
); /* set */
422 BT_CONTROL(BT_B2H_ATN
); /* clear it, ACK to the BMC */
423 BT_CONTROL(BT_CLR_RD_PTR
); /* reset the queue */
424 i
= read_all_bytes(bt
);
425 BT_CONTROL(BT_H_BUSY
); /* clear */
426 if (!i
) break; /* Try this state again */
427 bt
->state
= BT_STATE_READ_END
;
428 return SI_SM_CALL_WITHOUT_DELAY
; /* for logging */
430 case BT_STATE_READ_END
:
432 /* I could wait on BT_H_BUSY to go clear for a truly clean
433 exit. However, this is already done in XACTION_START
434 and the (possible) extra loop/status/possible wait affects
435 performance. So, as long as it works, just ignore H_BUSY */
437 #ifdef MAKE_THIS_TRUE_IF_NECESSARY
439 if (status
& BT_H_BUSY
) break;
442 bt
->state
= BT_STATE_IDLE
;
443 return SI_SM_TRANSACTION_COMPLETE
;
445 case BT_STATE_RESET1
:
447 bt
->timeout
= BT_RESET_DELAY
;
448 bt
->state
= BT_STATE_RESET2
;
451 case BT_STATE_RESET2
: /* Send a soft reset */
452 BT_CONTROL(BT_CLR_WR_PTR
);
453 HOST2BMC(3); /* number of bytes following */
454 HOST2BMC(0x18); /* NetFn/LUN == Application, LUN 0 */
455 HOST2BMC(42); /* Sequence number */
456 HOST2BMC(3); /* Cmd == Soft reset */
457 BT_CONTROL(BT_H2B_ATN
);
458 bt
->state
= BT_STATE_RESET3
;
461 case BT_STATE_RESET3
:
462 if (bt
->timeout
> 0) return SI_SM_CALL_WITH_DELAY
;
463 bt
->state
= BT_STATE_RESTART
; /* printk in debug modes */
466 case BT_STATE_RESTART
: /* don't reset retries! */
467 bt
->write_data
[2] = ++bt
->seq
;
469 bt
->nonzero_status
= 0;
470 bt
->timeout
= BT_NORMAL_TIMEOUT
;
471 bt
->state
= BT_STATE_XACTION_START
;
474 default: /* HOSED is supposed to be caught much earlier */
475 error_recovery(bt
, "internal logic error");
478 return SI_SM_CALL_WITH_DELAY
;
481 static int bt_detect(struct si_sm_data
*bt
)
483 /* It's impossible for the BT status and interrupt registers to be
484 all 1's, (assuming a properly functioning, self-initialized BMC)
485 but that's what you get from reading a bogus address, so we
486 test that first. The calling routine uses negative logic. */
488 if ((BT_STATUS
== 0xFF) && (BT_INTMASK_R
== 0xFF)) return 1;
493 static void bt_cleanup(struct si_sm_data
*bt
)
497 static int bt_size(void)
499 return sizeof(struct si_sm_data
);
502 struct si_sm_handlers bt_smi_handlers
=
504 .version
= IPMI_BT_VERSION
,
505 .init_data
= bt_init_data
,
506 .start_transaction
= bt_start_transaction
,
507 .get_result
= bt_get_result
,
510 .cleanup
= bt_cleanup
,