/*
 * ipmi_si.c
 *
 * The interface to the IPMI driver for the system interfaces (KCS, SMIC,
 * BT).
 *
 * Author: MontaVista Software, Inc.
 *         Corey Minyard <minyard@mvista.com>
 *         source@mvista.com
 *
 * Copyright 2002 MontaVista Software Inc.
 *
 *  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.
 */

/*
 * This file holds the "policy" for the interface to the SMI state
 * machine.  It does the configuration, handles timers and interrupts,
 * and drives the real SMI state machine.
 */

#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <asm/system.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/ioport.h>
#include <asm/irq.h>
#ifdef CONFIG_HIGH_RES_TIMERS
#include <linux/hrtime.h>
# if defined(schedule_next_int)
/* Old high-res timer code, do translations. */
#  define get_arch_cycles(a) quick_update_jiffies_sub(a)
#  define arch_cycles_per_jiffy cycles_per_jiffies
# endif
static inline void add_usec_to_timer(struct timer_list *t, long v)
{
	t->sub_expires += nsec_to_arch_cycle(v * 1000);
	while (t->sub_expires >= arch_cycles_per_jiffy)
	{
		t->expires++;
		t->sub_expires -= arch_cycles_per_jiffy;
	}
}
#endif
#include <linux/interrupt.h>
#include <linux/rcupdate.h>
#include <linux/ipmi_smi.h>
#include <asm/io.h>
#include "ipmi_si_sm.h"
#include <linux/init.h>

#define IPMI_SI_VERSION "v33"

/* Measure times between events in the driver. */
#undef DEBUG_TIMING

/* Call every 10 ms. */
#define SI_TIMEOUT_TIME_USEC	10000
#define SI_USEC_PER_JIFFY	(1000000/HZ)
#define SI_TIMEOUT_JIFFIES	(SI_TIMEOUT_TIME_USEC/SI_USEC_PER_JIFFY)
#define SI_SHORT_TIMEOUT_USEC  250 /* .25ms when the SM request a
                                       short timeout */

enum si_intf_state {
	SI_NORMAL,
	SI_GETTING_FLAGS,
	SI_GETTING_EVENTS,
	SI_CLEARING_FLAGS,
	SI_CLEARING_FLAGS_THEN_SET_IRQ,
	SI_GETTING_MESSAGES,
	SI_ENABLE_INTERRUPTS1,
	SI_ENABLE_INTERRUPTS2
	/* FIXME - add watchdog stuff. */
};

/* Some BT-specific defines we need here. */
#define IPMI_BT_INTMASK_REG		2
#define IPMI_BT_INTMASK_CLEAR_IRQ_BIT	2
#define IPMI_BT_INTMASK_ENABLE_IRQ_BIT	1

enum si_type {
    SI_KCS, SI_SMIC, SI_BT
};

struct smi_info
{
	ipmi_smi_t             intf;
	struct si_sm_data      *si_sm;
	struct si_sm_handlers  *handlers;
	enum si_type           si_type;
	spinlock_t             si_lock;
	spinlock_t             msg_lock;
	struct list_head       xmit_msgs;
	struct list_head       hp_xmit_msgs;
	struct ipmi_smi_msg    *curr_msg;
	enum si_intf_state     si_state;

	/* Used to handle the various types of I/O that can occur with
           IPMI */
	struct si_sm_io io;
	int (*io_setup)(struct smi_info *info);
	void (*io_cleanup)(struct smi_info *info);
	int (*irq_setup)(struct smi_info *info);
	void (*irq_cleanup)(struct smi_info *info);
	unsigned int io_size;

	/* Flags from the last GET_MSG_FLAGS command, used when an ATTN
	   is set to hold the flags until we are done handling everything
	   from the flags. */
#define RECEIVE_MSG_AVAIL	0x01
#define EVENT_MSG_BUFFER_FULL	0x02
#define WDT_PRE_TIMEOUT_INT	0x08
	unsigned char       msg_flags;

	/* If set to true, this will request events the next time the
	   state machine is idle. */
	atomic_t            req_events;

	/* If true, run the state machine to completion on every send
	   call.  Generally used after a panic to make sure stuff goes
	   out. */
	int                 run_to_completion;

	/* The I/O port of an SI interface. */
	int                 port;

	/* The space between start addresses of the two ports.  For
	   instance, if the first port is 0xca2 and the spacing is 4, then
	   the second port is 0xca6. */
	unsigned int        spacing;

	/* zero if no irq; */
	int                 irq;

	/* The timer for this si. */
	struct timer_list   si_timer;

	/* The time (in jiffies) the last timeout occurred at. */
	unsigned long       last_timeout_jiffies;

	/* Used to gracefully stop the timer without race conditions. */
	volatile int        stop_operation;
	volatile int        timer_stopped;

	/* The driver will disable interrupts when it gets into a
	   situation where it cannot handle messages due to lack of
	   memory.  Once that situation clears up, it will re-enable
	   interrupts. */
	int interrupt_disabled;

	unsigned char ipmi_si_dev_rev;
	unsigned char ipmi_si_fw_rev_major;
	unsigned char ipmi_si_fw_rev_minor;
	unsigned char ipmi_version_major;
	unsigned char ipmi_version_minor;

	/* Slave address, could be reported from DMI. */
	unsigned char slave_addr;

	/* Counters and things for the proc filesystem. */
	spinlock_t count_lock;
	unsigned long short_timeouts;
	unsigned long long_timeouts;
	unsigned long timeout_restarts;
	unsigned long idles;
	unsigned long interrupts;
	unsigned long attentions;
	unsigned long flag_fetches;
	unsigned long hosed_count;
	unsigned long complete_transactions;
	unsigned long events;
	unsigned long watchdog_pretimeouts;
	unsigned long incoming_messages;
};

static void si_restart_short_timer(struct smi_info *smi_info);

static void deliver_recv_msg(struct smi_info *smi_info,
			     struct ipmi_smi_msg *msg)
{
	/* Deliver the message to the upper layer with the lock
           released. */
	spin_unlock(&(smi_info->si_lock));
	ipmi_smi_msg_received(smi_info->intf, msg);
	spin_lock(&(smi_info->si_lock));
}

static void return_hosed_msg(struct smi_info *smi_info)
{
	struct ipmi_smi_msg *msg = smi_info->curr_msg;

	/* Make it a reponse */
	msg->rsp[0] = msg->data[0] | 4;
	msg->rsp[1] = msg->data[1];
	msg->rsp[2] = 0xFF; /* Unknown error. */
	msg->rsp_size = 3;

	smi_info->curr_msg = NULL;
	deliver_recv_msg(smi_info, msg);
}

static enum si_sm_result start_next_msg(struct smi_info *smi_info)
{
	int              rv;
	struct list_head *entry = NULL;
#ifdef DEBUG_TIMING
	struct timeval t;
#endif

	/* No need to save flags, we aleady have interrupts off and we
	   already hold the SMI lock. */
	spin_lock(&(smi_info->msg_lock));

	/* Pick the high priority queue first. */
	if (! list_empty(&(smi_info->hp_xmit_msgs))) {
		entry = smi_info->hp_xmit_msgs.next;
	} else if (! list_empty(&(smi_info->xmit_msgs))) {
		entry = smi_info->xmit_msgs.next;
	}

	if (!entry) {
		smi_info->curr_msg = NULL;
		rv = SI_SM_IDLE;
	} else {
		int err;

		list_del(entry);
		smi_info->curr_msg = list_entry(entry,
						struct ipmi_smi_msg,
						link);
#ifdef DEBUG_TIMING
		do_gettimeofday(&t);
		printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec);
#endif
		err = smi_info->handlers->start_transaction(
			smi_info->si_sm,
			smi_info->curr_msg->data,
			smi_info->curr_msg->data_size);
		if (err) {
			return_hosed_msg(smi_info);
		}

		rv = SI_SM_CALL_WITHOUT_DELAY;
	}
	spin_unlock(&(smi_info->msg_lock));

	return rv;
}

static void start_enable_irq(struct smi_info *smi_info)
{
	unsigned char msg[2];

	/* If we are enabling interrupts, we have to tell the
	   BMC to use them. */
	msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
	msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD;

	smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
	smi_info->si_state = SI_ENABLE_INTERRUPTS1;
}

static void start_clear_flags(struct smi_info *smi_info)
{
	unsigned char msg[3];

	/* Make sure the watchdog pre-timeout flag is not set at startup. */
	msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
	msg[1] = IPMI_CLEAR_MSG_FLAGS_CMD;
	msg[2] = WDT_PRE_TIMEOUT_INT;

	smi_info->handlers->start_transaction(smi_info->si_sm, msg, 3);
	smi_info->si_state = SI_CLEARING_FLAGS;
}

/* When we have a situtaion where we run out of memory and cannot
   allocate messages, we just leave them in the BMC and run the system
   polled until we can allocate some memory.  Once we have some
   memory, we will re-enable the interrupt. */
static inline void disable_si_irq(struct smi_info *smi_info)
{
	if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
		disable_irq_nosync(smi_info->irq);
		smi_info->interrupt_disabled = 1;
	}
}

static inline void enable_si_irq(struct smi_info *smi_info)
{
	if ((smi_info->irq) && (smi_info->interrupt_disabled)) {
		enable_irq(smi_info->irq);
		smi_info->interrupt_disabled = 0;
	}
}

static void handle_flags(struct smi_info *smi_info)
{
	if (smi_info->msg_flags & WDT_PRE_TIMEOUT_INT) {
		/* Watchdog pre-timeout */
		spin_lock(&smi_info->count_lock);
		smi_info->watchdog_pretimeouts++;
		spin_unlock(&smi_info->count_lock);

		start_clear_flags(smi_info);
		smi_info->msg_flags &= ~WDT_PRE_TIMEOUT_INT;
		spin_unlock(&(smi_info->si_lock));
		ipmi_smi_watchdog_pretimeout(smi_info->intf);
		spin_lock(&(smi_info->si_lock));
	} else if (smi_info->msg_flags & RECEIVE_MSG_AVAIL) {
		/* Messages available. */
		smi_info->curr_msg = ipmi_alloc_smi_msg();
		if (!smi_info->curr_msg) {
			disable_si_irq(smi_info);
			smi_info->si_state = SI_NORMAL;
			return;
		}
		enable_si_irq(smi_info);

		smi_info->curr_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2);
		smi_info->curr_msg->data[1] = IPMI_GET_MSG_CMD;
		smi_info->curr_msg->data_size = 2;

		smi_info->handlers->start_transaction(
			smi_info->si_sm,
			smi_info->curr_msg->data,
			smi_info->curr_msg->data_size);
		smi_info->si_state = SI_GETTING_MESSAGES;
	} else if (smi_info->msg_flags & EVENT_MSG_BUFFER_FULL) {
		/* Events available. */
		smi_info->curr_msg = ipmi_alloc_smi_msg();
		if (!smi_info->curr_msg) {
			disable_si_irq(smi_info);
			smi_info->si_state = SI_NORMAL;
			return;
		}
		enable_si_irq(smi_info);

		smi_info->curr_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2);
		smi_info->curr_msg->data[1] = IPMI_READ_EVENT_MSG_BUFFER_CMD;
		smi_info->curr_msg->data_size = 2;

		smi_info->handlers->start_transaction(
			smi_info->si_sm,
			smi_info->curr_msg->data,
			smi_info->curr_msg->data_size);
		smi_info->si_state = SI_GETTING_EVENTS;
	} else {
		smi_info->si_state = SI_NORMAL;
	}
}

static void handle_transaction_done(struct smi_info *smi_info)
{
	struct ipmi_smi_msg *msg;
#ifdef DEBUG_TIMING
	struct timeval t;

	do_gettimeofday(&t);
	printk("**Done: %d.%9.9d\n", t.tv_sec, t.tv_usec);
#endif
	switch (smi_info->si_state) {
	case SI_NORMAL:
		if (!smi_info->curr_msg)
			break;

		smi_info->curr_msg->rsp_size
			= smi_info->handlers->get_result(
				smi_info->si_sm,
				smi_info->curr_msg->rsp,
				IPMI_MAX_MSG_LENGTH);

		/* Do this here becase deliver_recv_msg() releases the
		   lock, and a new message can be put in during the
		   time the lock is released. */
		msg = smi_info->curr_msg;
		smi_info->curr_msg = NULL;
		deliver_recv_msg(smi_info, msg);
		break;

	case SI_GETTING_FLAGS:
	{
		unsigned char msg[4];
		unsigned int  len;

		/* We got the flags from the SMI, now handle them. */
		len = smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
		if (msg[2] != 0) {
			/* Error fetching flags, just give up for
			   now. */
			smi_info->si_state = SI_NORMAL;
		} else if (len < 4) {
			/* Hmm, no flags.  That's technically illegal, but
			   don't use uninitialized data. */
			smi_info->si_state = SI_NORMAL;
		} else {
			smi_info->msg_flags = msg[3];
			handle_flags(smi_info);
		}
		break;
	}

	case SI_CLEARING_FLAGS:
	case SI_CLEARING_FLAGS_THEN_SET_IRQ:
	{
		unsigned char msg[3];

		/* We cleared the flags. */
		smi_info->handlers->get_result(smi_info->si_sm, msg, 3);
		if (msg[2] != 0) {
			/* Error clearing flags */
			printk(KERN_WARNING
			       "ipmi_si: Error clearing flags: %2.2x\n",
			       msg[2]);
		}
		if (smi_info->si_state == SI_CLEARING_FLAGS_THEN_SET_IRQ)
			start_enable_irq(smi_info);
		else
			smi_info->si_state = SI_NORMAL;
		break;
	}

	case SI_GETTING_EVENTS:
	{
		smi_info->curr_msg->rsp_size
			= smi_info->handlers->get_result(
				smi_info->si_sm,
				smi_info->curr_msg->rsp,
				IPMI_MAX_MSG_LENGTH);

		/* Do this here becase deliver_recv_msg() releases the
		   lock, and a new message can be put in during the
		   time the lock is released. */
		msg = smi_info->curr_msg;
		smi_info->curr_msg = NULL;
		if (msg->rsp[2] != 0) {
			/* Error getting event, probably done. */
			msg->done(msg);

			/* Take off the event flag. */
			smi_info->msg_flags &= ~EVENT_MSG_BUFFER_FULL;
			handle_flags(smi_info);
		} else {
			spin_lock(&smi_info->count_lock);
			smi_info->events++;
			spin_unlock(&smi_info->count_lock);

			/* Do this before we deliver the message
			   because delivering the message releases the
			   lock and something else can mess with the
			   state. */
			handle_flags(smi_info);

			deliver_recv_msg(smi_info, msg);
		}
		break;
	}

	case SI_GETTING_MESSAGES:
	{
		smi_info->curr_msg->rsp_size
			= smi_info->handlers->get_result(
				smi_info->si_sm,
				smi_info->curr_msg->rsp,
				IPMI_MAX_MSG_LENGTH);

		/* Do this here becase deliver_recv_msg() releases the
		   lock, and a new message can be put in during the
		   time the lock is released. */
		msg = smi_info->curr_msg;
		smi_info->curr_msg = NULL;
		if (msg->rsp[2] != 0) {
			/* Error getting event, probably done. */
			msg->done(msg);

			/* Take off the msg flag. */
			smi_info->msg_flags &= ~RECEIVE_MSG_AVAIL;
			handle_flags(smi_info);
		} else {
			spin_lock(&smi_info->count_lock);
			smi_info->incoming_messages++;
			spin_unlock(&smi_info->count_lock);

			/* Do this before we deliver the message
			   because delivering the message releases the
			   lock and something else can mess with the
			   state. */
			handle_flags(smi_info);

			deliver_recv_msg(smi_info, msg);
		}
		break;
	}

	case SI_ENABLE_INTERRUPTS1:
	{
		unsigned char msg[4];

		/* We got the flags from the SMI, now handle them. */
		smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
		if (msg[2] != 0) {
			printk(KERN_WARNING
			       "ipmi_si: Could not enable interrupts"
			       ", failed get, using polled mode.\n");
			smi_info->si_state = SI_NORMAL;
		} else {
			msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
			msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD;
			msg[2] = msg[3] | 1; /* enable msg queue int */
			smi_info->handlers->start_transaction(
				smi_info->si_sm, msg, 3);
			smi_info->si_state = SI_ENABLE_INTERRUPTS2;
		}
		break;
	}

	case SI_ENABLE_INTERRUPTS2:
	{
		unsigned char msg[4];

		/* We got the flags from the SMI, now handle them. */
		smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
		if (msg[2] != 0) {
			printk(KERN_WARNING
			       "ipmi_si: Could not enable interrupts"
			       ", failed set, using polled mode.\n");
		}
		smi_info->si_state = SI_NORMAL;
		break;
	}
	}
}

/* Called on timeouts and events.  Timeouts should pass the elapsed
   time, interrupts should pass in zero. */
static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
					   int time)
{
	enum si_sm_result si_sm_result;

 restart:
	/* There used to be a loop here that waited a little while
	   (around 25us) before giving up.  That turned out to be
	   pointless, the minimum delays I was seeing were in the 300us
	   range, which is far too long to wait in an interrupt.  So
	   we just run until the state machine tells us something
	   happened or it needs a delay. */
	si_sm_result = smi_info->handlers->event(smi_info->si_sm, time);
	time = 0;
	while (si_sm_result == SI_SM_CALL_WITHOUT_DELAY)
	{
		si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0);
	}

	if (si_sm_result == SI_SM_TRANSACTION_COMPLETE)
	{
		spin_lock(&smi_info->count_lock);
		smi_info->complete_transactions++;
		spin_unlock(&smi_info->count_lock);

		handle_transaction_done(smi_info);
		si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0);
	}
	else if (si_sm_result == SI_SM_HOSED)
	{
		spin_lock(&smi_info->count_lock);
		smi_info->hosed_count++;
		spin_unlock(&smi_info->count_lock);

		/* Do the before return_hosed_msg, because that
		   releases the lock. */
		smi_info->si_state = SI_NORMAL;
		if (smi_info->curr_msg != NULL) {
			/* If we were handling a user message, format
                           a response to send to the upper layer to
                           tell it about the error. */
			return_hosed_msg(smi_info);
		}
		si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0);
	}

	/* We prefer handling attn over new messages. */
	if (si_sm_result == SI_SM_ATTN)
	{
		unsigned char msg[2];

		spin_lock(&smi_info->count_lock);
		smi_info->attentions++;
		spin_unlock(&smi_info->count_lock);

		/* Got a attn, send down a get message flags to see
                   what's causing it.  It would be better to handle
                   this in the upper layer, but due to the way
                   interrupts work with the SMI, that's not really
                   possible. */
		msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
		msg[1] = IPMI_GET_MSG_FLAGS_CMD;

		smi_info->handlers->start_transaction(
			smi_info->si_sm, msg, 2);
		smi_info->si_state = SI_GETTING_FLAGS;
		goto restart;
	}

	/* If we are currently idle, try to start the next message. */
	if (si_sm_result == SI_SM_IDLE) {
		spin_lock(&smi_info->count_lock);
		smi_info->idles++;
		spin_unlock(&smi_info->count_lock);

		si_sm_result = start_next_msg(smi_info);
		if (si_sm_result != SI_SM_IDLE)
			goto restart;
        }

	if ((si_sm_result == SI_SM_IDLE)
	    && (atomic_read(&smi_info->req_events)))
	{
		/* We are idle and the upper layer requested that I fetch
		   events, so do so. */
		unsigned char msg[2];

		spin_lock(&smi_info->count_lock);
		smi_info->flag_fetches++;
		spin_unlock(&smi_info->count_lock);

		atomic_set(&smi_info->req_events, 0);
		msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
		msg[1] = IPMI_GET_MSG_FLAGS_CMD;

		smi_info->handlers->start_transaction(
			smi_info->si_sm, msg, 2);
		smi_info->si_state = SI_GETTING_FLAGS;
		goto restart;
	}

	return si_sm_result;
}

static void sender(void                *send_info,
		   struct ipmi_smi_msg *msg,
		   int                 priority)
{
	struct smi_info   *smi_info = send_info;
	enum si_sm_result result;
	unsigned long     flags;
#ifdef DEBUG_TIMING
	struct timeval    t;
#endif

	spin_lock_irqsave(&(smi_info->msg_lock), flags);
#ifdef DEBUG_TIMING
	do_gettimeofday(&t);
	printk("**Enqueue: %d.%9.9d\n", t.tv_sec, t.tv_usec);
#endif

	if (smi_info->run_to_completion) {
		/* If we are running to completion, then throw it in
		   the list and run transactions until everything is
		   clear.  Priority doesn't matter here. */
		list_add_tail(&(msg->link), &(smi_info->xmit_msgs));

		/* We have to release the msg lock and claim the smi
		   lock in this case, because of race conditions. */
		spin_unlock_irqrestore(&(smi_info->msg_lock), flags);

		spin_lock_irqsave(&(smi_info->si_lock), flags);
		result = smi_event_handler(smi_info, 0);
		while (result != SI_SM_IDLE) {
			udelay(SI_SHORT_TIMEOUT_USEC);
			result = smi_event_handler(smi_info,
						   SI_SHORT_TIMEOUT_USEC);
		}
		spin_unlock_irqrestore(&(smi_info->si_lock), flags);
		return;
	} else {
		if (priority > 0) {
			list_add_tail(&(msg->link), &(smi_info->hp_xmit_msgs));
		} else {
			list_add_tail(&(msg->link), &(smi_info->xmit_msgs));
		}
	}
	spin_unlock_irqrestore(&(smi_info->msg_lock), flags);

	spin_lock_irqsave(&(smi_info->si_lock), flags);
	if ((smi_info->si_state == SI_NORMAL)
	    && (smi_info->curr_msg == NULL))
	{
		start_next_msg(smi_info);
		si_restart_short_timer(smi_info);
	}
	spin_unlock_irqrestore(&(smi_info->si_lock), flags);
}

static void set_run_to_completion(void *send_info, int i_run_to_completion)
{
	struct smi_info   *smi_info = send_info;
	enum si_sm_result result;
	unsigned long     flags;

	spin_lock_irqsave(&(smi_info->si_lock), flags);

	smi_info->run_to_completion = i_run_to_completion;
	if (i_run_to_completion) {
		result = smi_event_handler(smi_info, 0);
		while (result != SI_SM_IDLE) {
			udelay(SI_SHORT_TIMEOUT_USEC);
			result = smi_event_handler(smi_info,
						   SI_SHORT_TIMEOUT_USEC);
		}
	}

	spin_unlock_irqrestore(&(smi_info->si_lock), flags);
}

static void poll(void *send_info)
{
	struct smi_info *smi_info = send_info;

	smi_event_handler(smi_info, 0);
}

static void request_events(void *send_info)
{
	struct smi_info *smi_info = send_info;

	atomic_set(&smi_info->req_events, 1);
}

static int initialized = 0;

/* Must be called with interrupts off and with the si_lock held. */
static void si_restart_short_timer(struct smi_info *smi_info)
{
#if defined(CONFIG_HIGH_RES_TIMERS)
	unsigned long flags;
	unsigned long jiffies_now;

	if (del_timer(&(smi_info->si_timer))) {
		/* If we don't delete the timer, then it will go off
		   immediately, anyway.  So we only process if we
		   actually delete the timer. */

		/* We already have irqsave on, so no need for it
                   here. */
		read_lock(&xtime_lock);
		jiffies_now = jiffies;
		smi_info->si_timer.expires = jiffies_now;
		smi_info->si_timer.sub_expires = get_arch_cycles(jiffies_now);

		add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC);

		add_timer(&(smi_info->si_timer));
		spin_lock_irqsave(&smi_info->count_lock, flags);
		smi_info->timeout_restarts++;
		spin_unlock_irqrestore(&smi_info->count_lock, flags);
	}
#endif
}

static void smi_timeout(unsigned long data)
{
	struct smi_info   *smi_info = (struct smi_info *) data;
	enum si_sm_result smi_result;
	unsigned long     flags;
	unsigned long     jiffies_now;
	unsigned long     time_diff;
#ifdef DEBUG_TIMING
	struct timeval    t;
#endif

	if (smi_info->stop_operation) {
		smi_info->timer_stopped = 1;
		return;
	}

	spin_lock_irqsave(&(smi_info->si_lock), flags);
#ifdef DEBUG_TIMING
	do_gettimeofday(&t);
	printk("**Timer: %d.%9.9d\n", t.tv_sec, t.tv_usec);
#endif
	jiffies_now = jiffies;
	time_diff = ((jiffies_now - smi_info->last_timeout_jiffies)
		     * SI_USEC_PER_JIFFY);
	smi_result = smi_event_handler(smi_info, time_diff);

	spin_unlock_irqrestore(&(smi_info->si_lock), flags);

	smi_info->last_timeout_jiffies = jiffies_now;

	if ((smi_info->irq) && (! smi_info->interrupt_disabled)) {
		/* Running with interrupts, only do long timeouts. */
		smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
		spin_lock_irqsave(&smi_info->count_lock, flags);
		smi_info->long_timeouts++;
		spin_unlock_irqrestore(&smi_info->count_lock, flags);
		goto do_add_timer;
	}

	/* If the state machine asks for a short delay, then shorten
           the timer timeout. */
	if (smi_result == SI_SM_CALL_WITH_DELAY) {
		spin_lock_irqsave(&smi_info->count_lock, flags);
		smi_info->short_timeouts++;
		spin_unlock_irqrestore(&smi_info->count_lock, flags);
#if defined(CONFIG_HIGH_RES_TIMERS)
		read_lock(&xtime_lock);
                smi_info->si_timer.expires = jiffies;
                smi_info->si_timer.sub_expires
                        = get_arch_cycles(smi_info->si_timer.expires);
                read_unlock(&xtime_lock);
		add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC);
#else
		smi_info->si_timer.expires = jiffies + 1;
#endif
	} else {
		spin_lock_irqsave(&smi_info->count_lock, flags);
		smi_info->long_timeouts++;
		spin_unlock_irqrestore(&smi_info->count_lock, flags);
		smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
#if defined(CONFIG_HIGH_RES_TIMERS)
		smi_info->si_timer.sub_expires = 0;
#endif
	}

 do_add_timer:
	add_timer(&(smi_info->si_timer));
}

static irqreturn_t si_irq_handler(int irq, void *data, struct pt_regs *regs)
{
	struct smi_info *smi_info = data;
	unsigned long   flags;
#ifdef DEBUG_TIMING
	struct timeval  t;
#endif

	spin_lock_irqsave(&(smi_info->si_lock), flags);

	spin_lock(&smi_info->count_lock);
	smi_info->interrupts++;
	spin_unlock(&smi_info->count_lock);

	if (smi_info->stop_operation)
		goto out;

#ifdef DEBUG_TIMING
	do_gettimeofday(&t);
	printk("**Interrupt: %d.%9.9d\n", t.tv_sec, t.tv_usec);
#endif
	smi_event_handler(smi_info, 0);
 out:
	spin_unlock_irqrestore(&(smi_info->si_lock), flags);
	return IRQ_HANDLED;
}

static irqreturn_t si_bt_irq_handler(int irq, void *data, struct pt_regs *regs)
{
	struct smi_info *smi_info = data;
	/* We need to clear the IRQ flag for the BT interface. */
	smi_info->io.outputb(&smi_info->io, IPMI_BT_INTMASK_REG,
			     IPMI_BT_INTMASK_CLEAR_IRQ_BIT
			     | IPMI_BT_INTMASK_ENABLE_IRQ_BIT);
	return si_irq_handler(irq, data, regs);
}


static struct ipmi_smi_handlers handlers =
{
	.owner                  = THIS_MODULE,
	.sender			= sender,
	.request_events		= request_events,
	.set_run_to_completion  = set_run_to_completion,
	.poll			= poll,
};

/* There can be 4 IO ports passed in (with or without IRQs), 4 addresses,
   a default IO port, and 1 ACPI/SPMI address.  That sets SI_MAX_DRIVERS */

#define SI_MAX_PARMS 4
#define SI_MAX_DRIVERS ((SI_MAX_PARMS * 2) + 2)
static struct smi_info *smi_infos[SI_MAX_DRIVERS] =
{ NULL, NULL, NULL, NULL };

#define DEVICE_NAME "ipmi_si"

#define DEFAULT_KCS_IO_PORT	0xca2
#define DEFAULT_SMIC_IO_PORT	0xca9
#define DEFAULT_BT_IO_PORT	0xe4
#define DEFAULT_REGSPACING	1

static int           si_trydefaults = 1;
static char          *si_type[SI_MAX_PARMS];
#define MAX_SI_TYPE_STR 30
static char          si_type_str[MAX_SI_TYPE_STR];
static unsigned long addrs[SI_MAX_PARMS];
static int num_addrs;
static unsigned int  ports[SI_MAX_PARMS];
static int num_ports;
static int           irqs[SI_MAX_PARMS];
static int num_irqs;
static int           regspacings[SI_MAX_PARMS];
static int num_regspacings = 0;
static int           regsizes[SI_MAX_PARMS];
static int num_regsizes = 0;
static int           regshifts[SI_MAX_PARMS];
static int num_regshifts = 0;
static int slave_addrs[SI_MAX_PARMS];
static int num_slave_addrs = 0;


module_param_named(trydefaults, si_trydefaults, bool, 0);
MODULE_PARM_DESC(trydefaults, "Setting this to 'false' will disable the"
		 " default scan of the KCS and SMIC interface at the standard"
		 " address");
module_param_string(type, si_type_str, MAX_SI_TYPE_STR, 0);
MODULE_PARM_DESC(type, "Defines the type of each interface, each"
		 " interface separated by commas.  The types are 'kcs',"
		 " 'smic', and 'bt'.  For example si_type=kcs,bt will set"
		 " the first interface to kcs and the second to bt");
module_param_array(addrs, long, &num_addrs, 0);
MODULE_PARM_DESC(addrs, "Sets the memory address of each interface, the"
		 " addresses separated by commas.  Only use if an interface"
		 " is in memory.  Otherwise, set it to zero or leave"
		 " it blank.");
module_param_array(ports, int, &num_ports, 0);
MODULE_PARM_DESC(ports, "Sets the port address of each interface, the"
		 " addresses separated by commas.  Only use if an interface"
		 " is a port.  Otherwise, set it to zero or leave"
		 " it blank.");
module_param_array(irqs, int, &num_irqs, 0);
MODULE_PARM_DESC(irqs, "Sets the interrupt of each interface, the"
		 " addresses separated by commas.  Only use if an interface"
		 " has an interrupt.  Otherwise, set it to zero or leave"
		 " it blank.");
module_param_array(regspacings, int, &num_regspacings, 0);
MODULE_PARM_DESC(regspacings, "The number of bytes between the start address"
		 " and each successive register used by the interface.  For"
		 " instance, if the start address is 0xca2 and the spacing"
		 " is 2, then the second address is at 0xca4.  Defaults"
		 " to 1.");
module_param_array(regsizes, int, &num_regsizes, 0);
MODULE_PARM_DESC(regsizes, "The size of the specific IPMI register in bytes."
		 " This should generally be 1, 2, 4, or 8 for an 8-bit,"
		 " 16-bit, 32-bit, or 64-bit register.  Use this if you"
		 " the 8-bit IPMI register has to be read from a larger"
		 " register.");
module_param_array(regshifts, int, &num_regshifts, 0);
MODULE_PARM_DESC(regshifts, "The amount to shift the data read from the."
		 " IPMI register, in bits.  For instance, if the data"
		 " is read from a 32-bit word and the IPMI data is in"
		 " bit 8-15, then the shift would be 8");
module_param_array(slave_addrs, int, &num_slave_addrs, 0);
MODULE_PARM_DESC(slave_addrs, "Set the default IPMB slave address for"
		 " the controller.  Normally this is 0x20, but can be"
		 " overridden by this parm.  This is an array indexed"
		 " by interface number.");


#define IPMI_MEM_ADDR_SPACE 1
#define IPMI_IO_ADDR_SPACE  2

#if defined(CONFIG_ACPI_INTERPRETER) || defined(CONFIG_X86) || defined(CONFIG_PCI)
static int is_new_interface(int intf, u8 addr_space, unsigned long base_addr)
{
	int i;

	for (i = 0; i < SI_MAX_PARMS; ++i) {
		/* Don't check our address. */
		if (i == intf)
			continue;
		if (si_type[i] != NULL) {
			if ((addr_space == IPMI_MEM_ADDR_SPACE &&
			     base_addr == addrs[i]) ||
			    (addr_space == IPMI_IO_ADDR_SPACE &&
			     base_addr == ports[i]))
				return 0;
		}
		else
			break;
	}

	return 1;
}
#endif

static int std_irq_setup(struct smi_info *info)
{
	int rv;

	if (!info->irq)
		return 0;

	if (info->si_type == SI_BT) {
		rv = request_irq(info->irq,
				 si_bt_irq_handler,
				 SA_INTERRUPT,
				 DEVICE_NAME,
				 info);
		if (!rv)
			/* Enable the interrupt in the BT interface. */
			info->io.outputb(&info->io, IPMI_BT_INTMASK_REG,
					 IPMI_BT_INTMASK_ENABLE_IRQ_BIT);
	} else
		rv = request_irq(info->irq,
				 si_irq_handler,
				 SA_INTERRUPT,
				 DEVICE_NAME,
				 info);
	if (rv) {
		printk(KERN_WARNING
		       "ipmi_si: %s unable to claim interrupt %d,"
		       " running polled\n",
		       DEVICE_NAME, info->irq);
		info->irq = 0;
	} else {
		printk("  Using irq %d\n", info->irq);
	}

	return rv;
}

static void std_irq_cleanup(struct smi_info *info)
{
	if (!info->irq)
		return;

	if (info->si_type == SI_BT)
		/* Disable the interrupt in the BT interface. */
		info->io.outputb(&info->io, IPMI_BT_INTMASK_REG, 0);
	free_irq(info->irq, info);
}

static unsigned char port_inb(struct si_sm_io *io, unsigned int offset)
{
	unsigned int *addr = io->info;

	return inb((*addr)+(offset*io->regspacing));
}

static void port_outb(struct si_sm_io *io, unsigned int offset,
		      unsigned char b)
{
	unsigned int *addr = io->info;

	outb(b, (*addr)+(offset * io->regspacing));
}

static unsigned char port_inw(struct si_sm_io *io, unsigned int offset)
{
	unsigned int *addr = io->info;

	return (inw((*addr)+(offset * io->regspacing)) >> io->regshift) & 0xff;
}

static void port_outw(struct si_sm_io *io, unsigned int offset,
		      unsigned char b)
{
	unsigned int *addr = io->info;

	outw(b << io->regshift, (*addr)+(offset * io->regspacing));
}

static unsigned char port_inl(struct si_sm_io *io, unsigned int offset)
{
	unsigned int *addr = io->info;

	return (inl((*addr)+(offset * io->regspacing)) >> io->regshift) & 0xff;
}

static void port_outl(struct si_sm_io *io, unsigned int offset,
		      unsigned char b)
{
	unsigned int *addr = io->info;

	outl(b << io->regshift, (*addr)+(offset * io->regspacing));
}

static void port_cleanup(struct smi_info *info)
{
	unsigned int *addr = info->io.info;
	int           mapsize;

	if (addr && (*addr)) {
		mapsize = ((info->io_size * info->io.regspacing)
			   - (info->io.regspacing - info->io.regsize));

		release_region (*addr, mapsize);
	}
	kfree(info);
}

static int port_setup(struct smi_info *info)
{
	unsigned int *addr = info->io.info;
	int           mapsize;

	if (!addr || (!*addr))
		return -ENODEV;

	info->io_cleanup = port_cleanup;

	/* Figure out the actual inb/inw/inl/etc routine to use based
	   upon the register size. */
	switch (info->io.regsize) {
	case 1:
		info->io.inputb = port_inb;
		info->io.outputb = port_outb;
		break;
	case 2:
		info->io.inputb = port_inw;
		info->io.outputb = port_outw;
		break;
	case 4:
		info->io.inputb = port_inl;
		info->io.outputb = port_outl;
		break;
	default:
		printk("ipmi_si: Invalid register size: %d\n",
		       info->io.regsize);
		return -EINVAL;
	}

	/* Calculate the total amount of memory to claim.  This is an
	 * unusual looking calculation, but it avoids claiming any
	 * more memory than it has to.  It will claim everything
	 * between the first address to the end of the last full
	 * register. */
	mapsize = ((info->io_size * info->io.regspacing)
		   - (info->io.regspacing - info->io.regsize));

	if (request_region(*addr, mapsize, DEVICE_NAME) == NULL)
		return -EIO;
	return 0;
}

static int try_init_port(int intf_num, struct smi_info **new_info)
{
	struct smi_info *info;

	if (!ports[intf_num])
		return -ENODEV;

	if (!is_new_interface(intf_num, IPMI_IO_ADDR_SPACE,
			      ports[intf_num]))
		return -ENODEV;

	info = kmalloc(sizeof(*info), GFP_KERNEL);
	if (!info) {
		printk(KERN_ERR "ipmi_si: Could not allocate SI data (1)\n");
		return -ENOMEM;
	}
	memset(info, 0, sizeof(*info));

	info->io_setup = port_setup;
	info->io.info = &(ports[intf_num]);
	info->io.addr = NULL;
	info->io.regspacing = regspacings[intf_num];
	if (!info->io.regspacing)
		info->io.regspacing = DEFAULT_REGSPACING;
	info->io.regsize = regsizes[intf_num];
	if (!info->io.regsize)
		info->io.regsize = DEFAULT_REGSPACING;
	info->io.regshift = regshifts[intf_num];
	info->irq = 0;
	info->irq_setup = NULL;
	*new_info = info;

	if (si_type[intf_num] == NULL)
		si_type[intf_num] = "kcs";

	printk("ipmi_si: Trying \"%s\" at I/O port 0x%x\n",
	       si_type[intf_num], ports[intf_num]);
	return 0;
}

static unsigned char mem_inb(struct si_sm_io *io, unsigned int offset)
{
	return readb((io->addr)+(offset * io->regspacing));
}

static void mem_outb(struct si_sm_io *io, unsigned int offset,
		     unsigned char b)
{
	writeb(b, (io->addr)+(offset * io->regspacing));
}

static unsigned char mem_inw(struct si_sm_io *io, unsigned int offset)
{
	return (readw((io->addr)+(offset * io->regspacing)) >> io->regshift)
		&& 0xff;
}

static void mem_outw(struct si_sm_io *io, unsigned int offset,
		     unsigned char b)
{
	writeb(b << io->regshift, (io->addr)+(offset * io->regspacing));
}

static unsigned char mem_inl(struct si_sm_io *io, unsigned int offset)
{
	return (readl((io->addr)+(offset * io->regspacing)) >> io->regshift)
		&& 0xff;
}

static void mem_outl(struct si_sm_io *io, unsigned int offset,
		     unsigned char b)
{
	writel(b << io->regshift, (io->addr)+(offset * io->regspacing));
}

#ifdef readq
static unsigned char mem_inq(struct si_sm_io *io, unsigned int offset)
{
	return (readq((io->addr)+(offset * io->regspacing)) >> io->regshift)
		&& 0xff;
}

static void mem_outq(struct si_sm_io *io, unsigned int offset,
		     unsigned char b)
{
	writeq(b << io->regshift, (io->addr)+(offset * io->regspacing));
}
#endif

static void mem_cleanup(struct smi_info *info)
{
	unsigned long *addr = info->io.info;
	int           mapsize;

	if (info->io.addr) {
		iounmap(info->io.addr);

		mapsize = ((info->io_size * info->io.regspacing)
			   - (info->io.regspacing - info->io.regsize));

		release_mem_region(*addr, mapsize);
	}
	kfree(info);
}

static int mem_setup(struct smi_info *info)
{
	unsigned long *addr = info->io.info;
	int           mapsize;

	if (!addr || (!*addr))
		return -ENODEV;

	info->io_cleanup = mem_cleanup;

	/* Figure out the actual readb/readw/readl/etc routine to use based
	   upon the register size. */
	switch (info->io.regsize) {
	case 1:
		info->io.inputb = mem_inb;
		info->io.outputb = mem_outb;
		break;
	case 2:
		info->io.inputb = mem_inw;
		info->io.outputb = mem_outw;
		break;
	case 4:
		info->io.inputb = mem_inl;
		info->io.outputb = mem_outl;
		break;
#ifdef readq
	case 8:
		info->io.inputb = mem_inq;
		info->io.outputb = mem_outq;
		break;
#endif
	default:
		printk("ipmi_si: Invalid register size: %d\n",
		       info->io.regsize);
		return -EINVAL;
	}

	/* Calculate the total amount of memory to claim.  This is an
	 * unusual looking calculation, but it avoids claiming any
	 * more memory than it has to.  It will claim everything
	 * between the first address to the end of the last full
	 * register. */
	mapsize = ((info->io_size * info->io.regspacing)
		   - (info->io.regspacing - info->io.regsize));

	if (request_mem_region(*addr, mapsize, DEVICE_NAME) == NULL)
		return -EIO;

	info->io.addr = ioremap(*addr, mapsize);
	if (info->io.addr == NULL) {
		release_mem_region(*addr, mapsize);
		return -EIO;
	}
	return 0;
}

static int try_init_mem(int intf_num, struct smi_info **new_info)
{
	struct smi_info *info;

	if (!addrs[intf_num])
		return -ENODEV;

	if (!is_new_interface(intf_num, IPMI_MEM_ADDR_SPACE,
			      addrs[intf_num]))
		return -ENODEV;

	info = kmalloc(sizeof(*info), GFP_KERNEL);
	if (!info) {
		printk(KERN_ERR "ipmi_si: Could not allocate SI data (2)\n");
		return -ENOMEM;
	}
	memset(info, 0, sizeof(*info));

	info->io_setup = mem_setup;
	info->io.info = &addrs[intf_num];
	info->io.addr = NULL;
	info->io.regspacing = regspacings[intf_num];
	if (!info->io.regspacing)
		info->io.regspacing = DEFAULT_REGSPACING;
	info->io.regsize = regsizes[intf_num];
	if (!info->io.regsize)
		info->io.regsize = DEFAULT_REGSPACING;
	info->io.regshift = regshifts[intf_num];
	info->irq = 0;
	info->irq_setup = NULL;
	*new_info = info;

	if (si_type[intf_num] == NULL)
		si_type[intf_num] = "kcs";

	printk("ipmi_si: Trying \"%s\" at memory address 0x%lx\n",
	       si_type[intf_num], addrs[intf_num]);
	return 0;
}


#ifdef CONFIG_ACPI_INTERPRETER

#include <linux/acpi.h>

/* Once we get an ACPI failure, we don't try any more, because we go
   through the tables sequentially.  Once we don't find a table, there
   are no more. */
static int acpi_failure = 0;

/* For GPE-type interrupts. */
static u32 ipmi_acpi_gpe(void *context)
{
	struct smi_info *smi_info = context;
	unsigned long   flags;
#ifdef DEBUG_TIMING
	struct timeval t;
#endif

	spin_lock_irqsave(&(smi_info->si_lock), flags);

	spin_lock(&smi_info->count_lock);
	smi_info->interrupts++;
	spin_unlock(&smi_info->count_lock);

	if (smi_info->stop_operation)
		goto out;

#ifdef DEBUG_TIMING
	do_gettimeofday(&t);
	printk("**ACPI_GPE: %d.%9.9d\n", t.tv_sec, t.tv_usec);
#endif
	smi_event_handler(smi_info, 0);
 out:
	spin_unlock_irqrestore(&(smi_info->si_lock), flags);

	return ACPI_INTERRUPT_HANDLED;
}

static int acpi_gpe_irq_setup(struct smi_info *info)
{
	acpi_status status;

	if (!info->irq)
		return 0;

	/* FIXME - is level triggered right? */
	status = acpi_install_gpe_handler(NULL,
					  info->irq,
					  ACPI_GPE_LEVEL_TRIGGERED,
					  &ipmi_acpi_gpe,
					  info);
	if (status != AE_OK) {
		printk(KERN_WARNING
		       "ipmi_si: %s unable to claim ACPI GPE %d,"
		       " running polled\n",
		       DEVICE_NAME, info->irq);
		info->irq = 0;
		return -EINVAL;
	} else {
		printk("  Using ACPI GPE %d\n", info->irq);
		return 0;
	}
}

static void acpi_gpe_irq_cleanup(struct smi_info *info)
{
	if (!info->irq)
		return;

	acpi_remove_gpe_handler(NULL, info->irq, &ipmi_acpi_gpe);
}

/*
 * Defined at
 * http://h21007.www2.hp.com/dspp/files/unprotected/devresource/Docs/TechPapers/IA64/hpspmi.pdf
 */
struct SPMITable {
	s8	Signature[4];
	u32	Length;
	u8	Revision;
	u8	Checksum;
	s8	OEMID[6];
	s8	OEMTableID[8];
	s8	OEMRevision[4];
	s8	CreatorID[4];
	s8	CreatorRevision[4];
	u8	InterfaceType;
	u8	IPMIlegacy;
	s16	SpecificationRevision;

	/*
	 * Bit 0 - SCI interrupt supported
	 * Bit 1 - I/O APIC/SAPIC
	 */
	u8	InterruptType;

	/* If bit 0 of InterruptType is set, then this is the SCI
           interrupt in the GPEx_STS register. */
	u8	GPE;

	s16	Reserved;

	/* If bit 1 of InterruptType is set, then this is the I/O
           APIC/SAPIC interrupt. */
	u32	GlobalSystemInterrupt;

	/* The actual register address. */
	struct acpi_generic_address addr;

	u8	UID[4];

	s8      spmi_id[1]; /* A '\0' terminated array starts here. */
};

static int try_init_acpi(int intf_num, struct smi_info **new_info)
{
	struct smi_info  *info;
	acpi_status      status;
	struct SPMITable *spmi;
	char             *io_type;
	u8 		 addr_space;

	if (acpi_failure)
		return -ENODEV;

	status = acpi_get_firmware_table("SPMI", intf_num+1,
					 ACPI_LOGICAL_ADDRESSING,
					 (struct acpi_table_header **) &spmi);
	if (status != AE_OK) {
		acpi_failure = 1;
		return -ENODEV;
	}

	if (spmi->IPMIlegacy != 1) {
	    printk(KERN_INFO "IPMI: Bad SPMI legacy %d\n", spmi->IPMIlegacy);
  	    return -ENODEV;
	}

	if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
		addr_space = IPMI_MEM_ADDR_SPACE;
	else
		addr_space = IPMI_IO_ADDR_SPACE;
	if (!is_new_interface(-1, addr_space, spmi->addr.address))
		return -ENODEV;

	if (!spmi->addr.register_bit_width) {
		acpi_failure = 1;
		return -ENODEV;
	}

	/* Figure out the interface type. */
	switch (spmi->InterfaceType)
	{
	case 1:	/* KCS */
		si_type[intf_num] = "kcs";
		break;

	case 2:	/* SMIC */
		si_type[intf_num] = "smic";
		break;

	case 3:	/* BT */
		si_type[intf_num] = "bt";
		break;

	default:
		printk(KERN_INFO "ipmi_si: Unknown ACPI/SPMI SI type %d\n",
			spmi->InterfaceType);
		return -EIO;
	}

	info = kmalloc(sizeof(*info), GFP_KERNEL);
	if (!info) {
		printk(KERN_ERR "ipmi_si: Could not allocate SI data (3)\n");
		return -ENOMEM;
	}
	memset(info, 0, sizeof(*info));

	if (spmi->InterruptType & 1) {
		/* We've got a GPE interrupt. */
		info->irq = spmi->GPE;
		info->irq_setup = acpi_gpe_irq_setup;
		info->irq_cleanup = acpi_gpe_irq_cleanup;
	} else if (spmi->InterruptType & 2) {
		/* We've got an APIC/SAPIC interrupt. */
		info->irq = spmi->GlobalSystemInterrupt;
		info->irq_setup = std_irq_setup;
		info->irq_cleanup = std_irq_cleanup;
	} else {
		/* Use the default interrupt setting. */
		info->irq = 0;
		info->irq_setup = NULL;
	}

	if (spmi->addr.register_bit_width) {
		/* A (hopefully) properly formed register bit width. */
		regspacings[intf_num] = spmi->addr.register_bit_width / 8;
		info->io.regspacing = spmi->addr.register_bit_width / 8;
	} else {
		/* Some broken systems get this wrong and set the value
		 * to zero.  Assume it is the default spacing.  If that
		 * is wrong, too bad, the vendor should fix the tables. */
		regspacings[intf_num] = DEFAULT_REGSPACING;
		info->io.regspacing = DEFAULT_REGSPACING;
	}
	regsizes[intf_num] = regspacings[intf_num];
	info->io.regsize = regsizes[intf_num];
	regshifts[intf_num] = spmi->addr.register_bit_offset;
	info->io.regshift = regshifts[intf_num];

	if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
		io_type = "memory";
		info->io_setup = mem_setup;
		addrs[intf_num] = spmi->addr.address;
		info->io.info = &(addrs[intf_num]);
	} else if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
		io_type = "I/O";
		info->io_setup = port_setup;
		ports[intf_num] = spmi->addr.address;
		info->io.info = &(ports[intf_num]);
	} else {
		kfree(info);
		printk("ipmi_si: Unknown ACPI I/O Address type\n");
		return -EIO;
	}

	*new_info = info;

	printk("ipmi_si: ACPI/SPMI specifies \"%s\" %s SI @ 0x%lx\n",
	       si_type[intf_num], io_type, (unsigned long) spmi->addr.address);
	return 0;
}
#endif

#ifdef CONFIG_X86
typedef struct dmi_ipmi_data
{
	u8   		type;
	u8   		addr_space;
	unsigned long	base_addr;
	u8   		irq;
	u8              offset;
	u8              slave_addr;
} dmi_ipmi_data_t;

static dmi_ipmi_data_t dmi_data[SI_MAX_DRIVERS];
static int dmi_data_entries;

typedef struct dmi_header
{
	u8	type;
	u8	length;
	u16	handle;
} dmi_header_t;

static int decode_dmi(dmi_header_t __iomem *dm, int intf_num)
{
	u8		__iomem *data = (u8 __iomem *)dm;
	unsigned long  	base_addr;
	u8		reg_spacing;
	u8              len = readb(&dm->length);
	dmi_ipmi_data_t *ipmi_data = dmi_data+intf_num;

	ipmi_data->type = readb(&data[4]);

	memcpy(&base_addr, data+8, sizeof(unsigned long));
	if (len >= 0x11) {
		if (base_addr & 1) {
			/* I/O */
			base_addr &= 0xFFFE;
			ipmi_data->addr_space = IPMI_IO_ADDR_SPACE;
		}
		else {
			/* Memory */
			ipmi_data->addr_space = IPMI_MEM_ADDR_SPACE;
		}
		/* If bit 4 of byte 0x10 is set, then the lsb for the address
		   is odd. */
		ipmi_data->base_addr = base_addr | ((readb(&data[0x10]) & 0x10) >> 4);

		ipmi_data->irq = readb(&data[0x11]);

		/* The top two bits of byte 0x10 hold the register spacing. */
		reg_spacing = (readb(&data[0x10]) & 0xC0) >> 6;
		switch(reg_spacing){
		case 0x00: /* Byte boundaries */
		    ipmi_data->offset = 1;
		    break;
		case 0x01: /* 32-bit boundaries */
		    ipmi_data->offset = 4;
		    break;
		case 0x02: /* 16-byte boundaries */
		    ipmi_data->offset = 16;
		    break;
		default:
		    /* Some other interface, just ignore it. */
		    return -EIO;
		}
	} else {
		/* Old DMI spec. */
		/* Note that technically, the lower bit of the base
		 * address should be 1 if the address is I/O and 0 if
		 * the address is in memory.  So many systems get that
		 * wrong (and all that I have seen are I/O) so we just
		 * ignore that bit and assume I/O.  Systems that use
		 * memory should use the newer spec, anyway. */
		ipmi_data->base_addr = base_addr & 0xfffe;
		ipmi_data->addr_space = IPMI_IO_ADDR_SPACE;
		ipmi_data->offset = 1;
	}

	ipmi_data->slave_addr = readb(&data[6]);

	if (is_new_interface(-1, ipmi_data->addr_space,ipmi_data->base_addr)) {
		dmi_data_entries++;
		return 0;
	}

	memset(ipmi_data, 0, sizeof(dmi_ipmi_data_t));

	return -1;
}

static int dmi_table(u32 base, int len, int num)
{
	u8 		  __iomem *buf;
	struct dmi_header __iomem *dm;
	u8 		  __iomem *data;
	int 		  i=1;
	int		  status=-1;
	int               intf_num = 0;

	buf = ioremap(base, len);
	if(buf==NULL)
		return -1;

	data = buf;

	while(i<num && (data - buf) < len)
	{
		dm=(dmi_header_t __iomem *)data;

		if((data-buf+readb(&dm->length)) >= len)
        		break;

		if (readb(&dm->type) == 38) {
			if (decode_dmi(dm, intf_num) == 0) {
				intf_num++;
				if (intf_num >= SI_MAX_DRIVERS)
					break;
			}
		}

	        data+=readb(&dm->length);
		while((data-buf) < len && (readb(data)||readb(data+1)))
			data++;
		data+=2;
		i++;
	}
	iounmap(buf);

	return status;
}

inline static int dmi_checksum(u8 *buf)
{
	u8   sum=0;
	int  a;

	for(a=0; a<15; a++)
		sum+=buf[a];
	return (sum==0);
}

static int dmi_decode(void)
{
	u8   buf[15];
	u32  fp=0xF0000;

#ifdef CONFIG_SIMNOW
	return -1;
#endif

	while(fp < 0xFFFFF)
	{
		isa_memcpy_fromio(buf, fp, 15);
		if(memcmp(buf, "_DMI_", 5)==0 && dmi_checksum(buf))
		{
			u16 num=buf[13]<<8|buf[12];
			u16 len=buf[7]<<8|buf[6];
			u32 base=buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8];

			if(dmi_table(base, len, num) == 0)
				return 0;
		}
		fp+=16;
	}

	return -1;
}

static int try_init_smbios(int intf_num, struct smi_info **new_info)
{
	struct smi_info   *info;
	dmi_ipmi_data_t   *ipmi_data = dmi_data+intf_num;
	char              *io_type;

	if (intf_num >= dmi_data_entries)
		return -ENODEV;

	switch(ipmi_data->type) {
		case 0x01: /* KCS */
			si_type[intf_num] = "kcs";
			break;
		case 0x02: /* SMIC */
			si_type[intf_num] = "smic";
			break;
		case 0x03: /* BT */
			si_type[intf_num] = "bt";
			break;
		default:
			return -EIO;
	}

	info = kmalloc(sizeof(*info), GFP_KERNEL);
	if (!info) {
		printk(KERN_ERR "ipmi_si: Could not allocate SI data (4)\n");
		return -ENOMEM;
	}
	memset(info, 0, sizeof(*info));

	if (ipmi_data->addr_space == 1) {
		io_type = "memory";
		info->io_setup = mem_setup;
		addrs[intf_num] = ipmi_data->base_addr;
		info->io.info = &(addrs[intf_num]);
	} else if (ipmi_data->addr_space == 2) {
		io_type = "I/O";
		info->io_setup = port_setup;
		ports[intf_num] = ipmi_data->base_addr;
		info->io.info = &(ports[intf_num]);
	} else {
		kfree(info);
		printk("ipmi_si: Unknown SMBIOS I/O Address type.\n");
		return -EIO;
	}

	regspacings[intf_num] = ipmi_data->offset;
	info->io.regspacing = regspacings[intf_num];
	if (!info->io.regspacing)
		info->io.regspacing = DEFAULT_REGSPACING;
	info->io.regsize = DEFAULT_REGSPACING;
	info->io.regshift = regshifts[intf_num];

	info->slave_addr = ipmi_data->slave_addr;

	irqs[intf_num] = ipmi_data->irq;

	*new_info = info;

	printk("ipmi_si: Found SMBIOS-specified state machine at %s"
	       " address 0x%lx, slave address 0x%x\n",
	       io_type, (unsigned long)ipmi_data->base_addr,
	       ipmi_data->slave_addr);
	return 0;
}
#endif /* CONFIG_X86 */

#ifdef CONFIG_PCI

#define PCI_ERMC_CLASSCODE  0x0C0700
#define PCI_HP_VENDOR_ID    0x103C
#define PCI_MMC_DEVICE_ID   0x121A
#define PCI_MMC_ADDR_CW     0x10

/* Avoid more than one attempt to probe pci smic. */
static int pci_smic_checked = 0;

static int find_pci_smic(int intf_num, struct smi_info **new_info)
{
	struct smi_info  *info;
	int              error;
	struct pci_dev   *pci_dev = NULL;
	u16    		 base_addr;
	int              fe_rmc = 0;

	if (pci_smic_checked)
		return -ENODEV;

	pci_smic_checked = 1;

	if ((pci_dev = pci_get_device(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID,
				       NULL)))
		;
	else if ((pci_dev = pci_get_class(PCI_ERMC_CLASSCODE, NULL)) &&
		 pci_dev->subsystem_vendor == PCI_HP_VENDOR_ID)
		fe_rmc = 1;
	else
		return -ENODEV;

	error = pci_read_config_word(pci_dev, PCI_MMC_ADDR_CW, &base_addr);
	if (error)
	{
		pci_dev_put(pci_dev);
		printk(KERN_ERR
		       "ipmi_si: pci_read_config_word() failed (%d).\n",
		       error);
		return -ENODEV;
	}

	/* Bit 0: 1 specifies programmed I/O, 0 specifies memory mapped I/O */
	if (!(base_addr & 0x0001))
	{
		pci_dev_put(pci_dev);
		printk(KERN_ERR
		       "ipmi_si: memory mapped I/O not supported for PCI"
		       " smic.\n");
		return -ENODEV;
	}

	base_addr &= 0xFFFE;
	if (!fe_rmc)
		/* Data register starts at base address + 1 in eRMC */
		++base_addr;

	if (!is_new_interface(-1, IPMI_IO_ADDR_SPACE, base_addr)) {
		pci_dev_put(pci_dev);
		return -ENODEV;
	}

	info = kmalloc(sizeof(*info), GFP_KERNEL);
	if (!info) {
		pci_dev_put(pci_dev);
		printk(KERN_ERR "ipmi_si: Could not allocate SI data (5)\n");
		return -ENOMEM;
	}
	memset(info, 0, sizeof(*info));

	info->io_setup = port_setup;
	ports[intf_num] = base_addr;
	info->io.info = &(ports[intf_num]);
	info->io.regspacing = regspacings[intf_num];
	if (!info->io.regspacing)
		info->io.regspacing = DEFAULT_REGSPACING;
	info->io.regsize = DEFAULT_REGSPACING;
	info->io.regshift = regshifts[intf_num];

	*new_info = info;

	irqs[intf_num] = pci_dev->irq;
	si_type[intf_num] = "smic";

	printk("ipmi_si: Found PCI SMIC at I/O address 0x%lx\n",
		(long unsigned int) base_addr);

	pci_dev_put(pci_dev);
	return 0;
}
#endif /* CONFIG_PCI */

static int try_init_plug_and_play(int intf_num, struct smi_info **new_info)
{
#ifdef CONFIG_PCI
	if (find_pci_smic(intf_num, new_info)==0)
		return 0;
#endif
	/* Include other methods here. */

	return -ENODEV;
}


static int try_get_dev_id(struct smi_info *smi_info)
{
	unsigned char      msg[2];
	unsigned char      *resp;
	unsigned long      resp_len;
	enum si_sm_result smi_result;
	int               rv = 0;

	resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL);
	if (!resp)
		return -ENOMEM;

	/* Do a Get Device ID command, since it comes back with some
	   useful info. */
	msg[0] = IPMI_NETFN_APP_REQUEST << 2;
	msg[1] = IPMI_GET_DEVICE_ID_CMD;
	smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);

	smi_result = smi_info->handlers->event(smi_info->si_sm, 0);
	for (;;)
	{
		if (smi_result == SI_SM_CALL_WITH_DELAY) {
			set_current_state(TASK_UNINTERRUPTIBLE);
			schedule_timeout(1);
			smi_result = smi_info->handlers->event(
				smi_info->si_sm, 100);
		}
		else if (smi_result == SI_SM_CALL_WITHOUT_DELAY)
		{
			smi_result = smi_info->handlers->event(
				smi_info->si_sm, 0);
		}
		else
			break;
	}
	if (smi_result == SI_SM_HOSED) {
		/* We couldn't get the state machine to run, so whatever's at
		   the port is probably not an IPMI SMI interface. */
		rv = -ENODEV;
		goto out;
	}

	/* Otherwise, we got some data. */
	resp_len = smi_info->handlers->get_result(smi_info->si_sm,
						  resp, IPMI_MAX_MSG_LENGTH);
	if (resp_len < 6) {
		/* That's odd, it should be longer. */
		rv = -EINVAL;
		goto out;
	}

	if ((resp[1] != IPMI_GET_DEVICE_ID_CMD) || (resp[2] != 0)) {
		/* That's odd, it shouldn't be able to fail. */
		rv = -EINVAL;
		goto out;
	}

	/* Record info from the get device id, in case we need it. */
	smi_info->ipmi_si_dev_rev = resp[4] & 0xf;
	smi_info->ipmi_si_fw_rev_major = resp[5] & 0x7f;
	smi_info->ipmi_si_fw_rev_minor = resp[6];
	smi_info->ipmi_version_major = resp[7] & 0xf;
	smi_info->ipmi_version_minor = resp[7] >> 4;

 out:
	kfree(resp);
	return rv;
}

static int type_file_read_proc(char *page, char **start, off_t off,
			       int count, int *eof, void *data)
{
	char            *out = (char *) page;
	struct smi_info *smi = data;

	switch (smi->si_type) {
	    case SI_KCS:
		return sprintf(out, "kcs\n");
	    case SI_SMIC:
		return sprintf(out, "smic\n");
	    case SI_BT:
		return sprintf(out, "bt\n");
	    default:
		return 0;
	}
}

static int stat_file_read_proc(char *page, char **start, off_t off,
			       int count, int *eof, void *data)
{
	char            *out = (char *) page;
	struct smi_info *smi = data;

	out += sprintf(out, "interrupts_enabled:    %d\n",
		       smi->irq && !smi->interrupt_disabled);
	out += sprintf(out, "short_timeouts:        %ld\n",
		       smi->short_timeouts);
	out += sprintf(out, "long_timeouts:         %ld\n",
		       smi->long_timeouts);
	out += sprintf(out, "timeout_restarts:      %ld\n",
		       smi->timeout_restarts);
	out += sprintf(out, "idles:                 %ld\n",
		       smi->idles);
	out += sprintf(out, "interrupts:            %ld\n",
		       smi->interrupts);
	out += sprintf(out, "attentions:            %ld\n",
		       smi->attentions);
	out += sprintf(out, "flag_fetches:          %ld\n",
		       smi->flag_fetches);
	out += sprintf(out, "hosed_count:           %ld\n",
		       smi->hosed_count);
	out += sprintf(out, "complete_transactions: %ld\n",
		       smi->complete_transactions);
	out += sprintf(out, "events:                %ld\n",
		       smi->events);
	out += sprintf(out, "watchdog_pretimeouts:  %ld\n",
		       smi->watchdog_pretimeouts);
	out += sprintf(out, "incoming_messages:     %ld\n",
		       smi->incoming_messages);

	return (out - ((char *) page));
}

/* Returns 0 if initialized, or negative on an error. */
static int init_one_smi(int intf_num, struct smi_info **smi)
{
	int		rv;
	struct smi_info *new_smi;


	rv = try_init_mem(intf_num, &new_smi);
	if (rv)
		rv = try_init_port(intf_num, &new_smi);
#ifdef CONFIG_ACPI_INTERPRETER
	if ((rv) && (si_trydefaults)) {
		rv = try_init_acpi(intf_num, &new_smi);
	}
#endif
#ifdef CONFIG_X86
	if ((rv) && (si_trydefaults)) {
		rv = try_init_smbios(intf_num, &new_smi);
        }
#endif
	if ((rv) && (si_trydefaults)) {
		rv = try_init_plug_and_play(intf_num, &new_smi);
	}


	if (rv)
		return rv;

	/* So we know not to free it unless we have allocated one. */
	new_smi->intf = NULL;
	new_smi->si_sm = NULL;
	new_smi->handlers = NULL;

	if (!new_smi->irq_setup) {
		new_smi->irq = irqs[intf_num];
		new_smi->irq_setup = std_irq_setup;
		new_smi->irq_cleanup = std_irq_cleanup;
	}

	/* Default to KCS if no type is specified. */
	if (si_type[intf_num] == NULL) {
		if (si_trydefaults)
			si_type[intf_num] = "kcs";
		else {
			rv = -EINVAL;
			goto out_err;
		}
	}

	/* Set up the state machine to use. */
	if (strcmp(si_type[intf_num], "kcs") == 0) {
		new_smi->handlers = &kcs_smi_handlers;
		new_smi->si_type = SI_KCS;
	} else if (strcmp(si_type[intf_num], "smic") == 0) {
		new_smi->handlers = &smic_smi_handlers;
		new_smi->si_type = SI_SMIC;
	} else if (strcmp(si_type[intf_num], "bt") == 0) {
		new_smi->handlers = &bt_smi_handlers;
		new_smi->si_type = SI_BT;
	} else {
		/* No support for anything else yet. */
		rv = -EIO;
		goto out_err;
	}

	/* Allocate the state machine's data and initialize it. */
	new_smi->si_sm = kmalloc(new_smi->handlers->size(), GFP_KERNEL);
	if (!new_smi->si_sm) {
		printk(" Could not allocate state machine memory\n");
		rv = -ENOMEM;
		goto out_err;
	}
	new_smi->io_size = new_smi->handlers->init_data(new_smi->si_sm,
							&new_smi->io);

	/* Now that we know the I/O size, we can set up the I/O. */
	rv = new_smi->io_setup(new_smi);
	if (rv) {
		printk(" Could not set up I/O space\n");
		goto out_err;
	}

	spin_lock_init(&(new_smi->si_lock));
	spin_lock_init(&(new_smi->msg_lock));
	spin_lock_init(&(new_smi->count_lock));

	/* Do low-level detection first. */
	if (new_smi->handlers->detect(new_smi->si_sm)) {
		rv = -ENODEV;
		goto out_err;
	}

	/* Attempt a get device id command.  If it fails, we probably
           don't have a SMI here. */
	rv = try_get_dev_id(new_smi);
	if (rv)
		goto out_err;

	/* Try to claim any interrupts. */
	new_smi->irq_setup(new_smi);

	INIT_LIST_HEAD(&(new_smi->xmit_msgs));
	INIT_LIST_HEAD(&(new_smi->hp_xmit_msgs));
	new_smi->curr_msg = NULL;
	atomic_set(&new_smi->req_events, 0);
	new_smi->run_to_completion = 0;

	new_smi->interrupt_disabled = 0;
	new_smi->timer_stopped = 0;
	new_smi->stop_operation = 0;

	/* Start clearing the flags before we enable interrupts or the
	   timer to avoid racing with the timer. */
	start_clear_flags(new_smi);
	/* IRQ is defined to be set when non-zero. */
	if (new_smi->irq)
		new_smi->si_state = SI_CLEARING_FLAGS_THEN_SET_IRQ;

	/* The ipmi_register_smi() code does some operations to
	   determine the channel information, so we must be ready to
	   handle operations before it is called.  This means we have
	   to stop the timer if we get an error after this point. */
	init_timer(&(new_smi->si_timer));
	new_smi->si_timer.data = (long) new_smi;
	new_smi->si_timer.function = smi_timeout;
	new_smi->last_timeout_jiffies = jiffies;
	new_smi->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
	add_timer(&(new_smi->si_timer));

	rv = ipmi_register_smi(&handlers,
			       new_smi,
			       new_smi->ipmi_version_major,
			       new_smi->ipmi_version_minor,
			       new_smi->slave_addr,
			       &(new_smi->intf));
	if (rv) {
		printk(KERN_ERR
		       "ipmi_si: Unable to register device: error %d\n",
		       rv);
		goto out_err_stop_timer;
	}

	rv = ipmi_smi_add_proc_entry(new_smi->intf, "type",
				     type_file_read_proc, NULL,
				     new_smi, THIS_MODULE);
	if (rv) {
		printk(KERN_ERR
		       "ipmi_si: Unable to create proc entry: %d\n",
		       rv);
		goto out_err_stop_timer;
	}

	rv = ipmi_smi_add_proc_entry(new_smi->intf, "si_stats",
				     stat_file_read_proc, NULL,
				     new_smi, THIS_MODULE);
	if (rv) {
		printk(KERN_ERR
		       "ipmi_si: Unable to create proc entry: %d\n",
		       rv);
		goto out_err_stop_timer;
	}

	*smi = new_smi;

	printk(" IPMI %s interface initialized\n", si_type[intf_num]);

	return 0;

 out_err_stop_timer:
	new_smi->stop_operation = 1;

	/* Wait for the timer to stop.  This avoids problems with race
	   conditions removing the timer here. */
	while (!new_smi->timer_stopped) {
		set_current_state(TASK_UNINTERRUPTIBLE);
		schedule_timeout(1);
	}

 out_err:
	if (new_smi->intf)
		ipmi_unregister_smi(new_smi->intf);

	new_smi->irq_cleanup(new_smi);

	/* Wait until we know that we are out of any interrupt
	   handlers might have been running before we freed the
	   interrupt. */
	synchronize_sched();

	if (new_smi->si_sm) {
		if (new_smi->handlers)
			new_smi->handlers->cleanup(new_smi->si_sm);
		kfree(new_smi->si_sm);
	}
	new_smi->io_cleanup(new_smi);

	return rv;
}

static __init int init_ipmi_si(void)
{
	int  rv = 0;
	int  pos = 0;
	int  i;
	char *str;

	if (initialized)
		return 0;
	initialized = 1;

	/* Parse out the si_type string into its components. */
	str = si_type_str;
	if (*str != '\0') {
		for (i=0; (i<SI_MAX_PARMS) && (*str != '\0'); i++) {
			si_type[i] = str;
			str = strchr(str, ',');
			if (str) {
				*str = '\0';
				str++;
			} else {
				break;
			}
		}
	}

	printk(KERN_INFO "IPMI System Interface driver version "
	       IPMI_SI_VERSION);
	if (kcs_smi_handlers.version)
		printk(", KCS version %s", kcs_smi_handlers.version);
	if (smic_smi_handlers.version)
		printk(", SMIC version %s", smic_smi_handlers.version);
	if (bt_smi_handlers.version)
   	        printk(", BT version %s", bt_smi_handlers.version);
	printk("\n");

#ifdef CONFIG_X86
	dmi_decode();
#endif

	rv = init_one_smi(0, &(smi_infos[pos]));
	if (rv && !ports[0] && si_trydefaults) {
		/* If we are trying defaults and the initial port is
                   not set, then set it. */
		si_type[0] = "kcs";
		ports[0] = DEFAULT_KCS_IO_PORT;
		rv = init_one_smi(0, &(smi_infos[pos]));
		if (rv) {
			/* No KCS - try SMIC */
			si_type[0] = "smic";
			ports[0] = DEFAULT_SMIC_IO_PORT;
			rv = init_one_smi(0, &(smi_infos[pos]));
		}
		if (rv) {
			/* No SMIC - try BT */
			si_type[0] = "bt";
			ports[0] = DEFAULT_BT_IO_PORT;
			rv = init_one_smi(0, &(smi_infos[pos]));
		}
	}
	if (rv == 0)
		pos++;

	for (i=1; i < SI_MAX_PARMS; i++) {
		rv = init_one_smi(i, &(smi_infos[pos]));
		if (rv == 0)
			pos++;
	}

	if (smi_infos[0] == NULL) {
		printk("ipmi_si: Unable to find any System Interface(s)\n");
		return -ENODEV;
	}

	return 0;
}
module_init(init_ipmi_si);

static void __exit cleanup_one_si(struct smi_info *to_clean)
{
	int           rv;
	unsigned long flags;

	if (! to_clean)
		return;

	/* Tell the timer and interrupt handlers that we are shutting
	   down. */
	spin_lock_irqsave(&(to_clean->si_lock), flags);
	spin_lock(&(to_clean->msg_lock));

	to_clean->stop_operation = 1;

	to_clean->irq_cleanup(to_clean);

	spin_unlock(&(to_clean->msg_lock));
	spin_unlock_irqrestore(&(to_clean->si_lock), flags);

	/* Wait until we know that we are out of any interrupt
	   handlers might have been running before we freed the
	   interrupt. */
	synchronize_sched();

	/* Wait for the timer to stop.  This avoids problems with race
	   conditions removing the timer here. */
	while (!to_clean->timer_stopped) {
		set_current_state(TASK_UNINTERRUPTIBLE);
		schedule_timeout(1);
	}

	/* Interrupts and timeouts are stopped, now make sure the
	   interface is in a clean state. */
	while ((to_clean->curr_msg) || (to_clean->si_state != SI_NORMAL)) {
		poll(to_clean);
		set_current_state(TASK_UNINTERRUPTIBLE);
		schedule_timeout(1);
	}

	rv = ipmi_unregister_smi(to_clean->intf);
	if (rv) {
		printk(KERN_ERR
		       "ipmi_si: Unable to unregister device: errno=%d\n",
		       rv);
	}

	to_clean->handlers->cleanup(to_clean->si_sm);

	kfree(to_clean->si_sm);

	to_clean->io_cleanup(to_clean);
}

static __exit void cleanup_ipmi_si(void)
{
	int i;

	if (!initialized)
		return;

	for (i=0; i<SI_MAX_DRIVERS; i++) {
		cleanup_one_si(smi_infos[i]);
	}
}
module_exit(cleanup_ipmi_si);

MODULE_LICENSE("GPL");
