1 // SPDX-License-Identifier: GPL-2.0+
5 * The state machine for an Open IPMI BT sub-driver under ipmi_si.c, part
6 * of the driver architecture at http://sourceforge.net/projects/openipmi
8 * Author: Rocky Craig <first.last@hp.com>
11 #define DEBUG /* So dev_dbg() is always available. */
13 #include <linux/kernel.h> /* For printk. */
14 #include <linux/string.h>
15 #include <linux/module.h>
16 #include <linux/moduleparam.h>
17 #include <linux/ipmi_msgdefs.h> /* for completion codes */
18 #include "ipmi_si_sm.h"
20 #define BT_DEBUG_OFF 0 /* Used in production */
21 #define BT_DEBUG_ENABLE 1 /* Generic messages */
22 #define BT_DEBUG_MSG 2 /* Prints all request/response buffers */
23 #define BT_DEBUG_STATES 4 /* Verbose look at state changes */
25 * BT_DEBUG_OFF must be zero to correspond to the default uninitialized
29 static int bt_debug
; /* 0 == BT_DEBUG_OFF */
31 module_param(bt_debug
, int, 0644);
32 MODULE_PARM_DESC(bt_debug
, "debug bitmask, 1=enable, 2=messages, 4=states");
35 * Typical "Get BT Capabilities" values are 2-3 retries, 5-10 seconds,
36 * and 64 byte buffers. However, one HP implementation wants 255 bytes of
37 * buffer (with a documented message of 160 bytes) so go for the max.
38 * Since the Open IPMI architecture is single-message oriented at this
39 * stage, the queue depth of BT is of no concern.
42 #define BT_NORMAL_TIMEOUT 5 /* seconds */
43 #define BT_NORMAL_RETRY_LIMIT 2
44 #define BT_RESET_DELAY 6 /* seconds after warm reset */
47 * States are written in chronological order and usually cover
48 * multiple rows of the state table discussion in the IPMI spec.
52 BT_STATE_IDLE
= 0, /* Order is critical in this list */
53 BT_STATE_XACTION_START
,
55 BT_STATE_WRITE_CONSUME
,
59 BT_STATE_RESET1
, /* These must come last */
64 BT_STATE_LONG_BUSY
/* BT doesn't get hosed :-) */
68 * Macros seen at the end of state "case" blocks. They help with legibility
72 #define BT_STATE_CHANGE(X, Y) { bt->state = X; return Y; }
74 #define BT_SI_SM_RETURN(Y) { last_printed = BT_STATE_PRINTME; return Y; }
78 unsigned char seq
; /* BT sequence number */
80 unsigned char write_data
[IPMI_MAX_MSG_LENGTH
+ 2]; /* +2 for memcpy */
82 unsigned char read_data
[IPMI_MAX_MSG_LENGTH
+ 2]; /* +2 for memcpy */
85 long timeout
; /* microseconds countdown */
86 int error_retries
; /* end of "common" fields */
87 int nonzero_status
; /* hung BMCs stay all 0 */
88 enum bt_states complete
; /* to divert the state machine */
90 int BT_CAP_retries
; /* Recommended retries */
93 #define BT_CLR_WR_PTR 0x01 /* See IPMI 1.5 table 11.6.4 */
94 #define BT_CLR_RD_PTR 0x02
95 #define BT_H2B_ATN 0x04
96 #define BT_B2H_ATN 0x08
97 #define BT_SMS_ATN 0x10
99 #define BT_H_BUSY 0x40
100 #define BT_B_BUSY 0x80
103 * Some bits are toggled on each write: write once to set it, once
104 * more to clear it; writing a zero does nothing. To absolutely
105 * clear it, check its state and write if set. This avoids the "get
106 * current then use as mask" scheme to modify one bit. Note that the
107 * variable "bt" is hardcoded into these macros.
110 #define BT_STATUS bt->io->inputb(bt->io, 0)
111 #define BT_CONTROL(x) bt->io->outputb(bt->io, 0, x)
113 #define BMC2HOST bt->io->inputb(bt->io, 1)
114 #define HOST2BMC(x) bt->io->outputb(bt->io, 1, x)
116 #define BT_INTMASK_R bt->io->inputb(bt->io, 2)
117 #define BT_INTMASK_W(x) bt->io->outputb(bt->io, 2, x)
120 * Convenience routines for debugging. These are not multi-open safe!
121 * Note the macros have hardcoded variables in them.
124 static char *state2txt(unsigned char state
)
127 case BT_STATE_IDLE
: return("IDLE");
128 case BT_STATE_XACTION_START
: return("XACTION");
129 case BT_STATE_WRITE_BYTES
: return("WR_BYTES");
130 case BT_STATE_WRITE_CONSUME
: return("WR_CONSUME");
131 case BT_STATE_READ_WAIT
: return("RD_WAIT");
132 case BT_STATE_CLEAR_B2H
: return("CLEAR_B2H");
133 case BT_STATE_READ_BYTES
: return("RD_BYTES");
134 case BT_STATE_RESET1
: return("RESET1");
135 case BT_STATE_RESET2
: return("RESET2");
136 case BT_STATE_RESET3
: return("RESET3");
137 case BT_STATE_RESTART
: return("RESTART");
138 case BT_STATE_LONG_BUSY
: return("LONG_BUSY");
142 #define STATE2TXT state2txt(bt->state)
144 static char *status2txt(unsigned char status
)
147 * This cannot be called by two threads at the same time and
148 * the buffer is always consumed immediately, so the static is
154 if (status
& BT_B_BUSY
)
155 strcat(buf
, "B_BUSY ");
156 if (status
& BT_H_BUSY
)
157 strcat(buf
, "H_BUSY ");
158 if (status
& BT_OEM0
)
159 strcat(buf
, "OEM0 ");
160 if (status
& BT_SMS_ATN
)
162 if (status
& BT_B2H_ATN
)
164 if (status
& BT_H2B_ATN
)
169 #define STATUS2TXT status2txt(status)
171 /* called externally at insmod time, and internally on cleanup */
173 static unsigned int bt_init_data(struct si_sm_data
*bt
, struct si_sm_io
*io
)
175 memset(bt
, 0, sizeof(struct si_sm_data
));
177 /* external: one-time only things */
181 bt
->state
= BT_STATE_IDLE
; /* start here */
182 bt
->complete
= BT_STATE_IDLE
; /* end here */
183 bt
->BT_CAP_req2rsp
= BT_NORMAL_TIMEOUT
* USEC_PER_SEC
;
184 bt
->BT_CAP_retries
= BT_NORMAL_RETRY_LIMIT
;
185 return 3; /* We claim 3 bytes of space; ought to check SPMI table */
188 /* Jam a completion code (probably an error) into a response */
190 static void force_result(struct si_sm_data
*bt
, unsigned char completion_code
)
192 bt
->read_data
[0] = 4; /* # following bytes */
193 bt
->read_data
[1] = bt
->write_data
[1] | 4; /* Odd NetFn/LUN */
194 bt
->read_data
[2] = bt
->write_data
[2]; /* seq (ignored) */
195 bt
->read_data
[3] = bt
->write_data
[3]; /* Command */
196 bt
->read_data
[4] = completion_code
;
200 /* The upper state machine starts here */
202 static int bt_start_transaction(struct si_sm_data
*bt
,
209 return IPMI_REQ_LEN_INVALID_ERR
;
210 if (size
> IPMI_MAX_MSG_LENGTH
)
211 return IPMI_REQ_LEN_EXCEEDED_ERR
;
213 if (bt
->state
== BT_STATE_LONG_BUSY
)
214 return IPMI_NODE_BUSY_ERR
;
216 if (bt
->state
!= BT_STATE_IDLE
) {
217 dev_warn(bt
->io
->dev
, "BT in invalid state %d\n", bt
->state
);
218 return IPMI_NOT_IN_MY_STATE_ERR
;
221 if (bt_debug
& BT_DEBUG_MSG
) {
222 dev_dbg(bt
->io
->dev
, "+++++++++++++++++ New command\n");
223 dev_dbg(bt
->io
->dev
, "NetFn/LUN CMD [%d data]:", size
- 2);
224 for (i
= 0; i
< size
; i
++)
225 pr_cont(" %02x", data
[i
]);
228 bt
->write_data
[0] = size
+ 1; /* all data plus seq byte */
229 bt
->write_data
[1] = *data
; /* NetFn/LUN */
230 bt
->write_data
[2] = bt
->seq
++;
231 memcpy(bt
->write_data
+ 3, data
+ 1, size
- 1);
232 bt
->write_count
= size
+ 2;
233 bt
->error_retries
= 0;
234 bt
->nonzero_status
= 0;
236 bt
->state
= BT_STATE_XACTION_START
;
237 bt
->timeout
= bt
->BT_CAP_req2rsp
;
238 force_result(bt
, IPMI_ERR_UNSPECIFIED
);
243 * After the upper state machine has been told SI_SM_TRANSACTION_COMPLETE
244 * it calls this. Strip out the length and seq bytes.
247 static int bt_get_result(struct si_sm_data
*bt
,
253 msg_len
= bt
->read_count
- 2; /* account for length & seq */
254 if (msg_len
< 3 || msg_len
> IPMI_MAX_MSG_LENGTH
) {
255 force_result(bt
, IPMI_ERR_UNSPECIFIED
);
258 data
[0] = bt
->read_data
[1];
259 data
[1] = bt
->read_data
[3];
260 if (length
< msg_len
|| bt
->truncated
) {
261 data
[2] = IPMI_ERR_MSG_TRUNCATED
;
264 memcpy(data
+ 2, bt
->read_data
+ 4, msg_len
- 2);
266 if (bt_debug
& BT_DEBUG_MSG
) {
267 dev_dbg(bt
->io
->dev
, "result %d bytes:", msg_len
);
268 for (i
= 0; i
< msg_len
; i
++)
269 pr_cont(" %02x", data
[i
]);
275 /* This bit's functionality is optional */
276 #define BT_BMC_HWRST 0x80
278 static void reset_flags(struct si_sm_data
*bt
)
281 dev_dbg(bt
->io
->dev
, "flag reset %s\n", status2txt(BT_STATUS
));
282 if (BT_STATUS
& BT_H_BUSY
)
283 BT_CONTROL(BT_H_BUSY
); /* force clear */
284 BT_CONTROL(BT_CLR_WR_PTR
); /* always reset */
285 BT_CONTROL(BT_SMS_ATN
); /* always clear */
286 BT_INTMASK_W(BT_BMC_HWRST
);
290 * Get rid of an unwanted/stale response. This should only be needed for
291 * BMCs that support multiple outstanding requests.
294 static void drain_BMC2HOST(struct si_sm_data
*bt
)
298 if (!(BT_STATUS
& BT_B2H_ATN
)) /* Not signalling a response */
301 BT_CONTROL(BT_H_BUSY
); /* now set */
302 BT_CONTROL(BT_B2H_ATN
); /* always clear */
303 BT_STATUS
; /* pause */
304 BT_CONTROL(BT_B2H_ATN
); /* some BMCs are stubborn */
305 BT_CONTROL(BT_CLR_RD_PTR
); /* always reset */
307 dev_dbg(bt
->io
->dev
, "stale response %s; ",
308 status2txt(BT_STATUS
));
310 for (i
= 0; i
< size
; i
++)
312 BT_CONTROL(BT_H_BUSY
); /* now clear */
314 pr_cont("drained %d bytes\n", size
+ 1);
317 static inline void write_all_bytes(struct si_sm_data
*bt
)
321 if (bt_debug
& BT_DEBUG_MSG
) {
322 dev_dbg(bt
->io
->dev
, "write %d bytes seq=0x%02X",
323 bt
->write_count
, bt
->seq
);
324 for (i
= 0; i
< bt
->write_count
; i
++)
325 pr_cont(" %02x", bt
->write_data
[i
]);
328 for (i
= 0; i
< bt
->write_count
; i
++)
329 HOST2BMC(bt
->write_data
[i
]);
332 static inline int read_all_bytes(struct si_sm_data
*bt
)
337 * length is "framing info", minimum = 4: NetFn, Seq, Cmd, cCode.
338 * 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
)
347 "bad raw rsp len=%d\n", bt
->read_count
);
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
;
359 "got %d bytes seq=0x%02X", max
, bt
->read_data
[2]);
362 for (i
= 0; i
< max
; i
++)
363 pr_cont(" %02x", bt
->read_data
[i
]);
364 pr_cont("%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
)
375 "IPMI BT: bad packet: want 0x(%02X, %02X, %02X) got (%02X, %02X, %02X)\n",
376 bt
->write_data
[1] | 0x04, bt
->write_data
[2],
378 bt
->read_data
[1], bt
->read_data
[2], bt
->read_data
[3]);
382 /* Restart if retries are left, or return an error completion code */
384 static enum si_sm_result
error_recovery(struct si_sm_data
*bt
,
385 unsigned char status
,
390 bt
->timeout
= bt
->BT_CAP_req2rsp
;
393 case IPMI_TIMEOUT_ERR
:
397 reason
= "internal error";
401 dev_warn(bt
->io
->dev
, "IPMI BT: %s in %s %s ", /* open-ended line */
402 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.
408 (bt
->error_retries
)++;
409 if (bt
->error_retries
< bt
->BT_CAP_retries
) {
410 pr_cont("%d retries left\n",
411 bt
->BT_CAP_retries
- bt
->error_retries
);
412 bt
->state
= BT_STATE_RESTART
;
413 return SI_SM_CALL_WITHOUT_DELAY
;
416 dev_warn(bt
->io
->dev
, "failed %d retries, sending error response\n",
418 if (!bt
->nonzero_status
)
419 dev_err(bt
->io
->dev
, "stuck, try power cycle\n");
421 /* this is most likely during insmod */
422 else if (bt
->seq
<= (unsigned char)(bt
->BT_CAP_retries
& 0xFF)) {
423 dev_warn(bt
->io
->dev
, "BT reset (takes 5 secs)\n");
424 bt
->state
= BT_STATE_RESET1
;
425 return SI_SM_CALL_WITHOUT_DELAY
;
429 * Concoct a useful error message, set up the next state, and
430 * be done with this sequence.
433 bt
->state
= BT_STATE_IDLE
;
435 case IPMI_TIMEOUT_ERR
:
436 if (status
& BT_B_BUSY
) {
437 cCode
= IPMI_NODE_BUSY_ERR
;
438 bt
->state
= BT_STATE_LONG_BUSY
;
444 force_result(bt
, cCode
);
445 return SI_SM_TRANSACTION_COMPLETE
;
448 /* Check status and (usually) take action and change this state machine. */
450 static enum si_sm_result
bt_event(struct si_sm_data
*bt
, long time
)
452 unsigned char status
;
453 static enum bt_states last_printed
= BT_STATE_PRINTME
;
457 bt
->nonzero_status
|= status
;
458 if ((bt_debug
& BT_DEBUG_STATES
) && (bt
->state
!= last_printed
)) {
459 dev_dbg(bt
->io
->dev
, "BT: %s %s TO=%ld - %ld\n",
464 last_printed
= bt
->state
;
468 * Commands that time out may still (eventually) provide a response.
469 * This stale response will get in the way of a new response so remove
470 * it if possible (hopefully during IDLE). Even if it comes up later
471 * it will be rejected by its (now-forgotten) seq number.
474 if ((bt
->state
< BT_STATE_WRITE_BYTES
) && (status
& BT_B2H_ATN
)) {
476 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY
);
479 if ((bt
->state
!= BT_STATE_IDLE
) &&
480 (bt
->state
< BT_STATE_PRINTME
)) {
483 if ((bt
->timeout
< 0) && (bt
->state
< BT_STATE_RESET1
))
484 return error_recovery(bt
,
492 * Idle state first checks for asynchronous messages from another
493 * channel, then does some opportunistic housekeeping.
497 if (status
& BT_SMS_ATN
) {
498 BT_CONTROL(BT_SMS_ATN
); /* clear it */
502 if (status
& BT_H_BUSY
) /* clear a leftover H_BUSY */
503 BT_CONTROL(BT_H_BUSY
);
505 BT_SI_SM_RETURN(SI_SM_IDLE
);
507 case BT_STATE_XACTION_START
:
508 if (status
& (BT_B_BUSY
| BT_H2B_ATN
))
509 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY
);
510 if (BT_STATUS
& BT_H_BUSY
)
511 BT_CONTROL(BT_H_BUSY
); /* force clear */
512 BT_STATE_CHANGE(BT_STATE_WRITE_BYTES
,
513 SI_SM_CALL_WITHOUT_DELAY
);
515 case BT_STATE_WRITE_BYTES
:
516 if (status
& BT_H_BUSY
)
517 BT_CONTROL(BT_H_BUSY
); /* clear */
518 BT_CONTROL(BT_CLR_WR_PTR
);
520 BT_CONTROL(BT_H2B_ATN
); /* can clear too fast to catch */
521 BT_STATE_CHANGE(BT_STATE_WRITE_CONSUME
,
522 SI_SM_CALL_WITHOUT_DELAY
);
524 case BT_STATE_WRITE_CONSUME
:
525 if (status
& (BT_B_BUSY
| BT_H2B_ATN
))
526 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY
);
527 BT_STATE_CHANGE(BT_STATE_READ_WAIT
,
528 SI_SM_CALL_WITHOUT_DELAY
);
530 /* Spinning hard can suppress B2H_ATN and force a timeout */
532 case BT_STATE_READ_WAIT
:
533 if (!(status
& BT_B2H_ATN
))
534 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY
);
535 BT_CONTROL(BT_H_BUSY
); /* set */
538 * Uncached, ordered writes should just proceed serially but
539 * some BMCs don't clear B2H_ATN with one hit. Fast-path a
540 * workaround without too much penalty to the general case.
543 BT_CONTROL(BT_B2H_ATN
); /* clear it to ACK the BMC */
544 BT_STATE_CHANGE(BT_STATE_CLEAR_B2H
,
545 SI_SM_CALL_WITHOUT_DELAY
);
547 case BT_STATE_CLEAR_B2H
:
548 if (status
& BT_B2H_ATN
) {
549 /* keep hitting it */
550 BT_CONTROL(BT_B2H_ATN
);
551 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY
);
553 BT_STATE_CHANGE(BT_STATE_READ_BYTES
,
554 SI_SM_CALL_WITHOUT_DELAY
);
556 case BT_STATE_READ_BYTES
:
557 if (!(status
& BT_H_BUSY
))
558 /* check in case of retry */
559 BT_CONTROL(BT_H_BUSY
);
560 BT_CONTROL(BT_CLR_RD_PTR
); /* start of BMC2HOST buffer */
561 i
= read_all_bytes(bt
); /* true == packet seq match */
562 BT_CONTROL(BT_H_BUSY
); /* NOW clear */
563 if (!i
) /* Not my message */
564 BT_STATE_CHANGE(BT_STATE_READ_WAIT
,
565 SI_SM_CALL_WITHOUT_DELAY
);
566 bt
->state
= bt
->complete
;
567 return bt
->state
== BT_STATE_IDLE
? /* where to next? */
568 SI_SM_TRANSACTION_COMPLETE
: /* normal */
569 SI_SM_CALL_WITHOUT_DELAY
; /* Startup magic */
571 case BT_STATE_LONG_BUSY
: /* For example: after FW update */
572 if (!(status
& BT_B_BUSY
)) {
573 reset_flags(bt
); /* next state is now IDLE */
574 bt_init_data(bt
, bt
->io
);
576 return SI_SM_CALL_WITH_DELAY
; /* No repeat printing */
578 case BT_STATE_RESET1
:
581 BT_STATE_CHANGE(BT_STATE_RESET2
,
582 SI_SM_CALL_WITH_DELAY
);
584 case BT_STATE_RESET2
: /* Send a soft reset */
585 BT_CONTROL(BT_CLR_WR_PTR
);
586 HOST2BMC(3); /* number of bytes following */
587 HOST2BMC(0x18); /* NetFn/LUN == Application, LUN 0 */
588 HOST2BMC(42); /* Sequence number */
589 HOST2BMC(3); /* Cmd == Soft reset */
590 BT_CONTROL(BT_H2B_ATN
);
591 bt
->timeout
= BT_RESET_DELAY
* USEC_PER_SEC
;
592 BT_STATE_CHANGE(BT_STATE_RESET3
,
593 SI_SM_CALL_WITH_DELAY
);
595 case BT_STATE_RESET3
: /* Hold off everything for a bit */
597 return SI_SM_CALL_WITH_DELAY
;
599 BT_STATE_CHANGE(BT_STATE_RESTART
,
600 SI_SM_CALL_WITH_DELAY
);
602 case BT_STATE_RESTART
: /* don't reset retries or seq! */
604 bt
->nonzero_status
= 0;
605 bt
->timeout
= bt
->BT_CAP_req2rsp
;
606 BT_STATE_CHANGE(BT_STATE_XACTION_START
,
607 SI_SM_CALL_WITH_DELAY
);
609 default: /* should never occur */
610 return error_recovery(bt
,
612 IPMI_ERR_UNSPECIFIED
);
614 return SI_SM_CALL_WITH_DELAY
;
617 static int bt_detect(struct si_sm_data
*bt
)
619 unsigned char GetBT_CAP
[] = { 0x18, 0x36 };
620 unsigned char BT_CAP
[8];
621 enum si_sm_result smi_result
;
625 * It's impossible for the BT status and interrupt registers to be
626 * all 1's, (assuming a properly functioning, self-initialized BMC)
627 * but that's what you get from reading a bogus address, so we
628 * test that first. The calling routine uses negative logic.
631 if ((BT_STATUS
== 0xFF) && (BT_INTMASK_R
== 0xFF))
636 * Try getting the BT capabilities here.
638 rv
= bt_start_transaction(bt
, GetBT_CAP
, sizeof(GetBT_CAP
));
640 dev_warn(bt
->io
->dev
,
641 "Can't start capabilities transaction: %d\n", rv
);
645 smi_result
= SI_SM_CALL_WITHOUT_DELAY
;
647 if (smi_result
== SI_SM_CALL_WITH_DELAY
||
648 smi_result
== SI_SM_CALL_WITH_TICK_DELAY
) {
649 schedule_timeout_uninterruptible(1);
650 smi_result
= bt_event(bt
, jiffies_to_usecs(1));
651 } else if (smi_result
== SI_SM_CALL_WITHOUT_DELAY
) {
652 smi_result
= bt_event(bt
, 0);
657 rv
= bt_get_result(bt
, BT_CAP
, sizeof(BT_CAP
));
658 bt_init_data(bt
, bt
->io
);
660 dev_warn(bt
->io
->dev
, "bt cap response too short: %d\n", rv
);
665 dev_warn(bt
->io
->dev
, "Error fetching bt cap: %x\n", BT_CAP
[2]);
667 dev_warn(bt
->io
->dev
, "using default values\n");
669 bt
->BT_CAP_req2rsp
= BT_CAP
[6] * USEC_PER_SEC
;
670 bt
->BT_CAP_retries
= BT_CAP
[7];
673 dev_info(bt
->io
->dev
, "req2rsp=%ld secs retries=%d\n",
674 bt
->BT_CAP_req2rsp
/ USEC_PER_SEC
, bt
->BT_CAP_retries
);
679 static void bt_cleanup(struct si_sm_data
*bt
)
683 static int bt_size(void)
685 return sizeof(struct si_sm_data
);
688 const struct si_sm_handlers bt_smi_handlers
= {
689 .init_data
= bt_init_data
,
690 .start_transaction
= bt_start_transaction
,
691 .get_result
= bt_get_result
,
694 .cleanup
= bt_cleanup
,