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 return IPMI_NOT_IN_MY_STATE_ERR
;
219 if (bt_debug
& BT_DEBUG_MSG
) {
220 dev_dbg(bt
->io
->dev
, "+++++++++++++++++ New command\n");
221 dev_dbg(bt
->io
->dev
, "NetFn/LUN CMD [%d data]:", size
- 2);
222 for (i
= 0; i
< size
; i
++)
223 pr_cont(" %02x", data
[i
]);
226 bt
->write_data
[0] = size
+ 1; /* all data plus seq byte */
227 bt
->write_data
[1] = *data
; /* NetFn/LUN */
228 bt
->write_data
[2] = bt
->seq
++;
229 memcpy(bt
->write_data
+ 3, data
+ 1, size
- 1);
230 bt
->write_count
= size
+ 2;
231 bt
->error_retries
= 0;
232 bt
->nonzero_status
= 0;
234 bt
->state
= BT_STATE_XACTION_START
;
235 bt
->timeout
= bt
->BT_CAP_req2rsp
;
236 force_result(bt
, IPMI_ERR_UNSPECIFIED
);
241 * After the upper state machine has been told SI_SM_TRANSACTION_COMPLETE
242 * it calls this. Strip out the length and seq bytes.
245 static int bt_get_result(struct si_sm_data
*bt
,
251 msg_len
= bt
->read_count
- 2; /* account for length & seq */
252 if (msg_len
< 3 || msg_len
> IPMI_MAX_MSG_LENGTH
) {
253 force_result(bt
, IPMI_ERR_UNSPECIFIED
);
256 data
[0] = bt
->read_data
[1];
257 data
[1] = bt
->read_data
[3];
258 if (length
< msg_len
|| bt
->truncated
) {
259 data
[2] = IPMI_ERR_MSG_TRUNCATED
;
262 memcpy(data
+ 2, bt
->read_data
+ 4, msg_len
- 2);
264 if (bt_debug
& BT_DEBUG_MSG
) {
265 dev_dbg(bt
->io
->dev
, "result %d bytes:", msg_len
);
266 for (i
= 0; i
< msg_len
; i
++)
267 pr_cont(" %02x", data
[i
]);
273 /* This bit's functionality is optional */
274 #define BT_BMC_HWRST 0x80
276 static void reset_flags(struct si_sm_data
*bt
)
279 dev_dbg(bt
->io
->dev
, "flag reset %s\n", status2txt(BT_STATUS
));
280 if (BT_STATUS
& BT_H_BUSY
)
281 BT_CONTROL(BT_H_BUSY
); /* force clear */
282 BT_CONTROL(BT_CLR_WR_PTR
); /* always reset */
283 BT_CONTROL(BT_SMS_ATN
); /* always clear */
284 BT_INTMASK_W(BT_BMC_HWRST
);
288 * Get rid of an unwanted/stale response. This should only be needed for
289 * BMCs that support multiple outstanding requests.
292 static void drain_BMC2HOST(struct si_sm_data
*bt
)
296 if (!(BT_STATUS
& BT_B2H_ATN
)) /* Not signalling a response */
299 BT_CONTROL(BT_H_BUSY
); /* now set */
300 BT_CONTROL(BT_B2H_ATN
); /* always clear */
301 BT_STATUS
; /* pause */
302 BT_CONTROL(BT_B2H_ATN
); /* some BMCs are stubborn */
303 BT_CONTROL(BT_CLR_RD_PTR
); /* always reset */
305 dev_dbg(bt
->io
->dev
, "stale response %s; ",
306 status2txt(BT_STATUS
));
308 for (i
= 0; i
< size
; i
++)
310 BT_CONTROL(BT_H_BUSY
); /* now clear */
312 pr_cont("drained %d bytes\n", size
+ 1);
315 static inline void write_all_bytes(struct si_sm_data
*bt
)
319 if (bt_debug
& BT_DEBUG_MSG
) {
320 dev_dbg(bt
->io
->dev
, "write %d bytes seq=0x%02X",
321 bt
->write_count
, bt
->seq
);
322 for (i
= 0; i
< bt
->write_count
; i
++)
323 pr_cont(" %02x", bt
->write_data
[i
]);
326 for (i
= 0; i
< bt
->write_count
; i
++)
327 HOST2BMC(bt
->write_data
[i
]);
330 static inline int read_all_bytes(struct si_sm_data
*bt
)
335 * length is "framing info", minimum = 4: NetFn, Seq, Cmd, cCode.
336 * Keep layout of first four bytes aligned with write_data[]
339 bt
->read_data
[0] = BMC2HOST
;
340 bt
->read_count
= bt
->read_data
[0];
342 if (bt
->read_count
< 4 || bt
->read_count
>= IPMI_MAX_MSG_LENGTH
) {
343 if (bt_debug
& BT_DEBUG_MSG
)
345 "bad raw rsp len=%d\n", bt
->read_count
);
347 return 1; /* let next XACTION START clean it up */
349 for (i
= 1; i
<= bt
->read_count
; i
++)
350 bt
->read_data
[i
] = BMC2HOST
;
351 bt
->read_count
++; /* Account internally for length byte */
353 if (bt_debug
& BT_DEBUG_MSG
) {
354 int max
= bt
->read_count
;
357 "got %d bytes seq=0x%02X", max
, bt
->read_data
[2]);
360 for (i
= 0; i
< max
; i
++)
361 pr_cont(" %02x", bt
->read_data
[i
]);
362 pr_cont("%s\n", bt
->read_count
== max
? "" : " ...");
365 /* per the spec, the (NetFn[1], Seq[2], Cmd[3]) tuples must match */
366 if ((bt
->read_data
[3] == bt
->write_data
[3]) &&
367 (bt
->read_data
[2] == bt
->write_data
[2]) &&
368 ((bt
->read_data
[1] & 0xF8) == (bt
->write_data
[1] & 0xF8)))
371 if (bt_debug
& BT_DEBUG_MSG
)
373 "IPMI BT: bad packet: want 0x(%02X, %02X, %02X) got (%02X, %02X, %02X)\n",
374 bt
->write_data
[1] | 0x04, bt
->write_data
[2],
376 bt
->read_data
[1], bt
->read_data
[2], bt
->read_data
[3]);
380 /* Restart if retries are left, or return an error completion code */
382 static enum si_sm_result
error_recovery(struct si_sm_data
*bt
,
383 unsigned char status
,
388 bt
->timeout
= bt
->BT_CAP_req2rsp
;
391 case IPMI_TIMEOUT_ERR
:
395 reason
= "internal error";
399 dev_warn(bt
->io
->dev
, "IPMI BT: %s in %s %s ", /* open-ended line */
400 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.
406 (bt
->error_retries
)++;
407 if (bt
->error_retries
< bt
->BT_CAP_retries
) {
408 pr_cont("%d retries left\n",
409 bt
->BT_CAP_retries
- bt
->error_retries
);
410 bt
->state
= BT_STATE_RESTART
;
411 return SI_SM_CALL_WITHOUT_DELAY
;
414 dev_warn(bt
->io
->dev
, "failed %d retries, sending error response\n",
416 if (!bt
->nonzero_status
)
417 dev_err(bt
->io
->dev
, "stuck, try power cycle\n");
419 /* this is most likely during insmod */
420 else if (bt
->seq
<= (unsigned char)(bt
->BT_CAP_retries
& 0xFF)) {
421 dev_warn(bt
->io
->dev
, "BT reset (takes 5 secs)\n");
422 bt
->state
= BT_STATE_RESET1
;
423 return SI_SM_CALL_WITHOUT_DELAY
;
427 * Concoct a useful error message, set up the next state, and
428 * be done with this sequence.
431 bt
->state
= BT_STATE_IDLE
;
433 case IPMI_TIMEOUT_ERR
:
434 if (status
& BT_B_BUSY
) {
435 cCode
= IPMI_NODE_BUSY_ERR
;
436 bt
->state
= BT_STATE_LONG_BUSY
;
442 force_result(bt
, cCode
);
443 return SI_SM_TRANSACTION_COMPLETE
;
446 /* Check status and (usually) take action and change this state machine. */
448 static enum si_sm_result
bt_event(struct si_sm_data
*bt
, long time
)
450 unsigned char status
;
451 static enum bt_states last_printed
= BT_STATE_PRINTME
;
455 bt
->nonzero_status
|= status
;
456 if ((bt_debug
& BT_DEBUG_STATES
) && (bt
->state
!= last_printed
)) {
457 dev_dbg(bt
->io
->dev
, "BT: %s %s TO=%ld - %ld\n",
462 last_printed
= bt
->state
;
466 * Commands that time out may still (eventually) provide a response.
467 * This stale response will get in the way of a new response so remove
468 * it if possible (hopefully during IDLE). Even if it comes up later
469 * it will be rejected by its (now-forgotten) seq number.
472 if ((bt
->state
< BT_STATE_WRITE_BYTES
) && (status
& BT_B2H_ATN
)) {
474 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY
);
477 if ((bt
->state
!= BT_STATE_IDLE
) &&
478 (bt
->state
< BT_STATE_PRINTME
)) {
481 if ((bt
->timeout
< 0) && (bt
->state
< BT_STATE_RESET1
))
482 return error_recovery(bt
,
490 * Idle state first checks for asynchronous messages from another
491 * channel, then does some opportunistic housekeeping.
495 if (status
& BT_SMS_ATN
) {
496 BT_CONTROL(BT_SMS_ATN
); /* clear it */
500 if (status
& BT_H_BUSY
) /* clear a leftover H_BUSY */
501 BT_CONTROL(BT_H_BUSY
);
503 BT_SI_SM_RETURN(SI_SM_IDLE
);
505 case BT_STATE_XACTION_START
:
506 if (status
& (BT_B_BUSY
| BT_H2B_ATN
))
507 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY
);
508 if (BT_STATUS
& BT_H_BUSY
)
509 BT_CONTROL(BT_H_BUSY
); /* force clear */
510 BT_STATE_CHANGE(BT_STATE_WRITE_BYTES
,
511 SI_SM_CALL_WITHOUT_DELAY
);
513 case BT_STATE_WRITE_BYTES
:
514 if (status
& BT_H_BUSY
)
515 BT_CONTROL(BT_H_BUSY
); /* clear */
516 BT_CONTROL(BT_CLR_WR_PTR
);
518 BT_CONTROL(BT_H2B_ATN
); /* can clear too fast to catch */
519 BT_STATE_CHANGE(BT_STATE_WRITE_CONSUME
,
520 SI_SM_CALL_WITHOUT_DELAY
);
522 case BT_STATE_WRITE_CONSUME
:
523 if (status
& (BT_B_BUSY
| BT_H2B_ATN
))
524 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY
);
525 BT_STATE_CHANGE(BT_STATE_READ_WAIT
,
526 SI_SM_CALL_WITHOUT_DELAY
);
528 /* Spinning hard can suppress B2H_ATN and force a timeout */
530 case BT_STATE_READ_WAIT
:
531 if (!(status
& BT_B2H_ATN
))
532 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY
);
533 BT_CONTROL(BT_H_BUSY
); /* set */
536 * Uncached, ordered writes should just proceed serially but
537 * some BMCs don't clear B2H_ATN with one hit. Fast-path a
538 * workaround without too much penalty to the general case.
541 BT_CONTROL(BT_B2H_ATN
); /* clear it to ACK the BMC */
542 BT_STATE_CHANGE(BT_STATE_CLEAR_B2H
,
543 SI_SM_CALL_WITHOUT_DELAY
);
545 case BT_STATE_CLEAR_B2H
:
546 if (status
& BT_B2H_ATN
) {
547 /* keep hitting it */
548 BT_CONTROL(BT_B2H_ATN
);
549 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY
);
551 BT_STATE_CHANGE(BT_STATE_READ_BYTES
,
552 SI_SM_CALL_WITHOUT_DELAY
);
554 case BT_STATE_READ_BYTES
:
555 if (!(status
& BT_H_BUSY
))
556 /* check in case of retry */
557 BT_CONTROL(BT_H_BUSY
);
558 BT_CONTROL(BT_CLR_RD_PTR
); /* start of BMC2HOST buffer */
559 i
= read_all_bytes(bt
); /* true == packet seq match */
560 BT_CONTROL(BT_H_BUSY
); /* NOW clear */
561 if (!i
) /* Not my message */
562 BT_STATE_CHANGE(BT_STATE_READ_WAIT
,
563 SI_SM_CALL_WITHOUT_DELAY
);
564 bt
->state
= bt
->complete
;
565 return bt
->state
== BT_STATE_IDLE
? /* where to next? */
566 SI_SM_TRANSACTION_COMPLETE
: /* normal */
567 SI_SM_CALL_WITHOUT_DELAY
; /* Startup magic */
569 case BT_STATE_LONG_BUSY
: /* For example: after FW update */
570 if (!(status
& BT_B_BUSY
)) {
571 reset_flags(bt
); /* next state is now IDLE */
572 bt_init_data(bt
, bt
->io
);
574 return SI_SM_CALL_WITH_DELAY
; /* No repeat printing */
576 case BT_STATE_RESET1
:
579 BT_STATE_CHANGE(BT_STATE_RESET2
,
580 SI_SM_CALL_WITH_DELAY
);
582 case BT_STATE_RESET2
: /* Send a soft reset */
583 BT_CONTROL(BT_CLR_WR_PTR
);
584 HOST2BMC(3); /* number of bytes following */
585 HOST2BMC(0x18); /* NetFn/LUN == Application, LUN 0 */
586 HOST2BMC(42); /* Sequence number */
587 HOST2BMC(3); /* Cmd == Soft reset */
588 BT_CONTROL(BT_H2B_ATN
);
589 bt
->timeout
= BT_RESET_DELAY
* USEC_PER_SEC
;
590 BT_STATE_CHANGE(BT_STATE_RESET3
,
591 SI_SM_CALL_WITH_DELAY
);
593 case BT_STATE_RESET3
: /* Hold off everything for a bit */
595 return SI_SM_CALL_WITH_DELAY
;
597 BT_STATE_CHANGE(BT_STATE_RESTART
,
598 SI_SM_CALL_WITH_DELAY
);
600 case BT_STATE_RESTART
: /* don't reset retries or seq! */
602 bt
->nonzero_status
= 0;
603 bt
->timeout
= bt
->BT_CAP_req2rsp
;
604 BT_STATE_CHANGE(BT_STATE_XACTION_START
,
605 SI_SM_CALL_WITH_DELAY
);
607 default: /* should never occur */
608 return error_recovery(bt
,
610 IPMI_ERR_UNSPECIFIED
);
612 return SI_SM_CALL_WITH_DELAY
;
615 static int bt_detect(struct si_sm_data
*bt
)
617 unsigned char GetBT_CAP
[] = { 0x18, 0x36 };
618 unsigned char BT_CAP
[8];
619 enum si_sm_result smi_result
;
623 * It's impossible for the BT status and interrupt registers to be
624 * all 1's, (assuming a properly functioning, self-initialized BMC)
625 * but that's what you get from reading a bogus address, so we
626 * test that first. The calling routine uses negative logic.
629 if ((BT_STATUS
== 0xFF) && (BT_INTMASK_R
== 0xFF))
634 * Try getting the BT capabilities here.
636 rv
= bt_start_transaction(bt
, GetBT_CAP
, sizeof(GetBT_CAP
));
638 dev_warn(bt
->io
->dev
,
639 "Can't start capabilities transaction: %d\n", rv
);
643 smi_result
= SI_SM_CALL_WITHOUT_DELAY
;
645 if (smi_result
== SI_SM_CALL_WITH_DELAY
||
646 smi_result
== SI_SM_CALL_WITH_TICK_DELAY
) {
647 schedule_timeout_uninterruptible(1);
648 smi_result
= bt_event(bt
, jiffies_to_usecs(1));
649 } else if (smi_result
== SI_SM_CALL_WITHOUT_DELAY
) {
650 smi_result
= bt_event(bt
, 0);
655 rv
= bt_get_result(bt
, BT_CAP
, sizeof(BT_CAP
));
656 bt_init_data(bt
, bt
->io
);
658 dev_warn(bt
->io
->dev
, "bt cap response too short: %d\n", rv
);
663 dev_warn(bt
->io
->dev
, "Error fetching bt cap: %x\n", BT_CAP
[2]);
665 dev_warn(bt
->io
->dev
, "using default values\n");
667 bt
->BT_CAP_req2rsp
= BT_CAP
[6] * USEC_PER_SEC
;
668 bt
->BT_CAP_retries
= BT_CAP
[7];
671 dev_info(bt
->io
->dev
, "req2rsp=%ld secs retries=%d\n",
672 bt
->BT_CAP_req2rsp
/ USEC_PER_SEC
, bt
->BT_CAP_retries
);
677 static void bt_cleanup(struct si_sm_data
*bt
)
681 static int bt_size(void)
683 return sizeof(struct si_sm_data
);
686 const struct si_sm_handlers bt_smi_handlers
= {
687 .init_data
= bt_init_data
,
688 .start_transaction
= bt_start_transaction
,
689 .get_result
= bt_get_result
,
692 .cleanup
= bt_cleanup
,