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/module.h>
32 #include <linux/moduleparam.h>
33 #include <linux/ipmi_msgdefs.h> /* for completion codes */
34 #include "ipmi_si_sm.h"
36 #define BT_DEBUG_OFF 0 /* Used in production */
37 #define BT_DEBUG_ENABLE 1 /* Generic messages */
38 #define BT_DEBUG_MSG 2 /* Prints all request/response buffers */
39 #define BT_DEBUG_STATES 4 /* Verbose look at state changes */
40 /* BT_DEBUG_OFF must be zero to correspond to the default uninitialized
43 static int bt_debug; /* 0 == BT_DEBUG_OFF */
45 module_param(bt_debug, int, 0644);
46 MODULE_PARM_DESC(bt_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
48 /* Typical "Get BT Capabilities" values are 2-3 retries, 5-10 seconds,
49 and 64 byte buffers. However, one HP implementation wants 255 bytes of
50 buffer (with a documented message of 160 bytes) so go for the max.
51 Since the Open IPMI architecture is single-message oriented at this
52 stage, the queue depth of BT is of no concern. */
54 #define BT_NORMAL_TIMEOUT 5 /* seconds */
55 #define BT_NORMAL_RETRY_LIMIT 2
56 #define BT_RESET_DELAY 6 /* seconds after warm reset */
58 /* States are written in chronological order and usually cover
59 multiple rows of the state table discussion in the IPMI spec. */
62 BT_STATE_IDLE = 0, /* Order is critical in this list */
63 BT_STATE_XACTION_START,
65 BT_STATE_WRITE_CONSUME,
69 BT_STATE_RESET1, /* These must come last */
74 BT_STATE_CAPABILITIES_BEGIN,
75 BT_STATE_CAPABILITIES_END,
76 BT_STATE_LONG_BUSY /* BT doesn't get hosed :-) */
79 /* Macros seen at the end of state "case" blocks. They help with legibility
82 #define BT_STATE_CHANGE(X,Y) { bt->state = X; return Y; }
84 #define BT_SI_SM_RETURN(Y) { last_printed = BT_STATE_PRINTME; return Y; }
88 unsigned char seq; /* BT sequence number */
90 unsigned char write_data[IPMI_MAX_MSG_LENGTH];
92 unsigned char read_data[IPMI_MAX_MSG_LENGTH];
95 long timeout; /* microseconds countdown */
96 int error_retries; /* end of "common" fields */
97 int nonzero_status; /* hung BMCs stay all 0 */
98 enum bt_states complete; /* to divert the state machine */
101 int BT_CAP_retries; /* Recommended retries */
104 #define BT_CLR_WR_PTR 0x01 /* See IPMI 1.5 table 11.6.4 */
105 #define BT_CLR_RD_PTR 0x02
106 #define BT_H2B_ATN 0x04
107 #define BT_B2H_ATN 0x08
108 #define BT_SMS_ATN 0x10
110 #define BT_H_BUSY 0x40
111 #define BT_B_BUSY 0x80
113 /* Some bits are toggled on each write: write once to set it, once
114 more to clear it; writing a zero does nothing. To absolutely
115 clear it, check its state and write if set. This avoids the "get
116 current then use as mask" scheme to modify one bit. Note that the
117 variable "bt" is hardcoded into these macros. */
119 #define BT_STATUS bt->io->inputb(bt->io, 0)
120 #define BT_CONTROL(x) bt->io->outputb(bt->io, 0, x)
122 #define BMC2HOST bt->io->inputb(bt->io, 1)
123 #define HOST2BMC(x) bt->io->outputb(bt->io, 1, x)
125 #define BT_INTMASK_R bt->io->inputb(bt->io, 2)
126 #define BT_INTMASK_W(x) bt->io->outputb(bt->io, 2, x)
128 /* Convenience routines for debugging. These are not multi-open safe!
129 Note the macros have hardcoded variables in them. */
131 static char *state2txt(unsigned char state)
134 case BT_STATE_IDLE: return("IDLE");
135 case BT_STATE_XACTION_START: return("XACTION");
136 case BT_STATE_WRITE_BYTES: return("WR_BYTES");
137 case BT_STATE_WRITE_CONSUME: return("WR_CONSUME");
138 case BT_STATE_READ_WAIT: return("RD_WAIT");
139 case BT_STATE_CLEAR_B2H: return("CLEAR_B2H");
140 case BT_STATE_READ_BYTES: return("RD_BYTES");
141 case BT_STATE_RESET1: return("RESET1");
142 case BT_STATE_RESET2: return("RESET2");
143 case BT_STATE_RESET3: return("RESET3");
144 case BT_STATE_RESTART: return("RESTART");
145 case BT_STATE_LONG_BUSY: return("LONG_BUSY");
146 case BT_STATE_CAPABILITIES_BEGIN: return("CAP_BEGIN");
147 case BT_STATE_CAPABILITIES_END: return("CAP_END");
151 #define STATE2TXT state2txt(bt->state)
153 static char *status2txt(unsigned char status)
156 * This cannot be called by two threads at the same time and
157 * the buffer is always consumed immediately, so the static is
163 if (status & BT_B_BUSY)
164 strcat(buf, "B_BUSY ");
165 if (status & BT_H_BUSY)
166 strcat(buf, "H_BUSY ");
167 if (status & BT_OEM0)
168 strcat(buf, "OEM0 ");
169 if (status & BT_SMS_ATN)
171 if (status & BT_B2H_ATN)
173 if (status & BT_H2B_ATN)
178 #define STATUS2TXT status2txt(status)
180 /* called externally at insmod time, and internally on cleanup */
182 static unsigned int bt_init_data(struct si_sm_data *bt, struct si_sm_io *io)
184 memset(bt, 0, sizeof(struct si_sm_data));
185 if (bt->io != io) { /* external: one-time only things */
189 bt->state = BT_STATE_IDLE; /* start here */
190 bt->complete = BT_STATE_IDLE; /* end here */
191 bt->BT_CAP_req2rsp = BT_NORMAL_TIMEOUT * 1000000;
192 bt->BT_CAP_retries = BT_NORMAL_RETRY_LIMIT;
193 /* BT_CAP_outreqs == zero is a flag to read BT Capabilities */
194 return 3; /* We claim 3 bytes of space; ought to check SPMI table */
197 /* Jam a completion code (probably an error) into a response */
199 static void force_result(struct si_sm_data *bt, unsigned char completion_code)
201 bt->read_data[0] = 4; /* # following bytes */
202 bt->read_data[1] = bt->write_data[1] | 4; /* Odd NetFn/LUN */
203 bt->read_data[2] = bt->write_data[2]; /* seq (ignored) */
204 bt->read_data[3] = bt->write_data[3]; /* Command */
205 bt->read_data[4] = completion_code;
209 /* The upper state machine starts here */
211 static int bt_start_transaction(struct si_sm_data *bt,
218 return IPMI_REQ_LEN_INVALID_ERR;
219 if (size > IPMI_MAX_MSG_LENGTH)
220 return IPMI_REQ_LEN_EXCEEDED_ERR;
222 if (bt->state == BT_STATE_LONG_BUSY)
223 return IPMI_NODE_BUSY_ERR;
225 if (bt->state != BT_STATE_IDLE)
226 return IPMI_NOT_IN_MY_STATE_ERR;
228 if (bt_debug & BT_DEBUG_MSG) {
229 printk(KERN_WARNING "BT: +++++++++++++++++ New command\n");
230 printk(KERN_WARNING "BT: NetFn/LUN CMD [%d data]:", size - 2);
231 for (i = 0; i < size; i ++)
232 printk (" %02x", data[i]);
235 bt->write_data[0] = size + 1; /* all data plus seq byte */
236 bt->write_data[1] = *data; /* NetFn/LUN */
237 bt->write_data[2] = bt->seq++;
238 memcpy(bt->write_data + 3, data + 1, size - 1);
239 bt->write_count = size + 2;
240 bt->error_retries = 0;
241 bt->nonzero_status = 0;
243 bt->state = BT_STATE_XACTION_START;
244 bt->timeout = bt->BT_CAP_req2rsp;
245 force_result(bt, IPMI_ERR_UNSPECIFIED);
249 /* After the upper state machine has been told SI_SM_TRANSACTION_COMPLETE
250 it calls this. Strip out the length and seq bytes. */
252 static int bt_get_result(struct si_sm_data *bt,
258 msg_len = bt->read_count - 2; /* account for length & seq */
259 if (msg_len < 3 || msg_len > IPMI_MAX_MSG_LENGTH) {
260 force_result(bt, IPMI_ERR_UNSPECIFIED);
263 data[0] = bt->read_data[1];
264 data[1] = bt->read_data[3];
265 if (length < msg_len || bt->truncated) {
266 data[2] = IPMI_ERR_MSG_TRUNCATED;
269 memcpy(data + 2, bt->read_data + 4, msg_len - 2);
271 if (bt_debug & BT_DEBUG_MSG) {
272 printk (KERN_WARNING "BT: result %d bytes:", msg_len);
273 for (i = 0; i < msg_len; i++)
274 printk(" %02x", data[i]);
280 /* This bit's functionality is optional */
281 #define BT_BMC_HWRST 0x80
283 static void reset_flags(struct si_sm_data *bt)
286 printk(KERN_WARNING "IPMI BT: flag reset %s\n",
287 status2txt(BT_STATUS));
288 if (BT_STATUS & BT_H_BUSY)
289 BT_CONTROL(BT_H_BUSY); /* force clear */
290 BT_CONTROL(BT_CLR_WR_PTR); /* always reset */
291 BT_CONTROL(BT_SMS_ATN); /* always clear */
292 BT_INTMASK_W(BT_BMC_HWRST);
295 /* Get rid of an unwanted/stale response. This should only be needed for
296 BMCs that support multiple outstanding requests. */
298 static void drain_BMC2HOST(struct si_sm_data *bt)
302 if (!(BT_STATUS & BT_B2H_ATN)) /* Not signalling a response */
305 BT_CONTROL(BT_H_BUSY); /* now set */
306 BT_CONTROL(BT_B2H_ATN); /* always clear */
307 BT_STATUS; /* pause */
308 BT_CONTROL(BT_B2H_ATN); /* some BMCs are stubborn */
309 BT_CONTROL(BT_CLR_RD_PTR); /* always reset */
311 printk(KERN_WARNING "IPMI BT: stale response %s; ",
312 status2txt(BT_STATUS));
314 for (i = 0; i < size ; i++)
316 BT_CONTROL(BT_H_BUSY); /* now clear */
318 printk("drained %d bytes\n", size + 1);
321 static inline void write_all_bytes(struct si_sm_data *bt)
325 if (bt_debug & BT_DEBUG_MSG) {
326 printk(KERN_WARNING "BT: write %d bytes seq=0x%02X",
327 bt->write_count, bt->seq);
328 for (i = 0; i < bt->write_count; i++)
329 printk (" %02x", bt->write_data[i]);
332 for (i = 0; i < bt->write_count; i++)
333 HOST2BMC(bt->write_data[i]);
336 static inline int read_all_bytes(struct si_sm_data *bt)
340 /* length is "framing info", minimum = 4: NetFn, Seq, Cmd, cCode.
341 Keep layout of first four bytes aligned with write_data[] */
343 bt->read_data[0] = BMC2HOST;
344 bt->read_count = bt->read_data[0];
346 if (bt->read_count < 4 || bt->read_count >= IPMI_MAX_MSG_LENGTH) {
347 if (bt_debug & BT_DEBUG_MSG)
348 printk(KERN_WARNING "BT: bad raw rsp len=%d\n",
351 return 1; /* let next XACTION START clean it up */
353 for (i = 1; i <= bt->read_count; i++)
354 bt->read_data[i] = BMC2HOST;
355 bt->read_count++; /* Account internally for length byte */
357 if (bt_debug & BT_DEBUG_MSG) {
358 int max = bt->read_count;
360 printk(KERN_WARNING "BT: got %d bytes seq=0x%02X",
361 max, bt->read_data[2]);
364 for (i = 0; i < max; i++)
365 printk (" %02x", bt->read_data[i]);
366 printk ("%s\n", bt->read_count == max ? "" : " ...");
369 /* per the spec, the (NetFn[1], Seq[2], Cmd[3]) tuples must match */
370 if ((bt->read_data[3] == bt->write_data[3]) &&
371 (bt->read_data[2] == bt->write_data[2]) &&
372 ((bt->read_data[1] & 0xF8) == (bt->write_data[1] & 0xF8)))
375 if (bt_debug & BT_DEBUG_MSG)
376 printk(KERN_WARNING "IPMI BT: bad packet: "
377 "want 0x(%02X, %02X, %02X) got (%02X, %02X, %02X)\n",
378 bt->write_data[1] | 0x04, bt->write_data[2], bt->write_data[3],
379 bt->read_data[1], bt->read_data[2], bt->read_data[3]);
383 /* Restart if retries are left, or return an error completion code */
385 static enum si_sm_result error_recovery(struct si_sm_data *bt,
386 unsigned char status,
391 bt->timeout = bt->BT_CAP_req2rsp;
394 case IPMI_TIMEOUT_ERR:
398 reason = "internal error";
402 printk(KERN_WARNING "IPMI BT: %s in %s %s ", /* open-ended line */
403 reason, STATE2TXT, STATUS2TXT);
405 /* Per the IPMI spec, retries are based on the sequence number
406 known only to this module, so manage a restart here. */
407 (bt->error_retries)++;
408 if (bt->error_retries < bt->BT_CAP_retries) {
409 printk("%d retries left\n",
410 bt->BT_CAP_retries - bt->error_retries);
411 bt->state = BT_STATE_RESTART;
412 return SI_SM_CALL_WITHOUT_DELAY;
415 printk("failed %d retries, sending error response\n",
417 if (!bt->nonzero_status)
418 printk(KERN_ERR "IPMI BT: stuck, try power cycle\n");
420 /* this is most likely during insmod */
421 else if (bt->seq <= (unsigned char)(bt->BT_CAP_retries & 0xFF)) {
422 printk(KERN_WARNING "IPMI: BT reset (takes 5 secs)\n");
423 bt->state = BT_STATE_RESET1;
424 return SI_SM_CALL_WITHOUT_DELAY;
427 /* Concoct a useful error message, set up the next state, and
428 be done with this sequence. */
430 bt->state = BT_STATE_IDLE;
432 case IPMI_TIMEOUT_ERR:
433 if (status & BT_B_BUSY) {
434 cCode = IPMI_NODE_BUSY_ERR;
435 bt->state = BT_STATE_LONG_BUSY;
441 force_result(bt, cCode);
442 return SI_SM_TRANSACTION_COMPLETE;
445 /* Check status and (usually) take action and change this state machine. */
447 static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
449 unsigned char status, BT_CAP[8];
450 static enum bt_states last_printed = BT_STATE_PRINTME;
454 bt->nonzero_status |= status;
455 if ((bt_debug & BT_DEBUG_STATES) && (bt->state != last_printed)) {
456 printk(KERN_WARNING "BT: %s %s TO=%ld - %ld \n",
461 last_printed = bt->state;
464 /* Commands that time out may still (eventually) provide a response.
465 This stale response will get in the way of a new response so remove
466 it if possible (hopefully during IDLE). Even if it comes up later
467 it will be rejected by its (now-forgotten) seq number. */
469 if ((bt->state < BT_STATE_WRITE_BYTES) && (status & BT_B2H_ATN)) {
471 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
474 if ((bt->state != BT_STATE_IDLE) &&
475 (bt->state < BT_STATE_PRINTME)) { /* check timeout */
477 if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1))
478 return error_recovery(bt,
485 /* Idle state first checks for asynchronous messages from another
486 channel, then does some opportunistic housekeeping. */
489 if (status & BT_SMS_ATN) {
490 BT_CONTROL(BT_SMS_ATN); /* clear it */
494 if (status & BT_H_BUSY) /* clear a leftover H_BUSY */
495 BT_CONTROL(BT_H_BUSY);
497 /* Read BT capabilities if it hasn't been done yet */
498 if (!bt->BT_CAP_outreqs)
499 BT_STATE_CHANGE(BT_STATE_CAPABILITIES_BEGIN,
500 SI_SM_CALL_WITHOUT_DELAY);
501 bt->timeout = bt->BT_CAP_req2rsp;
502 BT_SI_SM_RETURN(SI_SM_IDLE);
504 case BT_STATE_XACTION_START:
505 if (status & (BT_B_BUSY | BT_H2B_ATN))
506 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
507 if (BT_STATUS & BT_H_BUSY)
508 BT_CONTROL(BT_H_BUSY); /* force clear */
509 BT_STATE_CHANGE(BT_STATE_WRITE_BYTES,
510 SI_SM_CALL_WITHOUT_DELAY);
512 case BT_STATE_WRITE_BYTES:
513 if (status & BT_H_BUSY)
514 BT_CONTROL(BT_H_BUSY); /* clear */
515 BT_CONTROL(BT_CLR_WR_PTR);
517 BT_CONTROL(BT_H2B_ATN); /* can clear too fast to catch */
518 BT_STATE_CHANGE(BT_STATE_WRITE_CONSUME,
519 SI_SM_CALL_WITHOUT_DELAY);
521 case BT_STATE_WRITE_CONSUME:
522 if (status & (BT_B_BUSY | BT_H2B_ATN))
523 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
524 BT_STATE_CHANGE(BT_STATE_READ_WAIT,
525 SI_SM_CALL_WITHOUT_DELAY);
527 /* Spinning hard can suppress B2H_ATN and force a timeout */
529 case BT_STATE_READ_WAIT:
530 if (!(status & BT_B2H_ATN))
531 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
532 BT_CONTROL(BT_H_BUSY); /* set */
534 /* Uncached, ordered writes should just proceeed serially but
535 some BMCs don't clear B2H_ATN with one hit. Fast-path a
536 workaround without too much penalty to the general case. */
538 BT_CONTROL(BT_B2H_ATN); /* clear it to ACK the BMC */
539 BT_STATE_CHANGE(BT_STATE_CLEAR_B2H,
540 SI_SM_CALL_WITHOUT_DELAY);
542 case BT_STATE_CLEAR_B2H:
543 if (status & BT_B2H_ATN) { /* keep hitting it */
544 BT_CONTROL(BT_B2H_ATN);
545 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
547 BT_STATE_CHANGE(BT_STATE_READ_BYTES,
548 SI_SM_CALL_WITHOUT_DELAY);
550 case BT_STATE_READ_BYTES:
551 if (!(status & BT_H_BUSY)) /* check in case of retry */
552 BT_CONTROL(BT_H_BUSY);
553 BT_CONTROL(BT_CLR_RD_PTR); /* start of BMC2HOST buffer */
554 i = read_all_bytes(bt); /* true == packet seq match */
555 BT_CONTROL(BT_H_BUSY); /* NOW clear */
556 if (!i) /* Not my message */
557 BT_STATE_CHANGE(BT_STATE_READ_WAIT,
558 SI_SM_CALL_WITHOUT_DELAY);
559 bt->state = bt->complete;
560 return bt->state == BT_STATE_IDLE ? /* where to next? */
561 SI_SM_TRANSACTION_COMPLETE : /* normal */
562 SI_SM_CALL_WITHOUT_DELAY; /* Startup magic */
564 case BT_STATE_LONG_BUSY: /* For example: after FW update */
565 if (!(status & BT_B_BUSY)) {
566 reset_flags(bt); /* next state is now IDLE */
567 bt_init_data(bt, bt->io);
569 return SI_SM_CALL_WITH_DELAY; /* No repeat printing */
571 case BT_STATE_RESET1:
574 BT_STATE_CHANGE(BT_STATE_RESET2,
575 SI_SM_CALL_WITH_DELAY);
577 case BT_STATE_RESET2: /* Send a soft reset */
578 BT_CONTROL(BT_CLR_WR_PTR);
579 HOST2BMC(3); /* number of bytes following */
580 HOST2BMC(0x18); /* NetFn/LUN == Application, LUN 0 */
581 HOST2BMC(42); /* Sequence number */
582 HOST2BMC(3); /* Cmd == Soft reset */
583 BT_CONTROL(BT_H2B_ATN);
584 bt->timeout = BT_RESET_DELAY * 1000000;
585 BT_STATE_CHANGE(BT_STATE_RESET3,
586 SI_SM_CALL_WITH_DELAY);
588 case BT_STATE_RESET3: /* Hold off everything for a bit */
590 return SI_SM_CALL_WITH_DELAY;
592 BT_STATE_CHANGE(BT_STATE_RESTART,
593 SI_SM_CALL_WITH_DELAY);
595 case BT_STATE_RESTART: /* don't reset retries or seq! */
597 bt->nonzero_status = 0;
598 bt->timeout = bt->BT_CAP_req2rsp;
599 BT_STATE_CHANGE(BT_STATE_XACTION_START,
600 SI_SM_CALL_WITH_DELAY);
602 /* Get BT Capabilities, using timing of upper level state machine.
603 Set outreqs to prevent infinite loop on timeout. */
604 case BT_STATE_CAPABILITIES_BEGIN:
605 bt->BT_CAP_outreqs = 1;
607 unsigned char GetBT_CAP[] = { 0x18, 0x36 };
608 bt->state = BT_STATE_IDLE;
609 bt_start_transaction(bt, GetBT_CAP, sizeof(GetBT_CAP));
611 bt->complete = BT_STATE_CAPABILITIES_END;
612 BT_STATE_CHANGE(BT_STATE_XACTION_START,
613 SI_SM_CALL_WITH_DELAY);
615 case BT_STATE_CAPABILITIES_END:
616 i = bt_get_result(bt, BT_CAP, sizeof(BT_CAP));
617 bt_init_data(bt, bt->io);
618 if ((i == 8) && !BT_CAP[2]) {
619 bt->BT_CAP_outreqs = BT_CAP[3];
620 bt->BT_CAP_req2rsp = BT_CAP[6] * 1000000;
621 bt->BT_CAP_retries = BT_CAP[7];
623 printk(KERN_WARNING "IPMI BT: using default values\n");
624 if (!bt->BT_CAP_outreqs)
625 bt->BT_CAP_outreqs = 1;
626 printk(KERN_WARNING "IPMI BT: req2rsp=%ld secs retries=%d\n",
627 bt->BT_CAP_req2rsp / 1000000L, bt->BT_CAP_retries);
628 bt->timeout = bt->BT_CAP_req2rsp;
629 return SI_SM_CALL_WITHOUT_DELAY;
631 default: /* should never occur */
632 return error_recovery(bt,
634 IPMI_ERR_UNSPECIFIED);
636 return SI_SM_CALL_WITH_DELAY;
639 static int bt_detect(struct si_sm_data *bt)
641 /* It's impossible for the BT status and interrupt registers to be
642 all 1's, (assuming a properly functioning, self-initialized BMC)
643 but that's what you get from reading a bogus address, so we
644 test that first. The calling routine uses negative logic. */
646 if ((BT_STATUS == 0xFF) && (BT_INTMASK_R == 0xFF))
652 static void bt_cleanup(struct si_sm_data *bt)
656 static int bt_size(void)
658 return sizeof(struct si_sm_data);
661 struct si_sm_handlers bt_smi_handlers =
663 .init_data = bt_init_data,
664 .start_transaction = bt_start_transaction,
665 .get_result = bt_get_result,
668 .cleanup = bt_cleanup,