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 static int bt_debug = 0x00; /* Production value 0, see following flags */
36 #define BT_DEBUG_ENABLE 1
37 #define BT_DEBUG_MSG 2
38 #define BT_DEBUG_STATES 4
40 /* 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
42 buffer (with a documented message of 160 bytes) so go for the max.
43 Since the Open IPMI architecture is single-message oriented at this
44 stage, the queue depth of BT is of no concern. */
46 #define BT_NORMAL_TIMEOUT 2000000 /* seconds in microseconds */
47 #define BT_RETRY_LIMIT 2
48 #define BT_RESET_DELAY 6000000 /* 6 seconds after warm reset */
52 BT_STATE_XACTION_START,
55 BT_STATE_WRITE_CONSUME,
58 BT_STATE_RESET1, /* These must come last */
67 enum bt_states last_state; /* assist printing and resets */
68 unsigned char seq; /* BT sequence number */
70 unsigned char write_data[IPMI_MAX_MSG_LENGTH];
72 unsigned char read_data[IPMI_MAX_MSG_LENGTH];
76 unsigned int error_retries; /* end of "common" fields */
77 int nonzero_status; /* hung BMCs stay all 0 */
80 #define BT_CLR_WR_PTR 0x01 /* See IPMI 1.5 table 11.6.4 */
81 #define BT_CLR_RD_PTR 0x02
82 #define BT_H2B_ATN 0x04
83 #define BT_B2H_ATN 0x08
84 #define BT_SMS_ATN 0x10
86 #define BT_H_BUSY 0x40
87 #define BT_B_BUSY 0x80
89 /* Some bits are toggled on each write: write once to set it, once
90 more to clear it; writing a zero does nothing. To absolutely
91 clear it, check its state and write if set. This avoids the "get
92 current then use as mask" scheme to modify one bit. Note that the
93 variable "bt" is hardcoded into these macros. */
95 #define BT_STATUS bt->io->inputb(bt->io, 0)
96 #define BT_CONTROL(x) bt->io->outputb(bt->io, 0, x)
98 #define BMC2HOST bt->io->inputb(bt->io, 1)
99 #define HOST2BMC(x) bt->io->outputb(bt->io, 1, x)
101 #define BT_INTMASK_R bt->io->inputb(bt->io, 2)
102 #define BT_INTMASK_W(x) bt->io->outputb(bt->io, 2, x)
104 /* Convenience routines for debugging. These are not multi-open safe!
105 Note the macros have hardcoded variables in them. */
107 static char *state2txt(unsigned char state)
110 case BT_STATE_IDLE: return("IDLE");
111 case BT_STATE_XACTION_START: return("XACTION");
112 case BT_STATE_WRITE_BYTES: return("WR_BYTES");
113 case BT_STATE_WRITE_END: return("WR_END");
114 case BT_STATE_WRITE_CONSUME: return("WR_CONSUME");
115 case BT_STATE_B2H_WAIT: return("B2H_WAIT");
116 case BT_STATE_READ_END: return("RD_END");
117 case BT_STATE_RESET1: return("RESET1");
118 case BT_STATE_RESET2: return("RESET2");
119 case BT_STATE_RESET3: return("RESET3");
120 case BT_STATE_RESTART: return("RESTART");
121 case BT_STATE_HOSED: return("HOSED");
125 #define STATE2TXT state2txt(bt->state)
127 static char *status2txt(unsigned char status, char *buf)
130 if (status & BT_B_BUSY) strcat(buf, "B_BUSY ");
131 if (status & BT_H_BUSY) strcat(buf, "H_BUSY ");
132 if (status & BT_OEM0) strcat(buf, "OEM0 ");
133 if (status & BT_SMS_ATN) strcat(buf, "SMS ");
134 if (status & BT_B2H_ATN) strcat(buf, "B2H ");
135 if (status & BT_H2B_ATN) strcat(buf, "H2B ");
139 #define STATUS2TXT(buf) status2txt(status, buf)
141 /* This will be called from within this module on a hosed condition */
143 static unsigned int bt_init_data(struct si_sm_data *bt, struct si_sm_io *io)
145 bt->state = BT_STATE_IDLE;
146 bt->last_state = BT_STATE_IDLE;
151 bt->error_retries = 0;
152 bt->nonzero_status = 0;
154 bt->timeout = BT_NORMAL_TIMEOUT;
155 return 3; /* We claim 3 bytes of space; ought to check SPMI table */
158 static int bt_start_transaction(struct si_sm_data *bt,
164 if ((size < 2) || (size > IPMI_MAX_MSG_LENGTH))
167 if ((bt->state != BT_STATE_IDLE) && (bt->state != BT_STATE_HOSED))
170 if (bt_debug & BT_DEBUG_MSG) {
171 printk(KERN_WARNING "+++++++++++++++++++++++++++++++++++++\n");
172 printk(KERN_WARNING "BT: write seq=0x%02X:", bt->seq);
173 for (i = 0; i < size; i ++)
174 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)
215 if (bt->truncated) { /* can be set in read_all_bytes() */
216 data[2] = IPMI_ERR_MSG_TRUNCATED;
219 memcpy(data + 2, bt->read_data + 4, msg_len - 2);
221 if (bt_debug & BT_DEBUG_MSG) {
222 printk (KERN_WARNING "BT: res (raw)");
223 for (i = 0; i < msg_len; i++)
224 printk(" %02x", data[i]);
228 bt->read_count = 0; /* paranoia */
232 /* This bit's functionality is optional */
233 #define BT_BMC_HWRST 0x80
235 static void reset_flags(struct si_sm_data *bt)
237 if (BT_STATUS & BT_H_BUSY)
238 BT_CONTROL(BT_H_BUSY);
239 if (BT_STATUS & BT_B_BUSY)
240 BT_CONTROL(BT_B_BUSY);
241 BT_CONTROL(BT_CLR_WR_PTR);
242 BT_CONTROL(BT_SMS_ATN);
243 #ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION
244 if (BT_STATUS & BT_B2H_ATN) {
246 BT_CONTROL(BT_H_BUSY);
247 BT_CONTROL(BT_B2H_ATN);
248 BT_CONTROL(BT_CLR_RD_PTR);
249 for (i = 0; i < IPMI_MAX_MSG_LENGTH + 2; i++)
251 BT_CONTROL(BT_H_BUSY);
256 static inline void write_all_bytes(struct si_sm_data *bt)
260 if (bt_debug & BT_DEBUG_MSG) {
261 printk(KERN_WARNING "BT: write %d bytes seq=0x%02X",
262 bt->write_count, bt->seq);
263 for (i = 0; i < bt->write_count; i++)
264 printk (" %02x", bt->write_data[i]);
267 for (i = 0; i < bt->write_count; i++)
268 HOST2BMC(bt->write_data[i]);
271 static inline int read_all_bytes(struct si_sm_data *bt)
275 bt->read_data[0] = BMC2HOST;
276 bt->read_count = bt->read_data[0];
277 if (bt_debug & BT_DEBUG_MSG)
278 printk(KERN_WARNING "BT: read %d bytes:", bt->read_count);
280 /* minimum: length, NetFn, Seq, Cmd, cCode == 5 total, or 4 more
281 following the length byte. */
282 if (bt->read_count < 4 || bt->read_count >= IPMI_MAX_MSG_LENGTH) {
283 if (bt_debug & BT_DEBUG_MSG)
284 printk("bad length %d\n", bt->read_count);
286 return 1; /* let next XACTION START clean it up */
288 for (i = 1; i <= bt->read_count; i++)
289 bt->read_data[i] = BMC2HOST;
290 bt->read_count++; /* account for the length byte */
292 if (bt_debug & BT_DEBUG_MSG) {
293 for (i = 0; i < bt->read_count; i++)
294 printk (" %02x", bt->read_data[i]);
297 if (bt->seq != bt->write_data[2]) /* idiot check */
298 printk(KERN_WARNING "BT: internal error: sequence mismatch\n");
300 /* per the spec, the (NetFn, Seq, Cmd) tuples should match */
301 if ((bt->read_data[3] == bt->write_data[3]) && /* Cmd */
302 (bt->read_data[2] == bt->write_data[2]) && /* Sequence */
303 ((bt->read_data[1] & 0xF8) == (bt->write_data[1] & 0xF8)))
306 if (bt_debug & BT_DEBUG_MSG)
307 printk(KERN_WARNING "BT: bad packet: "
308 "want 0x(%02X, %02X, %02X) got (%02X, %02X, %02X)\n",
309 bt->write_data[1], bt->write_data[2], bt->write_data[3],
310 bt->read_data[1], bt->read_data[2], bt->read_data[3]);
314 /* Modifies bt->state appropriately, need to get into the bt_event() switch */
316 static void error_recovery(struct si_sm_data *bt, char *reason)
318 unsigned char status;
319 char buf[40]; /* For getting status */
321 bt->timeout = BT_NORMAL_TIMEOUT; /* various places want to retry */
324 printk(KERN_WARNING "BT: %s in %s %s ", reason, STATE2TXT,
327 (bt->error_retries)++;
328 if (bt->error_retries > BT_RETRY_LIMIT) {
329 printk("retry limit (%d) exceeded\n", BT_RETRY_LIMIT);
330 bt->state = BT_STATE_HOSED;
331 if (!bt->nonzero_status)
332 printk(KERN_ERR "IPMI: BT stuck, try power cycle\n");
333 else if (bt->seq == FIRST_SEQ + BT_RETRY_LIMIT) {
334 /* most likely during insmod */
335 printk(KERN_WARNING "IPMI: BT reset (takes 5 secs)\n");
336 bt->state = BT_STATE_RESET1;
341 /* Sometimes the BMC queues get in an "off-by-one" state...*/
342 if ((bt->state == BT_STATE_B2H_WAIT) && (status & BT_B2H_ATN)) {
343 printk("retry B2H_WAIT\n");
347 printk("restart command\n");
348 bt->state = BT_STATE_RESTART;
351 /* Check the status and (possibly) advance the BT state machine. The
352 default return is SI_SM_CALL_WITH_DELAY. */
354 static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
356 unsigned char status;
357 char buf[40]; /* For getting status */
361 bt->nonzero_status |= status;
363 if ((bt_debug & BT_DEBUG_STATES) && (bt->state != bt->last_state))
364 printk(KERN_WARNING "BT: %s %s TO=%ld - %ld \n",
369 bt->last_state = bt->state;
371 if (bt->state == BT_STATE_HOSED)
374 if (bt->state != BT_STATE_IDLE) { /* do timeout test */
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. */
381 /* FIXME: bt_event is sometimes called with time > BT_NORMAL_TIMEOUT
382 (noticed in ipmi_smic_sm.c January 2004) */
384 if ((time <= 0) || (time >= BT_NORMAL_TIMEOUT))
387 if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1)) {
388 error_recovery(bt, "timed out");
389 return SI_SM_CALL_WITHOUT_DELAY;
395 case BT_STATE_IDLE: /* check for asynchronous messages */
396 if (status & BT_SMS_ATN) {
397 BT_CONTROL(BT_SMS_ATN); /* clear it */
402 case BT_STATE_XACTION_START:
403 if (status & BT_H_BUSY) {
404 BT_CONTROL(BT_H_BUSY);
407 if (status & BT_B2H_ATN)
409 bt->state = BT_STATE_WRITE_BYTES;
410 return SI_SM_CALL_WITHOUT_DELAY; /* for logging */
412 case BT_STATE_WRITE_BYTES:
413 if (status & (BT_B_BUSY | BT_H2B_ATN))
415 BT_CONTROL(BT_CLR_WR_PTR);
417 BT_CONTROL(BT_H2B_ATN); /* clears too fast to catch? */
418 bt->state = BT_STATE_WRITE_CONSUME;
419 return SI_SM_CALL_WITHOUT_DELAY; /* it MIGHT sail through */
421 case BT_STATE_WRITE_CONSUME: /* BMCs usually blow right thru here */
422 if (status & (BT_H2B_ATN | BT_B_BUSY))
424 bt->state = BT_STATE_B2H_WAIT;
425 /* fall through with status */
427 /* Stay in BT_STATE_B2H_WAIT until a packet matches. However, spinning
428 hard here, constantly reading status, seems to hold off the
429 generation of B2H_ATN so ALWAYS return CALL_WITH_DELAY. */
431 case BT_STATE_B2H_WAIT:
432 if (!(status & BT_B2H_ATN))
435 /* Assume ordered, uncached writes: no need to wait */
436 if (!(status & BT_H_BUSY))
437 BT_CONTROL(BT_H_BUSY); /* set */
438 BT_CONTROL(BT_B2H_ATN); /* clear it, ACK to the BMC */
439 BT_CONTROL(BT_CLR_RD_PTR); /* reset the queue */
440 i = read_all_bytes(bt);
441 BT_CONTROL(BT_H_BUSY); /* clear */
442 if (!i) /* Try this state again */
444 bt->state = BT_STATE_READ_END;
445 return SI_SM_CALL_WITHOUT_DELAY; /* for logging */
447 case BT_STATE_READ_END:
449 /* I could wait on BT_H_BUSY to go clear for a truly clean
450 exit. However, this is already done in XACTION_START
451 and the (possible) extra loop/status/possible wait affects
452 performance. So, as long as it works, just ignore H_BUSY */
454 #ifdef MAKE_THIS_TRUE_IF_NECESSARY
456 if (status & BT_H_BUSY)
460 bt->state = BT_STATE_IDLE;
461 return SI_SM_TRANSACTION_COMPLETE;
463 case BT_STATE_RESET1:
465 bt->timeout = BT_RESET_DELAY;
466 bt->state = BT_STATE_RESET2;
469 case BT_STATE_RESET2: /* Send a soft reset */
470 BT_CONTROL(BT_CLR_WR_PTR);
471 HOST2BMC(3); /* number of bytes following */
472 HOST2BMC(0x18); /* NetFn/LUN == Application, LUN 0 */
473 HOST2BMC(42); /* Sequence number */
474 HOST2BMC(3); /* Cmd == Soft reset */
475 BT_CONTROL(BT_H2B_ATN);
476 bt->state = BT_STATE_RESET3;
479 case BT_STATE_RESET3:
481 return SI_SM_CALL_WITH_DELAY;
482 bt->state = BT_STATE_RESTART; /* printk in debug modes */
485 case BT_STATE_RESTART: /* don't reset retries! */
486 bt->write_data[2] = ++bt->seq;
488 bt->nonzero_status = 0;
489 bt->timeout = BT_NORMAL_TIMEOUT;
490 bt->state = BT_STATE_XACTION_START;
493 default: /* HOSED is supposed to be caught much earlier */
494 error_recovery(bt, "internal logic error");
497 return SI_SM_CALL_WITH_DELAY;
500 static int bt_detect(struct si_sm_data *bt)
502 /* It's impossible for the BT status and interrupt registers to be
503 all 1's, (assuming a properly functioning, self-initialized BMC)
504 but that's what you get from reading a bogus address, so we
505 test that first. The calling routine uses negative logic. */
507 if ((BT_STATUS == 0xFF) && (BT_INTMASK_R == 0xFF))
513 static void bt_cleanup(struct si_sm_data *bt)
517 static int bt_size(void)
519 return sizeof(struct si_sm_data);
522 struct si_sm_handlers bt_smi_handlers =
524 .init_data = bt_init_data,
525 .start_transaction = bt_start_transaction,
526 .get_result = bt_get_result,
529 .cleanup = bt_cleanup,