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 */
41 static int bt_debug = BT_DEBUG_OFF;
43 module_param(bt_debug, int, 0644);
44 MODULE_PARM_DESC(bt_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
46 /* Typical "Get BT Capabilities" values are 2-3 retries, 5-10 seconds,
47 and 64 byte buffers. However, one HP implementation wants 255 bytes of
48 buffer (with a documented message of 160 bytes) so go for the max.
49 Since the Open IPMI architecture is single-message oriented at this
50 stage, the queue depth of BT is of no concern. */
52 #define BT_NORMAL_TIMEOUT 5 /* seconds */
53 #define BT_NORMAL_RETRY_LIMIT 2
54 #define BT_RESET_DELAY 6 /* seconds after warm reset */
56 /* States are written in chronological order and usually cover
57 multiple rows of the state table discussion in the IPMI spec. */
60 BT_STATE_IDLE = 0, /* Order is critical in this list */
61 BT_STATE_XACTION_START,
63 BT_STATE_WRITE_CONSUME,
67 BT_STATE_RESET1, /* These must come last */
72 BT_STATE_CAPABILITIES_BEGIN,
73 BT_STATE_CAPABILITIES_END,
74 BT_STATE_LONG_BUSY /* BT doesn't get hosed :-) */
77 /* Macros seen at the end of state "case" blocks. They help with legibility
80 #define BT_STATE_CHANGE(X,Y) { bt->state = X; return Y; }
82 #define BT_SI_SM_RETURN(Y) { last_printed = BT_STATE_PRINTME; return Y; }
86 unsigned char seq; /* BT sequence number */
88 unsigned char write_data[IPMI_MAX_MSG_LENGTH];
90 unsigned char read_data[IPMI_MAX_MSG_LENGTH];
93 long timeout; /* microseconds countdown */
94 int error_retries; /* end of "common" fields */
95 int nonzero_status; /* hung BMCs stay all 0 */
96 enum bt_states complete; /* to divert the state machine */
99 int BT_CAP_retries; /* Recommended retries */
102 #define BT_CLR_WR_PTR 0x01 /* See IPMI 1.5 table 11.6.4 */
103 #define BT_CLR_RD_PTR 0x02
104 #define BT_H2B_ATN 0x04
105 #define BT_B2H_ATN 0x08
106 #define BT_SMS_ATN 0x10
108 #define BT_H_BUSY 0x40
109 #define BT_B_BUSY 0x80
111 /* Some bits are toggled on each write: write once to set it, once
112 more to clear it; writing a zero does nothing. To absolutely
113 clear it, check its state and write if set. This avoids the "get
114 current then use as mask" scheme to modify one bit. Note that the
115 variable "bt" is hardcoded into these macros. */
117 #define BT_STATUS bt->io->inputb(bt->io, 0)
118 #define BT_CONTROL(x) bt->io->outputb(bt->io, 0, x)
120 #define BMC2HOST bt->io->inputb(bt->io, 1)
121 #define HOST2BMC(x) bt->io->outputb(bt->io, 1, x)
123 #define BT_INTMASK_R bt->io->inputb(bt->io, 2)
124 #define BT_INTMASK_W(x) bt->io->outputb(bt->io, 2, x)
126 /* Convenience routines for debugging. These are not multi-open safe!
127 Note the macros have hardcoded variables in them. */
129 static char *state2txt(unsigned char state)
132 case BT_STATE_IDLE: return("IDLE");
133 case BT_STATE_XACTION_START: return("XACTION");
134 case BT_STATE_WRITE_BYTES: return("WR_BYTES");
135 case BT_STATE_WRITE_CONSUME: return("WR_CONSUME");
136 case BT_STATE_READ_WAIT: return("RD_WAIT");
137 case BT_STATE_CLEAR_B2H: return("CLEAR_B2H");
138 case BT_STATE_READ_BYTES: return("RD_BYTES");
139 case BT_STATE_RESET1: return("RESET1");
140 case BT_STATE_RESET2: return("RESET2");
141 case BT_STATE_RESET3: return("RESET3");
142 case BT_STATE_RESTART: return("RESTART");
143 case BT_STATE_LONG_BUSY: return("LONG_BUSY");
144 case BT_STATE_CAPABILITIES_BEGIN: return("CAP_BEGIN");
145 case BT_STATE_CAPABILITIES_END: return("CAP_END");
149 #define STATE2TXT state2txt(bt->state)
151 static char *status2txt(unsigned char status)
154 * This cannot be called by two threads at the same time and
155 * the buffer is always consumed immediately, so the static is
161 if (status & BT_B_BUSY)
162 strcat(buf, "B_BUSY ");
163 if (status & BT_H_BUSY)
164 strcat(buf, "H_BUSY ");
165 if (status & BT_OEM0)
166 strcat(buf, "OEM0 ");
167 if (status & BT_SMS_ATN)
169 if (status & BT_B2H_ATN)
171 if (status & BT_H2B_ATN)
176 #define STATUS2TXT status2txt(status)
178 /* called externally at insmod time, and internally on cleanup */
180 static unsigned int bt_init_data(struct si_sm_data *bt, struct si_sm_io *io)
182 memset(bt, 0, sizeof(struct si_sm_data));
183 if (bt->io != io) { /* external: one-time only things */
187 bt->state = BT_STATE_IDLE; /* start here */
188 bt->complete = BT_STATE_IDLE; /* end here */
189 bt->BT_CAP_req2rsp = BT_NORMAL_TIMEOUT * 1000000;
190 bt->BT_CAP_retries = BT_NORMAL_RETRY_LIMIT;
191 /* BT_CAP_outreqs == zero is a flag to read BT Capabilities */
192 return 3; /* We claim 3 bytes of space; ought to check SPMI table */
195 /* Jam a completion code (probably an error) into a response */
197 static void force_result(struct si_sm_data *bt, unsigned char completion_code)
199 bt->read_data[0] = 4; /* # following bytes */
200 bt->read_data[1] = bt->write_data[1] | 4; /* Odd NetFn/LUN */
201 bt->read_data[2] = bt->write_data[2]; /* seq (ignored) */
202 bt->read_data[3] = bt->write_data[3]; /* Command */
203 bt->read_data[4] = completion_code;
207 /* The upper state machine starts here */
209 static int bt_start_transaction(struct si_sm_data *bt,
216 return IPMI_REQ_LEN_INVALID_ERR;
217 if (size > IPMI_MAX_MSG_LENGTH)
218 return IPMI_REQ_LEN_EXCEEDED_ERR;
220 if (bt->state == BT_STATE_LONG_BUSY)
221 return IPMI_NODE_BUSY_ERR;
223 if (bt->state != BT_STATE_IDLE)
224 return IPMI_NOT_IN_MY_STATE_ERR;
226 if (bt_debug & BT_DEBUG_MSG) {
227 printk(KERN_WARNING "BT: +++++++++++++++++ New command\n");
228 printk(KERN_WARNING "BT: NetFn/LUN CMD [%d data]:", size - 2);
229 for (i = 0; i < size; i ++)
230 printk (" %02x", data[i]);
233 bt->write_data[0] = size + 1; /* all data plus seq byte */
234 bt->write_data[1] = *data; /* NetFn/LUN */
235 bt->write_data[2] = bt->seq++;
236 memcpy(bt->write_data + 3, data + 1, size - 1);
237 bt->write_count = size + 2;
238 bt->error_retries = 0;
239 bt->nonzero_status = 0;
241 bt->state = BT_STATE_XACTION_START;
242 bt->timeout = bt->BT_CAP_req2rsp;
243 force_result(bt, IPMI_ERR_UNSPECIFIED);
247 /* After the upper state machine has been told SI_SM_TRANSACTION_COMPLETE
248 it calls this. Strip out the length and seq bytes. */
250 static int bt_get_result(struct si_sm_data *bt,
256 msg_len = bt->read_count - 2; /* account for length & seq */
257 if (msg_len < 3 || msg_len > IPMI_MAX_MSG_LENGTH) {
258 force_result(bt, IPMI_ERR_UNSPECIFIED);
261 data[0] = bt->read_data[1];
262 data[1] = bt->read_data[3];
263 if (length < msg_len || bt->truncated) {
264 data[2] = IPMI_ERR_MSG_TRUNCATED;
267 memcpy(data + 2, bt->read_data + 4, msg_len - 2);
269 if (bt_debug & BT_DEBUG_MSG) {
270 printk (KERN_WARNING "BT: result %d bytes:", msg_len);
271 for (i = 0; i < msg_len; i++)
272 printk(" %02x", data[i]);
278 /* This bit's functionality is optional */
279 #define BT_BMC_HWRST 0x80
281 static void reset_flags(struct si_sm_data *bt)
284 printk(KERN_WARNING "IPMI BT: flag reset %s\n",
285 status2txt(BT_STATUS));
286 if (BT_STATUS & BT_H_BUSY)
287 BT_CONTROL(BT_H_BUSY); /* force clear */
288 BT_CONTROL(BT_CLR_WR_PTR); /* always reset */
289 BT_CONTROL(BT_SMS_ATN); /* always clear */
290 BT_INTMASK_W(BT_BMC_HWRST);
293 /* Get rid of an unwanted/stale response. This should only be needed for
294 BMCs that support multiple outstanding requests. */
296 static void drain_BMC2HOST(struct si_sm_data *bt)
300 if (!(BT_STATUS & BT_B2H_ATN)) /* Not signalling a response */
303 BT_CONTROL(BT_H_BUSY); /* now set */
304 BT_CONTROL(BT_B2H_ATN); /* always clear */
305 BT_STATUS; /* pause */
306 BT_CONTROL(BT_B2H_ATN); /* some BMCs are stubborn */
307 BT_CONTROL(BT_CLR_RD_PTR); /* always reset */
309 printk(KERN_WARNING "IPMI BT: stale response %s; ",
310 status2txt(BT_STATUS));
312 for (i = 0; i < size ; i++)
314 BT_CONTROL(BT_H_BUSY); /* now clear */
316 printk("drained %d bytes\n", size + 1);
319 static inline void write_all_bytes(struct si_sm_data *bt)
323 if (bt_debug & BT_DEBUG_MSG) {
324 printk(KERN_WARNING "BT: write %d bytes seq=0x%02X",
325 bt->write_count, bt->seq);
326 for (i = 0; i < bt->write_count; i++)
327 printk (" %02x", bt->write_data[i]);
330 for (i = 0; i < bt->write_count; i++)
331 HOST2BMC(bt->write_data[i]);
334 static inline int read_all_bytes(struct si_sm_data *bt)
338 /* length is "framing info", minimum = 4: NetFn, Seq, Cmd, cCode.
339 Keep layout of first four bytes aligned with write_data[] */
341 bt->read_data[0] = BMC2HOST;
342 bt->read_count = bt->read_data[0];
344 if (bt->read_count < 4 || bt->read_count >= IPMI_MAX_MSG_LENGTH) {
345 if (bt_debug & BT_DEBUG_MSG)
346 printk(KERN_WARNING "BT: bad raw rsp len=%d\n",
349 return 1; /* let next XACTION START clean it up */
351 for (i = 1; i <= bt->read_count; i++)
352 bt->read_data[i] = BMC2HOST;
353 bt->read_count++; /* Account internally for length byte */
355 if (bt_debug & BT_DEBUG_MSG) {
356 int max = bt->read_count;
358 printk(KERN_WARNING "BT: got %d bytes seq=0x%02X",
359 max, bt->read_data[2]);
362 for (i = 0; i < max; i++)
363 printk (" %02x", bt->read_data[i]);
364 printk ("%s\n", bt->read_count == max ? "" : " ...");
367 /* per the spec, the (NetFn[1], Seq[2], Cmd[3]) tuples must match */
368 if ((bt->read_data[3] == bt->write_data[3]) &&
369 (bt->read_data[2] == bt->write_data[2]) &&
370 ((bt->read_data[1] & 0xF8) == (bt->write_data[1] & 0xF8)))
373 if (bt_debug & BT_DEBUG_MSG)
374 printk(KERN_WARNING "IPMI BT: bad packet: "
375 "want 0x(%02X, %02X, %02X) got (%02X, %02X, %02X)\n",
376 bt->write_data[1] | 0x04, bt->write_data[2], bt->write_data[3],
377 bt->read_data[1], bt->read_data[2], bt->read_data[3]);
381 /* Restart if retries are left, or return an error completion code */
383 static enum si_sm_result error_recovery(struct si_sm_data *bt,
384 unsigned char status,
389 bt->timeout = bt->BT_CAP_req2rsp;
392 case IPMI_TIMEOUT_ERR:
396 reason = "internal error";
400 printk(KERN_WARNING "IPMI BT: %s in %s %s ", /* open-ended line */
401 reason, STATE2TXT, STATUS2TXT);
403 /* Per the IPMI spec, retries are based on the sequence number
404 known only to this module, so manage a restart here. */
405 (bt->error_retries)++;
406 if (bt->error_retries < bt->BT_CAP_retries) {
407 printk("%d retries left\n",
408 bt->BT_CAP_retries - bt->error_retries);
409 bt->state = BT_STATE_RESTART;
410 return SI_SM_CALL_WITHOUT_DELAY;
413 printk("failed %d retries, sending error response\n",
415 if (!bt->nonzero_status)
416 printk(KERN_ERR "IPMI BT: stuck, try power cycle\n");
418 /* this is most likely during insmod */
419 else if (bt->seq <= (unsigned char)(bt->BT_CAP_retries & 0xFF)) {
420 printk(KERN_WARNING "IPMI: BT reset (takes 5 secs)\n");
421 bt->state = BT_STATE_RESET1;
422 return SI_SM_CALL_WITHOUT_DELAY;
425 /* Concoct a useful error message, set up the next state, and
426 be done with this sequence. */
428 bt->state = BT_STATE_IDLE;
430 case IPMI_TIMEOUT_ERR:
431 if (status & BT_B_BUSY) {
432 cCode = IPMI_NODE_BUSY_ERR;
433 bt->state = BT_STATE_LONG_BUSY;
439 force_result(bt, cCode);
440 return SI_SM_TRANSACTION_COMPLETE;
443 /* Check status and (usually) take action and change this state machine. */
445 static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
447 unsigned char status, BT_CAP[8];
448 static enum bt_states last_printed = BT_STATE_PRINTME;
452 bt->nonzero_status |= status;
453 if ((bt_debug & BT_DEBUG_STATES) && (bt->state != last_printed)) {
454 printk(KERN_WARNING "BT: %s %s TO=%ld - %ld \n",
459 last_printed = bt->state;
462 /* Commands that time out may still (eventually) provide a response.
463 This stale response will get in the way of a new response so remove
464 it if possible (hopefully during IDLE). Even if it comes up later
465 it will be rejected by its (now-forgotten) seq number. */
467 if ((bt->state < BT_STATE_WRITE_BYTES) && (status & BT_B2H_ATN)) {
469 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
472 if ((bt->state != BT_STATE_IDLE) &&
473 (bt->state < BT_STATE_PRINTME)) { /* check timeout */
475 if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1))
476 return error_recovery(bt,
483 /* Idle state first checks for asynchronous messages from another
484 channel, then does some opportunistic housekeeping. */
487 if (status & BT_SMS_ATN) {
488 BT_CONTROL(BT_SMS_ATN); /* clear it */
492 if (status & BT_H_BUSY) /* clear a leftover H_BUSY */
493 BT_CONTROL(BT_H_BUSY);
495 /* Read BT capabilities if it hasn't been done yet */
496 if (!bt->BT_CAP_outreqs)
497 BT_STATE_CHANGE(BT_STATE_CAPABILITIES_BEGIN,
498 SI_SM_CALL_WITHOUT_DELAY);
499 bt->timeout = bt->BT_CAP_req2rsp;
500 BT_SI_SM_RETURN(SI_SM_IDLE);
502 case BT_STATE_XACTION_START:
503 if (status & (BT_B_BUSY | BT_H2B_ATN))
504 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
505 if (BT_STATUS & BT_H_BUSY)
506 BT_CONTROL(BT_H_BUSY); /* force clear */
507 BT_STATE_CHANGE(BT_STATE_WRITE_BYTES,
508 SI_SM_CALL_WITHOUT_DELAY);
510 case BT_STATE_WRITE_BYTES:
511 if (status & BT_H_BUSY)
512 BT_CONTROL(BT_H_BUSY); /* clear */
513 BT_CONTROL(BT_CLR_WR_PTR);
515 BT_CONTROL(BT_H2B_ATN); /* can clear too fast to catch */
516 BT_STATE_CHANGE(BT_STATE_WRITE_CONSUME,
517 SI_SM_CALL_WITHOUT_DELAY);
519 case BT_STATE_WRITE_CONSUME:
520 if (status & (BT_B_BUSY | BT_H2B_ATN))
521 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
522 BT_STATE_CHANGE(BT_STATE_READ_WAIT,
523 SI_SM_CALL_WITHOUT_DELAY);
525 /* Spinning hard can suppress B2H_ATN and force a timeout */
527 case BT_STATE_READ_WAIT:
528 if (!(status & BT_B2H_ATN))
529 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
530 BT_CONTROL(BT_H_BUSY); /* set */
532 /* Uncached, ordered writes should just proceeed serially but
533 some BMCs don't clear B2H_ATN with one hit. Fast-path a
534 workaround without too much penalty to the general case. */
536 BT_CONTROL(BT_B2H_ATN); /* clear it to ACK the BMC */
537 BT_STATE_CHANGE(BT_STATE_CLEAR_B2H,
538 SI_SM_CALL_WITHOUT_DELAY);
540 case BT_STATE_CLEAR_B2H:
541 if (status & BT_B2H_ATN) { /* keep hitting it */
542 BT_CONTROL(BT_B2H_ATN);
543 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
545 BT_STATE_CHANGE(BT_STATE_READ_BYTES,
546 SI_SM_CALL_WITHOUT_DELAY);
548 case BT_STATE_READ_BYTES:
549 if (!(status & BT_H_BUSY)) /* check in case of retry */
550 BT_CONTROL(BT_H_BUSY);
551 BT_CONTROL(BT_CLR_RD_PTR); /* start of BMC2HOST buffer */
552 i = read_all_bytes(bt); /* true == packet seq match */
553 BT_CONTROL(BT_H_BUSY); /* NOW clear */
554 if (!i) /* Not my message */
555 BT_STATE_CHANGE(BT_STATE_READ_WAIT,
556 SI_SM_CALL_WITHOUT_DELAY);
557 bt->state = bt->complete;
558 return bt->state == BT_STATE_IDLE ? /* where to next? */
559 SI_SM_TRANSACTION_COMPLETE : /* normal */
560 SI_SM_CALL_WITHOUT_DELAY; /* Startup magic */
562 case BT_STATE_LONG_BUSY: /* For example: after FW update */
563 if (!(status & BT_B_BUSY)) {
564 reset_flags(bt); /* next state is now IDLE */
565 bt_init_data(bt, bt->io);
567 return SI_SM_CALL_WITH_DELAY; /* No repeat printing */
569 case BT_STATE_RESET1:
572 BT_STATE_CHANGE(BT_STATE_RESET2,
573 SI_SM_CALL_WITH_DELAY);
575 case BT_STATE_RESET2: /* Send a soft reset */
576 BT_CONTROL(BT_CLR_WR_PTR);
577 HOST2BMC(3); /* number of bytes following */
578 HOST2BMC(0x18); /* NetFn/LUN == Application, LUN 0 */
579 HOST2BMC(42); /* Sequence number */
580 HOST2BMC(3); /* Cmd == Soft reset */
581 BT_CONTROL(BT_H2B_ATN);
582 bt->timeout = BT_RESET_DELAY * 1000000;
583 BT_STATE_CHANGE(BT_STATE_RESET3,
584 SI_SM_CALL_WITH_DELAY);
586 case BT_STATE_RESET3: /* Hold off everything for a bit */
588 return SI_SM_CALL_WITH_DELAY;
590 BT_STATE_CHANGE(BT_STATE_RESTART,
591 SI_SM_CALL_WITH_DELAY);
593 case BT_STATE_RESTART: /* don't reset retries or seq! */
595 bt->nonzero_status = 0;
596 bt->timeout = bt->BT_CAP_req2rsp;
597 BT_STATE_CHANGE(BT_STATE_XACTION_START,
598 SI_SM_CALL_WITH_DELAY);
600 /* Get BT Capabilities, using timing of upper level state machine.
601 Set outreqs to prevent infinite loop on timeout. */
602 case BT_STATE_CAPABILITIES_BEGIN:
603 bt->BT_CAP_outreqs = 1;
605 unsigned char GetBT_CAP[] = { 0x18, 0x36 };
606 bt->state = BT_STATE_IDLE;
607 bt_start_transaction(bt, GetBT_CAP, sizeof(GetBT_CAP));
609 bt->complete = BT_STATE_CAPABILITIES_END;
610 BT_STATE_CHANGE(BT_STATE_XACTION_START,
611 SI_SM_CALL_WITH_DELAY);
613 case BT_STATE_CAPABILITIES_END:
614 i = bt_get_result(bt, BT_CAP, sizeof(BT_CAP));
615 bt_init_data(bt, bt->io);
616 if ((i == 8) && !BT_CAP[2]) {
617 bt->BT_CAP_outreqs = BT_CAP[3];
618 bt->BT_CAP_req2rsp = BT_CAP[6] * 1000000;
619 bt->BT_CAP_retries = BT_CAP[7];
621 printk(KERN_WARNING "IPMI BT: using default values\n");
622 if (!bt->BT_CAP_outreqs)
623 bt->BT_CAP_outreqs = 1;
624 printk(KERN_WARNING "IPMI BT: req2rsp=%ld secs retries=%d\n",
625 bt->BT_CAP_req2rsp / 1000000L, bt->BT_CAP_retries);
626 bt->timeout = bt->BT_CAP_req2rsp;
627 return SI_SM_CALL_WITHOUT_DELAY;
629 default: /* should never occur */
630 return error_recovery(bt,
632 IPMI_ERR_UNSPECIFIED);
634 return SI_SM_CALL_WITH_DELAY;
637 static int bt_detect(struct si_sm_data *bt)
639 /* It's impossible for the BT status and interrupt registers to be
640 all 1's, (assuming a properly functioning, self-initialized BMC)
641 but that's what you get from reading a bogus address, so we
642 test that first. The calling routine uses negative logic. */
644 if ((BT_STATUS == 0xFF) && (BT_INTMASK_R == 0xFF))
650 static void bt_cleanup(struct si_sm_data *bt)
654 static int bt_size(void)
656 return sizeof(struct si_sm_data);
659 struct si_sm_handlers bt_smi_handlers =
661 .init_data = bt_init_data,
662 .start_transaction = bt_start_transaction,
663 .get_result = bt_get_result,
666 .cleanup = bt_cleanup,