[Openipmi-developer] [PATCH v4 1/1] Support IPMB
Brought to you by:
cminyard
|
From: Asmaa M. <As...@me...> - 2019-07-27 00:44:47
|
Support receiving IPMB request on Satellite MC. The Satellite
MC uses this code to handle the incoming IPMB request,
generate a response and send it back to the requester.
For instance, if it is an IPMB bridged request, a BMC will be
fowarding the request message to the responder device
(satellite MC for example), so this code would be supported
on the responder device, which will generate a response and send
it back to the BMC.
Signed-off-by: Asmaa Mnebhi <As...@me...>
---
lanserv/Makefile.am | 2 +-
lanserv/OpenIPMI/Makefile.am | 2 +-
lanserv/OpenIPMI/ipmbserv.h | 62 +++++++++++
lanserv/OpenIPMI/serv.h | 6 +
lanserv/README.design | 6 +-
lanserv/bmc.c | 4 +
lanserv/config.c | 3 +
lanserv/ipmb_ipmi.c | 256 +++++++++++++++++++++++++++++++++++++++++++
lanserv/ipmi_sim.c | 86 +++++++++++++++
lanserv/lan.conf | 13 +++
10 files changed, 437 insertions(+), 3 deletions(-)
create mode 100644 lanserv/OpenIPMI/ipmbserv.h
create mode 100644 lanserv/ipmb_ipmi.c
diff --git a/lanserv/Makefile.am b/lanserv/Makefile.am
index 265b74a..659e957 100644
--- a/lanserv/Makefile.am
+++ b/lanserv/Makefile.am
@@ -34,7 +34,7 @@ noinst_HEADERS = emu.h bmc.h
libIPMIlanserv_la_SOURCES = lanserv_ipmi.c lanserv_asf.c priv_table.c \
lanserv_oem_force.c lanserv_config.c config.c serv.c serial_ipmi.c \
- persist.c extcmd.c
+ persist.c extcmd.c ipmb_ipmi.c
libIPMIlanserv_la_LIBADD = $(OPENSSLLIBS) -ldl $(RT_LIB)
libIPMIlanserv_la_LDFLAGS = -version-info $(LD_VERSION) \
../utils/libOpenIPMIutils.la
diff --git a/lanserv/OpenIPMI/Makefile.am b/lanserv/OpenIPMI/Makefile.am
index ab1e514..7c17c10 100644
--- a/lanserv/OpenIPMI/Makefile.am
+++ b/lanserv/OpenIPMI/Makefile.am
@@ -1,3 +1,3 @@
pkginclude_HEADERS = lanserv.h serserv.h serv.h extcmd.h persist.h msg.h \
- mcserv.h
+ mcserv.h ipmbserv.h
diff --git a/lanserv/OpenIPMI/ipmbserv.h b/lanserv/OpenIPMI/ipmbserv.h
new file mode 100644
index 0000000..938ace3
--- /dev/null
+++ b/lanserv/OpenIPMI/ipmbserv.h
@@ -0,0 +1,62 @@
+/*
+ * ipmbserv.h
+ *
+ * IPMB server include file
+ *
+ * Copyright 2019 Mellanox
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * Lesser General Public License (GPL) Version 2 or the modified BSD
+ * license below. The following disclamer applies to both licenses:
+ *
+ * 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.
+ *
+ * GNU Lesser General Public Licence
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Modified BSD Licence
+ *
+ * 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.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ */
+
+#ifndef __IPMBSERV_H
+#define __IPMBSERV_H
+
+#include <OpenIPMI/msg.h>
+#include <OpenIPMI/serserv.h>
+
+typedef struct serserv_data_s ipmbserv_data_t;
+
+int ipmb_read_config(char **tokptr, sys_data_t *sys, const char **errstr);
+
+#endif /* __IPMBSERV_H */
diff --git a/lanserv/OpenIPMI/serv.h b/lanserv/OpenIPMI/serv.h
index d2087f5..3d40060 100644
--- a/lanserv/OpenIPMI/serv.h
+++ b/lanserv/OpenIPMI/serv.h
@@ -219,6 +219,9 @@ struct channel_s
*/
int (*oem_intf_recv_handler)(channel_t *chan, msg_t *msg,
unsigned char *rdata, unsigned int *rdata_len);
+
+ /* Set to 1 if ipmb channel 0 is listed in the config file, 0 otherwise */
+ int prim_ipmb_in_cfg_file;
};
struct user_s
@@ -408,6 +411,9 @@ struct sys_data_s {
void (*cfree)(channel_t *chan, void *data);
int (*lan_channel_init)(void *info, channel_t *chan);
int (*ser_channel_init)(void *info, channel_t *chan);
+ int (*ipmb_channel_init)(void *info, channel_t *chan);
+
+ char ipmidev[15];
};
static inline void
diff --git a/lanserv/README.design b/lanserv/README.design
index 2f897c4..5260a6c 100644
--- a/lanserv/README.design
+++ b/lanserv/README.design
@@ -31,6 +31,8 @@ msg.h - This defines an IPMI message that is passed around, and a few
serserv.h - The configuration of a serial interface.
+ipmbserv.h - The configuration of an IPMB interface.
+
serv.h - This defines data structures used by the whole system.
@@ -77,6 +79,8 @@ emu.h - Defines the interface between bmc_xxx.c and emu_cmd.c
extcmd.c - Code for running the external command for dealing with LAN
configuration.
+ipmb_ipmi.c - An implementation of the IPMB protocol.
+
ipmi_sim.c - The main file for the ipmi_sim program.
lanserv_asf.c - Handles LAN ASF commands.
@@ -179,4 +183,4 @@ It is called from config.c to handle sol-specific configuration.
It installs a hook into lanserv_ipmi.c to receive the SOL payload and
send the SOL payload.
-It ties into bmc.c to handle SOL-specific commands.
\ No newline at end of file
+It ties into bmc.c to handle SOL-specific commands.
diff --git a/lanserv/bmc.c b/lanserv/bmc.c
index 93d0b3f..264b4ae 100644
--- a/lanserv/bmc.c
+++ b/lanserv/bmc.c
@@ -613,6 +613,9 @@ ipmi_mc_enable(lmc_data_t *mc)
err = sys->lan_channel_init(sys->info, chan);
else if (chan->medium_type == IPMI_CHANNEL_MEDIUM_RS232)
err = sys->ser_channel_init(sys->info, chan);
+ else if ((chan->medium_type == IPMI_CHANNEL_MEDIUM_IPMB) &&
+ ((chan->channel_num != 0) || (chan->prim_ipmb_in_cfg_file)))
+ err = sys->ipmb_channel_init(sys->info, chan);
else
chan_init(chan);
if (err) {
@@ -802,6 +805,7 @@ ipmi_mc_alloc_unconfigured(sys_data_t *sys, unsigned char ipmb,
mc->ipmb_channel.protocol_type = IPMI_CHANNEL_PROTOCOL_IPMB;
mc->ipmb_channel.session_support = IPMI_CHANNEL_SESSION_LESS;
mc->ipmb_channel.active_sessions = 0;
+ mc->ipmb_channel.prim_ipmb_in_cfg_file = 0;
mc->channels[0] = &mc->ipmb_channel;
mc->channels[0]->log = sys->clog;
diff --git a/lanserv/config.c b/lanserv/config.c
index f0dda9f..976f8f2 100644
--- a/lanserv/config.c
+++ b/lanserv/config.c
@@ -64,6 +64,7 @@
#include <OpenIPMI/serv.h>
#include <OpenIPMI/lanserv.h>
#include <OpenIPMI/serserv.h>
+#include <OpenIPMI/ipmbserv.h>
#include <OpenIPMI/persist.h>
void
@@ -829,6 +830,8 @@ read_config(sys_data_t *sys,
}
} else if (strcmp(tok, "user") == 0) {
err = get_user(&tokptr, sys, &errstr);
+ } else if (strcmp(tok, "ipmb") == 0) {
+ err = ipmb_read_config(&tokptr, sys, &errstr);
} else if (strcmp(tok, "serial") == 0) {
err = serserv_read_config(&tokptr, sys, &errstr);
} else if (strcmp(tok, "sol") == 0) {
diff --git a/lanserv/ipmb_ipmi.c b/lanserv/ipmb_ipmi.c
new file mode 100644
index 0000000..16914aa
--- /dev/null
+++ b/lanserv/ipmb_ipmi.c
@@ -0,0 +1,256 @@
+/*
+ * ipmb_ipmi.c
+ *
+ * IPMB server interface.
+ *
+ * Copyright 2019 Mellanox
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * Lesser General Public License (GPL) Version 2 or the modified BSD
+ * license below. The following disclamer applies to both licenses:
+ *
+ * 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.
+ *
+ * GNU Lesser General Public Licence
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Modified BSD Licence
+ *
+ * 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.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <OpenIPMI/serv.h>
+#include <OpenIPMI/ipmbserv.h>
+#include <OpenIPMI/ipmi_mc.h>
+
+#define IPMIDEV_MAX_SIZE 15
+
+static void
+raw_send(ipmbserv_data_t *ipmb, unsigned char *data, unsigned int len)
+{
+ if (ipmb->sysinfo->debug & DEBUG_RAW_MSG)
+ debug_log_raw_msg(ipmb->sysinfo, data, len, "Raw serial send:");
+ ipmb->send_out(ipmb, data, len);
+}
+
+/***********************************************************************
+ *
+ * IPMB message
+ *
+ * According to the IPMI spec, the IPMB message size should never
+ * exceed 32 bytes. So it doesn't harm to set the max size of the
+ * recv_msg to 36 bytes.
+ *
+ ***********************************************************************/
+struct ipmb_data {
+ unsigned char recv_msg[IPMI_SIM_MAX_MSG_LENGTH + 4];
+ unsigned int recv_msg_len;
+ int recv_msg_too_many;
+};
+
+static void
+ipmb_handle_msg(unsigned char *imsg, unsigned int len, ipmbserv_data_t *ipmb)
+{
+ msg_t msg;
+
+ if (len < 8) {
+ fprintf(stderr, "Message too short\n");
+ return;
+ }
+ /* subtract len field and checksum */
+ len--;
+ imsg++;
+
+ if (ipmb_checksum(imsg, len, 0) != 0) {
+ fprintf(stderr, "Message checksum failure\n");
+ return;
+ }
+ len--;
+
+ memset(&msg, 0, sizeof(msg));
+
+ msg.rs_addr = imsg[0];
+ msg.netfn = imsg[1] >> 2;
+ msg.rs_lun = imsg[1] & 3;
+ /* imsg[2] is first checksum */
+ msg.rq_addr = imsg[3];
+ msg.rq_seq = imsg[4] >> 2;
+ msg.rq_lun = imsg[4] & 3;
+ msg.cmd = imsg[5];
+
+ msg.len = len - 6;
+ msg.data = imsg + 6;
+
+ msg.src_addr = NULL;
+ msg.src_len = 0;
+
+ channel_smi_send(&ipmb->channel, &msg);
+}
+
+static void
+ipmb_handle_char(unsigned char ch, ipmbserv_data_t *ipmb)
+{
+ struct ipmb_data *info = ipmb->codec_info;
+ unsigned int len = info->recv_msg_len;
+
+ if (ipmb->bind_fd == 0) {
+ if (info->recv_msg_len != 0) {
+ ipmb_handle_msg(info->recv_msg, info->recv_msg_len, ipmb);
+ info->recv_msg_len = 0;
+ }
+ return;
+ }
+
+ if (len >= sizeof(info->recv_msg))
+ return;
+
+ info->recv_msg[len] = ch;
+ info->recv_msg_len++;
+}
+
+static void
+ipmb_send(msg_t *imsg, ipmbserv_data_t *ipmb)
+{
+ unsigned char msg[(IPMI_SIM_MAX_MSG_LENGTH + 7) * 3];
+ unsigned int msg_len;
+
+ msg[0] = imsg->len + 7;
+ msg[1] = imsg->rs_addr;
+ msg[2] = (imsg->netfn << 2) | imsg->rs_lun;
+ msg[3] = -ipmb_checksum(msg + 1, 2, 0);
+ msg[4] = imsg->rq_addr;
+ msg[5] = (imsg->rq_seq << 2) | imsg->rq_lun;
+ msg[6] = imsg->cmd;
+ memcpy(msg + 7, imsg->data, imsg->len);
+ msg_len = imsg->len + 7;
+ msg[msg_len] = -ipmb_checksum(msg + 4, msg_len - 4, 0);
+ msg_len++;
+
+ raw_send(ipmb, msg, msg_len);
+}
+
+static int
+ipmb_setup(ipmbserv_data_t *ipmb)
+{
+ struct ipmb_data *info;
+
+ info = malloc(sizeof(*info));
+ if (!info)
+ return -1;
+ memset(info, 0, sizeof(*info));
+ ipmb->codec_info = info;
+ ipmb->connected = 1;
+ return 0;
+}
+
+int
+ipmb_read_config(char **tokptr, sys_data_t *sys, const char **errstr)
+{
+ ipmbserv_data_t *ipmb;
+ unsigned int chan_num;
+ int err;
+ const char *tok;
+
+ err = get_uint(tokptr, &chan_num, errstr);
+ if (!err && (chan_num >= IPMI_MAX_CHANNELS)) {
+ return -1;
+ }
+
+ /*
+ * Primary IPMB associated with channel 0 was already
+ * initialized in ipmi_mc_alloc_unconfigured.
+ * So skip the check for channel already in use if
+ * ipmb is listed in the config file (lan.conf).
+ */
+ if (chan_num != 0) {
+ if (sys->chan_set[chan_num] != NULL) {
+ *errstr = "Channel already in use";
+ return -1;
+ }
+ }
+
+ tok = mystrtok(NULL, " \t\n", tokptr);
+ if (!tok || strcmp(tok, "ipmb_dev_int")) {
+ *errstr = "Config file missing <linux ipmb driver name>";
+ return -1;
+ }
+
+ tok = mystrtok(NULL, " \t\n", tokptr);
+ if (strlen(tok) > IPMIDEV_MAX_SIZE) {
+ *errstr = "Length of device file name %s > 15";
+ return -1;
+ }
+
+ strcpy(sys->ipmidev, tok);
+ if (!(sys->ipmidev)) {
+ *errstr = "Unable to set ipmidev";
+ return -1;
+ }
+
+ ipmb = malloc(sizeof(*ipmb));
+ if (!ipmb) {
+ *errstr = "Out of memory";
+ return -1;
+ }
+ memset(ipmb, 0, sizeof(*ipmb));
+
+ ipmb->codec = (ser_codec_t *)malloc(sizeof(ser_codec_t));
+ if (!ipmb->codec) {
+ *errstr = "Out of memory";
+ return -1;
+ }
+
+ ipmb->channel.session_support = IPMI_CHANNEL_SESSION_LESS;
+ ipmb->channel.medium_type = IPMI_CHANNEL_MEDIUM_IPMB;
+ ipmb->channel.protocol_type = IPMI_CHANNEL_PROTOCOL_IPMB;
+
+ ipmb->channel.channel_num = chan_num;
+
+ ipmb->codec->handle_char = ipmb_handle_char;
+ ipmb->codec->send = ipmb_send;
+ ipmb->codec->setup = ipmb_setup;
+
+ ipmb->sysinfo = sys;
+ ipmb->channel.chan_info = ipmb;
+
+ if (chan_num == 0)
+ ipmb->channel.prim_ipmb_in_cfg_file = 1;
+ else
+ ipmb->channel.prim_ipmb_in_cfg_file = 0;
+
+ sys->chan_set[chan_num] = &ipmb->channel;
+
+ return 0;
+}
diff --git a/lanserv/ipmi_sim.c b/lanserv/ipmi_sim.c
index c4e5b18..0a20e22 100644
--- a/lanserv/ipmi_sim.c
+++ b/lanserv/ipmi_sim.c
@@ -90,6 +90,7 @@
#include <OpenIPMI/serv.h>
#include <OpenIPMI/lanserv.h>
#include <OpenIPMI/serserv.h>
+#include <OpenIPMI/ipmbserv.h>
#include "emu.h"
#include <OpenIPMI/persist.h>
@@ -103,6 +104,7 @@ static char *command_string = NULL;
static char *command_file = NULL;
static int debug = 0;
static int nostdio = 0;
+static char g_ipmi_dev[15];
/*
* Keep track of open sockets so we can close them on exec().
@@ -567,6 +569,86 @@ ser_channel_init(void *info, channel_t *chan)
return err;
}
+static int
+ipmb_open(char *ipmi_dev)
+{
+ int ipmi_fd;
+
+ if (!ipmi_dev) {
+ fprintf(stderr, "ipmi_dev is not specified\n");
+ return -1;
+ }
+
+ ipmi_fd = open(ipmi_dev, O_RDWR);
+ if (ipmi_fd == -1)
+ fprintf(stderr, "Could not open ipmi device\n");
+
+ return ipmi_fd;
+}
+
+static void
+ipmb_data_ready(int fd, void *cb_data, os_hnd_fd_id_t *id)
+{
+ ipmbserv_data_t *ipmb = cb_data;
+ unsigned int len;
+ unsigned char msgd[256];
+
+ len = read(fd, msgd, sizeof(msgd));
+
+ if (ipmb->sysinfo->debug & DEBUG_MSG)
+ printf(">ipmb_data_ready size %d\n", len);
+ if (len <= 0) {
+ if ((len < 0) && (errno == EINTR))
+ return;
+
+ ipmb->os_hnd->remove_fd_to_wait_for(ipmb->os_hnd, id);
+ close(fd);
+ ipmb->con_fd = -1;
+ return;
+ }
+
+ ipmb->bind_fd = -1;
+ serserv_handle_data(ipmb, msgd, len);
+ ipmb->bind_fd = 0;
+ serserv_handle_data(ipmb, msgd, 1);
+}
+
+static int
+ipmb_channel_init(void *info, channel_t *chan)
+{
+ misc_data_t *data = info;
+ ipmbserv_data_t *ipmb = chan->chan_info;
+ int err;
+ int fd;
+ os_hnd_fd_id_t *fd_id;
+
+ ipmb->os_hnd = data->os_hnd;
+ ipmb->user_info = data;
+ ipmb->send_out = ser_send;
+ err = serserv_init(ipmb);
+
+ if (err) {
+ fprintf(stderr, "Unable to init ipmb: 0x%x\n", err);
+ exit(1);
+ }
+
+ fd = ipmb_open(g_ipmi_dev);
+ if (fd == -1){
+ fprintf(stderr, "Unable to open ipmi device file: 0x%x\n", err);
+ exit(1);
+ }
+
+ ipmb->con_fd = fd;
+
+ err = data->os_hnd->add_fd_to_wait_for(data->os_hnd, ipmb->con_fd,
+ ipmb_data_ready, ipmb,
+ NULL, &fd_id);
+ if (!err)
+ isim_add_fd(fd);
+
+ return err;
+}
+
static void
isim_log(sys_data_t *sys, int logtype, msg_t *msg, const char *format,
va_list ap, int len)
@@ -1438,6 +1520,7 @@ main(int argc, const char *argv[])
sysinfo.cfree = ifree;
sysinfo.lan_channel_init = lan_channel_init;
sysinfo.ser_channel_init = ser_channel_init;
+ sysinfo.ipmb_channel_init = ipmb_channel_init;
data.sys = &sysinfo;
err = pipe(sigpipeh);
@@ -1501,6 +1584,9 @@ main(int argc, const char *argv[])
if (read_config(&sysinfo, config_file, print_version))
exit(1);
+ if (sysinfo.ipmidev != NULL)
+ strcpy(g_ipmi_dev, sysinfo.ipmidev);
+
if (print_version)
exit(0);
diff --git a/lanserv/lan.conf b/lanserv/lan.conf
index 37732d4..cec7ebb 100644
--- a/lanserv/lan.conf
+++ b/lanserv/lan.conf
@@ -126,3 +126,16 @@ set_working_mc 0x30
# where initstr is the init string passed on the module load line.
# It should return 0 on success or an errno no failure.
#loadlib "/opt/lib/ipmi_sim_extend.so" "Initialization String"
+
+# "ipmb" should be added to the config file of a device
+# that needs to handle an IPMB request and generate a response
+# back to the requester.
+# In the case of an IPMB bridge request for example, the
+# BMC is considered the requester and the responder device
+# should have a config file defining the IPMB channel number.
+# For example:
+# ipmb <channel number> <linux ipmb driver name> <device file>
+# ipmb 2 ipmb_dev_int /dev/ipmb-2
+#
+# At the moment, this OpenIPMI ipmb interface works with the
+# linux driver ipmb_dev_int.c.
--
2.1.2
|