/*
 *  ipmi_bt_sm.c
 *
 *  The state machine for an Open IPMI BT sub-driver under ipmi_si.c, part
 *  of the driver architecture at http://sourceforge.net/projects/openipmi 
 *
 *  Author:	Rocky Craig <first.last@hp.com>
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License as published by the
 *  Free Software Foundation; either version 2 of the License, or (at your
 *  option) any later version.
 *
 *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  675 Mass Ave, Cambridge, MA 02139, USA.  */

#include <linux/kernel.h> /* For printk. */
#include <linux/string.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/ipmi_msgdefs.h>		/* for completion codes */
#include "ipmi_si_sm.h"

#define BT_DEBUG_OFF	0	/* Used in production */
#define BT_DEBUG_ENABLE	1	/* Generic messages */
#define BT_DEBUG_MSG	2	/* Prints all request/response buffers */
#define BT_DEBUG_STATES	4	/* Verbose look at state changes */
/*
 * BT_DEBUG_OFF must be zero to correspond to the default uninitialized
 * value
 */

static int bt_debug; /* 0 == BT_DEBUG_OFF */

module_param(bt_debug, int, 0644);
MODULE_PARM_DESC(bt_debug, "debug bitmask, 1=enable, 2=messages, 4=states");

/*
 * Typical "Get BT Capabilities" values are 2-3 retries, 5-10 seconds,
 * and 64 byte buffers.  However, one HP implementation wants 255 bytes of
 * buffer (with a documented message of 160 bytes) so go for the max.
 * Since the Open IPMI architecture is single-message oriented at this
 * stage, the queue depth of BT is of no concern.
 */

#define BT_NORMAL_TIMEOUT	5	/* seconds */
#define BT_NORMAL_RETRY_LIMIT	2
#define BT_RESET_DELAY		6	/* seconds after warm reset */

/*
 * States are written in chronological order and usually cover
 * multiple rows of the state table discussion in the IPMI spec.
 */

enum bt_states {
	BT_STATE_IDLE = 0,	/* Order is critical in this list */
	BT_STATE_XACTION_START,
	BT_STATE_WRITE_BYTES,
	BT_STATE_WRITE_CONSUME,
	BT_STATE_READ_WAIT,
	BT_STATE_CLEAR_B2H,
	BT_STATE_READ_BYTES,
	BT_STATE_RESET1,	/* These must come last */
	BT_STATE_RESET2,
	BT_STATE_RESET3,
	BT_STATE_RESTART,
	BT_STATE_PRINTME,
	BT_STATE_CAPABILITIES_BEGIN,
	BT_STATE_CAPABILITIES_END,
	BT_STATE_LONG_BUSY	/* BT doesn't get hosed :-) */
};

/*
 * Macros seen at the end of state "case" blocks.  They help with legibility
 * and debugging.
 */

#define BT_STATE_CHANGE(X, Y) { bt->state = X; return Y; }

#define BT_SI_SM_RETURN(Y)   { last_printed = BT_STATE_PRINTME; return Y; }

struct si_sm_data {
	enum bt_states	state;
	unsigned char	seq;		/* BT sequence number */
	struct si_sm_io	*io;
	unsigned char	write_data[IPMI_MAX_MSG_LENGTH + 2]; /* +2 for memcpy */
	int		write_count;
	unsigned char	read_data[IPMI_MAX_MSG_LENGTH + 2]; /* +2 for memcpy */
	int		read_count;
	int		truncated;
	long		timeout;	/* microseconds countdown */
	int		error_retries;	/* end of "common" fields */
	int		nonzero_status;	/* hung BMCs stay all 0 */
	enum bt_states	complete;	/* to divert the state machine */
	int		BT_CAP_outreqs;
	long		BT_CAP_req2rsp;
	int		BT_CAP_retries;	/* Recommended retries */
};

#define BT_CLR_WR_PTR	0x01	/* See IPMI 1.5 table 11.6.4 */
#define BT_CLR_RD_PTR	0x02
#define BT_H2B_ATN	0x04
#define BT_B2H_ATN	0x08
#define BT_SMS_ATN	0x10
#define BT_OEM0		0x20
#define BT_H_BUSY	0x40
#define BT_B_BUSY	0x80

/*
 * Some bits are toggled on each write: write once to set it, once
 * more to clear it; writing a zero does nothing.  To absolutely
 * clear it, check its state and write if set.  This avoids the "get
 * current then use as mask" scheme to modify one bit.  Note that the
 * variable "bt" is hardcoded into these macros.
 */

#define BT_STATUS	bt->io->inputb(bt->io, 0)
#define BT_CONTROL(x)	bt->io->outputb(bt->io, 0, x)

#define BMC2HOST	bt->io->inputb(bt->io, 1)
#define HOST2BMC(x)	bt->io->outputb(bt->io, 1, x)

#define BT_INTMASK_R	bt->io->inputb(bt->io, 2)
#define BT_INTMASK_W(x)	bt->io->outputb(bt->io, 2, x)

/*
 * Convenience routines for debugging.  These are not multi-open safe!
 * Note the macros have hardcoded variables in them.
 */

static char *state2txt(unsigned char state)
{
	switch (state) {
	case BT_STATE_IDLE:		return("IDLE");
	case BT_STATE_XACTION_START:	return("XACTION");
	case BT_STATE_WRITE_BYTES:	return("WR_BYTES");
	case BT_STATE_WRITE_CONSUME:	return("WR_CONSUME");
	case BT_STATE_READ_WAIT:	return("RD_WAIT");
	case BT_STATE_CLEAR_B2H:	return("CLEAR_B2H");
	case BT_STATE_READ_BYTES:	return("RD_BYTES");
	case BT_STATE_RESET1:		return("RESET1");
	case BT_STATE_RESET2:		return("RESET2");
	case BT_STATE_RESET3:		return("RESET3");
	case BT_STATE_RESTART:		return("RESTART");
	case BT_STATE_LONG_BUSY:	return("LONG_BUSY");
	case BT_STATE_CAPABILITIES_BEGIN: return("CAP_BEGIN");
	case BT_STATE_CAPABILITIES_END:	return("CAP_END");
	}
	return("BAD STATE");
}
#define STATE2TXT state2txt(bt->state)

static char *status2txt(unsigned char status)
{
	/*
	 * This cannot be called by two threads at the same time and
	 * the buffer is always consumed immediately, so the static is
	 * safe to use.
	 */
	static char buf[40];

	strcpy(buf, "[ ");
	if (status & BT_B_BUSY)
		strcat(buf, "B_BUSY ");
	if (status & BT_H_BUSY)
		strcat(buf, "H_BUSY ");
	if (status & BT_OEM0)
		strcat(buf, "OEM0 ");
	if (status & BT_SMS_ATN)
		strcat(buf, "SMS ");
	if (status & BT_B2H_ATN)
		strcat(buf, "B2H ");
	if (status & BT_H2B_ATN)
		strcat(buf, "H2B ");
	strcat(buf, "]");
	return buf;
}
#define STATUS2TXT status2txt(status)

/* called externally at insmod time, and internally on cleanup */

static unsigned int bt_init_data(struct si_sm_data *bt, struct si_sm_io *io)
{
	memset(bt, 0, sizeof(struct si_sm_data));
	if (bt->io != io) {
		/* external: one-time only things */
		bt->io = io;
		bt->seq = 0;
	}
	bt->state = BT_STATE_IDLE;	/* start here */
	bt->complete = BT_STATE_IDLE;	/* end here */
	bt->BT_CAP_req2rsp = BT_NORMAL_TIMEOUT * USEC_PER_SEC;
	bt->BT_CAP_retries = BT_NORMAL_RETRY_LIMIT;
	/* BT_CAP_outreqs == zero is a flag to read BT Capabilities */
	return 3; /* We claim 3 bytes of space; ought to check SPMI table */
}

/* Jam a completion code (probably an error) into a response */

static void force_result(struct si_sm_data *bt, unsigned char completion_code)
{
	bt->read_data[0] = 4;				/* # following bytes */
	bt->read_data[1] = bt->write_data[1] | 4;	/* Odd NetFn/LUN */
	bt->read_data[2] = bt->write_data[2];		/* seq (ignored) */
	bt->read_data[3] = bt->write_data[3];		/* Command */
	bt->read_data[4] = completion_code;
	bt->read_count = 5;
}

/* The upper state machine starts here */

static int bt_start_transaction(struct si_sm_data *bt,
				unsigned char *data,
				unsigned int size)
{
	unsigned int i;

	if (size < 2)
		return IPMI_REQ_LEN_INVALID_ERR;
	if (size > IPMI_MAX_MSG_LENGTH)
		return IPMI_REQ_LEN_EXCEEDED_ERR;

	if (bt->state == BT_STATE_LONG_BUSY)
		return IPMI_NODE_BUSY_ERR;

	if (bt->state != BT_STATE_IDLE)
		return IPMI_NOT_IN_MY_STATE_ERR;

	if (bt_debug & BT_DEBUG_MSG) {
		printk(KERN_WARNING "BT: +++++++++++++++++ New command\n");
		printk(KERN_WARNING "BT: NetFn/LUN CMD [%d data]:", size - 2);
		for (i = 0; i < size; i ++)
			printk(" %02x", data[i]);
		printk("\n");
	}
	bt->write_data[0] = size + 1;	/* all data plus seq byte */
	bt->write_data[1] = *data;	/* NetFn/LUN */
	bt->write_data[2] = bt->seq++;
	memcpy(bt->write_data + 3, data + 1, size - 1);
	bt->write_count = size + 2;
	bt->error_retries = 0;
	bt->nonzero_status = 0;
	bt->truncated = 0;
	bt->state = BT_STATE_XACTION_START;
	bt->timeout = bt->BT_CAP_req2rsp;
	force_result(bt, IPMI_ERR_UNSPECIFIED);
	return 0;
}

/*
 * After the upper state machine has been told SI_SM_TRANSACTION_COMPLETE
 * it calls this.  Strip out the length and seq bytes.
 */

static int bt_get_result(struct si_sm_data *bt,
			 unsigned char *data,
			 unsigned int length)
{
	int i, msg_len;

	msg_len = bt->read_count - 2;		/* account for length & seq */
	if (msg_len < 3 || msg_len > IPMI_MAX_MSG_LENGTH) {
		force_result(bt, IPMI_ERR_UNSPECIFIED);
		msg_len = 3;
	}
	data[0] = bt->read_data[1];
	data[1] = bt->read_data[3];
	if (length < msg_len || bt->truncated) {
		data[2] = IPMI_ERR_MSG_TRUNCATED;
		msg_len = 3;
	} else
		memcpy(data + 2, bt->read_data + 4, msg_len - 2);

	if (bt_debug & BT_DEBUG_MSG) {
		printk(KERN_WARNING "BT: result %d bytes:", msg_len);
		for (i = 0; i < msg_len; i++)
			printk(" %02x", data[i]);
		printk("\n");
	}
	return msg_len;
}

/* This bit's functionality is optional */
#define BT_BMC_HWRST	0x80

static void reset_flags(struct si_sm_data *bt)
{
	if (bt_debug)
		printk(KERN_WARNING "IPMI BT: flag reset %s\n",
					status2txt(BT_STATUS));
	if (BT_STATUS & BT_H_BUSY)
		BT_CONTROL(BT_H_BUSY);	/* force clear */
	BT_CONTROL(BT_CLR_WR_PTR);	/* always reset */
	BT_CONTROL(BT_SMS_ATN);		/* always clear */
	BT_INTMASK_W(BT_BMC_HWRST);
}

/*
 * Get rid of an unwanted/stale response.  This should only be needed for
 * BMCs that support multiple outstanding requests.
 */

static void drain_BMC2HOST(struct si_sm_data *bt)
{
	int i, size;

	if (!(BT_STATUS & BT_B2H_ATN)) 	/* Not signalling a response */
		return;

	BT_CONTROL(BT_H_BUSY);		/* now set */
	BT_CONTROL(BT_B2H_ATN);		/* always clear */
	BT_STATUS;			/* pause */
	BT_CONTROL(BT_B2H_ATN);		/* some BMCs are stubborn */
	BT_CONTROL(BT_CLR_RD_PTR);	/* always reset */
	if (bt_debug)
		printk(KERN_WARNING "IPMI BT: stale response %s; ",
			status2txt(BT_STATUS));
	size = BMC2HOST;
	for (i = 0; i < size ; i++)
		BMC2HOST;
	BT_CONTROL(BT_H_BUSY);		/* now clear */
	if (bt_debug)
		printk("drained %d bytes\n", size + 1);
}

static inline void write_all_bytes(struct si_sm_data *bt)
{
	int i;

	if (bt_debug & BT_DEBUG_MSG) {
		printk(KERN_WARNING "BT: write %d bytes seq=0x%02X",
			bt->write_count, bt->seq);
		for (i = 0; i < bt->write_count; i++)
			printk(" %02x", bt->write_data[i]);
		printk("\n");
	}
	for (i = 0; i < bt->write_count; i++)
		HOST2BMC(bt->write_data[i]);
}

static inline int read_all_bytes(struct si_sm_data *bt)
{
	unsigned int i;

	/*
	 * length is "framing info", minimum = 4: NetFn, Seq, Cmd, cCode.
	 * Keep layout of first four bytes aligned with write_data[]
	 */

	bt->read_data[0] = BMC2HOST;
	bt->read_count = bt->read_data[0];

	if (bt->read_count < 4 || bt->read_count >= IPMI_MAX_MSG_LENGTH) {
		if (bt_debug & BT_DEBUG_MSG)
			printk(KERN_WARNING "BT: bad raw rsp len=%d\n",
				bt->read_count);
		bt->truncated = 1;
		return 1;	/* let next XACTION START clean it up */
	}
	for (i = 1; i <= bt->read_count; i++)
		bt->read_data[i] = BMC2HOST;
	bt->read_count++;	/* Account internally for length byte */

	if (bt_debug & BT_DEBUG_MSG) {
		int max = bt->read_count;

		printk(KERN_WARNING "BT: got %d bytes seq=0x%02X",
			max, bt->read_data[2]);
		if (max > 16)
			max = 16;
		for (i = 0; i < max; i++)
			printk(KERN_CONT " %02x", bt->read_data[i]);
		printk(KERN_CONT "%s\n", bt->read_count == max ? "" : " ...");
	}

	/* per the spec, the (NetFn[1], Seq[2], Cmd[3]) tuples must match */
	if ((bt->read_data[3] == bt->write_data[3]) &&
	    (bt->read_data[2] == bt->write_data[2]) &&
	    ((bt->read_data[1] & 0xF8) == (bt->write_data[1] & 0xF8)))
			return 1;

	if (bt_debug & BT_DEBUG_MSG)
		printk(KERN_WARNING "IPMI BT: bad packet: "
		"want 0x(%02X, %02X, %02X) got (%02X, %02X, %02X)\n",
		bt->write_data[1] | 0x04, bt->write_data[2], bt->write_data[3],
		bt->read_data[1],  bt->read_data[2],  bt->read_data[3]);
	return 0;
}

/* Restart if retries are left, or return an error completion code */

static enum si_sm_result error_recovery(struct si_sm_data *bt,
					unsigned char status,
					unsigned char cCode)
{
	char *reason;

	bt->timeout = bt->BT_CAP_req2rsp;

	switch (cCode) {
	case IPMI_TIMEOUT_ERR:
		reason = "timeout";
		break;
	default:
		reason = "internal error";
		break;
	}

	printk(KERN_WARNING "IPMI BT: %s in %s %s ", 	/* open-ended line */
		reason, STATE2TXT, STATUS2TXT);

	/*
	 * Per the IPMI spec, retries are based on the sequence number
	 * known only to this module, so manage a restart here.
	 */
	(bt->error_retries)++;
	if (bt->error_retries < bt->BT_CAP_retries) {
		printk("%d retries left\n",
			bt->BT_CAP_retries - bt->error_retries);
		bt->state = BT_STATE_RESTART;
		return SI_SM_CALL_WITHOUT_DELAY;
	}

	printk(KERN_WARNING "failed %d retries, sending error response\n",
	       bt->BT_CAP_retries);
	if (!bt->nonzero_status)
		printk(KERN_ERR "IPMI BT: stuck, try power cycle\n");

	/* this is most likely during insmod */
	else if (bt->seq <= (unsigned char)(bt->BT_CAP_retries & 0xFF)) {
		printk(KERN_WARNING "IPMI: BT reset (takes 5 secs)\n");
		bt->state = BT_STATE_RESET1;
		return SI_SM_CALL_WITHOUT_DELAY;
	}

	/*
	 * Concoct a useful error message, set up the next state, and
	 * be done with this sequence.
	 */

	bt->state = BT_STATE_IDLE;
	switch (cCode) {
	case IPMI_TIMEOUT_ERR:
		if (status & BT_B_BUSY) {
			cCode = IPMI_NODE_BUSY_ERR;
			bt->state = BT_STATE_LONG_BUSY;
		}
		break;
	default:
		break;
	}
	force_result(bt, cCode);
	return SI_SM_TRANSACTION_COMPLETE;
}

/* Check status and (usually) take action and change this state machine. */

static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
{
	unsigned char status, BT_CAP[8];
	static enum bt_states last_printed = BT_STATE_PRINTME;
	int i;

	status = BT_STATUS;
	bt->nonzero_status |= status;
	if ((bt_debug & BT_DEBUG_STATES) && (bt->state != last_printed)) {
		printk(KERN_WARNING "BT: %s %s TO=%ld - %ld \n",
			STATE2TXT,
			STATUS2TXT,
			bt->timeout,
			time);
		last_printed = bt->state;
	}

	/*
	 * Commands that time out may still (eventually) provide a response.
	 * This stale response will get in the way of a new response so remove
	 * it if possible (hopefully during IDLE).  Even if it comes up later
	 * it will be rejected by its (now-forgotten) seq number.
	 */

	if ((bt->state < BT_STATE_WRITE_BYTES) && (status & BT_B2H_ATN)) {
		drain_BMC2HOST(bt);
		BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
	}

	if ((bt->state != BT_STATE_IDLE) &&
	    (bt->state <  BT_STATE_PRINTME)) {
		/* check timeout */
		bt->timeout -= time;
		if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1))
			return error_recovery(bt,
					      status,
					      IPMI_TIMEOUT_ERR);
	}

	switch (bt->state) {

	/*
	 * Idle state first checks for asynchronous messages from another
	 * channel, then does some opportunistic housekeeping.
	 */

	case BT_STATE_IDLE:
		if (status & BT_SMS_ATN) {
			BT_CONTROL(BT_SMS_ATN);	/* clear it */
			return SI_SM_ATTN;
		}

		if (status & BT_H_BUSY)		/* clear a leftover H_BUSY */
			BT_CONTROL(BT_H_BUSY);

		/* Read BT capabilities if it hasn't been done yet */
		if (!bt->BT_CAP_outreqs)
			BT_STATE_CHANGE(BT_STATE_CAPABILITIES_BEGIN,
					SI_SM_CALL_WITHOUT_DELAY);
		bt->timeout = bt->BT_CAP_req2rsp;
		BT_SI_SM_RETURN(SI_SM_IDLE);

	case BT_STATE_XACTION_START:
		if (status & (BT_B_BUSY | BT_H2B_ATN))
			BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
		if (BT_STATUS & BT_H_BUSY)
			BT_CONTROL(BT_H_BUSY);	/* force clear */
		BT_STATE_CHANGE(BT_STATE_WRITE_BYTES,
				SI_SM_CALL_WITHOUT_DELAY);

	case BT_STATE_WRITE_BYTES:
		if (status & BT_H_BUSY)
			BT_CONTROL(BT_H_BUSY);	/* clear */
		BT_CONTROL(BT_CLR_WR_PTR);
		write_all_bytes(bt);
		BT_CONTROL(BT_H2B_ATN);	/* can clear too fast to catch */
		BT_STATE_CHANGE(BT_STATE_WRITE_CONSUME,
				SI_SM_CALL_WITHOUT_DELAY);

	case BT_STATE_WRITE_CONSUME:
		if (status & (BT_B_BUSY | BT_H2B_ATN))
			BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
		BT_STATE_CHANGE(BT_STATE_READ_WAIT,
				SI_SM_CALL_WITHOUT_DELAY);

	/* Spinning hard can suppress B2H_ATN and force a timeout */

	case BT_STATE_READ_WAIT:
		if (!(status & BT_B2H_ATN))
			BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
		BT_CONTROL(BT_H_BUSY);		/* set */

		/*
		 * Uncached, ordered writes should just proceed serially but
		 * some BMCs don't clear B2H_ATN with one hit.  Fast-path a
		 * workaround without too much penalty to the general case.
		 */

		BT_CONTROL(BT_B2H_ATN);		/* clear it to ACK the BMC */
		BT_STATE_CHANGE(BT_STATE_CLEAR_B2H,
				SI_SM_CALL_WITHOUT_DELAY);

	case BT_STATE_CLEAR_B2H:
		if (status & BT_B2H_ATN) {
			/* keep hitting it */
			BT_CONTROL(BT_B2H_ATN);
			BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
		}
		BT_STATE_CHANGE(BT_STATE_READ_BYTES,
				SI_SM_CALL_WITHOUT_DELAY);

	case BT_STATE_READ_BYTES:
		if (!(status & BT_H_BUSY))
			/* check in case of retry */
			BT_CONTROL(BT_H_BUSY);
		BT_CONTROL(BT_CLR_RD_PTR);	/* start of BMC2HOST buffer */
		i = read_all_bytes(bt);		/* true == packet seq match */
		BT_CONTROL(BT_H_BUSY);		/* NOW clear */
		if (!i) 			/* Not my message */
			BT_STATE_CHANGE(BT_STATE_READ_WAIT,
					SI_SM_CALL_WITHOUT_DELAY);
		bt->state = bt->complete;
		return bt->state == BT_STATE_IDLE ?	/* where to next? */
			SI_SM_TRANSACTION_COMPLETE :	/* normal */
			SI_SM_CALL_WITHOUT_DELAY;	/* Startup magic */

	case BT_STATE_LONG_BUSY:	/* For example: after FW update */
		if (!(status & BT_B_BUSY)) {
			reset_flags(bt);	/* next state is now IDLE */
			bt_init_data(bt, bt->io);
		}
		return SI_SM_CALL_WITH_DELAY;	/* No repeat printing */

	case BT_STATE_RESET1:
		reset_flags(bt);
		drain_BMC2HOST(bt);
		BT_STATE_CHANGE(BT_STATE_RESET2,
				SI_SM_CALL_WITH_DELAY);

	case BT_STATE_RESET2:		/* Send a soft reset */
		BT_CONTROL(BT_CLR_WR_PTR);
		HOST2BMC(3);		/* number of bytes following */
		HOST2BMC(0x18);		/* NetFn/LUN == Application, LUN 0 */
		HOST2BMC(42);		/* Sequence number */
		HOST2BMC(3);		/* Cmd == Soft reset */
		BT_CONTROL(BT_H2B_ATN);
		bt->timeout = BT_RESET_DELAY * USEC_PER_SEC;
		BT_STATE_CHANGE(BT_STATE_RESET3,
				SI_SM_CALL_WITH_DELAY);

	case BT_STATE_RESET3:		/* Hold off everything for a bit */
		if (bt->timeout > 0)
			return SI_SM_CALL_WITH_DELAY;
		drain_BMC2HOST(bt);
		BT_STATE_CHANGE(BT_STATE_RESTART,
				SI_SM_CALL_WITH_DELAY);

	case BT_STATE_RESTART:		/* don't reset retries or seq! */
		bt->read_count = 0;
		bt->nonzero_status = 0;
		bt->timeout = bt->BT_CAP_req2rsp;
		BT_STATE_CHANGE(BT_STATE_XACTION_START,
				SI_SM_CALL_WITH_DELAY);

	/*
	 * Get BT Capabilities, using timing of upper level state machine.
	 * Set outreqs to prevent infinite loop on timeout.
	 */
	case BT_STATE_CAPABILITIES_BEGIN:
		bt->BT_CAP_outreqs = 1;
		{
			unsigned char GetBT_CAP[] = { 0x18, 0x36 };
			bt->state = BT_STATE_IDLE;
			bt_start_transaction(bt, GetBT_CAP, sizeof(GetBT_CAP));
		}
		bt->complete = BT_STATE_CAPABILITIES_END;
		BT_STATE_CHANGE(BT_STATE_XACTION_START,
				SI_SM_CALL_WITH_DELAY);

	case BT_STATE_CAPABILITIES_END:
		i = bt_get_result(bt, BT_CAP, sizeof(BT_CAP));
		bt_init_data(bt, bt->io);
		if ((i == 8) && !BT_CAP[2]) {
			bt->BT_CAP_outreqs = BT_CAP[3];
			bt->BT_CAP_req2rsp = BT_CAP[6] * USEC_PER_SEC;
			bt->BT_CAP_retries = BT_CAP[7];
		} else
			printk(KERN_WARNING "IPMI BT: using default values\n");
		if (!bt->BT_CAP_outreqs)
			bt->BT_CAP_outreqs = 1;
		printk(KERN_WARNING "IPMI BT: req2rsp=%ld secs retries=%d\n",
			bt->BT_CAP_req2rsp / USEC_PER_SEC, bt->BT_CAP_retries);
		bt->timeout = bt->BT_CAP_req2rsp;
		return SI_SM_CALL_WITHOUT_DELAY;

	default:	/* should never occur */
		return error_recovery(bt,
				      status,
				      IPMI_ERR_UNSPECIFIED);
	}
	return SI_SM_CALL_WITH_DELAY;
}

static int bt_detect(struct si_sm_data *bt)
{
	/*
	 * It's impossible for the BT status and interrupt registers to be
	 * all 1's, (assuming a properly functioning, self-initialized BMC)
	 * but that's what you get from reading a bogus address, so we
	 * test that first.  The calling routine uses negative logic.
	 */

	if ((BT_STATUS == 0xFF) && (BT_INTMASK_R == 0xFF))
		return 1;
	reset_flags(bt);
	return 0;
}

static void bt_cleanup(struct si_sm_data *bt)
{
}

static int bt_size(void)
{
	return sizeof(struct si_sm_data);
}

struct si_sm_handlers bt_smi_handlers = {
	.init_data		= bt_init_data,
	.start_transaction	= bt_start_transaction,
	.get_result		= bt_get_result,
	.event			= bt_event,
	.detect			= bt_detect,
	.cleanup		= bt_cleanup,
	.size			= bt_size,
};
