Module Name:    src
Committed By:   mlelstv
Date:           Sat May 18 08:38:00 UTC 2019

Modified Files:
        src/distrib/sets/lists/comp: mi
        src/etc: MAKEDEV.tmpl
        src/sys/conf: majors
        src/sys/dev: ipmi.c ipmivar.h
        src/sys/sys: Makefile
Added Files:
        src/sys/sys: ipmi.h

Log Message:
Add experimental userland interface to IPMI driver. Currently, transactions
(like sensor readout) are locked, so that a userland program may interfere with
envsys operation.

To use this you need a program like ipmitool built with OpenIPMI support.


To generate a diff of this commit:
cvs rdiff -u -r1.2273 -r1.2274 src/distrib/sets/lists/comp/mi
cvs rdiff -u -r1.202 -r1.203 src/etc/MAKEDEV.tmpl
cvs rdiff -u -r1.86 -r1.87 src/sys/conf/majors
cvs rdiff -u -r1.3 -r1.4 src/sys/dev/ipmi.c
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/ipmivar.h
cvs rdiff -u -r1.169 -r1.170 src/sys/sys/Makefile
cvs rdiff -u -r0 -r1.1 src/sys/sys/ipmi.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/sets/lists/comp/mi
diff -u src/distrib/sets/lists/comp/mi:1.2273 src/distrib/sets/lists/comp/mi:1.2274
--- src/distrib/sets/lists/comp/mi:1.2273	Wed May  8 14:25:38 2019
+++ src/distrib/sets/lists/comp/mi	Sat May 18 08:38:00 2019
@@ -1,4 +1,4 @@
-#	$NetBSD: mi,v 1.2273 2019/05/08 14:25:38 isaki Exp $
+#	$NetBSD: mi,v 1.2274 2019/05/18 08:38:00 mlelstv Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 ./etc/mtree/set.comp				comp-sys-root
@@ -3016,6 +3016,7 @@
 ./usr/include/sys/ioctl_compat.h		comp-c-include
 ./usr/include/sys/iostat.h			comp-c-include
 ./usr/include/sys/ipc.h				comp-c-include
+./usr/include/sys/ipmi.h			comp-c-include
 ./usr/include/sys/joystick.h			comp-c-include
 ./usr/include/sys/kcore.h			comp-c-include
 ./usr/include/sys/kcov.h			comp-c-include

Index: src/etc/MAKEDEV.tmpl
diff -u src/etc/MAKEDEV.tmpl:1.202 src/etc/MAKEDEV.tmpl:1.203
--- src/etc/MAKEDEV.tmpl:1.202	Mon Apr  1 13:08:24 2019
+++ src/etc/MAKEDEV.tmpl	Sat May 18 08:38:00 2019
@@ -1,5 +1,5 @@
 #!/bin/sh -
-#	$NetBSD: MAKEDEV.tmpl,v 1.202 2019/04/01 13:08:24 martin Exp $
+#	$NetBSD: MAKEDEV.tmpl,v 1.203 2019/05/18 08:38:00 mlelstv Exp $
 #
 # Copyright (c) 2003,2007,2008 The NetBSD Foundation, Inc.
 # All rights reserved.
@@ -242,6 +242,7 @@
 #	iic*	IIC bus device
 #	io	x86 IOPL access for COMPAT_10, COMPAT_FREEBSD
 #	iop*	I2O IOP control interface
+#	ipmi*	OpenIPMI compatible interface
 #	ipl	IP Filter
 #	irframe* IrDA physical frame
 #	ite*	terminal emulator interface to HP300 graphics devices
@@ -2228,6 +2229,11 @@ kcov)
         mkdev kcov c %kcov_chr% 0
         ;;
 
+ipmi[0-9]*)
+	unit=${i#ipmi}
+	mkdev ipmi${unit} c %ipmi_chr% $unit 600
+	;;
+
 midevend)
 %MI_DEVICES_END%
 local)

Index: src/sys/conf/majors
diff -u src/sys/conf/majors:1.86 src/sys/conf/majors:1.87
--- src/sys/conf/majors:1.86	Sun May  5 17:24:00 2019
+++ src/sys/conf/majors	Sat May 18 08:38:00 2019
@@ -1,4 +1,4 @@
-# $NetBSD: majors,v 1.86 2019/05/05 17:24:00 mlelstv Exp $
+# $NetBSD: majors,v 1.87 2019/05/18 08:38:00 mlelstv Exp $
 #
 # Device majors for Machine-Independent drivers.
 #
@@ -85,4 +85,4 @@ device-major spi       char 347		   spi
 # Major 351 is reserved for sys/modules/examples
 # Major 352 is reserved for external/cddl/osnet/dev/fbt/fbt.c
 # Major 353 is reserved for external/cddl/osnet/dev/sdt/sdt.c
-# Major 354 is reserved for IPMI userland driver
+device-major ipmi      char 354		   ipmi

Index: src/sys/dev/ipmi.c
diff -u src/sys/dev/ipmi.c:1.3 src/sys/dev/ipmi.c:1.4
--- src/sys/dev/ipmi.c:1.3	Fri Dec 28 12:44:15 2018
+++ src/sys/dev/ipmi.c	Sat May 18 08:38:00 2019
@@ -1,6 +1,30 @@
-/*	$NetBSD: ipmi.c,v 1.3 2018/12/28 12:44:15 mlelstv Exp $ */
+/*	$NetBSD: ipmi.c,v 1.4 2019/05/18 08:38:00 mlelstv Exp $ */
 
 /*
+ * Copyright (c) 2019 Michael van Elst
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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.
+ *
+ */
+/*
  * Copyright (c) 2006 Manuel Bouyer.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -52,7 +76,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipmi.c,v 1.3 2018/12/28 12:44:15 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipmi.c,v 1.4 2019/05/18 08:38:00 mlelstv Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -66,14 +90,42 @@ __KERNEL_RCSID(0, "$NetBSD: ipmi.c,v 1.3
 #include <sys/kthread.h>
 #include <sys/bus.h>
 #include <sys/intr.h>
+#include <sys/ioctl.h>
+#include <sys/poll.h>
+#include <sys/conf.h>
 
 #include <dev/isa/isareg.h>
 #include <dev/isa/isavar.h>
 
+#include <sys/ipmi.h>
 #include <dev/ipmivar.h>
 
 #include <uvm/uvm_extern.h>
 
+#include "ioconf.h"
+
+static dev_type_open(ipmi_open);
+static dev_type_close(ipmi_close);
+static dev_type_ioctl(ipmi_ioctl);
+static dev_type_poll(ipmi_poll);
+
+const struct cdevsw ipmi_cdevsw = {
+	.d_open = ipmi_open,
+	.d_close = ipmi_close,
+	.d_read = noread,
+	.d_write = nowrite,
+	.d_ioctl = ipmi_ioctl,
+	.d_stop = nostop,
+	.d_tty = notty,
+	.d_poll = ipmi_poll,
+	.d_mmap = nommap,
+	.d_kqfilter = nokqfilter,
+	.d_discard = nodiscard,
+	.d_flag = D_OTHER
+};
+
+#define IPMIUNIT(n) (minor(n))
+
 struct ipmi_sensor {
 	uint8_t	*i_sdr;
 	int		i_num;
@@ -344,6 +396,8 @@ bmc_io_wait_spin(struct ipmi_softc *sc, 
 }
 
 #define NETFN_LUN(nf,ln) (((nf) << 2) | ((ln) & 0x3))
+#define GET_NETFN(m) (((m) >> 2)
+#define GET_LUN(m) ((m) & 0x03)
 
 /*
  * BT interface
@@ -1014,7 +1068,7 @@ ipmi_recvcmd(struct ipmi_softc *sc, int 
 		return -1;
 	}
 
-	*rxlen = rawlen - IPMI_MSG_DATARCV;
+	*rxlen = rawlen >= IPMI_MSG_DATARCV ? rawlen - IPMI_MSG_DATARCV : 0;
 	if (*rxlen > 0 && data)
 		memcpy(data, buf + IPMI_MSG_DATARCV, *rxlen);
 
@@ -2037,13 +2091,20 @@ ipmi_thread(void *cookie)
 
 	mutex_enter(&sc->sc_poll_mtx);
 	while (sc->sc_thread_running) {
-		ipmi_refresh_sensors(sc);
-		cv_timedwait(&sc->sc_poll_cv, &sc->sc_poll_mtx,
-		    SENSOR_REFRESH_RATE);
+		while (sc->sc_mode == IPMI_MODE_COMMAND)
+			cv_wait(&sc->sc_mode_cv, &sc->sc_poll_mtx);
+		sc->sc_mode = IPMI_MODE_ENVSYS;
+
 		if (sc->sc_tickle_due) {
 			ipmi_dotickle(sc);
 			sc->sc_tickle_due = false;
 		}
+		ipmi_refresh_sensors(sc);
+
+		sc->sc_mode = IPMI_MODE_IDLE;
+		cv_broadcast(&sc->sc_mode_cv);
+		cv_timedwait(&sc->sc_poll_cv, &sc->sc_poll_mtx,
+		    SENSOR_REFRESH_RATE);
 	}
 	mutex_exit(&sc->sc_poll_mtx);
 	self->dv_flags &= ~DVF_ATTACH_INPROGRESS;
@@ -2067,6 +2128,7 @@ ipmi_attach(device_t parent, device_t se
 
 	mutex_init(&sc->sc_poll_mtx, MUTEX_DEFAULT, IPL_SOFTCLOCK);
 	cv_init(&sc->sc_poll_cv, "ipmipoll");
+	cv_init(&sc->sc_mode_cv, "ipmimode");
 
 	if (kthread_create(PRI_NONE, 0, NULL, ipmi_thread, self,
 	    &sc->sc_kthread, "%s", device_xname(self)) != 0) {
@@ -2121,6 +2183,7 @@ ipmi_detach(device_t self, int flags)
 
 	ipmi_unmap_regs(sc);
 
+	cv_destroy(&sc->sc_mode_cv);
 	cv_destroy(&sc->sc_poll_cv);
 	mutex_destroy(&sc->sc_poll_mtx);
 	cv_destroy(&sc->sc_cmd_sleep);
@@ -2247,3 +2310,208 @@ ipmi_suspend(device_t dev, const pmf_qua
 		return false;
 	return true;
 }
+
+static int
+ipmi_open(dev_t dev, int flag, int fmt, lwp_t *l)
+{
+	return 0;
+}
+
+static int
+ipmi_close(dev_t dev, int flag, int fmt, lwp_t *l)
+{
+	struct ipmi_softc *sc;
+	int unit;
+
+	unit = IPMIUNIT(dev);
+	if ((sc = device_lookup_private(&ipmi_cd, unit)) == NULL)
+		return (ENXIO);
+
+	mutex_enter(&sc->sc_poll_mtx);
+	if (sc->sc_mode == IPMI_MODE_COMMAND) {
+		sc->sc_mode = IPMI_MODE_IDLE;
+		cv_broadcast(&sc->sc_mode_cv);
+	}
+	mutex_exit(&sc->sc_poll_mtx);
+	return 0;
+}
+
+static int
+ipmi_ioctl(dev_t dev, u_long cmd, void *data, int flag, lwp_t *l)
+{
+	struct ipmi_softc *sc;
+	int unit, error = 0, len;
+	struct ipmi_req *req;
+	struct ipmi_recv *recv;
+	struct ipmi_addr addr;
+	unsigned char ccode, *buf = NULL;
+
+	unit = IPMIUNIT(dev);
+	if ((sc = device_lookup_private(&ipmi_cd, unit)) == NULL)
+		return (ENXIO);
+
+	switch (cmd) {
+	case IPMICTL_SEND_COMMAND:
+		mutex_enter(&sc->sc_poll_mtx);
+		while (sc->sc_mode == IPMI_MODE_ENVSYS) {
+			error = cv_wait_sig(&sc->sc_mode_cv, &sc->sc_poll_mtx);
+			if (error == EINTR) {
+				mutex_exit(&sc->sc_poll_mtx);
+				return error;
+			}
+		}
+		sc->sc_mode = IPMI_MODE_COMMAND;
+		mutex_exit(&sc->sc_poll_mtx);
+		break;
+	}
+
+	mutex_enter(&sc->sc_cmd_mtx);
+
+	switch (cmd) {
+	case IPMICTL_SEND_COMMAND:
+		req = data;
+		buf = malloc(IPMI_MAX_RX, M_DEVBUF, M_WAITOK);
+
+		len = req->msg.data_len;
+		if (len < 0 || len > IPMI_MAX_RX) {
+			error = EINVAL;
+			break;
+		}
+
+		/* clear pending result */
+		if (sc->sc_sent)
+			(void)ipmi_recvcmd(sc, IPMI_MAX_RX, &len, buf);
+
+		/* XXX */
+		error = copyin(req->addr, &addr, sizeof(addr));
+		if (error)
+			break;
+
+		error = copyin(req->msg.data, buf, len);
+		if (error)
+			break;
+
+		/* save for receive */
+		sc->sc_msgid = req->msgid;
+		sc->sc_netfn = req->msg.netfn;
+		sc->sc_cmd = req->msg.cmd;
+
+		if (ipmi_sendcmd(sc, BMC_SA, 0, req->msg.netfn,
+		    req->msg.cmd, len, buf)) {
+			error = EIO;
+			break;
+		}
+		sc->sc_sent = true;
+		break;
+	case IPMICTL_RECEIVE_MSG_TRUNC:
+	case IPMICTL_RECEIVE_MSG:
+		recv = data;
+		buf = malloc(IPMI_MAX_RX, M_DEVBUF, M_WAITOK);
+
+		if (recv->msg.data_len < 1) {
+			error = EINVAL;
+			break;
+		}
+
+		/* XXX */
+		error = copyin(recv->addr, &addr, sizeof(addr));
+		if (error)
+			break;
+
+
+		if (!sc->sc_sent) {
+			error = EIO;
+			break;
+		}
+
+		len = 0;
+		error = ipmi_recvcmd(sc, IPMI_MAX_RX, &len, buf);
+		if (error < 0) {
+			error = EIO;
+			break;
+		}
+		ccode = (unsigned char)error;
+		sc->sc_sent = false;
+
+		if (len > recv->msg.data_len - 1) {
+			if (cmd == IPMICTL_RECEIVE_MSG) {
+				error = EMSGSIZE;
+				break;
+			}
+			len = recv->msg.data_len - 1;
+		}
+
+		addr.channel = IPMI_BMC_CHANNEL;
+
+		recv->recv_type = IPMI_RESPONSE_RECV_TYPE;
+		recv->msgid = sc->sc_msgid;
+		recv->msg.netfn = sc->sc_netfn;
+		recv->msg.cmd = sc->sc_cmd;
+		recv->msg.data_len = len+1;
+
+		error = copyout(&addr, recv->addr, sizeof(addr));
+		if (error == 0)
+			error = copyout(&ccode, recv->msg.data, 1);
+		if (error == 0)
+			error = copyout(buf, recv->msg.data+1, len);
+		break;
+	case IPMICTL_SET_MY_ADDRESS_CMD:
+		sc->sc_address = *(int *)data;
+		break;
+	case IPMICTL_GET_MY_ADDRESS_CMD:
+		*(int *)data = sc->sc_address;
+		break;
+	case IPMICTL_SET_MY_LUN_CMD:
+		sc->sc_lun = *(int *)data & 0x3;
+		break;
+	case IPMICTL_GET_MY_LUN_CMD:
+		*(int *)data = sc->sc_lun;
+		break;
+	case IPMICTL_SET_GETS_EVENTS_CMD:
+		break;
+	case IPMICTL_REGISTER_FOR_CMD:
+	case IPMICTL_UNREGISTER_FOR_CMD:
+		error = EOPNOTSUPP;
+		break;
+	default:
+		error = ENODEV;	
+		break;
+	}
+
+	if (buf)
+		free(buf, M_DEVBUF);
+
+	mutex_exit(&sc->sc_cmd_mtx);
+
+	switch (cmd) {
+	case IPMICTL_RECEIVE_MSG:
+	case IPMICTL_RECEIVE_MSG_TRUNC:
+		mutex_enter(&sc->sc_poll_mtx);
+		sc->sc_mode = IPMI_MODE_IDLE;
+		cv_broadcast(&sc->sc_mode_cv);
+		mutex_exit(&sc->sc_poll_mtx);
+		break;
+	}
+
+	return error;
+}
+
+static int
+ipmi_poll(dev_t dev, int events, lwp_t *l)
+{
+	struct ipmi_softc *sc;
+	int unit, revents = 0;
+
+	unit = IPMIUNIT(dev);
+	if ((sc = device_lookup_private(&ipmi_cd, unit)) == NULL)
+		return (ENXIO);
+
+	mutex_enter(&sc->sc_cmd_mtx);
+	if (events & (POLLIN | POLLRDNORM)) {
+		if (sc->sc_sent)
+			revents |= events & (POLLIN | POLLRDNORM);
+	}
+	mutex_exit(&sc->sc_cmd_mtx);
+
+	return revents;
+}

Index: src/sys/dev/ipmivar.h
diff -u src/sys/dev/ipmivar.h:1.2 src/sys/dev/ipmivar.h:1.3
--- src/sys/dev/ipmivar.h:1.2	Fri Dec 28 12:44:15 2018
+++ src/sys/dev/ipmivar.h	Sat May 18 08:38:00 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: ipmivar.h,v 1.2 2018/12/28 12:44:15 mlelstv Exp $ */
+/* $NetBSD: ipmivar.h,v 1.3 2019/05/18 08:38:00 mlelstv Exp $ */
 
 /*
  * Copyright (c) 2005 Jordan Hargrave
@@ -92,6 +92,7 @@ struct ipmi_softc {
 
 	kmutex_t		sc_poll_mtx;
 	kcondvar_t		sc_poll_cv;
+	kcondvar_t		sc_mode_cv;
 
 	kmutex_t		sc_cmd_mtx;
 	kmutex_t		sc_sleep_mtx;
@@ -107,8 +108,24 @@ struct ipmi_softc {
 	envsys_data_t		*sc_sensor;
 	int 		sc_nsensors; /* total number of sensors */
 
-	char		sc_buf[64];
+	char		sc_buf[1024 + 3]; /* IPMI_MAX_RX + 3 */
 	bool		sc_buf_rsvd;
+
+	/* request busy */
+	int		sc_mode;
+#define IPMI_MODE_IDLE		0
+#define IPMI_MODE_COMMAND	1
+#define IPMI_MODE_ENVSYS	2
+	bool		sc_sent;
+
+	/* dummy */
+	int		sc_address;
+	int		sc_lun;
+
+	/* saved from last SEND_COMMAND */
+	int		sc_msgid;
+	int		sc_netfn;
+	int		sc_cmd;
 };
 
 struct ipmi_device_id {

Index: src/sys/sys/Makefile
diff -u src/sys/sys/Makefile:1.169 src/sys/sys/Makefile:1.170
--- src/sys/sys/Makefile:1.169	Sat Feb 23 03:10:06 2019
+++ src/sys/sys/Makefile	Sat May 18 08:38:00 2019
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.169 2019/02/23 03:10:06 kamil Exp $
+#	$NetBSD: Makefile,v 1.170 2019/05/18 08:38:00 mlelstv Exp $
 
 .include <bsd.own.mk>
 
@@ -23,7 +23,7 @@ INCS=	acct.h agpio.h aio.h ansi.h aout_m
 	fcntl.h fd_set.h fdio.h featuretest.h file.h filedesc.h filio.h \
 	flashio.h float_ieee754.h fstypes.h gcq.h gmon.h gpio.h hash.h \
 	idtype.h ieee754.h intr.h intrio.h inttypes.h ioccom.h ioctl.h \
-	ioctl_compat.h iostat.h ipc.h \
+	ioctl_compat.h iostat.h ipc.h ipmi.h \
 	joystick.h \
 	kcore.h kcov.h kcpuset.h kgdb.h kmem.h ksem.h ksyms.h ktrace.h \
 	localcount.h localedef.h lock.h lockf.h lua.h lwp.h lwpctl.h \

Added files:

Index: src/sys/sys/ipmi.h
diff -u /dev/null src/sys/sys/ipmi.h:1.1
--- /dev/null	Sat May 18 08:38:01 2019
+++ src/sys/sys/ipmi.h	Sat May 18 08:38:00 2019
@@ -0,0 +1,105 @@
+/*	$NetBSD: ipmi.h,v 1.1 2019/05/18 08:38:00 mlelstv Exp $	*/
+
+/*-
+ * Copyright (c) 2019 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Michael van Elst
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 FOUNDATION OR CONTRIBUTORS
+ * 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.
+ */
+
+#ifndef _SYS_IPMI_H_
+#define	_SYS_IPMI_H_
+
+#define	IPMI_MAX_ADDR_SIZE		0x20
+#define IPMI_MAX_RX			1024
+#define	IPMI_BMC_SLAVE_ADDR		0x20
+#define	IPMI_BMC_CHANNEL		0x0f
+#define	IPMI_BMC_SMS_LUN		0x02
+
+#define IPMI_SYSTEM_INTERFACE_ADDR_TYPE	0x0c
+#define IPMI_IPMB_ADDR_TYPE		0x01
+#define IPMI_IPMB_BROADCAST_ADDR_TYPE	0x41
+
+struct ipmi_msg {
+	unsigned char	netfn;
+	unsigned char	cmd;
+	unsigned short	data_len;
+	unsigned char	*data;
+};
+
+struct ipmi_req {
+	unsigned char	*addr;
+	unsigned int	addr_len;
+	long		msgid;
+	struct ipmi_msg msg;
+};
+
+struct ipmi_recv {
+	int		recv_type;
+#define IPMI_RESPONSE_RECV_TYPE		1
+#define IPMI_ASYNC_EVENT_RECV_TYPE	2
+#define IPMI_CMD_RECV_TYPE		3
+	unsigned char	*addr;
+	unsigned int	addr_len;
+	long		msgid;
+	struct ipmi_msg msg;
+};
+
+struct ipmi_cmdspec {
+	unsigned char	netfn;
+	unsigned char	cmd;
+};
+
+struct ipmi_addr {
+	int		addr_type;
+	short		channel;
+	unsigned char	data[IPMI_MAX_ADDR_SIZE];
+};
+
+struct ipmi_system_interface_addr {
+	int		addr_type;
+	short		channel;
+	unsigned char	lun;
+};
+
+struct ipmi_ipmb_addr {
+	int		addr_type;
+	short		channel;
+	unsigned char	slave_addr;
+	unsigned char	lun;
+};
+
+#define IPMICTL_RECEIVE_MSG_TRUNC       _IOWR('i', 11, struct ipmi_recv)
+#define IPMICTL_RECEIVE_MSG             _IOWR('i', 12, struct ipmi_recv)
+#define IPMICTL_SEND_COMMAND            _IOW('i', 13, struct ipmi_req)
+#define IPMICTL_REGISTER_FOR_CMD        _IOW('i', 14, struct ipmi_cmdspec)
+#define IPMICTL_UNREGISTER_FOR_CMD      _IOW('i', 15, struct ipmi_cmdspec)
+#define IPMICTL_SET_GETS_EVENTS_CMD     _IOW('i', 16, int)
+#define IPMICTL_SET_MY_ADDRESS_CMD      _IOW('i', 17, unsigned int)
+#define IPMICTL_GET_MY_ADDRESS_CMD      _IOR('i', 18, unsigned int)
+#define IPMICTL_SET_MY_LUN_CMD          _IOW('i', 19, unsigned int) 
+#define IPMICTL_GET_MY_LUN_CMD          _IOR('i', 20, unsigned int)
+
+#endif /* !_SYS_IPMI_H_ */

Reply via email to