summaryrefslogtreecommitdiff
path: root/kern/linux-ipmi-emu-2.4.20-v17.diff
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2014-07-06 18:04:32 +0200
committerJörg Frings-Fürst <debian@jff-webhosting.net>2014-07-06 18:04:32 +0200
commita7f89980e5b3f4b9a74c70dbc5ffe8aabd28be28 (patch)
tree41c4deec1fdfbafd7821b4ca7a9772ac0abd92f5 /kern/linux-ipmi-emu-2.4.20-v17.diff
Imported Upstream version 2.9.3upstream/2.9.3
Diffstat (limited to 'kern/linux-ipmi-emu-2.4.20-v17.diff')
-rw-r--r--kern/linux-ipmi-emu-2.4.20-v17.diff2776
1 files changed, 2776 insertions, 0 deletions
diff --git a/kern/linux-ipmi-emu-2.4.20-v17.diff b/kern/linux-ipmi-emu-2.4.20-v17.diff
new file mode 100644
index 0000000..2d0fa40
--- /dev/null
+++ b/kern/linux-ipmi-emu-2.4.20-v17.diff
@@ -0,0 +1,2776 @@
+diff -urN linux/Documentation/Configure.help linux-emu/Documentation/Configure.help
+--- linux/Documentation/Configure.help Fri Dec 6 09:12:27 2002
++++ linux-emu/Documentation/Configure.help Fri Jan 10 11:24:14 2003
+@@ -26267,6 +26267,17 @@
+ CONFIG_IPMI_WATCHDOG
+ This enables the IPMI watchdog timer.
+
++Emulate Radisys IPMI driver
++CONFIG_IPMI_EMULATE_RADISYS
++ This enables emulation of the Radisys IPMI device driver.
++
++Emulate Intel IBM driver
++CONFIG_IPMI_EMULATE_IMB
++ This enables emulation of the Intel IMB device driver. Note that you
++ MUST have the IPMI watchdog timer enabled to use this. This code
++ uses some of the watchdog code, but the dependency is not enforced
++ by config.
++
+ #
+ # A couple of things I keep forgetting:
+ # capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet,
+--- linux/drivers/char/Config.in Fri Dec 6 09:12:38 2002
++++ linux-emu/drivers/char/Config.in Fri Jan 10 11:24:14 2003
+@@ -195,6 +195,8 @@
+ dep_tristate ' Device interface for IPMI' CONFIG_IPMI_DEVICE_INTERFACE $CONFIG_IPMI_HANDLER
+ dep_tristate ' IPMI KCS handler' CONFIG_IPMI_KCS $CONFIG_IPMI_HANDLER
+ dep_tristate ' IPMI Watchdog Timer' CONFIG_IPMI_WATCHDOG $CONFIG_IPMI_HANDLER
++dep_tristate ' Emulate Radisys IPMI driver' CONFIG_IPMI_EMULATE_RADISYS $CONFIG_IPMI_HANDLER
++dep_tristate ' Emulate Intel IMB driver' CONFIG_IPMI_EMULATE_IMB $CONFIG_IPMI_WATCHDOG
+
+ mainmenu_option next_comment
+ comment 'Watchdog Cards'
+diff -urN linux/drivers/char/ipmi/Makefile linux-emu/drivers/char/ipmi/Makefile
+--- linux/drivers/char/ipmi/Makefile Thu Aug 22 16:58:48 2002
++++ linux-emu/drivers/char/ipmi/Makefile Fri Jan 10 11:24:14 2003
+@@ -13,6 +13,8 @@
+ obj-$(CONFIG_IPMI_DEVICE_INTERFACE) += ipmi_devintf.o
+ obj-$(CONFIG_IPMI_KCS) += ipmi_kcs_drv.o
+ obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o
++obj-$(CONFIG_IPMI_EMULATE_RADISYS) += ipmi_radisys.o
++obj-$(CONFIG_IPMI_EMULATE_IMB) += ipmi_imb.o
+
+ include $(TOPDIR)/Rules.make
+
+diff -urN linux/drivers/char/ipmi/ipmi_imb.c linux-emu/drivers/char/ipmi/ipmi_imb.c
+--- linux/drivers/char/ipmi/ipmi_imb.c Wed Dec 31 18:00:00 1969
++++ linux-emu/drivers/char/ipmi/ipmi_imb.c Fri Jan 10 11:24:37 2003
+@@ -0,0 +1,744 @@
++/*
++ * ipmi_imb.c
++ *
++ * Intel IMB emulation for the IPMI interface.
++ *
++ * 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.
++ */
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <asm/system.h>
++#include <linux/sched.h>
++#include <linux/poll.h>
++#include <linux/spinlock.h>
++#include <linux/slab.h>
++#include <linux/devfs_fs_kernel.h>
++#include <linux/ipmi.h>
++#include <linux/ipmi_imb.h>
++
++
++
++#define MAX_BUFFER_SIZE 64
++#define BMC_SA 0x20
++
++struct priv_data
++{
++ /* This is for supporting the old Imb interface. */
++ ipmi_user_t imb_user;
++ spinlock_t imb_lock;
++
++ unsigned long curr_msgid;
++
++ /* A list of responses in the queue. */
++ struct list_head imb_waiting_rsps;
++
++ /* A list of things waiting for responses. We wake them all up
++ when a response comes in. */
++ wait_queue_head_t imb_waiting_rsp_rcvrs;
++
++ /* A list of commands that have come in. */
++ struct list_head imb_waiting_cmds;
++
++ /* A list of thing waiting for commands. We wake them all up
++ when a command comes in. */
++ wait_queue_head_t imb_waiting_cmd_rcvrs;
++
++ /* The registered command receiver value. This only allows someone
++ with the "magic number" to issue commands. */
++ unsigned long imb_cmd_receiver;
++
++ /* Is someone already waiting for a command? The Imb driver
++ only allows one waiter, this enforces that. */
++ int imb_cmd_waiting;
++
++ /* A list of IPMI events waiting to be delivered. (not that
++ the Imb driver calls incoming commands "events", this
++ variable is actual IPMI events, not incoming commands). */
++ struct list_head imb_waiting_events;
++
++#define IMB_EVENT_QUEUE_LIMIT 16 /* Allow up to 16 events. */
++ /* The number of events in the event queue. */
++ unsigned int imb_waiting_event_count;
++};
++
++static devfs_handle_t devfs_handle;
++
++
++/* We cheat and use a piece of the address as the timeout. */
++static long *imb_timeout(struct ipmi_recv_msg *msg)
++{
++ char *base = (char *) &(msg->addr);
++ base += sizeof(struct ipmi_ipmb_addr);
++ return (long *) base;
++}
++
++static void imb_msg_recv(struct ipmi_recv_msg *msg,
++ void *data)
++{
++ struct priv_data *priv = data;
++ unsigned long flags;
++
++ spin_lock_irqsave(&(priv->imb_lock), flags);
++ if (msg->recv_type == IPMI_RESPONSE_RECV_TYPE) {
++ *imb_timeout(msg) = 5000;
++ list_add_tail(&(msg->link), &(priv->imb_waiting_rsps));
++ wake_up_all(&(priv->imb_waiting_rsp_rcvrs));
++ } else if (msg->recv_type == IPMI_CMD_RECV_TYPE) {
++ *imb_timeout(msg) = 5000;
++ list_add_tail(&(msg->link), &(priv->imb_waiting_cmds));
++ wake_up_all(&(priv->imb_waiting_cmd_rcvrs));
++ } else if (msg->recv_type == IPMI_ASYNC_EVENT_RECV_TYPE) {
++ if (priv->imb_waiting_event_count > IMB_EVENT_QUEUE_LIMIT) {
++ ipmi_free_recv_msg(msg);
++ } else {
++ list_add_tail(&(msg->link),&(priv->imb_waiting_events));
++ (priv->imb_waiting_event_count)++;
++ }
++ } else {
++ ipmi_free_recv_msg(msg);
++ }
++ spin_unlock_irqrestore(&(priv->imb_lock), flags);
++}
++
++/* We emulate the event queue in the driver for the imb emulation. */
++static int imb_handle_event_request(struct priv_data *priv,
++ struct ipmi_recv_msg **rsp)
++{
++ struct list_head *entry;
++ unsigned long flags;
++ struct ipmi_recv_msg *msg = NULL;
++ int rv = 0;
++
++ spin_lock_irqsave(&(priv->imb_lock), flags);
++ if (list_empty(&(priv->imb_waiting_events))) {
++ /* Nothing in the event queue, just return an error. */
++ msg = ipmi_alloc_recv_msg();
++ if (msg == NULL) {
++ rv = -EAGAIN;
++ goto out_err;
++ }
++ msg->addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
++ msg->addr.channel = IPMI_BMC_CHANNEL;
++ msg->msg.cmd = IPMI_READ_EVENT_MSG_BUFFER_CMD;
++ msg->msgid = 0;
++ msg->recv_type = IPMI_ASYNC_EVENT_RECV_TYPE;
++ msg->msg.netfn = IPMI_NETFN_APP_RESPONSE;
++ msg->msg.data = msg->msg_data;
++ msg->msg.data[0] = 0x80; /* Data not available. */
++ msg->msg.data_len = 1;
++ } else {
++ /* Pull an item from the event queue . */
++ entry = priv->imb_waiting_events.next;
++ list_del(entry);
++ msg = list_entry(entry, struct ipmi_recv_msg, link);
++ (priv->imb_waiting_event_count)--;
++ }
++
++ *rsp = msg;
++
++ out_err:
++ spin_unlock_irqrestore(&(priv->imb_lock), flags);
++ return rv;
++}
++
++static struct priv_data *ipmi_user;
++static unsigned int user_count = 0; /* How many users have this open. */
++static spinlock_t dev_lock = SPIN_LOCK_UNLOCKED;
++
++static int ipmi_imb_open(struct inode *inode, struct file *file)
++{
++ int rv;
++
++ if (user_count == 0) {
++ rv = ipmi_register_all_cmd_rcvr(ipmi_user->imb_user);
++ if (rv) {
++ return rv;
++ }
++ }
++
++ file->private_data = ipmi_user;
++ spin_lock(&dev_lock);
++ if (user_count == 0)
++ ipmi_set_gets_events(ipmi_user->imb_user, 1);
++ user_count++;
++ spin_unlock(&dev_lock);
++
++ return 0;
++}
++
++static int ipmi_imb_release(struct inode *inode, struct file *file)
++{
++ spin_lock(&dev_lock);
++ user_count--;
++ if (user_count == 0) {
++ ipmi_set_gets_events(ipmi_user->imb_user, 0);
++ ipmi_unregister_all_cmd_rcvr(ipmi_user->imb_user);
++ }
++ spin_unlock(&dev_lock);
++ return 0;
++}
++
++static unsigned char
++ipmb_checksum(unsigned char *data, int size)
++{
++ unsigned char csum = 0;
++
++ for (; size > 0; size--, data++)
++ csum += *data;
++
++ return -csum;
++}
++
++extern void ipmi_delayed_shutdown(long delay, int power_off);
++
++static int ipmi_imb_ioctl(struct inode *inode,
++ struct file *file,
++ unsigned int cmd,
++ unsigned long data)
++{
++ struct priv_data *priv = file->private_data;
++ int rv = -EINVAL;
++ struct smi smi;
++ unsigned long flags;
++
++ if (copy_from_user((caddr_t)&smi, (caddr_t)data, sizeof(smi))) {
++ return -EFAULT;
++ }
++
++ switch(cmd) {
++ case IOCTL_IMB_POLL_ASYNC:
++ /*
++ * No-op for this, the low-level driver polls.
++ */
++ break;
++
++ case IOCTL_IMB_GET_ASYNC_MSG:
++ {
++ unsigned char resp[MAX_ASYNC_RESP_SIZE];
++ struct ipmi_recv_msg *msg = NULL;
++ ImbAsyncResponse *pAsyncResp = (ImbAsyncResponse *) resp;
++ unsigned long length = 0;
++
++ if (smi.cbInBuffer < sizeof(ImbAsyncRequest))
++ return -EINVAL;
++ if (smi.cbOutBuffer < MIN_ASYNC_RESP_SIZE)
++ return -EINVAL;
++
++ spin_lock_irqsave(&(priv->imb_lock), flags);
++
++ if (list_empty(&(priv->imb_waiting_cmds))) {
++ /* No command waiting, just return an error. */
++ rv = IMB_NO_ASYNC_MSG;
++ } else {
++ struct list_head *entry;
++
++ /* Got a command, pull it out and handle it. */
++ entry = priv->imb_waiting_cmds.next;
++ list_del(entry);
++ msg = list_entry(entry, struct ipmi_recv_msg, link);
++ rv = STATUS_SUCCESS;
++ }
++ spin_unlock_irqrestore(&(priv->imb_lock), flags);
++
++ if (msg != NULL) {
++ struct ipmi_ipmb_addr *ipmb_addr;
++
++ ipmb_addr = (struct ipmi_ipmb_addr *) &(msg->addr);
++ pAsyncResp->thisSeq = msg->msgid;
++ pAsyncResp->data[0] = IPMI_NETFN_APP_REQUEST << 2;
++ pAsyncResp->data[1] = IPMI_SEND_MSG_CMD;
++ pAsyncResp->data[2] = 0;
++ pAsyncResp->data[3] = msg->addr.channel;
++ pAsyncResp->data[4] = ((msg->msg.netfn << 2)
++ | 2);
++ pAsyncResp->data[5]
++ = ipmb_checksum(&(pAsyncResp->data[3]),
++ 2);
++ pAsyncResp->data[6] = ipmb_addr->slave_addr;
++ pAsyncResp->data[7] = ((msg->msgid << 2)
++ | ipmb_addr->lun);
++ pAsyncResp->data[8] = msg->msg.cmd;
++
++ memcpy(&(pAsyncResp->data[9]),
++ &(msg->msg.data[0]),
++ msg->msg.data_len);
++
++ length = msg->msg.data_len + MIN_ASYNC_RESP_SIZE;
++
++ ipmi_free_recv_msg(msg);
++
++ if (copy_to_user(smi.lpvOutBuffer, pAsyncResp, length))
++ {
++ return -EFAULT;
++ }
++ }
++
++ if (copy_to_user(smi.lpcbBytesReturned,
++ &length,
++ sizeof(length)))
++ {
++ return -EFAULT;
++ }
++ rv = 0;
++ break;
++ }
++
++ case IOCTL_IMB_SEND_MESSAGE:
++ {
++ unsigned char imbReqBuffer[MAX_IMB_RESPONSE_SIZE + 8];
++ unsigned char imbRespBuffer[MAX_IMB_RESPONSE_SIZE + 8];
++ ImbRequestBuffer *pImbReq=(ImbRequestBuffer *)imbReqBuffer;
++ ImbResponseBuffer *pImbResp=(ImbResponseBuffer*)imbRespBuffer;
++ struct ipmi_addr addr;
++ struct ipmi_msg msg;
++ unsigned long msgid;
++ struct ipmi_recv_msg *rsp;
++ unsigned long length;
++ wait_queue_t wait;
++ struct list_head *entry;
++
++
++ if ((smi.cbInBuffer < MIN_IMB_REQ_BUF_SIZE)
++ || (smi.cbOutBuffer < MIN_IMB_RESP_BUF_SIZE))
++ {
++ return -EINVAL;
++ }
++
++ if (smi.cbInBuffer > (MAX_IMB_RESPONSE_SIZE + 8)) {
++ /* Input buffer is too large */
++ return -EINVAL;
++ }
++
++ if (copy_from_user(pImbReq, smi.lpvInBuffer, smi.cbInBuffer)) {
++ return -EFAULT;
++ }
++ if ((pImbReq->req.dataLength + MIN_IMB_REQ_BUF_SIZE)
++ > smi.cbInBuffer)
++ {
++ return -EINVAL;
++ }
++ if (pImbReq->req.dataLength > MAX_BUFFER_SIZE) {
++ return -EINVAL;
++ }
++
++ if (pImbReq->req.rsSa == BMC_SA) {
++ struct ipmi_system_interface_addr *smi_addr
++ = (struct ipmi_system_interface_addr *) &addr;
++
++ if ((pImbReq->req.netFn
++ == (IPMI_NETFN_APP_REQUEST << 2))
++ && (pImbReq->req.cmd
++ == IPMI_READ_EVENT_MSG_BUFFER_CMD))
++ {
++ /* The driver gets event messages
++ automatically, so we emulate
++ this. */
++ rv = imb_handle_event_request(priv, &rsp);
++ goto copy_resp;
++ } else {
++ smi_addr->addr_type
++ = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
++ smi_addr->channel = IPMI_BMC_CHANNEL;
++ smi_addr->lun = 0;
++ }
++ } else {
++ struct ipmi_ipmb_addr *ipmb_addr =
++ (struct ipmi_ipmb_addr *) &addr;
++
++ ipmb_addr->addr_type = IPMI_IPMB_ADDR_TYPE;
++ ipmb_addr->slave_addr = pImbReq->req.rsSa;
++ ipmb_addr->lun = pImbReq->req.rsLun;
++ ipmb_addr->channel = 0;
++ }
++
++ if (pImbReq->flags & NO_RESPONSE_EXPECTED) {
++ spin_lock(&priv->imb_lock);
++ msgid = priv->curr_msgid;
++ (priv->curr_msgid)++;
++ spin_unlock(&priv->imb_lock);
++ } else {
++ msgid = 0;
++ }
++
++ msg.netfn = pImbReq->req.netFn;
++ msg.cmd = pImbReq->req.cmd;
++ msg.data = pImbReq->req.data;
++ msg.data_len = pImbReq->req.dataLength;
++ rv = ipmi_request(priv->imb_user,
++ &addr,
++ msgid,
++ &msg,
++ 0);
++ if (rv) {
++ rv = IMB_SEND_REQUEST_FAILED;
++ goto copy_resp;
++ }
++
++ if (pImbReq->flags & NO_RESPONSE_EXPECTED)
++ goto no_response;
++
++ /* Now wait for the response to come back. */
++ spin_lock_irqsave(&(priv->imb_lock), flags);
++ init_waitqueue_entry(&wait, current);
++ add_wait_queue(&(priv->imb_waiting_rsp_rcvrs),
++ &wait);
++ for (;;) {
++ /* Check to see if it's there. */
++ if (!list_empty(&(priv->imb_waiting_rsps))) {
++ entry = priv->imb_waiting_rsps.next;
++ list_del(entry);
++ rsp = list_entry(entry,
++ struct ipmi_recv_msg,
++ link);
++ if (rsp->msgid != msgid) {
++ ipmi_free_recv_msg(rsp);
++ rsp = NULL;
++ } else {
++ break;
++ }
++ }
++
++ set_current_state(TASK_INTERRUPTIBLE);
++ if (!signal_pending(current)) {
++ spin_unlock_irqrestore
++ (&(priv->imb_lock), flags);
++ schedule();
++ spin_lock_irqsave
++ (&(priv->imb_lock), flags);
++ } else {
++ rv = -ERESTARTSYS;
++ break;
++ }
++ }
++ remove_wait_queue(&(priv->imb_waiting_rsp_rcvrs),
++ &wait);
++ spin_unlock_irqrestore(&(priv->imb_lock), flags);
++
++ copy_resp:
++ if (rsp != NULL) {
++ pImbResp->cCode = rsp->msg.data[0];
++ memcpy(pImbResp->data,
++ rsp->msg.data+1,
++ rsp->msg.data_len-1);
++ length = (rsp->msg.data_len - 1
++ + MIN_IMB_RESP_BUF_SIZE);
++
++ if (copy_to_user(smi.lpvOutBuffer, pImbResp, length)) {
++ return -EFAULT;
++ }
++
++ if (copy_to_user(smi.lpcbBytesReturned,
++ &length,
++ sizeof(length)))
++ {
++ return -EFAULT;
++ }
++ }
++ no_response:
++ break;
++ }
++
++ case IOCTL_IMB_SHUTDOWN_CODE:
++ {
++ ShutdownCmdBuffer shutdownCmd;
++
++ if (copy_from_user(&shutdownCmd,
++ smi.lpvInBuffer,
++ sizeof(ShutdownCmdBuffer)))
++ {
++ return -EFAULT;
++ }
++
++ if (smi.cbInBuffer < sizeof(ShutdownCmdBuffer))
++ {
++ return -EINVAL;
++ }
++
++ rv = 0;
++ switch (shutdownCmd.code) {
++ case SD_POWER_OFF:
++ ipmi_delayed_shutdown(shutdownCmd.delayTime / 10, 1);
++ break;
++
++ case SD_RESET:
++ ipmi_delayed_shutdown(shutdownCmd.delayTime / 10, 0);
++ break;
++
++ case SD_NO_ACTION:
++ break;
++
++ default:
++ rv = INVALID_ARGUMENTS;
++ }
++
++ }
++
++ case IOCTL_IMB_REGISTER_ASYNC_OBJ:
++ rv = STATUS_SUCCESS;
++ break;
++
++
++ case IOCTL_IMB_CHECK_EVENT:
++ {
++ wait_queue_t wait;
++
++ spin_lock_irqsave(&(priv->imb_lock), flags);
++ init_waitqueue_entry(&wait, current);
++ add_wait_queue(&(priv->imb_waiting_cmd_rcvrs),
++ &wait);
++ while (!list_empty(&(priv->imb_waiting_cmds))) {
++ set_current_state(TASK_INTERRUPTIBLE);
++ if (!signal_pending(current)) {
++ spin_unlock_irqrestore
++ (&(priv->imb_lock), flags);
++ schedule();
++ spin_lock_irqsave
++ (&(priv->imb_lock), flags);
++ } else {
++ rv = -ERESTARTSYS;
++ break;
++ }
++ }
++ remove_wait_queue(&(priv->imb_waiting_cmd_rcvrs),
++ &wait);
++ spin_unlock_irqrestore(&(priv->imb_lock), flags);
++ rv = 0;
++ break;
++ }
++ }
++
++ return rv;
++}
++
++static int ipmi_imb_mmap(struct file *file, struct vm_area_struct *vma)
++{
++ off_t offset = vma->vm_pgoff << PAGE_SHIFT;
++
++ if (offset < 0)
++ return -EINVAL;
++
++ if (remap_page_range(vma->vm_start, offset,
++ vma->vm_end - vma->vm_start,
++ vma->vm_page_prot))
++ {
++ return -EAGAIN;
++ }
++
++ /*vma->vm_inode = what_goes_here; */
++
++ return 0;
++
++}
++
++
++static struct file_operations ipmi_fops = {
++ owner: THIS_MODULE,
++ ioctl: ipmi_imb_ioctl,
++ open: ipmi_imb_open,
++ release: ipmi_imb_release,
++ mmap: ipmi_imb_mmap
++};
++
++static struct timer_list ipmi_imb_timer;
++
++/* Call every 100 ms. */
++#define IPMI_TIMEOUT_TIME 100
++#define IPMI_TIMEOUT_JIFFIES (IPMI_TIMEOUT_TIME/(1000/HZ))
++
++static volatile int stop_operation = 0;
++static volatile int timer_stopped = 0;
++
++static void ipmi_imb_timeout(unsigned long data)
++{
++ struct list_head *entry, *entry2;
++ struct priv_data *priv = (struct priv_data *) data;
++ int timeout_period = IPMI_TIMEOUT_TIME;
++ struct ipmi_recv_msg *msg;
++
++ if (stop_operation) {
++ timer_stopped = 1;
++ return;
++ }
++
++ /* Now time out any messages in the Imb message queue. */
++ spin_lock(&(priv->imb_lock));
++ list_for_each_safe(entry, entry2, &(priv->imb_waiting_rsps)) {
++ long *timeout;
++ msg = list_entry(entry, struct ipmi_recv_msg, link);
++ timeout = imb_timeout(msg);
++ *timeout -= timeout_period;
++ if ((*timeout) <= 0) {
++ list_del(entry);
++ ipmi_free_recv_msg(msg);
++ }
++ }
++ list_for_each_safe(entry, entry2, &(priv->imb_waiting_cmds)) {
++ long *timeout;
++ msg = list_entry(entry, struct ipmi_recv_msg, link);
++ timeout = imb_timeout(msg);
++ *timeout -= timeout_period;
++ if ((*timeout) <= 0) {
++ list_del(entry);
++ ipmi_free_recv_msg(msg);
++ }
++ }
++ spin_unlock(&priv->imb_lock);
++
++ ipmi_imb_timer.expires += IPMI_TIMEOUT_JIFFIES;
++ add_timer(&ipmi_imb_timer);
++}
++
++#define DEVICE_NAME "imb"
++
++static int ipmi_imb_major = 0;
++MODULE_PARM(ipmi_imb_major, "i");
++
++static struct ipmi_user_hndl ipmi_hndlrs =
++{
++ ipmi_recv_hndl : imb_msg_recv
++};
++
++static int init_ipmi_imb(void)
++{
++ int rv;
++
++ if (ipmi_imb_major < 0)
++ return -EINVAL;
++
++ ipmi_user = kmalloc(sizeof(*ipmi_user), GFP_KERNEL);
++ if (!ipmi_user) {
++ return -ENOMEM;
++ }
++
++ /* Create the Imb interface user. */
++ spin_lock_init(&(ipmi_user->imb_lock));
++ INIT_LIST_HEAD(&(ipmi_user->imb_waiting_rsps));
++ init_waitqueue_head(&(ipmi_user->imb_waiting_rsp_rcvrs));
++ INIT_LIST_HEAD(&(ipmi_user->imb_waiting_cmds));
++ init_waitqueue_head(&(ipmi_user->imb_waiting_cmd_rcvrs));
++ ipmi_user->imb_cmd_waiting = 0;
++ INIT_LIST_HEAD(&(ipmi_user->imb_waiting_events));
++
++ rv = ipmi_create_user(0,
++ &ipmi_hndlrs,
++ ipmi_user,
++ &(ipmi_user->imb_user));
++ if (rv) {
++ kfree(ipmi_user);
++ ipmi_user = NULL;
++ return rv;
++ }
++
++ rv = register_chrdev(ipmi_imb_major, DEVICE_NAME, &ipmi_fops);
++ if (rv < 0)
++ {
++ kfree(ipmi_user);
++ ipmi_user = NULL;
++ printk(KERN_ERR "ipmi: can't get major %d\n",
++ ipmi_imb_major);
++ return rv;
++ }
++
++ if (ipmi_imb_major == 0)
++ {
++ ipmi_imb_major = rv;
++ }
++
++ devfs_handle = devfs_register(NULL, DEVICE_NAME, DEVFS_FL_NONE,
++ ipmi_imb_major, 0,
++ S_IFCHR | S_IRUSR | S_IWUSR,
++ &ipmi_fops, NULL);
++
++ ipmi_imb_timer.data = (long) ipmi_user;
++ ipmi_imb_timer.function = ipmi_imb_timeout;
++ ipmi_imb_timer.expires = jiffies + IPMI_TIMEOUT_JIFFIES;
++ add_timer(&ipmi_imb_timer);
++
++ printk(KERN_INFO "ipmi_imb: driver initialized at char major %d\n",
++ ipmi_imb_major);
++
++ return 0;
++}
++
++#ifdef MODULE
++static void free_recv_msg_list(struct list_head *q)
++{
++ struct list_head *entry, *entry2;
++ struct ipmi_recv_msg *msg;
++
++ list_for_each_safe(entry, entry2, q) {
++ msg = list_entry(entry, struct ipmi_recv_msg, link);
++ list_del(entry);
++ ipmi_free_recv_msg(msg);
++ }
++}
++
++static void cleanup_ipmi_imb(void)
++{
++ devfs_unregister(devfs_handle);
++
++ /* Tell the timer to stop, then wait for it to stop. This avoids
++ problems with race conditions removing the timer here. */
++ stop_operation = 1;
++ while (!timer_stopped) {
++ schedule_timeout(1);
++ }
++
++ ipmi_destroy_user(ipmi_user->imb_user);
++
++ free_recv_msg_list(&(ipmi_user->imb_waiting_rsps));
++ free_recv_msg_list(&(ipmi_user->imb_waiting_cmds));
++ free_recv_msg_list(&(ipmi_user->imb_waiting_events));
++
++ kfree(ipmi_user);
++ ipmi_user = NULL;
++
++ unregister_chrdev(ipmi_imb_major, DEVICE_NAME);
++}
++module_exit(cleanup_ipmi_imb);
++#else
++static int __init ipmi_imb_setup (char *str)
++{
++ int x;
++
++ if (get_option (&str, &x)) {
++ /* ipmi=x sets the major number to x. */
++ ipmi_imb_major = x;
++ } else if (!strcmp(str, "off")) {
++ ipmi_imb_major = -1;
++ }
++
++ return 1;
++}
++__setup("ipmi_imb=", ipmi_imb_setup);
++#endif
++
++module_init(init_ipmi_imb);
++MODULE_LICENSE("GPL");
+diff -urN linux/drivers/char/ipmi/ipmi_radisys.c linux-emu/drivers/char/ipmi/ipmi_radisys.c
+--- linux/drivers/char/ipmi/ipmi_radisys.c Wed Dec 31 18:00:00 1969
++++ linux-emu/drivers/char/ipmi/ipmi_radisys.c Fri Jan 10 11:24:56 2003
+@@ -0,0 +1,834 @@
++/*
++ * ipmi_radisys.c
++ *
++ * Radisys emulation for the IPMI interface.
++ *
++ * 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.
++ */
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <asm/system.h>
++#include <linux/sched.h>
++#include <linux/poll.h>
++#include <linux/spinlock.h>
++#include <linux/slab.h>
++#include <linux/devfs_fs_kernel.h>
++#include <linux/ipmi.h>
++#include <linux/ipmi_radisys.h>
++
++
++struct priv_data
++{
++ /* This is for supporting the old Radisys interface. */
++ ipmi_user_t rs_user;
++ spinlock_t rs_lock;
++
++ /* A list of responses in the queue. */
++ struct list_head rs_waiting_rsps;
++
++ /* A list of things waiting for responses. We wake them all up
++ when a response comes in. */
++ wait_queue_head_t rs_waiting_rsp_rcvrs;
++
++ /* A list of commands that have come in. */
++ struct list_head rs_waiting_cmds;
++
++ /* A list of thing waiting for commands. We wake them all up
++ when a command comes in. */
++ wait_queue_head_t rs_waiting_cmd_rcvrs;
++
++ /* The registered command receiver value. This only allows someone
++ with the "magic number" to issue commands. */
++ unsigned long rs_cmd_receiver;
++
++ /* Is someone already waiting for a command? The Radisys driver
++ only allows one waiter, this enforces that. */
++ int rs_cmd_waiting;
++
++ /* A list of IPMI events waiting to be delivered. (not that
++ the Radisys driver calls incoming commands "events", this
++ variable is actual IPMI events, not incoming commands). */
++ struct list_head rs_waiting_events;
++
++#define RS_EVENT_QUEUE_LIMIT 16 /* Allow up to 16 events. */
++ /* The number of events in the event queue. */
++ unsigned int rs_waiting_event_count;
++};
++
++
++static devfs_handle_t devfs_handle;
++
++/* We cheat and use a piece of the address as the timeout. */
++static long *rs_timeout(struct ipmi_recv_msg *msg)
++{
++ char *base = (char *) &(msg->addr);
++ base += sizeof(struct ipmi_ipmb_addr);
++ return (long *) base;
++}
++
++static void rs_msg_recv(struct ipmi_recv_msg *msg,
++ void *data)
++{
++ struct priv_data *priv = data;
++ unsigned long flags;
++
++ spin_lock_irqsave(&(priv->rs_lock), flags);
++ if (msg->recv_type == IPMI_RESPONSE_RECV_TYPE) {
++ *rs_timeout(msg) = 5000;
++ list_add_tail(&(msg->link), &(priv->rs_waiting_rsps));
++ wake_up_all(&(priv->rs_waiting_rsp_rcvrs));
++ } else if (msg->recv_type == IPMI_CMD_RECV_TYPE) {
++ *rs_timeout(msg) = 5000;
++ list_add_tail(&(msg->link), &(priv->rs_waiting_cmds));
++ wake_up_all(&(priv->rs_waiting_cmd_rcvrs));
++ } else if (msg->recv_type == IPMI_ASYNC_EVENT_RECV_TYPE) {
++ if (priv->rs_waiting_event_count > RS_EVENT_QUEUE_LIMIT) {
++ ipmi_free_recv_msg(msg);
++ } else {
++ list_add_tail(&(msg->link),&(priv->rs_waiting_events));
++ (priv->rs_waiting_event_count)++;
++ }
++ } else {
++ ipmi_free_recv_msg(msg);
++ }
++ spin_unlock_irqrestore(&(priv->rs_lock), flags);
++}
++
++/* We emulate the event queue in the driver for the Radisys emulation. */
++static int rs_handle_event_request(struct priv_data *priv)
++{
++ struct list_head *entry;
++ unsigned long flags;
++ struct ipmi_recv_msg *msg = NULL;
++ int rv = 0;
++
++ spin_lock_irqsave(&(priv->rs_lock), flags);
++ if (list_empty(&(priv->rs_waiting_events))) {
++ /* Nothing in the event queue, just return an error. */
++ msg = ipmi_alloc_recv_msg();
++ if (msg == NULL) {
++ rv = -EAGAIN;
++ goto out_err;
++ }
++ msg->addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
++ msg->addr.channel = IPMI_BMC_CHANNEL;
++ msg->msg.cmd = IPMI_READ_EVENT_MSG_BUFFER_CMD;
++ msg->msgid = 0;
++ msg->recv_type = IPMI_ASYNC_EVENT_RECV_TYPE;
++ msg->msg.netfn = IPMI_NETFN_APP_RESPONSE;
++ msg->msg.data = msg->msg_data;
++ msg->msg.data[0] = 0x80; /* Data not available. */
++ msg->msg.data_len = 1;
++ } else {
++ /* Pull an item from the event queue . */
++ entry = priv->rs_waiting_events.next;
++ list_del(entry);
++ msg = list_entry(entry, struct ipmi_recv_msg, link);
++ (priv->rs_waiting_event_count)--;
++ }
++
++ /* Put the response into the list of waiting responses and
++ wake all the response waiters up. */
++ *rs_timeout(msg) = 5000;
++ list_add_tail(&(msg->link), &(priv->rs_waiting_rsps));
++ wake_up_all(&(priv->rs_waiting_rsp_rcvrs));
++
++ out_err:
++ spin_unlock_irqrestore(&(priv->rs_lock), flags);
++ return rv;
++}
++
++static struct ipmi_recv_msg *rs_find_in_list(struct list_head *q,
++ unsigned char slave_addr,
++ unsigned char lun,
++ unsigned char netfn,
++ unsigned char cmd,
++ unsigned char seq)
++{
++ struct list_head *entry;
++ struct ipmi_recv_msg *msg;
++ struct ipmi_addr addr;
++ unsigned char msg_seq;
++
++ if (slave_addr == 1) {
++ struct ipmi_system_interface_addr *smi_addr;
++ smi_addr = (struct ipmi_system_interface_addr *) &addr;
++ smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
++ smi_addr->lun = lun;
++ /* Slave address 1 means no matching sequence in the
++ Radisys driver. */
++ } else {
++ struct ipmi_ipmb_addr *ipmb_addr;
++ ipmb_addr = (struct ipmi_ipmb_addr *) &addr;
++ ipmb_addr->addr_type = IPMI_IPMB_ADDR_TYPE;
++ ipmb_addr->slave_addr = slave_addr;
++ ipmb_addr->lun = lun;
++ }
++
++ list_for_each(entry, q) {
++ msg = list_entry(entry, struct ipmi_recv_msg, link);
++ if (msg->addr.channel == IPMI_BMC_CHANNEL)
++ msg_seq = 0;
++ else
++ msg_seq = msg->msgid;
++
++ /* We ignore the channel for these comparisons, since the
++ Radisys driver seems to ignore it. */
++ addr.channel = msg->addr.channel;
++
++ if ((msg_seq == seq)
++ && (msg->msg.cmd == cmd)
++ && (msg->msg.netfn == (netfn >> 2))
++ && ipmi_addr_equal(&addr, &(msg->addr)))
++ {
++ list_del(entry);
++ return msg;
++ }
++ }
++
++ return NULL;
++}
++
++static struct priv_data *ipmi_user;
++static unsigned int user_count = 0; /* How many users have this open. */
++static spinlock_t dev_lock = SPIN_LOCK_UNLOCKED;
++
++static int ipmi_open(struct inode *inode, struct file *file)
++{
++ file->private_data = ipmi_user;
++ spin_lock(&dev_lock);
++ if (user_count == 0)
++ ipmi_set_gets_events(ipmi_user->rs_user, 1);
++ user_count++;
++ spin_unlock(&dev_lock);
++
++ return 0;
++}
++
++static int ipmi_release(struct inode *inode, struct file *file)
++{
++ spin_lock(&dev_lock);
++ user_count--;
++ if (user_count == 0)
++ ipmi_set_gets_events(ipmi_user->rs_user, 0);
++ spin_unlock(&dev_lock);
++ return 0;
++}
++
++static unsigned char
++ipmb_checksum(unsigned char *data, int size)
++{
++ unsigned char csum = 0;
++
++ for (; size > 0; size--, data++)
++ csum += *data;
++
++ return -csum;
++}
++
++static int ipmi_ioctl(struct inode *inode,
++ struct file *file,
++ unsigned int cmd,
++ unsigned long data)
++{
++ struct priv_data *priv = file->private_data;
++ int rv = -EINVAL;
++
++ switch(cmd) {
++ case IOCTL_IPMI_RCV: /* get ipmi message */
++ {
++ IPMI_MSGDESC rsp;
++ struct ipmi_recv_msg *msg;
++ unsigned long flags;
++ long timeout;
++ wait_queue_t wait;
++
++ if (copy_from_user(&rsp, (void *) data, sizeof(rsp))) {
++ rv = -EFAULT;
++ break;
++ }
++
++ rv = 0;
++
++ spin_lock_irqsave(&(priv->rs_lock), flags);
++
++ msg = rs_find_in_list(&(priv->rs_waiting_rsps),
++ rsp.Dest.uchSlave,
++ rsp.Dest.uchLun,
++ rsp.uchNetFn,
++ rsp.uchCmd,
++ rsp.uchSeq);
++ init_waitqueue_entry(&wait, current);
++ add_wait_queue(&(priv->rs_waiting_rsp_rcvrs),
++ &wait);
++ timeout = 5000 / (1000 / HZ);
++ while (msg == NULL) {
++ set_current_state(TASK_INTERRUPTIBLE);
++ if (!signal_pending(current)) {
++ spin_unlock_irqrestore
++ (&(priv->rs_lock), flags);
++ timeout = schedule_timeout(timeout);
++ spin_lock_irqsave
++ (&(priv->rs_lock), flags);
++ } else {
++ rv = -ERESTARTSYS;
++ break;
++ }
++ if (timeout <= 0) {
++ rsp.uchComplete = IPMI_TIMEOUT_COMPLETION_CODE;
++ break;
++ } else {
++ msg = rs_find_in_list
++ (&(priv->rs_waiting_rsps),
++ rsp.Dest.uchSlave,
++ rsp.Dest.uchLun,
++ rsp.uchNetFn,
++ rsp.uchCmd,
++ rsp.uchSeq);
++ }
++ }
++ remove_wait_queue(&(priv->rs_waiting_rsp_rcvrs),
++ &wait);
++ spin_unlock_irqrestore(&(priv->rs_lock), flags);
++
++ if (msg != NULL) {
++ rsp.uchComplete = msg->msg.data[0];
++ /* The Radisys driver expects all the data to
++ be there in the data, even the stuff we
++ already have processed for it. So make is
++ so. */
++ if (msg->addr.channel == IPMI_BMC_CHANNEL) {
++ struct ipmi_system_interface_addr *smi_addr;
++
++ smi_addr = ((struct ipmi_system_interface_addr *)
++ &(msg->addr));
++ memcpy(&(rsp.auchBuffer[2]),
++ &(msg->msg.data[0]),
++ msg->msg.data_len);
++ rsp.ulLength = msg->msg.data_len+2;
++ rsp.auchBuffer[0] = ((msg->msg.netfn << 2)
++ | (smi_addr->lun));
++ rsp.auchBuffer[1] = msg->msg.cmd;
++ } else {
++ struct ipmi_ipmb_addr *ipmb_addr;
++
++ ipmb_addr = (struct ipmi_ipmb_addr *) &msg->addr;
++ memcpy(&(rsp.auchBuffer[9]),
++ &(msg->msg.data[0]),
++ msg->msg.data_len);
++ rsp.ulLength = msg->msg.data_len+10;
++ rsp.auchBuffer[0] = IPMI_NETFN_APP_REQUEST << 2;
++ rsp.auchBuffer[1] = IPMI_GET_MSG_CMD;
++ rsp.auchBuffer[2] = 0;
++ rsp.auchBuffer[3] = msg->addr.channel;
++ rsp.auchBuffer[4] = ((msg->msg.netfn << 2)
++ | 2);
++ rsp.auchBuffer[5]
++ = ipmb_checksum(&(rsp.auchBuffer[3]),
++ 2);
++ rsp.auchBuffer[6] = ipmb_addr->slave_addr;
++ rsp.auchBuffer[7] = ((msg->msgid << 2)
++ | ipmb_addr->lun);
++ rsp.auchBuffer[8] = msg->msg.cmd;
++ rsp.auchBuffer[msg->msg.data_len+9]
++ = ipmb_checksum(&(rsp.auchBuffer[6]),
++ msg->msg.data_len+3);
++ }
++ ipmi_free_recv_msg(msg);
++ }
++
++ if (copy_to_user((void *) data, &rsp, sizeof(rsp))) {
++ rv = -EFAULT;
++ break;
++ }
++
++ break;
++ }
++
++ case IOCTL_IPMI_SEND: /* send ipmi message */
++ {
++ IPMI_MSGDESC req;
++ struct ipmi_addr addr;
++ struct ipmi_msg msg;
++ unsigned char source_address;
++ unsigned char source_lun;
++ unsigned int start_offset;
++
++ if (copy_from_user(&req, (void *) data, sizeof(req))) {
++ rv = -EFAULT;
++ break;
++ }
++
++ if (req.Dest.uchSlave == 1) {
++ struct ipmi_system_interface_addr *smi_addr
++ = (struct ipmi_system_interface_addr *) &addr;
++ if ((req.uchNetFn == (IPMI_NETFN_APP_REQUEST << 2))
++ && (req.uchCmd == IPMI_READ_EVENT_MSG_BUFFER_CMD))
++ {
++ /* The driver gets event messages
++ automatically, so we emulate
++ this. */
++ rv = rs_handle_event_request(priv);
++ break;
++ }
++
++ smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
++ smi_addr->channel = IPMI_BMC_CHANNEL;
++ smi_addr->lun = req.uchNetFn & 0x3;
++ source_address = 0;
++ source_lun = 0;
++ start_offset = 2;
++ } else {
++ struct ipmi_ipmb_addr *ipmb_addr =
++ (struct ipmi_ipmb_addr *) &addr;
++
++ ipmb_addr->addr_type = IPMI_IPMB_ADDR_TYPE;
++ ipmb_addr->channel = 0;
++ ipmb_addr->slave_addr = req.Dest.uchSlave;
++ ipmb_addr->lun = req.Dest.uchLun;
++ source_address = req.auchBuffer[6];
++ source_lun = req.auchBuffer[7] & 0x3;
++ start_offset = 9;
++ req.ulLength--; /* Remove the checksum the userland
++ process adds. */
++ }
++
++ msg.netfn = req.uchNetFn >> 2;
++ msg.cmd = req.uchCmd;
++ msg.data = req.auchBuffer + start_offset;
++ msg.data_len = req.ulLength - start_offset;
++
++ rv = ipmi_request_with_source(priv->rs_user,
++ &addr,
++ req.uchSeq,
++ &msg,
++ 0,
++ source_address,
++ source_lun);
++ if (rv)
++ req.uchComplete = IPMI_UNKNOWN_ERR_COMPLETION_CODE;
++ else
++ req.uchComplete = 0;
++ /* The Radisys driver does no error checking here. */
++ copy_to_user((void *) data, &req, sizeof(req));
++ rv = 0;
++ break;
++ }
++
++ case IOCTL_IPMI_EVENT: /* get an incoming command. Don't be
++ fooled by the name, these are
++ commands, not IPMI events. */
++ {
++ IPMI_MSGDESC rsp;
++ struct ipmi_recv_msg *msg = NULL;
++ struct list_head *entry;
++ unsigned long flags;
++ long timeout;
++ unsigned long receiver;
++ wait_queue_t wait;
++
++ if (copy_from_user(&receiver, (void *) data, sizeof(receiver)))
++ {
++ rv = -EFAULT;
++ break;
++ }
++
++ if (copy_from_user(&timeout,
++ (void *) (data + sizeof(receiver)),
++ sizeof(timeout)))
++ {
++ rv = -EFAULT;
++ break;
++ }
++
++ rv = 0;
++
++ spin_lock_irqsave(&(priv->rs_lock), flags);
++
++ /* If someone else is already waiting, the Radisys driver
++ returns EFAULT, so we do to. */
++ if (priv->rs_cmd_waiting) {
++ spin_unlock_irqrestore(&(priv->rs_lock), flags);
++ rv = -EFAULT;
++ break;
++ }
++
++ /* If the user thread doesn't match up, abort. */
++ if (receiver != priv->rs_cmd_receiver) {
++ spin_unlock_irqrestore(&(priv->rs_lock), flags);
++ rsp.uchComplete = IPMI_INVALID_CMD_COMPLETION_CODE;
++ break;
++ }
++
++ init_waitqueue_entry(&wait, current);
++ add_wait_queue(&(priv->rs_waiting_cmd_rcvrs),
++ &wait);
++ priv->rs_cmd_waiting = 1;
++ timeout = timeout / (1000 / HZ); /* from ms to jiffies */
++ while ((timeout > 0) &&
++ list_empty(&(priv->rs_waiting_cmds)))
++ {
++ set_current_state(TASK_INTERRUPTIBLE);
++ if (!signal_pending(current)) {
++ spin_unlock_irqrestore
++ (&(priv->rs_lock), flags);
++ timeout = schedule_timeout(timeout);
++ spin_lock_irqsave
++ (&(priv->rs_lock), flags);
++ } else {
++ rv = -ERESTARTSYS;
++ break;
++ }
++ }
++ if (!list_empty(&(priv->rs_waiting_cmds))) {
++ entry = priv->rs_waiting_cmds.next;
++ list_del(entry);
++ msg = list_entry(entry, struct ipmi_recv_msg, link);
++ }
++ priv->rs_cmd_waiting = 0;
++ remove_wait_queue(&(priv->rs_waiting_cmd_rcvrs),
++ &wait);
++ spin_unlock_irqrestore(&(priv->rs_lock), flags);
++
++ if (msg != NULL) {
++ /* The Radisys driver expects all the data to
++ be there in the data, even the stuff we
++ already have processed for it. So make is
++ so. */
++ struct ipmi_ipmb_addr *ipmb_addr;
++
++ ipmb_addr = (struct ipmi_ipmb_addr *) &msg->addr;
++ memcpy(&(rsp.auchBuffer[9]),
++ &(msg->msg.data[0]),
++ msg->msg.data_len);
++ rsp.ulLength = msg->msg.data_len+9;
++ rsp.auchBuffer[0] = IPMI_NETFN_APP_REQUEST << 2;
++ rsp.auchBuffer[1] = IPMI_SEND_MSG_CMD;
++ rsp.auchBuffer[2] = 0;
++ rsp.auchBuffer[3] = msg->addr.channel;
++ rsp.auchBuffer[4] = ((msg->msg.netfn << 2)
++ | 2);
++ rsp.auchBuffer[5]
++ = ipmb_checksum(&(rsp.auchBuffer[3]),
++ 2);
++ rsp.auchBuffer[6] = ipmb_addr->slave_addr;
++ rsp.auchBuffer[7] = ((msg->msgid << 2)
++ | ipmb_addr->lun);
++ rsp.auchBuffer[8] = msg->msg.cmd;
++
++ rsp.uchNetFn = (msg->msg.netfn << 2);
++ rsp.uchCmd = msg->msg.cmd;
++ rsp.uchSeq = msg->msgid;
++ rsp.ulLength = msg->msg.data_len + 9;
++ ipmi_free_recv_msg(msg);
++ } else if (!rv) {
++ /* On a time out, the Radisys driver returns
++ IPMIRC_ERROR in the completion code, for
++ some wierd reason. */
++ rsp.uchComplete = IPMI_UNKNOWN_ERR_COMPLETION_CODE;
++ }
++
++ /* The Radisys driver does no error checking here. */
++ copy_to_user((void *) data, &rsp, sizeof(rsp));
++ rv = 0;
++ break;
++ }
++
++ case IOCTL_IPMI_REGISTER: /* register as event receiver */
++ {
++ unsigned long receiver;
++ unsigned char rc = LOWLRC_SUCCESS;
++ unsigned long flags;
++
++ if (copy_from_user(&receiver, (void *) data, sizeof(receiver)))
++ {
++ rv = -EFAULT;
++ break;
++ }
++
++ spin_lock_irqsave(&(priv->rs_lock), flags);
++ if (priv->rs_cmd_receiver == 0) {
++ rv = ipmi_register_all_cmd_rcvr(priv->rs_user);
++ if (rv) {
++ priv->rs_cmd_receiver = receiver;
++ } else {
++ rc = LOWLRC_ERROR;
++ }
++ } else if (priv->rs_cmd_receiver != receiver) {
++ rc = LOWLRC_ERROR;
++ }
++ spin_unlock_irqrestore(&(priv->rs_lock), flags);
++
++ /* The Radisys driver does no error checking here. */
++ copy_to_user((void *) data, &rc, sizeof(rc));
++ rv = 0;
++ break;
++ }
++
++ case IOCTL_IPMI_UNREGISTER: /* unregister as event receiver */
++ {
++ unsigned long receiver;
++ unsigned char rc = LOWLRC_SUCCESS;
++ unsigned long flags;
++
++ if (copy_from_user(&receiver, (void *) data, sizeof(receiver)))
++ {
++ rv = -EFAULT;
++ break;
++ }
++
++ spin_lock_irqsave(&(priv->rs_lock), flags);
++ if (priv->rs_cmd_receiver == receiver) {
++ ipmi_unregister_all_cmd_rcvr(priv->rs_user);
++ priv->rs_cmd_receiver = 0;
++ } else {
++ rc = LOWLRC_ERROR;
++ }
++ spin_unlock_irqrestore(&(priv->rs_lock), flags);
++
++ /* The Radisys driver does no error checking here. */
++ copy_to_user((void *) data, &rc, sizeof(rc));
++ rv = 0;
++ break;
++ }
++
++ case IOCTL_IPMI_CLEAR: /* clear registered event receiver */
++ {
++ unsigned char rc = LOWLRC_SUCCESS;
++ unsigned long flags;
++
++ spin_lock_irqsave(&(priv->rs_lock), flags);
++ ipmi_unregister_all_cmd_rcvr(priv->rs_user);
++ priv->rs_cmd_receiver = 0;
++ spin_unlock_irqrestore(&(priv->rs_lock), flags);
++
++ /* The Radisys driver does no error checking here. */
++ copy_to_user((void *) data, &rc, sizeof(rc));
++ rv = 0;
++ break;
++ }
++ }
++
++ return rv;
++}
++
++static struct file_operations ipmi_fops = {
++ owner: THIS_MODULE,
++ ioctl: ipmi_ioctl,
++ open: ipmi_open,
++ release: ipmi_release
++};
++
++static struct timer_list ipmi_radisys_timer;
++
++/* Call every 100 ms. */
++#define IPMI_TIMEOUT_TIME 100
++#define IPMI_TIMEOUT_JIFFIES (IPMI_TIMEOUT_TIME/(1000/HZ))
++
++/* Request events from the queue every second. Hopefully, in the
++ future, IPMI will add a way to know immediately if an event is
++ in the queue. */
++#define IPMI_REQUEST_EV_TIME (1000 / (IPMI_TIMEOUT_TIME))
++
++static volatile int stop_operation = 0;
++static volatile int timer_stopped = 0;
++
++static void ipmi_radisys_timeout(unsigned long data)
++{
++ struct list_head *entry, *entry2;
++ struct priv_data *priv = (struct priv_data *) data;
++ int timeout_period = IPMI_TIMEOUT_TIME;
++ struct ipmi_recv_msg *msg;
++
++ if (stop_operation) {
++ timer_stopped = 1;
++ return;
++ }
++
++ /* Now time out any messages in the Radisys message queue. */
++ spin_lock(&(priv->rs_lock));
++ list_for_each_safe(entry, entry2, &(priv->rs_waiting_rsps)) {
++ long *timeout;
++ msg = list_entry(entry, struct ipmi_recv_msg, link);
++ timeout = rs_timeout(msg);
++ *timeout -= timeout_period;
++ if ((*timeout) <= 0) {
++ list_del(entry);
++ ipmi_free_recv_msg(msg);
++ }
++ }
++ list_for_each_safe(entry, entry2, &(priv->rs_waiting_cmds)) {
++ long *timeout;
++ msg = list_entry(entry, struct ipmi_recv_msg, link);
++ timeout = rs_timeout(msg);
++ *timeout -= timeout_period;
++ if ((*timeout) <= 0) {
++ list_del(entry);
++ ipmi_free_recv_msg(msg);
++ }
++ }
++ spin_unlock(&priv->rs_lock);
++
++ ipmi_radisys_timer.expires += IPMI_TIMEOUT_JIFFIES;
++ add_timer(&ipmi_radisys_timer);
++}
++
++#define DEVICE_NAME "ipmi_radisys"
++
++static int ipmi_radisys_major = 0;
++MODULE_PARM(ipmi_radisys_major, "i");
++
++static struct ipmi_user_hndl ipmi_hndlrs =
++{
++ ipmi_recv_hndl : rs_msg_recv
++};
++
++
++static int init_ipmi_radisys(void)
++{
++ int rv;
++
++ if (ipmi_radisys_major < 0)
++ return -EINVAL;
++
++ ipmi_user = kmalloc(sizeof(*ipmi_user), GFP_KERNEL);
++ if (!ipmi_user) {
++ printk("ipmi_radisys: Unable to allocate memory\n");
++ return -ENOMEM;
++ }
++
++ /* Create the Radisys interface user. */
++ spin_lock_init(&(ipmi_user->rs_lock));
++ INIT_LIST_HEAD(&(ipmi_user->rs_waiting_rsps));
++ init_waitqueue_head(&(ipmi_user->rs_waiting_rsp_rcvrs));
++ INIT_LIST_HEAD(&(ipmi_user->rs_waiting_cmds));
++ init_waitqueue_head(&(ipmi_user->rs_waiting_cmd_rcvrs));
++ ipmi_user->rs_cmd_waiting = 0;
++ INIT_LIST_HEAD(&(ipmi_user->rs_waiting_events));
++
++ rv = ipmi_create_user(0,
++ &ipmi_hndlrs,
++ ipmi_user,
++ &(ipmi_user->rs_user));
++ if (rv) {
++ printk("ipmi_radisys: Unable to create an IPMI user, probably"
++ " no physical devices present.\n");
++ kfree(ipmi_user);
++ ipmi_user = NULL;
++ return rv;
++ }
++
++ rv = register_chrdev(ipmi_radisys_major, DEVICE_NAME, &ipmi_fops);
++ if (rv < 0)
++ {
++ printk("ipmi_radisys: Unable to create the character device\n");
++ kfree(ipmi_user);
++ ipmi_user = NULL;
++ printk(KERN_ERR "ipmi: can't get major %d\n",
++ ipmi_radisys_major);
++ return rv;
++ }
++
++ if (ipmi_radisys_major == 0)
++ {
++ ipmi_radisys_major = rv;
++ }
++
++ devfs_handle = devfs_register(NULL, DEVICE_NAME, DEVFS_FL_NONE,
++ ipmi_radisys_major, 0,
++ S_IFCHR | S_IRUSR | S_IWUSR,
++ &ipmi_fops, NULL);
++
++ ipmi_radisys_timer.data = (long) ipmi_user;
++ ipmi_radisys_timer.function = ipmi_radisys_timeout;
++ ipmi_radisys_timer.expires = jiffies + IPMI_TIMEOUT_JIFFIES;
++ add_timer(&ipmi_radisys_timer);
++
++ printk(KERN_INFO "ipmi_radisys: driver initialized at char major %d\n",
++ ipmi_radisys_major);
++
++ return 0;
++}
++
++#ifdef MODULE
++static void free_recv_msg_list(struct list_head *q)
++{
++ struct list_head *entry, *entry2;
++ struct ipmi_recv_msg *msg;
++
++ list_for_each_safe(entry, entry2, q) {
++ msg = list_entry(entry, struct ipmi_recv_msg, link);
++ list_del(entry);
++ ipmi_free_recv_msg(msg);
++ }
++}
++
++static void cleanup_ipmi_radisys(void)
++{
++ devfs_unregister(devfs_handle);
++
++ /* Tell the timer to stop, then wait for it to stop. This avoids
++ problems with race conditions removing the timer here. */
++ stop_operation = 1;
++ while (!timer_stopped) {
++ schedule_timeout(1);
++ }
++
++ ipmi_destroy_user(ipmi_user->rs_user);
++
++ free_recv_msg_list(&(ipmi_user->rs_waiting_rsps));
++ free_recv_msg_list(&(ipmi_user->rs_waiting_cmds));
++ free_recv_msg_list(&(ipmi_user->rs_waiting_events));
++
++ kfree(ipmi_user);
++ ipmi_user = NULL;
++
++ unregister_chrdev(ipmi_radisys_major, DEVICE_NAME);
++}
++module_exit(cleanup_ipmi_radisys);
++#else
++static int __init ipmi_radisys_setup (char *str)
++{
++ int x;
++
++ if (get_option (&str, &x)) {
++ /* ipmi=x sets the major number to x. */
++ ipmi_radisys_major = x;
++ } else if (!strcmp(str, "off")) {
++ ipmi_radisys_major = -1;
++ }
++
++ return 1;
++}
++__setup("ipmi_radisys=", ipmi_radisys_setup);
++#endif
++
++module_init(init_ipmi_radisys);
++MODULE_LICENSE("GPL");
+diff -urN linux/include/linux/autoconf.h linux-emu/include/linux/autoconf.h
+--- linux/include/linux/autoconf.h Mon Jan 13 13:25:58 2003
++++ linux-emu/include/linux/autoconf.h Wed Dec 31 18:00:00 1969
+@@ -1,862 +0,0 @@
+-/*
+- * Automatically generated C config: don't edit
+- */
+-#define AUTOCONF_INCLUDED
+-#define CONFIG_X86 1
+-#undef CONFIG_SBUS
+-#define CONFIG_UID16 1
+-
+-/*
+- * Code maturity level options
+- */
+-#define CONFIG_EXPERIMENTAL 1
+-
+-/*
+- * Loadable module support
+- */
+-#define CONFIG_MODULES 1
+-#undef CONFIG_MODVERSIONS
+-#define CONFIG_KMOD 1
+-
+-/*
+- * Processor type and features
+- */
+-#undef CONFIG_M386
+-#undef CONFIG_M486
+-#undef CONFIG_M586
+-#undef CONFIG_M586TSC
+-#undef CONFIG_M586MMX
+-#undef CONFIG_M686
+-#define CONFIG_MPENTIUMIII 1
+-#undef CONFIG_MPENTIUM4
+-#undef CONFIG_MK6
+-#undef CONFIG_MK7
+-#undef CONFIG_MELAN
+-#undef CONFIG_MCRUSOE
+-#undef CONFIG_MWINCHIPC6
+-#undef CONFIG_MWINCHIP2
+-#undef CONFIG_MWINCHIP3D
+-#undef CONFIG_MCYRIXIII
+-#define CONFIG_X86_WP_WORKS_OK 1
+-#define CONFIG_X86_INVLPG 1
+-#define CONFIG_X86_CMPXCHG 1
+-#define CONFIG_X86_XADD 1
+-#define CONFIG_X86_BSWAP 1
+-#define CONFIG_X86_POPAD_OK 1
+-#undef CONFIG_RWSEM_GENERIC_SPINLOCK
+-#define CONFIG_RWSEM_XCHGADD_ALGORITHM 1
+-#define CONFIG_X86_L1_CACHE_SHIFT (5)
+-#define CONFIG_X86_HAS_TSC 1
+-#define CONFIG_X86_GOOD_APIC 1
+-#define CONFIG_X86_PGE 1
+-#define CONFIG_X86_USE_PPRO_CHECKSUM 1
+-#define CONFIG_X86_F00F_WORKS_OK 1
+-#define CONFIG_X86_MCE 1
+-#undef CONFIG_TOSHIBA
+-#undef CONFIG_I8K
+-#undef CONFIG_MICROCODE
+-#undef CONFIG_X86_MSR
+-#undef CONFIG_X86_CPUID
+-#define CONFIG_NOHIGHMEM 1
+-#undef CONFIG_HIGHMEM4G
+-#undef CONFIG_HIGHMEM64G
+-#undef CONFIG_HIGHMEM
+-#undef CONFIG_MATH_EMULATION
+-#undef CONFIG_MTRR
+-#define CONFIG_SMP 1
+-#undef CONFIG_MULTIQUAD
+-#undef CONFIG_X86_TSC_DISABLE
+-#define CONFIG_X86_TSC 1
+-#define CONFIG_HAVE_DEC_LOCK 1
+-
+-/*
+- * General setup
+- */
+-#define CONFIG_NET 1
+-#define CONFIG_X86_IO_APIC 1
+-#define CONFIG_X86_LOCAL_APIC 1
+-#define CONFIG_PCI 1
+-#undef CONFIG_PCI_GOBIOS
+-#undef CONFIG_PCI_GODIRECT
+-#define CONFIG_PCI_GOANY 1
+-#define CONFIG_PCI_BIOS 1
+-#define CONFIG_PCI_DIRECT 1
+-#define CONFIG_ISA 1
+-#define CONFIG_PCI_NAMES 1
+-#undef CONFIG_EISA
+-#undef CONFIG_MCA
+-#define CONFIG_HOTPLUG 1
+-
+-/*
+- * PCMCIA/CardBus support
+- */
+-#define CONFIG_PCMCIA 1
+-#define CONFIG_CARDBUS 1
+-#undef CONFIG_TCIC
+-#undef CONFIG_I82092
+-#undef CONFIG_I82365
+-
+-/*
+- * PCI Hotplug Support
+- */
+-#undef CONFIG_HOTPLUG_PCI
+-#undef CONFIG_HOTPLUG_PCI_COMPAQ
+-#undef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM
+-#undef CONFIG_HOTPLUG_PCI_IBM
+-#undef CONFIG_HOTPLUG_PCI_ACPI
+-#define CONFIG_SYSVIPC 1
+-#undef CONFIG_BSD_PROCESS_ACCT
+-#define CONFIG_SYSCTL 1
+-#define CONFIG_KCORE_ELF 1
+-#undef CONFIG_KCORE_AOUT
+-#define CONFIG_BINFMT_AOUT 1
+-#define CONFIG_BINFMT_ELF 1
+-#define CONFIG_BINFMT_MISC 1
+-#define CONFIG_PM 1
+-#undef CONFIG_ACPI
+-#undef CONFIG_APM
+-
+-/*
+- * Memory Technology Devices (MTD)
+- */
+-#undef CONFIG_MTD
+-
+-/*
+- * Parallel port support
+- */
+-#undef CONFIG_PARPORT
+-
+-/*
+- * Plug and Play configuration
+- */
+-#define CONFIG_PNP 1
+-#define CONFIG_ISAPNP 1
+-
+-/*
+- * Block devices
+- */
+-#define CONFIG_BLK_DEV_FD 1
+-#undef CONFIG_BLK_DEV_XD
+-#undef CONFIG_PARIDE
+-#undef CONFIG_BLK_CPQ_DA
+-#undef CONFIG_BLK_CPQ_CISS_DA
+-#undef CONFIG_CISS_SCSI_TAPE
+-#undef CONFIG_BLK_DEV_DAC960
+-#undef CONFIG_BLK_DEV_UMEM
+-#undef CONFIG_BLK_DEV_LOOP
+-#undef CONFIG_BLK_DEV_NBD
+-#define CONFIG_BLK_DEV_RAM 1
+-#define CONFIG_BLK_DEV_RAM_SIZE (4096)
+-#define CONFIG_BLK_DEV_INITRD 1
+-#undef CONFIG_BLK_STATS
+-
+-/*
+- * Multi-device support (RAID and LVM)
+- */
+-#undef CONFIG_MD
+-#undef CONFIG_BLK_DEV_MD
+-#undef CONFIG_MD_LINEAR
+-#undef CONFIG_MD_RAID0
+-#undef CONFIG_MD_RAID1
+-#undef CONFIG_MD_RAID5
+-#undef CONFIG_MD_MULTIPATH
+-#undef CONFIG_BLK_DEV_LVM
+-
+-/*
+- * Networking options
+- */
+-#define CONFIG_PACKET 1
+-#undef CONFIG_PACKET_MMAP
+-#undef CONFIG_NETLINK_DEV
+-#undef CONFIG_NETFILTER
+-#undef CONFIG_FILTER
+-#define CONFIG_UNIX 1
+-#define CONFIG_INET 1
+-#define CONFIG_IP_MULTICAST 1
+-#undef CONFIG_IP_ADVANCED_ROUTER
+-#define CONFIG_IP_PNP 1
+-#define CONFIG_IP_PNP_DHCP 1
+-#undef CONFIG_IP_PNP_BOOTP
+-#undef CONFIG_IP_PNP_RARP
+-#undef CONFIG_NET_IPIP
+-#undef CONFIG_NET_IPGRE
+-#undef CONFIG_IP_MROUTE
+-#undef CONFIG_ARPD
+-#undef CONFIG_INET_ECN
+-#undef CONFIG_SYN_COOKIES
+-#undef CONFIG_IPV6
+-#undef CONFIG_KHTTPD
+-#undef CONFIG_ATM
+-#undef CONFIG_VLAN_8021Q
+-
+-/*
+- *
+- */
+-#undef CONFIG_IPX
+-#undef CONFIG_ATALK
+-
+-/*
+- * Appletalk devices
+- */
+-#undef CONFIG_DEV_APPLETALK
+-#undef CONFIG_DECNET
+-#undef CONFIG_BRIDGE
+-#undef CONFIG_X25
+-#undef CONFIG_LAPB
+-#undef CONFIG_LLC
+-#undef CONFIG_NET_DIVERT
+-#undef CONFIG_ECONET
+-#undef CONFIG_WAN_ROUTER
+-#undef CONFIG_NET_FASTROUTE
+-#undef CONFIG_NET_HW_FLOWCONTROL
+-
+-/*
+- * QoS and/or fair queueing
+- */
+-#undef CONFIG_NET_SCHED
+-
+-/*
+- * Network testing
+- */
+-#undef CONFIG_NET_PKTGEN
+-
+-/*
+- * Telephony Support
+- */
+-#undef CONFIG_PHONE
+-#undef CONFIG_PHONE_IXJ
+-#undef CONFIG_PHONE_IXJ_PCMCIA
+-
+-/*
+- * ATA/IDE/MFM/RLL support
+- */
+-#define CONFIG_IDE 1
+-
+-/*
+- * IDE, ATA and ATAPI Block devices
+- */
+-#define CONFIG_BLK_DEV_IDE 1
+-
+-/*
+- * Please see Documentation/ide.txt for help/info on IDE drives
+- */
+-#undef CONFIG_BLK_DEV_HD_IDE
+-#undef CONFIG_BLK_DEV_HD
+-#define CONFIG_BLK_DEV_IDEDISK 1
+-#define CONFIG_IDEDISK_MULTI_MODE 1
+-#undef CONFIG_IDEDISK_STROKE
+-#undef CONFIG_BLK_DEV_IDEDISK_VENDOR
+-#undef CONFIG_BLK_DEV_IDEDISK_FUJITSU
+-#undef CONFIG_BLK_DEV_IDEDISK_IBM
+-#undef CONFIG_BLK_DEV_IDEDISK_MAXTOR
+-#undef CONFIG_BLK_DEV_IDEDISK_QUANTUM
+-#undef CONFIG_BLK_DEV_IDEDISK_SEAGATE
+-#undef CONFIG_BLK_DEV_IDEDISK_WD
+-#undef CONFIG_BLK_DEV_COMMERIAL
+-#undef CONFIG_BLK_DEV_TIVO
+-#undef CONFIG_BLK_DEV_IDECS
+-#define CONFIG_BLK_DEV_IDECD 1
+-#undef CONFIG_BLK_DEV_IDETAPE
+-#undef CONFIG_BLK_DEV_IDEFLOPPY
+-#undef CONFIG_BLK_DEV_IDESCSI
+-#undef CONFIG_IDE_TASK_IOCTL
+-
+-/*
+- * IDE chipset support/bugfixes
+- */
+-#define CONFIG_BLK_DEV_CMD640 1
+-#undef CONFIG_BLK_DEV_CMD640_ENHANCED
+-#undef CONFIG_BLK_DEV_ISAPNP
+-#define CONFIG_BLK_DEV_RZ1000 1
+-#define CONFIG_BLK_DEV_IDEPCI 1
+-#define CONFIG_IDEPCI_SHARE_IRQ 1
+-#define CONFIG_BLK_DEV_IDEDMA_PCI 1
+-#undef CONFIG_BLK_DEV_OFFBOARD
+-#undef CONFIG_BLK_DEV_IDEDMA_FORCED
+-#define CONFIG_IDEDMA_PCI_AUTO 1
+-#undef CONFIG_IDEDMA_ONLYDISK
+-#define CONFIG_BLK_DEV_IDEDMA 1
+-#undef CONFIG_IDEDMA_PCI_WIP
+-#undef CONFIG_BLK_DEV_IDEDMA_TIMEOUT
+-#undef CONFIG_IDEDMA_NEW_DRIVE_LISTINGS
+-#define CONFIG_BLK_DEV_ADMA 1
+-#undef CONFIG_BLK_DEV_AEC62XX
+-#undef CONFIG_AEC62XX_TUNING
+-#undef CONFIG_BLK_DEV_ALI15X3
+-#undef CONFIG_WDC_ALI15X3
+-#undef CONFIG_BLK_DEV_AMD74XX
+-#undef CONFIG_AMD74XX_OVERRIDE
+-#undef CONFIG_BLK_DEV_CMD64X
+-#undef CONFIG_BLK_DEV_CMD680
+-#undef CONFIG_BLK_DEV_CY82C693
+-#undef CONFIG_BLK_DEV_CS5530
+-#undef CONFIG_BLK_DEV_HPT34X
+-#undef CONFIG_HPT34X_AUTODMA
+-#undef CONFIG_BLK_DEV_HPT366
+-#define CONFIG_BLK_DEV_PIIX 1
+-#define CONFIG_PIIX_TUNING 1
+-#undef CONFIG_BLK_DEV_NS87415
+-#undef CONFIG_BLK_DEV_OPTI621
+-#undef CONFIG_BLK_DEV_PDC202XX
+-#undef CONFIG_PDC202XX_BURST
+-#undef CONFIG_PDC202XX_FORCE
+-#undef CONFIG_BLK_DEV_SVWKS
+-#undef CONFIG_BLK_DEV_SIS5513
+-#undef CONFIG_BLK_DEV_SLC90E66
+-#undef CONFIG_BLK_DEV_TRM290
+-#undef CONFIG_BLK_DEV_VIA82CXXX
+-#undef CONFIG_IDE_CHIPSETS
+-#define CONFIG_IDEDMA_AUTO 1
+-#undef CONFIG_IDEDMA_IVB
+-#undef CONFIG_DMA_NONPCI
+-#define CONFIG_BLK_DEV_IDE_MODES 1
+-#undef CONFIG_BLK_DEV_ATARAID
+-#undef CONFIG_BLK_DEV_ATARAID_PDC
+-#undef CONFIG_BLK_DEV_ATARAID_HPT
+-
+-/*
+- * SCSI support
+- */
+-#undef CONFIG_SCSI
+-
+-/*
+- * Fusion MPT device support
+- */
+-#undef CONFIG_FUSION
+-#undef CONFIG_FUSION_BOOT
+-#undef CONFIG_FUSION_ISENSE
+-#undef CONFIG_FUSION_CTL
+-#undef CONFIG_FUSION_LAN
+-
+-/*
+- * IEEE 1394 (FireWire) support (EXPERIMENTAL)
+- */
+-#undef CONFIG_IEEE1394
+-
+-/*
+- * I2O device support
+- */
+-#undef CONFIG_I2O
+-#undef CONFIG_I2O_PCI
+-#undef CONFIG_I2O_BLOCK
+-#undef CONFIG_I2O_LAN
+-#undef CONFIG_I2O_SCSI
+-#undef CONFIG_I2O_PROC
+-
+-/*
+- * Network device support
+- */
+-#define CONFIG_NETDEVICES 1
+-
+-/*
+- * ARCnet devices
+- */
+-#undef CONFIG_ARCNET
+-#undef CONFIG_DUMMY
+-#define CONFIG_DUMMY_MODULE 1
+-#undef CONFIG_BONDING
+-#undef CONFIG_EQUALIZER
+-#undef CONFIG_TUN
+-#undef CONFIG_ETHERTAP
+-#undef CONFIG_NET_SB1000
+-
+-/*
+- * Ethernet (10 or 100Mbit)
+- */
+-#define CONFIG_NET_ETHERNET 1
+-#undef CONFIG_SUNLANCE
+-#undef CONFIG_HAPPYMEAL
+-#undef CONFIG_SUNBMAC
+-#undef CONFIG_SUNQE
+-#undef CONFIG_SUNGEM
+-#undef CONFIG_NET_VENDOR_3COM
+-#undef CONFIG_LANCE
+-#undef CONFIG_NET_VENDOR_SMC
+-#undef CONFIG_NET_VENDOR_RACAL
+-#undef CONFIG_AT1700
+-#undef CONFIG_DEPCA
+-#undef CONFIG_HP100
+-#undef CONFIG_NET_ISA
+-#define CONFIG_NET_PCI 1
+-#undef CONFIG_PCNET32
+-#undef CONFIG_ADAPTEC_STARFIRE
+-#undef CONFIG_AC3200
+-#undef CONFIG_APRICOT
+-#undef CONFIG_CS89x0
+-#undef CONFIG_TULIP
+-#undef CONFIG_DE4X5
+-#undef CONFIG_DGRS
+-#undef CONFIG_DM9102
+-#define CONFIG_EEPRO100 1
+-#undef CONFIG_E100
+-#undef CONFIG_LNE390
+-#undef CONFIG_FEALNX
+-#undef CONFIG_NATSEMI
+-#undef CONFIG_NE2K_PCI
+-#undef CONFIG_NE3210
+-#undef CONFIG_ES3210
+-#undef CONFIG_8139CP
+-#undef CONFIG_8139TOO
+-#undef CONFIG_8139TOO_PIO
+-#undef CONFIG_8139TOO_TUNE_TWISTER
+-#undef CONFIG_8139TOO_8129
+-#undef CONFIG_8139_OLD_RX_RESET
+-#undef CONFIG_SIS900
+-#undef CONFIG_EPIC100
+-#undef CONFIG_SUNDANCE
+-#undef CONFIG_SUNDANCE_MMIO
+-#undef CONFIG_TLAN
+-#undef CONFIG_TC35815
+-#undef CONFIG_VIA_RHINE
+-#undef CONFIG_VIA_RHINE_MMIO
+-#undef CONFIG_WINBOND_840
+-#undef CONFIG_NET_POCKET
+-
+-/*
+- * Ethernet (1000 Mbit)
+- */
+-#undef CONFIG_ACENIC
+-#undef CONFIG_DL2K
+-#undef CONFIG_E1000
+-#undef CONFIG_MYRI_SBUS
+-#undef CONFIG_NS83820
+-#undef CONFIG_HAMACHI
+-#undef CONFIG_YELLOWFIN
+-#undef CONFIG_SK98LIN
+-#undef CONFIG_TIGON3
+-#undef CONFIG_FDDI
+-#undef CONFIG_HIPPI
+-#undef CONFIG_PLIP
+-#undef CONFIG_PPP
+-#undef CONFIG_SLIP
+-
+-/*
+- * Wireless LAN (non-hamradio)
+- */
+-#undef CONFIG_NET_RADIO
+-
+-/*
+- * Token Ring devices
+- */
+-#undef CONFIG_TR
+-#undef CONFIG_NET_FC
+-#undef CONFIG_RCPCI
+-#undef CONFIG_SHAPER
+-
+-/*
+- * Wan interfaces
+- */
+-#undef CONFIG_WAN
+-
+-/*
+- * PCMCIA network device support
+- */
+-#define CONFIG_NET_PCMCIA 1
+-#undef CONFIG_PCMCIA_3C589
+-#undef CONFIG_PCMCIA_3C574
+-#undef CONFIG_PCMCIA_FMVJ18X
+-#define CONFIG_PCMCIA_PCNET 1
+-#undef CONFIG_PCMCIA_AXNET
+-#undef CONFIG_PCMCIA_NMCLAN
+-#undef CONFIG_PCMCIA_SMC91C92
+-#undef CONFIG_PCMCIA_XIRC2PS
+-#undef CONFIG_ARCNET_COM20020_CS
+-#undef CONFIG_PCMCIA_IBMTR
+-#undef CONFIG_PCMCIA_XIRCOM
+-#undef CONFIG_PCMCIA_XIRTULIP
+-#define CONFIG_NET_PCMCIA_RADIO 1
+-#define CONFIG_PCMCIA_RAYCS 1
+-#undef CONFIG_PCMCIA_NETWAVE
+-#undef CONFIG_PCMCIA_WAVELAN
+-#undef CONFIG_AIRONET4500_CS
+-
+-/*
+- * Amateur Radio support
+- */
+-#undef CONFIG_HAMRADIO
+-
+-/*
+- * IrDA (infrared) support
+- */
+-#undef CONFIG_IRDA
+-
+-/*
+- * ISDN subsystem
+- */
+-#undef CONFIG_ISDN
+-
+-/*
+- * Old CD-ROM drivers (not SCSI, not IDE)
+- */
+-#undef CONFIG_CD_NO_IDESCSI
+-
+-/*
+- * Input core support
+- */
+-#undef CONFIG_INPUT
+-#undef CONFIG_INPUT_KEYBDEV
+-#undef CONFIG_INPUT_MOUSEDEV
+-#undef CONFIG_INPUT_JOYDEV
+-#undef CONFIG_INPUT_EVDEV
+-
+-/*
+- * Character devices
+- */
+-#define CONFIG_VT 1
+-#define CONFIG_VT_CONSOLE 1
+-#define CONFIG_SERIAL 1
+-#define CONFIG_SERIAL_CONSOLE 1
+-#undef CONFIG_SERIAL_EXTENDED
+-#undef CONFIG_SERIAL_NONSTANDARD
+-#define CONFIG_UNIX98_PTYS 1
+-#define CONFIG_UNIX98_PTY_COUNT (256)
+-
+-/*
+- * I2C support
+- */
+-#undef CONFIG_I2C
+-
+-/*
+- * Mice
+- */
+-#undef CONFIG_BUSMOUSE
+-#define CONFIG_MOUSE 1
+-#define CONFIG_PSMOUSE 1
+-#undef CONFIG_82C710_MOUSE
+-#undef CONFIG_PC110_PAD
+-#undef CONFIG_MK712_MOUSE
+-
+-/*
+- * Joysticks
+- */
+-#undef CONFIG_INPUT_GAMEPORT
+-
+-/*
+- * Input core support is needed for gameports
+- */
+-
+-/*
+- * Input core support is needed for joysticks
+- */
+-#undef CONFIG_QIC02_TAPE
+-#undef CONFIG_IPMI_HANDLER
+-#define CONFIG_IPMI_HANDLER_MODULE 1
+-#define CONFIG_IPMI_PANIC_EVENT 1
+-#undef CONFIG_IPMI_DEVICE_INTERFACE
+-#define CONFIG_IPMI_DEVICE_INTERFACE_MODULE 1
+-#undef CONFIG_IPMI_KCS
+-#define CONFIG_IPMI_KCS_MODULE 1
+-#undef CONFIG_IPMI_WATCHDOG
+-#define CONFIG_IPMI_WATCHDOG_MODULE 1
+-
+-/*
+- * Watchdog Cards
+- */
+-#undef CONFIG_WATCHDOG
+-#undef CONFIG_AMD_RNG
+-#undef CONFIG_INTEL_RNG
+-#undef CONFIG_AMD_PM768
+-#undef CONFIG_NVRAM
+-#undef CONFIG_RTC
+-#undef CONFIG_DTLK
+-#undef CONFIG_R3964
+-#undef CONFIG_APPLICOM
+-#undef CONFIG_SONYPI
+-
+-/*
+- * Ftape, the floppy tape device driver
+- */
+-#undef CONFIG_FTAPE
+-#define CONFIG_AGP 1
+-#define CONFIG_AGP_INTEL 1
+-#define CONFIG_AGP_I810 1
+-#define CONFIG_AGP_VIA 1
+-#define CONFIG_AGP_AMD 1
+-#undef CONFIG_AGP_AMD_8151
+-#define CONFIG_AGP_SIS 1
+-#define CONFIG_AGP_ALI 1
+-#undef CONFIG_AGP_SWORKS
+-#define CONFIG_DRM 1
+-#undef CONFIG_DRM_OLD
+-
+-/*
+- * DRM 4.1 drivers
+- */
+-#define CONFIG_DRM_NEW 1
+-#define CONFIG_DRM_TDFX 1
+-#undef CONFIG_DRM_R128
+-#define CONFIG_DRM_RADEON 1
+-#undef CONFIG_DRM_I810
+-#undef CONFIG_DRM_I810_XFREE_41
+-#undef CONFIG_DRM_I830
+-#undef CONFIG_DRM_MGA
+-#undef CONFIG_DRM_SIS
+-
+-/*
+- * PCMCIA character devices
+- */
+-#undef CONFIG_PCMCIA_SERIAL_CS
+-#undef CONFIG_SYNCLINK_CS
+-#undef CONFIG_MWAVE
+-
+-/*
+- * Multimedia devices
+- */
+-#undef CONFIG_VIDEO_DEV
+-
+-/*
+- * File systems
+- */
+-#undef CONFIG_QUOTA
+-#undef CONFIG_AUTOFS_FS
+-#define CONFIG_AUTOFS4_FS 1
+-#undef CONFIG_REISERFS_FS
+-#undef CONFIG_REISERFS_CHECK
+-#undef CONFIG_REISERFS_PROC_INFO
+-#undef CONFIG_ADFS_FS
+-#undef CONFIG_ADFS_FS_RW
+-#undef CONFIG_AFFS_FS
+-#undef CONFIG_HFS_FS
+-#undef CONFIG_BEFS_FS
+-#undef CONFIG_BEFS_DEBUG
+-#undef CONFIG_BFS_FS
+-#undef CONFIG_EXT3_FS
+-#undef CONFIG_JBD
+-#undef CONFIG_JBD_DEBUG
+-#undef CONFIG_FAT_FS
+-#undef CONFIG_MSDOS_FS
+-#undef CONFIG_UMSDOS_FS
+-#undef CONFIG_VFAT_FS
+-#undef CONFIG_EFS_FS
+-#undef CONFIG_JFFS_FS
+-#undef CONFIG_JFFS2_FS
+-#undef CONFIG_CRAMFS
+-#define CONFIG_TMPFS 1
+-#define CONFIG_RAMFS 1
+-#define CONFIG_ISO9660_FS 1
+-#undef CONFIG_JOLIET
+-#undef CONFIG_ZISOFS
+-#undef CONFIG_JFS_FS
+-#undef CONFIG_JFS_DEBUG
+-#undef CONFIG_JFS_STATISTICS
+-#undef CONFIG_MINIX_FS
+-#undef CONFIG_VXFS_FS
+-#undef CONFIG_NTFS_FS
+-#undef CONFIG_NTFS_RW
+-#undef CONFIG_HPFS_FS
+-#define CONFIG_PROC_FS 1
+-#undef CONFIG_DEVFS_FS
+-#undef CONFIG_DEVFS_MOUNT
+-#undef CONFIG_DEVFS_DEBUG
+-#define CONFIG_DEVPTS_FS 1
+-#undef CONFIG_QNX4FS_FS
+-#undef CONFIG_QNX4FS_RW
+-#undef CONFIG_ROMFS_FS
+-#define CONFIG_EXT2_FS 1
+-#undef CONFIG_SYSV_FS
+-#undef CONFIG_UDF_FS
+-#undef CONFIG_UDF_RW
+-#undef CONFIG_UFS_FS
+-#undef CONFIG_UFS_FS_WRITE
+-
+-/*
+- * Network File Systems
+- */
+-#undef CONFIG_CODA_FS
+-#undef CONFIG_INTERMEZZO_FS
+-#define CONFIG_NFS_FS 1
+-#define CONFIG_NFS_V3 1
+-#define CONFIG_ROOT_NFS 1
+-#undef CONFIG_NFSD
+-#undef CONFIG_NFSD_V3
+-#undef CONFIG_NFSD_TCP
+-#define CONFIG_SUNRPC 1
+-#define CONFIG_LOCKD 1
+-#define CONFIG_LOCKD_V4 1
+-#undef CONFIG_SMB_FS
+-#undef CONFIG_NCP_FS
+-#undef CONFIG_NCPFS_PACKET_SIGNING
+-#undef CONFIG_NCPFS_IOCTL_LOCKING
+-#undef CONFIG_NCPFS_STRONG
+-#undef CONFIG_NCPFS_NFS_NS
+-#undef CONFIG_NCPFS_OS2_NS
+-#undef CONFIG_NCPFS_SMALLDOS
+-#undef CONFIG_NCPFS_NLS
+-#undef CONFIG_NCPFS_EXTRAS
+-#undef CONFIG_ZISOFS_FS
+-
+-/*
+- * Partition Types
+- */
+-#undef CONFIG_PARTITION_ADVANCED
+-#define CONFIG_MSDOS_PARTITION 1
+-#undef CONFIG_SMB_NLS
+-#undef CONFIG_NLS
+-
+-/*
+- * Console drivers
+- */
+-#define CONFIG_VGA_CONSOLE 1
+-#undef CONFIG_VIDEO_SELECT
+-#undef CONFIG_MDA_CONSOLE
+-
+-/*
+- * Frame-buffer support
+- */
+-#undef CONFIG_FB
+-
+-/*
+- * Sound
+- */
+-#define CONFIG_SOUND 1
+-#undef CONFIG_SOUND_ALI5455
+-#undef CONFIG_SOUND_BT878
+-#undef CONFIG_SOUND_CMPCI
+-#undef CONFIG_SOUND_EMU10K1
+-#undef CONFIG_MIDI_EMU10K1
+-#undef CONFIG_SOUND_FUSION
+-#undef CONFIG_SOUND_CS4281
+-#undef CONFIG_SOUND_ES1370
+-#define CONFIG_SOUND_ES1371 1
+-#undef CONFIG_SOUND_ESSSOLO1
+-#undef CONFIG_SOUND_MAESTRO
+-#undef CONFIG_SOUND_MAESTRO3
+-#undef CONFIG_SOUND_FORTE
+-#undef CONFIG_SOUND_ICH
+-#undef CONFIG_SOUND_RME96XX
+-#undef CONFIG_SOUND_SONICVIBES
+-#undef CONFIG_SOUND_TRIDENT
+-#undef CONFIG_SOUND_MSNDCLAS
+-#undef CONFIG_SOUND_MSNDPIN
+-#undef CONFIG_SOUND_VIA82CXXX
+-#undef CONFIG_MIDI_VIA82CXXX
+-#undef CONFIG_SOUND_OSS
+-#undef CONFIG_SOUND_TVMIXER
+-
+-/*
+- * USB support
+- */
+-#define CONFIG_USB 1
+-#undef CONFIG_USB_DEBUG
+-
+-/*
+- * Miscellaneous USB options
+- */
+-#undef CONFIG_USB_DEVICEFS
+-#undef CONFIG_USB_BANDWIDTH
+-#undef CONFIG_USB_LONG_TIMEOUT
+-
+-/*
+- * USB Host Controller Drivers
+- */
+-#undef CONFIG_USB_EHCI_HCD
+-#define CONFIG_USB_UHCI_ALT 1
+-#undef CONFIG_USB_OHCI
+-
+-/*
+- * USB Device Class drivers
+- */
+-#undef CONFIG_USB_AUDIO
+-#undef CONFIG_USB_EMI26
+-#undef CONFIG_USB_BLUETOOTH
+-#undef CONFIG_USB_MIDI
+-
+-/*
+- * SCSI support is needed for USB Storage
+- */
+-#undef CONFIG_USB_STORAGE
+-#undef CONFIG_USB_STORAGE_DEBUG
+-#undef CONFIG_USB_STORAGE_DATAFAB
+-#undef CONFIG_USB_STORAGE_FREECOM
+-#undef CONFIG_USB_STORAGE_ISD200
+-#undef CONFIG_USB_STORAGE_DPCM
+-#undef CONFIG_USB_STORAGE_HP8200e
+-#undef CONFIG_USB_STORAGE_SDDR09
+-#undef CONFIG_USB_STORAGE_SDDR55
+-#undef CONFIG_USB_STORAGE_JUMPSHOT
+-#undef CONFIG_USB_ACM
+-#undef CONFIG_USB_PRINTER
+-
+-/*
+- * USB Human Interface Devices (HID)
+- */
+-#undef CONFIG_USB_HID
+-
+-/*
+- * Input core support is needed for USB HID input layer or HIDBP support
+- */
+-#undef CONFIG_USB_HIDINPUT
+-#undef CONFIG_USB_HIDDEV
+-#undef CONFIG_USB_KBD
+-#undef CONFIG_USB_MOUSE
+-#undef CONFIG_USB_AIPTEK
+-#undef CONFIG_USB_WACOM
+-
+-/*
+- * USB Imaging devices
+- */
+-#undef CONFIG_USB_DC2XX
+-#undef CONFIG_USB_MDC800
+-#undef CONFIG_USB_SCANNER
+-#undef CONFIG_USB_MICROTEK
+-#undef CONFIG_USB_HPUSBSCSI
+-
+-/*
+- * USB Multimedia devices
+- */
+-
+-/*
+- * Video4Linux support is needed for USB Multimedia device support
+- */
+-
+-/*
+- * USB Network adaptors
+- */
+-#undef CONFIG_USB_PEGASUS
+-#undef CONFIG_USB_RTL8150
+-#undef CONFIG_USB_KAWETH
+-#undef CONFIG_USB_CATC
+-#undef CONFIG_USB_CDCETHER
+-#undef CONFIG_USB_USBNET
+-
+-/*
+- * USB port drivers
+- */
+-#undef CONFIG_USB_USS720
+-
+-/*
+- * USB Serial Converter support
+- */
+-#undef CONFIG_USB_SERIAL
+-
+-/*
+- * USB Miscellaneous drivers
+- */
+-#undef CONFIG_USB_RIO500
+-#undef CONFIG_USB_AUERSWALD
+-#undef CONFIG_USB_TIGL
+-#undef CONFIG_USB_BRLVGER
+-#undef CONFIG_USB_LCD
+-
+-/*
+- * Bluetooth support
+- */
+-#undef CONFIG_BLUEZ
+-
+-/*
+- * Kernel hacking
+- */
+-#define CONFIG_DEBUG_KERNEL 1
+-#undef CONFIG_DEBUG_STACKOVERFLOW
+-#undef CONFIG_DEBUG_HIGHMEM
+-#undef CONFIG_DEBUG_SLAB
+-#undef CONFIG_DEBUG_IOVIRT
+-#undef CONFIG_MAGIC_SYSRQ
+-#undef CONFIG_DEBUG_SPINLOCK
+-#undef CONFIG_FRAME_POINTER
+-
+-/*
+- * Library routines
+- */
+-#undef CONFIG_ZLIB_INFLATE
+-#undef CONFIG_ZLIB_DEFLATE
+diff -urN linux/include/linux/ipmi_imb.h linux-emu/include/linux/ipmi_imb.h
+--- linux/include/linux/ipmi_imb.h Wed Dec 31 18:00:00 1969
++++ linux-emu/include/linux/ipmi_imb.h Fri Jan 10 11:24:14 2003
+@@ -0,0 +1,144 @@
++/*
++ * ipmi_imb.h
++ *
++ * Intels IMB emulation on the MontaVista IPMI interface
++ *
++ * 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.
++ */
++
++#ifndef __LINUX_IPMI_IMB_H
++#define __LINUX_IPMI_IMB_H
++
++typedef struct overlapped_s {
++ unsigned long Internal;
++ unsigned long InternalHigh;
++ unsigned long Offset;
++ unsigned long OffsetHigh;
++} overlapped_t;
++
++struct smi {
++ unsigned long smi_VersionNo;
++ unsigned long smi_Reserved1;
++ unsigned long smi_Reserved2;
++ void *ntstatus; /* address of NT status block*/
++ void *lpvInBuffer; /* address of buffer for input data*/
++ unsigned long cbInBuffer; /* size of input buffer*/
++ void *lpvOutBuffer; /* address of output buffer*/
++ unsigned long cbOutBuffer; /* size of output buffer*/
++ unsigned long *lpcbBytesReturned; /* address of actual bytes of output*/
++ overlapped_t *lpoOverlapped; /* address of overlapped structure*/
++};
++
++
++#define MAX_IMB_PACKET_SIZE 33
++
++typedef struct {
++ unsigned char rsSa;
++ unsigned char cmd;
++ unsigned char netFn;
++ unsigned char rsLun;
++ unsigned char dataLength;
++ unsigned char data[1];
++} ImbRequest;
++
++typedef struct {
++ unsigned long flags;
++#define NO_RESPONSE_EXPECTED 0x01
++
++ unsigned long timeOut;
++ ImbRequest req;
++} ImbRequestBuffer;
++
++#define MIN_IMB_REQ_BUF_SIZE 13
++
++
++typedef struct {
++ unsigned char cCode;
++ unsigned char data[1];
++} ImbResponseBuffer;
++
++#define MIN_IMB_RESP_BUF_SIZE 1 // a buffer without any request data
++#define MAX_IMB_RESP_SIZE (MIN_IMB_RESP_BUF_SIZE + MAX_IMB_RESPONSE_SIZE)
++
++#define MIN_IMB_RESPONSE_SIZE 7
++#define MAX_IMB_RESPONSE_SIZE MAX_IMB_PACKET_SIZE
++
++typedef struct {
++ unsigned long timeOut;
++ unsigned long lastSeq;
++} ImbAsyncRequest;
++
++typedef struct {
++ unsigned long thisSeq;
++ unsigned char data[1];
++} ImbAsyncResponse;
++
++#define MIN_ASYNC_RESP_SIZE sizeof(unsigned long)
++#define MAX_ASYNC_RESP_SIZE (MIN_ASYNC_RESP_SIZE + MAX_IMB_PACKET_SIZE)
++
++#define STATUS_SUCCESS (0x00000000U)
++#define IMB_NO_ASYNC_MSG ((unsigned long)0xE0070012L)
++#define IMB_SEND_REQUEST_FAILED ((unsigned long)0xE0070013L)
++#define INVALID_ARGUMENTS ((unsigned long)0xE0070002L)
++
++
++#define FILE_DEVICE_IMB 0x00008010
++#define IOCTL_IMB_BASE 0x00000880
++
++#define CTL_CODE(DeviceType, Function, Method, Access)\
++ _IO(DeviceType & 0x00FF, Function & 0x00FF)
++
++#define FILE_DEVICE_IMB 0x00008010
++#define IOCTL_IMB_BASE 0x00000880
++#define METHOD_BUFFERED 0
++#define FILE_ANY_ACCESS 0
++
++
++typedef struct {
++ int code;
++#define SD_NO_ACTION 0
++#define SD_RESET 1
++#define SD_POWER_OFF 2
++
++ int delayTime; /* in units of 100 millisecond */
++} ShutdownCmdBuffer;
++
++
++/* BMC added parentheses around IOCTL_IMB_BASE + 2 */
++#define IOCTL_IMB_SEND_MESSAGE CTL_CODE(FILE_DEVICE_IMB, (IOCTL_IMB_BASE + 2), METHOD_BUFFERED, FILE_ANY_ACCESS)
++#define IOCTL_IMB_GET_ASYNC_MSG CTL_CODE(FILE_DEVICE_IMB, (IOCTL_IMB_BASE + 8), METHOD_BUFFERED, FILE_ANY_ACCESS)
++#define IOCTL_IMB_MAP_MEMORY CTL_CODE(FILE_DEVICE_IMB, (IOCTL_IMB_BASE + 14),METHOD_BUFFERED, FILE_ANY_ACCESS)
++#define IOCTL_IMB_UNMAP_MEMORY CTL_CODE(FILE_DEVICE_IMB, (IOCTL_IMB_BASE + 16),METHOD_BUFFERED, FILE_ANY_ACCESS)
++#define IOCTL_IMB_SHUTDOWN_CODE CTL_CODE(FILE_DEVICE_IMB, (IOCTL_IMB_BASE + 18),METHOD_BUFFERED, FILE_ANY_ACCESS)
++#define IOCTL_IMB_REGISTER_ASYNC_OBJ CTL_CODE(FILE_DEVICE_IMB, (IOCTL_IMB_BASE + 24),METHOD_BUFFERED, FILE_ANY_ACCESS)
++#define IOCTL_IMB_DEREGISTER_ASYNC_OBJ CTL_CODE(FILE_DEVICE_IMB, (IOCTL_IMB_BASE + 26),METHOD_BUFFERED, FILE_ANY_ACCESS)
++#define IOCTL_IMB_CHECK_EVENT CTL_CODE(FILE_DEVICE_IMB, (IOCTL_IMB_BASE + 28),METHOD_BUFFERED, FILE_ANY_ACCESS)
++#define IOCTL_IMB_POLL_ASYNC CTL_CODE(FILE_DEVICE_IMB, (IOCTL_IMB_BASE + 20),METHOD_BUFFERED, FILE_ANY_ACCESS)
++
++
++#endif /* __LINUX_IPMI_IMB_H */
+diff -urN linux/include/linux/ipmi_radisys.h linux-emu/include/linux/ipmi_radisys.h
+--- linux/include/linux/ipmi_radisys.h Wed Dec 31 18:00:00 1969
++++ linux-emu/include/linux/ipmi_radisys.h Fri Jan 10 11:24:14 2003
+@@ -0,0 +1,128 @@
++/*
++ * ipmi_radisys.h
++ *
++ * An emulation of the Radisys IPMI interface on top of the MontaVista
++ * interface.
++ *
++ * 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.
++ */
++
++#ifndef __LINUX_IPMI_RADISYS_H
++#define __LINUX_IPMI_RADISYS_H
++
++/******************************************************************************
++ * This is the old IPMI interface defined by Radisys. We are
++ * compliant with that. Don't use it for new designs, though.
++ */
++#define IOCTL_IPMI_RCV ( IPMI_IOC_MAGIC<<8 | 1 )
++#define IOCTL_IPMI_SEND ( IPMI_IOC_MAGIC<<8 | 2 )
++#define IOCTL_IPMI_EVENT ( IPMI_IOC_MAGIC<<8 | 3 )
++#define IOCTL_IPMI_REGISTER ( IPMI_IOC_MAGIC<<8 | 4 )
++#define IOCTL_IPMI_UNREGISTER ( IPMI_IOC_MAGIC<<8 | 5 )
++#define IOCTL_IPMI_CLEAR ( IPMI_IOC_MAGIC<<8 | 9 )
++
++/* These don't seem to be implemented in the Radisys driver.
++#define IOCTL_IPMI_RESET_BMC ( IPMI_IOC_MAGIC<<8 | 6 )
++#define IOCTL_IPMI_GET_BMC_ADDR ( IPMI_IOC_MAGIC<<8 | 7 )
++#define IOCTL_IPMI_SET_BMC_ADDR ( IPMI_IOC_MAGIC<<8 | 8 )
++*/
++
++/*
++ * Network Function Codes
++ */
++#define IPMI_NETFN_CHASSIS 0x00 /* Chassis - 0x00 << 2 */
++#define IPMI_NETFN_CHASSIS_RESP 0x04 /* Chassis - 0x01 << 2 */
++
++#define IPMI_NETFN_BRIDGE 0x08 /* Bridge - 0x02 << 2 */
++#define IPMI_NETFN_BRIDGE_RESP 0x0c /* Bridge - 0x03 << 2 */
++
++#define IPMI_NETFN_SENSOR_EVT 0x10 /* Sensor/Event - 0x04 << 2 */
++#define IPMI_NETFN_SENSOR_EVT_RESP 0x14 /* Sensor/Event - 0x05 << 2 */
++
++#define IPMI_NETFN_APP 0x18 /* Application - 0x06 << 2 */
++#define IPMI_NETFN_APP_RESP 0x1c /* Application - 0x07 << 2 */
++
++#define IPMI_NETFN_FIRMWARE 0x20 /* Firmware - 0x08 << 2 */
++#define IPMI_NETFN_FIRMWARE_RESP 0x24 /* Firmware - 0x09 << 2 */
++
++#define IPMI_NETFN_STORAGE 0x28 /* Storage - 0x0a << 2 */
++#define IPMI_NETFN_STORAGE_RESP 0x2c /* Storage - 0x0b << 2 */
++
++#define IPMI_NETFN_OEM_1 0xC0 /* Storage - 0x30 << 2 */
++#define IPMI_NETFN_OEM_1_RESP 0xC4 /* Storage - 0x31 << 2 */
++
++/* there are 15 other OEM netfn pairs (OEM - 0x30-0x3f) */
++
++typedef struct _IPMI_LIST_ENTRY {
++ struct _IPMI_LIST_ENTRY * volatile Flink;
++ struct _IPMI_LIST_ENTRY * volatile Blink;
++} IPMI_LIST_ENTRY, *PIPMI_LIST_ENTRY;
++
++typedef struct IPMI_semaphore IPMI_KSEMAPHORE;
++typedef struct IPMI_semaphore * IPMI_PKSEMAPHORE;
++
++/* IPMI Address structure */
++typedef struct _IPMI_ADDR {
++ unsigned char uchSlave; /* Slave Address */
++ unsigned char uchLun; /* Logical Unit Number */
++} IPMI_ADDR, *PIPMI_ADDR;
++
++#define IPMI_MAX_MSG_SIZE 36
++
++/* IPMI Message Descriptor structure */
++typedef struct _IPMI_MSGDESC {
++ /************************************/
++ /* Device Driver Specific Elements */
++ /************************************/
++ IPMI_LIST_ENTRY Entry; /* Linked list element */
++ void *pIRPacket; /* Pointer to IRP object */
++ IPMI_PKSEMAPHORE pSema; /* Semaphore Object */
++ long lTimeout; /* Timeout value */
++ /************************************/
++ /* Shared elements */
++ /************************************/
++ unsigned char auchBuffer[IPMI_MAX_MSG_SIZE]; /* Message buffer */
++ unsigned long ulLength; /* Length of message in bytes */
++ int fDefer; /* TRUE - Defer I/O
++ operation, doesn't seem
++ to be used in the
++ Radisys driver. */
++ IPMI_ADDR Dest; /* Destination IPM Address */
++ unsigned char uchNetFn; /* Network Function */
++ unsigned char uchCmd; /* Command */
++ unsigned char uchSeq; /* Sequence Number */
++ unsigned char uchComplete; /* Completion Code */
++} IPMI_MSGDESC, *PIPMI_MSGDESC;
++
++/* Byte return codes for some things. */
++#define LOWLRC_SUCCESS 0x00 /* routine completed successfully */
++#define LOWLRC_ERROR 0xff /* routine did not complete */
++#define LOWLRC_INVALID_PARAMETERS 0xfe /* invalid parameters */
++#define LOWLRC_INVALID_REQUEST_DATA 0xfd /* invalid request data */
++
++#endif /* __LINUX_IPMI_RADISYS_H */