Jim Mankovich
2013-04-17 16:20:02 UTC
Signed-off-by: Jim Mankovich <***@hp.com>
---
include/ipmitool/ipmi_intf.h | 3 +
include/ipmitool/ipmi_picmg.h | 2 +
include/ipmitool/ipmi_sdr.h | 24 +++++++
lib/ipmi_fru.c | 20 ++++--
lib/ipmi_main.c | 146 ++++++++++++++++-------------------------
lib/ipmi_picmg.c | 94 ++++++++++++++++++++++++++
lib/ipmi_sdr.c | 106 ++++++++++++++++--------------
lib/ipmi_sel.c | 4 +-
lib/ipmi_sensor.c | 44 ++++++++-----
src/plugins/lanplus/lanplus.c | 26 ++++++--
src/plugins/open/open.c | 19 ++++--
11 files changed, 320 insertions(+), 168 deletions(-)
diff --git a/include/ipmitool/ipmi_intf.h b/include/ipmitool/ipmi_intf.h
index 8b5b6f6..270f92d 100644
--- a/include/ipmitool/ipmi_intf.h
+++ b/include/ipmitool/ipmi_intf.h
@@ -165,11 +165,13 @@ struct ipmi_intf {
int opened;
int abort;
int noanswer;
+ int picmg_avail;
IPMI_OEM manufacturer_id;
struct ipmi_session * session;
struct ipmi_oem_handle * oem;
struct ipmi_cmd * cmdlist;
+ uint8_t target_ipmb_addr;
uint32_t my_addr;
uint32_t target_addr;
uint8_t target_lun;
@@ -188,6 +190,7 @@ struct ipmi_intf {
struct ipmi_rs *(*recv_sol)(struct ipmi_intf * intf);
struct ipmi_rs *(*send_sol)(struct ipmi_intf * intf, struct ipmi_v2_payload * payload);
int (*keepalive)(struct ipmi_intf * intf);
+ int (*set_my_addr)(struct ipmi_intf * intf, uint8_t addr);
};
struct ipmi_intf * ipmi_intf_load(char * name);
diff --git a/include/ipmitool/ipmi_picmg.h b/include/ipmitool/ipmi_picmg.h
index 5f73be2..4247e37 100644
--- a/include/ipmitool/ipmi_picmg.h
+++ b/include/ipmitool/ipmi_picmg.h
@@ -205,5 +205,7 @@ struct sAmcPortState {
int ipmi_picmg_main (struct ipmi_intf * intf, int argc, char ** argv);
+uint8_t picmg_ipmb_discover(struct ipmi_intf *intf);
+uint8_t ipmi_picmg_ipmb_address(struct ipmi_intf *intf);
#endif
diff --git a/include/ipmitool/ipmi_sdr.h b/include/ipmitool/ipmi_sdr.h
index 0f168d2..724d0cd 100644
--- a/include/ipmitool/ipmi_sdr.h
+++ b/include/ipmitool/ipmi_sdr.h
@@ -836,6 +836,30 @@ struct sensor_reading {
const char *s_a_units; /* analog value units string */
};
+/*
+ * Determine if bridging is necessary to address a sensor at the given
+ * address (_addr) and (_chan) via the interface (_intf).
+ *
+ * If the sensor is being addressed on channel zero, it resides on
+ * IPMB-0. If the interface target IPMB-0 address is exactly the same as
+ * the sensor address then the sensor resides on the target IPMB-0
+ * so we don't need extra levels of bridging to address the sensor.
+ * Or
+ * If the sensor target address and channel match the interface target address
+ * and channel then there is no extra levels of bridging required.
+ *
+ * Note:
+ * The target IPMB-0 address is the address of the SDR repository that was
+ * accessed using the user specified bridging command line arguments.
+ * Access to any sensor on the target IPMB-0 can be addressed using the
+ * target address and transit address in the interface.
+ */
+#define BRIDGE_TO_SENSOR(_intf, _addr, _chan) \
+ ( !((_chan == 0 && _intf->target_ipmb_addr && \
+ _intf->target_ipmb_addr == _addr) || \
+ (_addr == _intf->target_addr && _chan == _intf->target_channel)) )
+
+
struct ipmi_sdr_iterator *ipmi_sdr_start(struct ipmi_intf *intf,
int use_builtin);
struct sdr_get_rs *ipmi_sdr_get_next_header(struct ipmi_intf *intf,
diff --git a/lib/ipmi_fru.c b/lib/ipmi_fru.c
index 90da15b..07c8675 100644
--- a/lib/ipmi_fru.c
+++ b/lib/ipmi_fru.c
@@ -3006,7 +3006,8 @@ int
ipmi_fru_print(struct ipmi_intf * intf, struct sdr_record_fru_locator * fru)
{
char desc[17];
- uint32_t save_addr;
+ uint32_t save_addr = 0;
+ uint32_t save_channel;
int rc = 0;
if (fru == NULL)
@@ -3046,14 +3047,19 @@ ipmi_fru_print(struct ipmi_intf * intf, struct sdr_record_fru_locator * fru)
switch (fru->dev_type_modifier) {
case 0x00:
case 0x02:
- /* save current target address */
- save_addr = intf->target_addr;
- /* set new target address for bridged commands */
- intf->target_addr = fru->dev_slave_addr;
+ if (BRIDGE_TO_SENSOR(intf, fru->dev_slave_addr,
+ fru->channel_num)) {
+ save_addr = intf->target_addr;
+ intf->target_addr = fru->dev_slave_addr;
+ save_channel = intf->target_channel;
+ intf->target_channel = fru->channel_num;
+ }
/* print FRU */
rc = __ipmi_fru_print(intf, fru->device_id);
- /* restore previous target */
- intf->target_addr = save_addr;
+ if (save_addr) {
+ intf->target_addr = save_addr;
+ intf->target_channel = save_channel;
+ }
break;
case 0x01:
rc = ipmi_spd_print_fru(intf, fru->device_id);
diff --git a/lib/ipmi_main.c b/lib/ipmi_main.c
index cc04b51..01dd648 100644
--- a/lib/ipmi_main.c
+++ b/lib/ipmi_main.c
@@ -84,13 +84,6 @@ extern int csv_output;
extern const struct valstr ipmi_privlvl_vals[];
extern const struct valstr ipmi_authtype_session_vals[];
-/* defined in ipmishell.c */
-#ifdef HAVE_READLINE
-extern int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv);
-#endif
-extern int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv);
-extern int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv);
-
static struct ipmi_intf * ipmi_main_intf = NULL;
/* ipmi_password_file_read - Open file and read password from it
@@ -245,7 +238,6 @@ ipmi_option_usage(const char * progname, struct ipmi_cmd * cmdlist, struct ipmi_
lprintf(LOG_NOTICE, " -m address Set local IPMB address");
lprintf(LOG_NOTICE, " -b channel Set destination channel for bridged request");
lprintf(LOG_NOTICE, " -t address Bridge request to remote target address");
- lprintf(LOG_NOTICE, " -M address Set transit local address for bridge request(dual bridge)");
lprintf(LOG_NOTICE, " -B channel Set transit channel for bridged request (dual bridge)");
lprintf(LOG_NOTICE, " -T address Set transit address for bridge request (dual bridge)");
lprintf(LOG_NOTICE, " -l lun Set destination lun for raw commands");
@@ -364,7 +356,7 @@ ipmi_main(int argc, char ** argv,
uint8_t transit_addr = 0;
uint8_t transit_channel = 0;
uint8_t target_lun = 0;
- uint8_t my_addr = 0;
+ uint8_t arg_addr = 0, addr;
uint16_t my_long_packet_size=0;
uint8_t my_long_packet_set=0;
uint8_t lookupbit = 0x10; /* use name-only lookup by default */
@@ -727,7 +719,7 @@ ipmi_main(int argc, char ** argv,
}
break;
case 'm':
- if (str2uchar(optarg, &my_addr) != 0) {
+ if (str2uchar(optarg, &arg_addr) != 0) {
lprintf(LOG_ERR, "Invalid parameter given or out of range for '-m'.");
rc = -1;
goto out_free;
@@ -880,93 +872,69 @@ ipmi_main(int argc, char ** argv,
ipmi_intf_session_set_sol_escape_char(ipmi_main_intf, sol_escape_char);
ipmi_intf_session_set_cipher_suite_id(ipmi_main_intf, cipher_suite_id);
- /* setup destination lun if given */
- ipmi_main_intf->target_lun = target_lun ;
+ ipmi_main_intf->devnum = devnum;
- /* setup destination channel if given */
- ipmi_main_intf->target_channel = target_channel ;
+ /* Open the interface with the default local or specified address */
+ ipmi_main_intf->my_addr = arg_addr ? arg_addr : IPMI_BMC_SLAVE_ADDR;
+ if (ipmi_main_intf->open != NULL)
+ ipmi_main_intf->open(ipmi_main_intf);
- ipmi_main_intf->devnum = devnum;
+ /* Attempt picmg discovery of the actual interface address */
+ addr = picmg_ipmb_discover(ipmi_main_intf);
- /* setup IPMB local and target address if given */
- if (my_addr) {
- ipmi_main_intf->my_addr = my_addr;
- } else {
- /* Use the default for the payload source address */
- my_addr = 0x20;
-
- /* Check if PICMG extension is available to use the function
- * GetDeviceLocator to retreive i2c address PICMG hack to set
- * right IPMB address, If extension is not supported, should
- * not give any problems
- * PICMG Extension Version 2.0 (PICMG 3.0 Revision 1.0 ATCA) to
- * PICMG Extension Version 2.3 (PICMG 3.0 Revision 3.0 ATCA)
- */
-
- /* First, check if PICMG extension is available and supported */
- struct ipmi_rq req;
- struct ipmi_rs *rsp;
- char msg_data;
- unsigned char version_accepted = 0;
-
- lprintf(LOG_INFO, "Running PICMG GetDeviceLocator" );
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_PICMG;
- req.msg.cmd = PICMG_GET_PICMG_PROPERTIES_CMD;
- msg_data = 0x00;
- req.msg.data = &msg_data;
- req.msg.data_len = 1;
- msg_data = 0;
-
- rsp = ipmi_main_intf->sendrecv(ipmi_main_intf, &req);
- if (rsp && !rsp->ccode) {
- if ( (rsp->data[0] == 0) &&
- ((rsp->data[1] & 0x0F) == PICMG_ATCA_MAJOR_VERSION) ) {
- version_accepted = 1;
- lprintf(LOG_INFO, "Discovered PICMG Extension %d.%d",
- (rsp->data[1] & 0x0f), (rsp->data[1] >> 4));
- }
- }
-
- if (version_accepted == 1) {
- lprintf(LOG_DEBUG, "Running PICMG GetDeviceLocator");
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_PICMG;
- req.msg.cmd = PICMG_GET_ADDRESS_INFO_CMD;
- msg_data = 0x00;
- req.msg.data = &msg_data;
- req.msg.data_len = 1;
- msg_data = 0;
-
- rsp = ipmi_main_intf->sendrecv(ipmi_main_intf, &req);
- if (rsp && !rsp->ccode) {
- ipmi_main_intf->my_addr = rsp->data[2];
- ipmi_main_intf->target_addr = ipmi_main_intf->my_addr;
- lprintf(LOG_INFO, "Discovered IPMB address = 0x%x",
- ipmi_main_intf->my_addr);
- }
- } else {
- lprintf(LOG_INFO,
- "No PICMG Extenstion discovered, keeping IPMB address 0x20");
+ /*
+ * If we discovered the ipmb address and it is not the same as what we
+ * used for open, Set the discovered IPMB address as my address if the
+ * interface supports it.
+ */
+ if (addr != 0 && addr != ipmi_main_intf->my_addr &&
+ ipmi_main_intf->set_my_addr) {
+ /* ignore failure and move on */
+ (void) ipmi_main_intf->set_my_addr(ipmi_main_intf, addr);
+ }
+
+ /* If bridging addresses are specified, handle them */
+ if (transit_addr > 0 || target_addr > 0) {
+ /* sanity check, transit makes no sense without a target */
+ if ((transit_addr != 0 || transit_channel != 0) &&
+ target_addr == 0) {
+ lprintf(LOG_ERR,
+ "Transit address/channel %#x/%#x ignored. "
+ "Target address must be specified!",
+ transit_addr, transit_channel);
+ goto out_free;
}
- }
+ ipmi_main_intf->target_addr = target_addr;
+ ipmi_main_intf->target_lun = target_lun ;
+ ipmi_main_intf->target_channel = target_channel ;
- if ( target_addr > 0 && (target_addr != my_addr) ) {
- /* need to open the interface first */
- if (ipmi_main_intf->open != NULL)
- ipmi_main_intf->open(ipmi_main_intf);
+ ipmi_main_intf->transit_addr = transit_addr;
+ ipmi_main_intf->transit_channel = transit_channel;
- ipmi_main_intf->target_addr = target_addr;
- if (transit_addr > 0) {
- ipmi_main_intf->transit_addr = transit_addr;
- ipmi_main_intf->transit_channel = transit_channel;
- } else {
- ipmi_main_intf->transit_addr = ipmi_main_intf->my_addr;
- }
/* must be admin level to do this over lan */
ipmi_intf_session_set_privlvl(ipmi_main_intf, IPMI_SESSION_PRIV_ADMIN);
- }
+ /* Get the ipmb address of the targeted entity */
+ ipmi_main_intf->target_ipmb_addr =
+ ipmi_picmg_ipmb_address(ipmi_main_intf);
+ lprintf(LOG_DEBUG, "Specified addressing Target %#x:%#x Transit %#x:%#x",
+ ipmi_main_intf->target_addr,
+ ipmi_main_intf->target_channel,
+ ipmi_main_intf->transit_addr,
+ ipmi_main_intf->transit_channel);
+ lprintf(LOG_DEBUG, "Discovered Target IPMB-0 address %#x",
+ ipmi_main_intf->target_ipmb_addr);
+ }
+
+ lprintf(LOG_DEBUG, "Interface address: my_addr %#x "
+ "transit %#x:%#x target %#x:%#x "
+ "ipmb_target %#x\n",
+ ipmi_main_intf->my_addr,
+ ipmi_main_intf->transit_addr,
+ ipmi_main_intf->transit_channel,
+ ipmi_main_intf->target_addr,
+ ipmi_main_intf->target_channel,
+ ipmi_main_intf->target_ipmb_addr);
/* parse local SDR cache if given */
if (sdrcache != NULL) {
@@ -1048,3 +1016,5 @@ ipmi_main(int argc, char ** argv,
return rc;
}
+
+
diff --git a/lib/ipmi_picmg.c b/lib/ipmi_picmg.c
index ba43924..f33adce 100644
--- a/lib/ipmi_picmg.c
+++ b/lib/ipmi_picmg.c
@@ -141,6 +141,10 @@ ipmi_picmg_getaddr(struct ipmi_intf * intf, int argc, char ** argv)
req.msg.netfn = IPMI_NETFN_PICMG;
req.msg.cmd = PICMG_GET_ADDRESS_INFO_CMD;
req.msg.data = msg_data;
+ //
+ // Melanie says to fix this so we don't specify fruid (data_len == 1)
+ // unless it is specified on the command line
+ //
req.msg.data_len = 2;
msg_data[0] = 0; /* picmg identifier */
msg_data[1] = 0; /* default fru id */
@@ -1780,3 +1784,93 @@ ipmi_picmg_main (struct ipmi_intf * intf, int argc, char ** argv)
return rc;
}
+
+uint8_t
+ipmi_picmg_ipmb_address(struct ipmi_intf *intf) {
+ struct ipmi_rq req;
+ struct ipmi_rs *rsp;
+ char msg_data;
+
+ if (!intf->picmg_avail) {
+ return 0;
+ }
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = PICMG_GET_ADDRESS_INFO_CMD;
+ msg_data = 0x00;
+ req.msg.data = &msg_data;
+ req.msg.data_len = 1;
+ msg_data = 0;
+
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp && !rsp->ccode) {
+ return rsp->data[2];
+ }
+ if (rsp) {
+ lprintf(LOG_DEBUG, "Get Address Info failed: %#x %s",
+ rsp->ccode, val2str(rsp->ccode, completion_code_vals));
+ } else {
+ lprintf(LOG_DEBUG, "Get Address Info failed: No Response");
+ }
+ return 0;
+}
+
+uint8_t
+picmg_ipmb_discover(struct ipmi_intf *intf) {
+ /* Check if PICMG extension is available to use the function
+ * GetDeviceLocator to retreive i2c address PICMG hack to set
+ * right IPMB address, If extension is not supported, should
+ * not give any problems
+ * PICMG Extension Version 2.0 (PICMG 3.0 Revision 1.0 ATCA) to
+ * PICMG Extension Version 2.3 (PICMG 3.0 Revision 3.0 ATCA)
+ * PICMG Extension Version 4.1 (PICMG 3.0 Revision 3.0 AMC)
+ */
+
+ /* First, check if PICMG extension is available and supported */
+ struct ipmi_rq req;
+ struct ipmi_rs *rsp;
+ char msg_data;
+
+ if (intf->picmg_avail == 0) {
+ lprintf(LOG_INFO, "Running PICMG GetDeviceLocator" );
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = PICMG_GET_PICMG_PROPERTIES_CMD;
+ msg_data = 0x00;
+ req.msg.data = &msg_data;
+ req.msg.data_len = 1;
+ msg_data = 0;
+
+ lprintf(LOG_DEBUG, "Get PICMG Properties my_addr %#x, transit %#x, target %#x",
+ intf->my_addr, intf->transit_addr, intf->target_addr);
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp && !rsp->ccode) {
+ if ( (rsp->data[0] == 0) &&
+ ((rsp->data[1] & 0x0F) == PICMG_ATCA_MAJOR_VERSION
+ || (rsp->data[1] & 0x0F) == PICMG_AMC_MAJOR_VERSION) ) {
+ intf->picmg_avail = 1;
+ lprintf(LOG_INFO, "Discovered PICMG Extension %d.%d",
+ (rsp->data[1] & 0x0f), (rsp->data[1] >> 4));
+ }
+ } else {
+ if (rsp == NULL) {
+ lprintf(LOG_INFO,"No Response from Get PICMG Properties");
+ } else {
+ lprintf(LOG_INFO,"Error Response %#x from Get PICMG Properities", rsp->ccode);
+ }
+ }
+ }
+ if (intf->picmg_avail == 1) {
+ lprintf(LOG_DEBUG, "Running PICMG Get Address Info");
+ uint8_t addr = ipmi_picmg_ipmb_address(intf);
+ if (addr) {
+ lprintf(LOG_INFO, "Discovered IPMB-0 address = 0x%x", addr);
+ return addr;
+ }
+ } else {
+ lprintf(LOG_INFO,
+ "No PICMG Extenstion discovered, keeping IPMB address %#x",
+ intf->my_addr);
+ }
+ return 0;
+}
diff --git a/lib/ipmi_sdr.c b/lib/ipmi_sdr.c
index a2163e3..03334fb 100644
--- a/lib/ipmi_sdr.c
+++ b/lib/ipmi_sdr.c
@@ -456,13 +456,15 @@ ipmi_sdr_get_sensor_thresholds(struct ipmi_intf *intf, uint8_t sensor,
{
struct ipmi_rq req;
struct ipmi_rs *rsp;
- uint32_t save_addr;
+ uint32_t save_addr = 0;
uint32_t save_channel;
- save_addr = intf->target_addr;
- intf->target_addr = target;
- save_channel = intf->target_channel;
- intf->target_channel = channel;
+ if ( BRIDGE_TO_SENSOR(intf, target, channel) ) {
+ save_addr = intf->target_addr;
+ intf->target_addr = target;
+ save_channel = intf->target_channel;
+ intf->target_channel = channel;
+ }
memset(&req, 0, sizeof (req));
req.msg.netfn = IPMI_NETFN_SE;
@@ -471,8 +473,10 @@ ipmi_sdr_get_sensor_thresholds(struct ipmi_intf *intf, uint8_t sensor,
req.msg.data_len = sizeof (sensor);
rsp = intf->sendrecv(intf, &req);
- intf->target_addr = save_addr;
- intf->target_channel = save_channel;
+ if ( save_addr ) {
+ intf->target_addr = save_addr;
+ intf->target_channel = save_channel;
+ }
return rsp;
}
@@ -493,13 +497,15 @@ ipmi_sdr_get_sensor_hysteresis(struct ipmi_intf *intf, uint8_t sensor,
struct ipmi_rq req;
uint8_t rqdata[2];
struct ipmi_rs *rsp;
- uint32_t save_addr;
+ uint32_t save_addr = 0;
uint32_t save_channel;
- save_addr = intf->target_addr;
- intf->target_addr = target;
- save_channel = intf->target_channel;
- intf->target_channel = channel;
+ if ( BRIDGE_TO_SENSOR(intf, target, channel) ) {
+ save_addr = intf->target_addr;
+ intf->target_addr = target;
+ save_channel = intf->target_channel;
+ intf->target_channel = channel;
+ }
rqdata[0] = sensor;
rqdata[1] = 0xff; /* reserved */
@@ -511,8 +517,10 @@ ipmi_sdr_get_sensor_hysteresis(struct ipmi_intf *intf, uint8_t sensor,
req.msg.data_len = 2;
rsp = intf->sendrecv(intf, &req);
- intf->target_addr = save_addr;
- intf->target_channel = save_channel;
+ if ( save_addr ) {
+ intf->target_addr = save_addr;
+ intf->target_channel = save_channel;
+ }
return rsp;
}
@@ -537,6 +545,7 @@ ipmi_sdr_get_sensor_reading(struct ipmi_intf *intf, uint8_t sensor)
return intf->sendrecv(intf, &req);
}
+
/* ipmi_sdr_get_sensor_reading_ipmb - retrieve a raw sensor reading from ipmb
*
* @intf: ipmi interface
@@ -553,25 +562,15 @@ ipmi_sdr_get_sensor_reading_ipmb(struct ipmi_intf *intf, uint8_t sensor,
{
struct ipmi_rq req;
struct ipmi_rs *rsp;
- uint32_t save_addr;
+ uint32_t save_addr = 0;
uint32_t save_channel;
-#if 0
- /* Enabling this code will cause sensors with an SDR Owner ID
- * not equal to IPMI_BMC_SLAVE_ADDR to be not readable when
- * running over the lanplus interface. The
- * ipmi_sdr_get_sensor_reading function does not update the interface
- * target address or channel, so the failure makes sense. I believe
- * the following code and function being called should be removed.
- */
- if ((strncmp(intf->name, "ipmb", 4)) != 0)
- return ipmi_sdr_get_sensor_reading(intf, sensor);
-#endif
- save_addr = intf->target_addr;
- intf->target_addr = target;
- save_channel = intf->target_channel;
- intf->target_channel = channel;
-
+ if ( BRIDGE_TO_SENSOR(intf, target, channel) ) {
+ save_addr = intf->target_addr;
+ intf->target_addr = target;
+ save_channel = intf->target_channel;
+ intf->target_channel = channel;
+ }
memset(&req, 0, sizeof (req));
req.msg.netfn = IPMI_NETFN_SE;
req.msg.cmd = GET_SENSOR_READING;
@@ -579,8 +578,10 @@ ipmi_sdr_get_sensor_reading_ipmb(struct ipmi_intf *intf, uint8_t sensor,
req.msg.data_len = 1;
rsp = intf->sendrecv(intf, &req);
- intf->target_addr = save_addr;
- intf->target_channel = save_channel;
+ if ( save_addr ) {
+ intf->target_addr = save_addr;
+ intf->target_channel = save_channel;
+ }
return rsp;
}
@@ -600,14 +601,15 @@ ipmi_sdr_get_sensor_event_status(struct ipmi_intf *intf, uint8_t sensor,
{
struct ipmi_rq req;
struct ipmi_rs *rsp;
- uint32_t save_addr;
+ uint32_t save_addr = 0;
uint32_t save_channel;
- save_addr = intf->target_addr;
- intf->target_addr = target;
- save_channel = intf->target_channel;
- intf->target_channel = channel;
-
+ if ( BRIDGE_TO_SENSOR(intf, target, channel) ) {
+ save_addr = intf->target_addr;
+ intf->target_addr = target;
+ save_channel = intf->target_channel;
+ intf->target_channel = channel;
+ }
memset(&req, 0, sizeof (req));
req.msg.netfn = IPMI_NETFN_SE;
req.msg.cmd = GET_SENSOR_EVENT_STATUS;
@@ -615,8 +617,10 @@ ipmi_sdr_get_sensor_event_status(struct ipmi_intf *intf, uint8_t sensor,
req.msg.data_len = 1;
rsp = intf->sendrecv(intf, &req);
- intf->target_addr = save_addr;
- intf->target_channel = save_channel;
+ if ( save_addr ) {
+ intf->target_addr = save_addr;
+ intf->target_channel = save_channel;
+ }
return rsp;
}
@@ -636,13 +640,15 @@ ipmi_sdr_get_sensor_event_enable(struct ipmi_intf *intf, uint8_t sensor,
{
struct ipmi_rq req;
struct ipmi_rs *rsp;
- uint32_t save_addr;
+ uint32_t save_addr = 0;
uint32_t save_channel;
- save_addr = intf->target_addr;
- intf->target_addr = target;
- save_channel = intf->target_channel;
- intf->target_channel = channel;
+ if ( BRIDGE_TO_SENSOR(intf, target, channel) ) {
+ save_addr = intf->target_addr;
+ intf->target_addr = target;
+ save_channel = intf->target_channel;
+ intf->target_channel = channel;
+ }
memset(&req, 0, sizeof (req));
req.msg.netfn = IPMI_NETFN_SE;
@@ -651,8 +657,10 @@ ipmi_sdr_get_sensor_event_enable(struct ipmi_intf *intf, uint8_t sensor,
req.msg.data_len = 1;
rsp = intf->sendrecv(intf, &req);
- intf->target_addr = save_addr;
- intf->target_channel = save_channel;
+ if ( save_addr ) {
+ intf->target_addr = save_addr;
+ intf->target_channel = save_channel;
+ }
return rsp;
}
@@ -2838,6 +2846,8 @@ ipmi_sdr_start(struct ipmi_intf *intf, int use_builtin)
return NULL;
}
if (rsp->ccode > 0) {
+ lprintf(LOG_ERR, "Get Device ID command failed: %#x %s",
+ rsp->ccode, val2str(rsp->ccode, completion_code_vals));
free(itr);
itr = NULL;
return NULL;
diff --git a/lib/ipmi_sel.c b/lib/ipmi_sel.c
index 16c807b..b34499b 100644
--- a/lib/ipmi_sel.c
+++ b/lib/ipmi_sel.c
@@ -309,8 +309,8 @@ ipmi_get_oem(struct ipmi_intf * intf)
return IPMI_OEM_UNKNOWN;
}
if (rsp->ccode > 0) {
- lprintf(LOG_ERR, "Get Device ID command failed: %s",
- val2str(rsp->ccode, completion_code_vals));
+ lprintf(LOG_ERR, "Get Device ID command failed: %#x %s",
+ rsp->ccode, val2str(rsp->ccode, completion_code_vals));
return IPMI_OEM_UNKNOWN;
}
diff --git a/lib/ipmi_sensor.c b/lib/ipmi_sensor.c
index 41276b1..9abac00 100644
--- a/lib/ipmi_sensor.c
+++ b/lib/ipmi_sensor.c
@@ -104,12 +104,13 @@ struct ipmi_rs *
ipmi_sensor_set_sensor_thresholds(struct ipmi_intf *intf,
uint8_t sensor,
uint8_t threshold, uint8_t setting,
- uint8_t target, uint8_t lun)
+ uint8_t target, uint8_t lun, uint8_t channel)
{
struct ipmi_rq req;
static struct sensor_set_thresh_rq set_thresh_rq;
struct ipmi_rs *rsp;
- uint8_t save_addr;
+ uint32_t save_addr = 0;
+ uint32_t save_channel;
memset(&set_thresh_rq, 0, sizeof (set_thresh_rq));
set_thresh_rq.sensor_num = sensor;
@@ -129,9 +130,12 @@ ipmi_sensor_set_sensor_thresholds(struct ipmi_intf *intf,
else
return NULL;
- save_addr = intf->target_addr;
- intf->target_addr = target;
-
+ if (BRIDGE_TO_SENSOR(intf, target, channel)) {
+ save_addr = intf->target_addr;
+ intf->target_addr = target;
+ save_channel = intf->target_channel;
+ intf->target_channel = channel;
+ }
memset(&req, 0, sizeof (req));
req.msg.netfn = IPMI_NETFN_SE;
req.msg.cmd = SET_SENSOR_THRESHOLDS;
@@ -139,7 +143,10 @@ ipmi_sensor_set_sensor_thresholds(struct ipmi_intf *intf,
req.msg.data_len = sizeof (set_thresh_rq);
rsp = intf->sendrecv(intf, &req);
- intf->target_addr = save_addr;
+ if (save_addr) {
+ intf->target_addr = save_addr;
+ intf->target_channel = save_channel;
+ }
return rsp;
}
@@ -463,12 +470,12 @@ static const struct valstr threshold_vals[] = {
static int
__ipmi_sensor_set_threshold(struct ipmi_intf *intf,
uint8_t num, uint8_t mask, uint8_t setting,
- uint8_t target, uint8_t lun)
+ uint8_t target, uint8_t lun, uint8_t channel)
{
struct ipmi_rs *rsp;
rsp = ipmi_sensor_set_sensor_thresholds(intf, num, mask, setting,
- target, lun);
+ target, lun, channel);
if (rsp == NULL) {
lprintf(LOG_ERR, "Error setting threshold");
@@ -625,7 +632,8 @@ ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv)
sensor_num, settingMask,
__ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1),
sdr->record.common->keys.owner_id,
- sdr->record.common->keys.lun);
+ sdr->record.common->keys.lun,
+ sdr->record.common->keys.channel);
settingMask = UPPER_CRIT_SPECIFIED;
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
@@ -636,7 +644,8 @@ ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv)
sensor_num, settingMask,
__ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting2),
sdr->record.common->keys.owner_id,
- sdr->record.common->keys.lun);
+ sdr->record.common->keys.lun,
+ sdr->record.common->keys.channel);
settingMask = UPPER_NON_RECOV_SPECIFIED;
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
@@ -647,7 +656,8 @@ ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv)
sensor_num, settingMask,
__ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting3),
sdr->record.common->keys.owner_id,
- sdr->record.common->keys.lun);
+ sdr->record.common->keys.lun,
+ sdr->record.common->keys.channel);
} else if (allLower) {
settingMask = LOWER_NON_RECOV_SPECIFIED;
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
@@ -658,7 +668,8 @@ ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv)
sensor_num, settingMask,
__ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1),
sdr->record.common->keys.owner_id,
- sdr->record.common->keys.lun);
+ sdr->record.common->keys.lun,
+ sdr->record.common->keys.channel);
settingMask = LOWER_CRIT_SPECIFIED;
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
@@ -669,7 +680,8 @@ ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv)
sensor_num, settingMask,
__ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting2),
sdr->record.common->keys.owner_id,
- sdr->record.common->keys.lun);
+ sdr->record.common->keys.lun,
+ sdr->record.common->keys.channel);
settingMask = LOWER_NON_CRIT_SPECIFIED;
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
@@ -680,7 +692,8 @@ ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv)
sensor_num, settingMask,
__ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting3),
sdr->record.common->keys.owner_id,
- sdr->record.common->keys.lun);
+ sdr->record.common->keys.lun,
+ sdr->record.common->keys.channel);
} else {
/*
@@ -778,7 +791,8 @@ ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv)
sensor_num, settingMask,
__ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1),
sdr->record.common->keys.owner_id,
- sdr->record.common->keys.lun);
+ sdr->record.common->keys.lun,
+ sdr->record.common->keys.channel);
}
return ret;
diff --git a/src/plugins/lanplus/lanplus.c b/src/plugins/lanplus/lanplus.c
index 4288224..dc0e59a 100644
--- a/src/plugins/lanplus/lanplus.c
+++ b/src/plugins/lanplus/lanplus.c
@@ -1356,9 +1356,9 @@ void getIpmiPayloadWireRep(
len = 0;
/* IPMI Message Header -- Figure 13-4 of the IPMI v2.0 spec */
- if ((intf->target_addr == ourAddress) || (!bridgePossible))
+ if ((intf->target_addr == ourAddress) || (!bridgePossible)) {
cs = len;
- else {
+ } else {
bridgedRequest = 1;
if(intf->transit_addr != ourAddress && intf->transit_addr != 0)
@@ -1401,6 +1401,14 @@ void getIpmiPayloadWireRep(
entry->req.msg.target_cmd = entry->req.msg.cmd; /* Save target command */
entry->req.msg.cmd = 0x34; /* (fixup request entry) */
#endif
+// Test that sensors can be read correctly on Channel 7 when doulbe briding on
+// gemini. With this code, the sensors can be read without problem
+// 3/18/2013
+// src/ipmitool -I lanplus -U admin -P admin123 -H 16.85.18.239 -t 0x72 -T
+// 0xa4 -b 7 sdr list all
+// if (intf->target_channel == 0 && intf->target_addr == 0x72) {
+// intf->target_channel = 7;
+// }
msg[len++] = (0x40|intf->target_channel); /* Track request*/
payload->payload_length += 7;
@@ -1409,6 +1417,13 @@ void getIpmiPayloadWireRep(
}
}
+ lprintf(LOG_DEBUG,"%s RqAddr %#x transit %#x:%#x target %#x:%#x "
+ "bridgePossible %d",
+ bridgedRequest ? "Bridging" : "Local",
+ intf->my_addr, intf->transit_addr, intf->transit_channel,
+ intf->target_addr, intf->target_channel,
+ bridgePossible);
+
/* rsAddr */
msg[len++] = intf->target_addr; /* IPMI_BMC_SLAVE_ADDR; */
@@ -3296,6 +3311,7 @@ ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf)
if (rsp == NULL) {
lprintf(LOG_ERR, "Set Session Privilege Level to %s failed",
val2str(privlvl, ipmi_privlvl_vals));
+ bridgePossible = backupBridgePossible;
return -1;
}
if (verbose > 2)
@@ -3305,6 +3321,7 @@ ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf)
lprintf(LOG_ERR, "Set Session Privilege Level to %s failed: %s",
val2str(privlvl, ipmi_privlvl_vals),
val2str(rsp->ccode, completion_code_vals));
+ bridgePossible = backupBridgePossible;
return -1;
}
@@ -3453,13 +3470,14 @@ ipmi_lanplus_open(struct ipmi_intf * intf)
lprintf(LOG_DEBUG, "IPMIv2 / RMCP+ SESSION OPENED SUCCESSFULLY\n");
- bridgePossible = 1;
-
rc = ipmi_set_session_privlvl_cmd(intf);
+
if (rc < 0)
goto fail;
intf->manufacturer_id = ipmi_get_oem(intf);
+ bridgePossible = 1;
+
return intf->fd;
fail:
diff --git a/src/plugins/open/open.c b/src/plugins/open/open.c
index 34cb10c..5567992 100644
--- a/src/plugins/open/open.c
+++ b/src/plugins/open/open.c
@@ -107,12 +107,10 @@ ipmi_openipmi_open(struct ipmi_intf * intf)
/* This is never set to 0, the default is IPMI_BMC_SLAVE_ADDR */
if (intf->my_addr != 0) {
- unsigned int a = intf->my_addr;
- if (ioctl(intf->fd, IPMICTL_SET_MY_ADDRESS_CMD, &a) < 0) {
+ if (intf->set_my_addr(intf, intf->my_addr) < 0) {
lperror(LOG_ERR, "Could not set IPMB address");
return -1;
}
-
lprintf(LOG_DEBUG, "Set IPMB address to 0x%x",
intf->my_addr );
}
@@ -120,6 +118,17 @@ ipmi_openipmi_open(struct ipmi_intf * intf)
intf->manufacturer_id = ipmi_get_oem(intf);
return intf->fd;
}
+static int
+ipmi_openipmi_set_my_addr(struct ipmi_intf *intf, uint8_t addr)
+{
+ unsigned int a = addr;
+ if (ioctl(intf->fd, IPMICTL_SET_MY_ADDRESS_CMD, &a) < 0) {
+ lperror(LOG_ERR, "Could not set IPMB address");
+ return -1;
+ }
+ intf->my_addr = addr;
+ return 0;
+}
static void
ipmi_openipmi_close(struct ipmi_intf * intf)
@@ -179,7 +188,8 @@ ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
ipmb_addr.slave_addr = intf->target_addr;
ipmb_addr.lun = req->msg.lun;
lprintf(LOG_DEBUG, "Sending request to "
- "IPMB target @ 0x%x (from 0x%x)", intf->target_addr,intf->my_addr);
+ "IPMB target @ 0x%x:0x%x (from 0x%x)",
+ intf->target_addr,intf->target_channel, intf->my_addr);
if(intf->transit_addr != 0 && intf->transit_addr != intf->my_addr) {
uint8_t index = 0;
@@ -396,6 +406,7 @@ struct ipmi_intf ipmi_open_intf = {
open: ipmi_openipmi_open,
close: ipmi_openipmi_close,
sendrecv: ipmi_openipmi_send_cmd,
+ set_my_addr: ipmi_openipmi_set_my_addr,
my_addr: IPMI_BMC_SLAVE_ADDR,
target_addr: 0, /* init so -m local_addr does not cause bridging */
};
---
include/ipmitool/ipmi_intf.h | 3 +
include/ipmitool/ipmi_picmg.h | 2 +
include/ipmitool/ipmi_sdr.h | 24 +++++++
lib/ipmi_fru.c | 20 ++++--
lib/ipmi_main.c | 146 ++++++++++++++++-------------------------
lib/ipmi_picmg.c | 94 ++++++++++++++++++++++++++
lib/ipmi_sdr.c | 106 ++++++++++++++++--------------
lib/ipmi_sel.c | 4 +-
lib/ipmi_sensor.c | 44 ++++++++-----
src/plugins/lanplus/lanplus.c | 26 ++++++--
src/plugins/open/open.c | 19 ++++--
11 files changed, 320 insertions(+), 168 deletions(-)
diff --git a/include/ipmitool/ipmi_intf.h b/include/ipmitool/ipmi_intf.h
index 8b5b6f6..270f92d 100644
--- a/include/ipmitool/ipmi_intf.h
+++ b/include/ipmitool/ipmi_intf.h
@@ -165,11 +165,13 @@ struct ipmi_intf {
int opened;
int abort;
int noanswer;
+ int picmg_avail;
IPMI_OEM manufacturer_id;
struct ipmi_session * session;
struct ipmi_oem_handle * oem;
struct ipmi_cmd * cmdlist;
+ uint8_t target_ipmb_addr;
uint32_t my_addr;
uint32_t target_addr;
uint8_t target_lun;
@@ -188,6 +190,7 @@ struct ipmi_intf {
struct ipmi_rs *(*recv_sol)(struct ipmi_intf * intf);
struct ipmi_rs *(*send_sol)(struct ipmi_intf * intf, struct ipmi_v2_payload * payload);
int (*keepalive)(struct ipmi_intf * intf);
+ int (*set_my_addr)(struct ipmi_intf * intf, uint8_t addr);
};
struct ipmi_intf * ipmi_intf_load(char * name);
diff --git a/include/ipmitool/ipmi_picmg.h b/include/ipmitool/ipmi_picmg.h
index 5f73be2..4247e37 100644
--- a/include/ipmitool/ipmi_picmg.h
+++ b/include/ipmitool/ipmi_picmg.h
@@ -205,5 +205,7 @@ struct sAmcPortState {
int ipmi_picmg_main (struct ipmi_intf * intf, int argc, char ** argv);
+uint8_t picmg_ipmb_discover(struct ipmi_intf *intf);
+uint8_t ipmi_picmg_ipmb_address(struct ipmi_intf *intf);
#endif
diff --git a/include/ipmitool/ipmi_sdr.h b/include/ipmitool/ipmi_sdr.h
index 0f168d2..724d0cd 100644
--- a/include/ipmitool/ipmi_sdr.h
+++ b/include/ipmitool/ipmi_sdr.h
@@ -836,6 +836,30 @@ struct sensor_reading {
const char *s_a_units; /* analog value units string */
};
+/*
+ * Determine if bridging is necessary to address a sensor at the given
+ * address (_addr) and (_chan) via the interface (_intf).
+ *
+ * If the sensor is being addressed on channel zero, it resides on
+ * IPMB-0. If the interface target IPMB-0 address is exactly the same as
+ * the sensor address then the sensor resides on the target IPMB-0
+ * so we don't need extra levels of bridging to address the sensor.
+ * Or
+ * If the sensor target address and channel match the interface target address
+ * and channel then there is no extra levels of bridging required.
+ *
+ * Note:
+ * The target IPMB-0 address is the address of the SDR repository that was
+ * accessed using the user specified bridging command line arguments.
+ * Access to any sensor on the target IPMB-0 can be addressed using the
+ * target address and transit address in the interface.
+ */
+#define BRIDGE_TO_SENSOR(_intf, _addr, _chan) \
+ ( !((_chan == 0 && _intf->target_ipmb_addr && \
+ _intf->target_ipmb_addr == _addr) || \
+ (_addr == _intf->target_addr && _chan == _intf->target_channel)) )
+
+
struct ipmi_sdr_iterator *ipmi_sdr_start(struct ipmi_intf *intf,
int use_builtin);
struct sdr_get_rs *ipmi_sdr_get_next_header(struct ipmi_intf *intf,
diff --git a/lib/ipmi_fru.c b/lib/ipmi_fru.c
index 90da15b..07c8675 100644
--- a/lib/ipmi_fru.c
+++ b/lib/ipmi_fru.c
@@ -3006,7 +3006,8 @@ int
ipmi_fru_print(struct ipmi_intf * intf, struct sdr_record_fru_locator * fru)
{
char desc[17];
- uint32_t save_addr;
+ uint32_t save_addr = 0;
+ uint32_t save_channel;
int rc = 0;
if (fru == NULL)
@@ -3046,14 +3047,19 @@ ipmi_fru_print(struct ipmi_intf * intf, struct sdr_record_fru_locator * fru)
switch (fru->dev_type_modifier) {
case 0x00:
case 0x02:
- /* save current target address */
- save_addr = intf->target_addr;
- /* set new target address for bridged commands */
- intf->target_addr = fru->dev_slave_addr;
+ if (BRIDGE_TO_SENSOR(intf, fru->dev_slave_addr,
+ fru->channel_num)) {
+ save_addr = intf->target_addr;
+ intf->target_addr = fru->dev_slave_addr;
+ save_channel = intf->target_channel;
+ intf->target_channel = fru->channel_num;
+ }
/* print FRU */
rc = __ipmi_fru_print(intf, fru->device_id);
- /* restore previous target */
- intf->target_addr = save_addr;
+ if (save_addr) {
+ intf->target_addr = save_addr;
+ intf->target_channel = save_channel;
+ }
break;
case 0x01:
rc = ipmi_spd_print_fru(intf, fru->device_id);
diff --git a/lib/ipmi_main.c b/lib/ipmi_main.c
index cc04b51..01dd648 100644
--- a/lib/ipmi_main.c
+++ b/lib/ipmi_main.c
@@ -84,13 +84,6 @@ extern int csv_output;
extern const struct valstr ipmi_privlvl_vals[];
extern const struct valstr ipmi_authtype_session_vals[];
-/* defined in ipmishell.c */
-#ifdef HAVE_READLINE
-extern int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv);
-#endif
-extern int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv);
-extern int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv);
-
static struct ipmi_intf * ipmi_main_intf = NULL;
/* ipmi_password_file_read - Open file and read password from it
@@ -245,7 +238,6 @@ ipmi_option_usage(const char * progname, struct ipmi_cmd * cmdlist, struct ipmi_
lprintf(LOG_NOTICE, " -m address Set local IPMB address");
lprintf(LOG_NOTICE, " -b channel Set destination channel for bridged request");
lprintf(LOG_NOTICE, " -t address Bridge request to remote target address");
- lprintf(LOG_NOTICE, " -M address Set transit local address for bridge request(dual bridge)");
lprintf(LOG_NOTICE, " -B channel Set transit channel for bridged request (dual bridge)");
lprintf(LOG_NOTICE, " -T address Set transit address for bridge request (dual bridge)");
lprintf(LOG_NOTICE, " -l lun Set destination lun for raw commands");
@@ -364,7 +356,7 @@ ipmi_main(int argc, char ** argv,
uint8_t transit_addr = 0;
uint8_t transit_channel = 0;
uint8_t target_lun = 0;
- uint8_t my_addr = 0;
+ uint8_t arg_addr = 0, addr;
uint16_t my_long_packet_size=0;
uint8_t my_long_packet_set=0;
uint8_t lookupbit = 0x10; /* use name-only lookup by default */
@@ -727,7 +719,7 @@ ipmi_main(int argc, char ** argv,
}
break;
case 'm':
- if (str2uchar(optarg, &my_addr) != 0) {
+ if (str2uchar(optarg, &arg_addr) != 0) {
lprintf(LOG_ERR, "Invalid parameter given or out of range for '-m'.");
rc = -1;
goto out_free;
@@ -880,93 +872,69 @@ ipmi_main(int argc, char ** argv,
ipmi_intf_session_set_sol_escape_char(ipmi_main_intf, sol_escape_char);
ipmi_intf_session_set_cipher_suite_id(ipmi_main_intf, cipher_suite_id);
- /* setup destination lun if given */
- ipmi_main_intf->target_lun = target_lun ;
+ ipmi_main_intf->devnum = devnum;
- /* setup destination channel if given */
- ipmi_main_intf->target_channel = target_channel ;
+ /* Open the interface with the default local or specified address */
+ ipmi_main_intf->my_addr = arg_addr ? arg_addr : IPMI_BMC_SLAVE_ADDR;
+ if (ipmi_main_intf->open != NULL)
+ ipmi_main_intf->open(ipmi_main_intf);
- ipmi_main_intf->devnum = devnum;
+ /* Attempt picmg discovery of the actual interface address */
+ addr = picmg_ipmb_discover(ipmi_main_intf);
- /* setup IPMB local and target address if given */
- if (my_addr) {
- ipmi_main_intf->my_addr = my_addr;
- } else {
- /* Use the default for the payload source address */
- my_addr = 0x20;
-
- /* Check if PICMG extension is available to use the function
- * GetDeviceLocator to retreive i2c address PICMG hack to set
- * right IPMB address, If extension is not supported, should
- * not give any problems
- * PICMG Extension Version 2.0 (PICMG 3.0 Revision 1.0 ATCA) to
- * PICMG Extension Version 2.3 (PICMG 3.0 Revision 3.0 ATCA)
- */
-
- /* First, check if PICMG extension is available and supported */
- struct ipmi_rq req;
- struct ipmi_rs *rsp;
- char msg_data;
- unsigned char version_accepted = 0;
-
- lprintf(LOG_INFO, "Running PICMG GetDeviceLocator" );
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_PICMG;
- req.msg.cmd = PICMG_GET_PICMG_PROPERTIES_CMD;
- msg_data = 0x00;
- req.msg.data = &msg_data;
- req.msg.data_len = 1;
- msg_data = 0;
-
- rsp = ipmi_main_intf->sendrecv(ipmi_main_intf, &req);
- if (rsp && !rsp->ccode) {
- if ( (rsp->data[0] == 0) &&
- ((rsp->data[1] & 0x0F) == PICMG_ATCA_MAJOR_VERSION) ) {
- version_accepted = 1;
- lprintf(LOG_INFO, "Discovered PICMG Extension %d.%d",
- (rsp->data[1] & 0x0f), (rsp->data[1] >> 4));
- }
- }
-
- if (version_accepted == 1) {
- lprintf(LOG_DEBUG, "Running PICMG GetDeviceLocator");
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_PICMG;
- req.msg.cmd = PICMG_GET_ADDRESS_INFO_CMD;
- msg_data = 0x00;
- req.msg.data = &msg_data;
- req.msg.data_len = 1;
- msg_data = 0;
-
- rsp = ipmi_main_intf->sendrecv(ipmi_main_intf, &req);
- if (rsp && !rsp->ccode) {
- ipmi_main_intf->my_addr = rsp->data[2];
- ipmi_main_intf->target_addr = ipmi_main_intf->my_addr;
- lprintf(LOG_INFO, "Discovered IPMB address = 0x%x",
- ipmi_main_intf->my_addr);
- }
- } else {
- lprintf(LOG_INFO,
- "No PICMG Extenstion discovered, keeping IPMB address 0x20");
+ /*
+ * If we discovered the ipmb address and it is not the same as what we
+ * used for open, Set the discovered IPMB address as my address if the
+ * interface supports it.
+ */
+ if (addr != 0 && addr != ipmi_main_intf->my_addr &&
+ ipmi_main_intf->set_my_addr) {
+ /* ignore failure and move on */
+ (void) ipmi_main_intf->set_my_addr(ipmi_main_intf, addr);
+ }
+
+ /* If bridging addresses are specified, handle them */
+ if (transit_addr > 0 || target_addr > 0) {
+ /* sanity check, transit makes no sense without a target */
+ if ((transit_addr != 0 || transit_channel != 0) &&
+ target_addr == 0) {
+ lprintf(LOG_ERR,
+ "Transit address/channel %#x/%#x ignored. "
+ "Target address must be specified!",
+ transit_addr, transit_channel);
+ goto out_free;
}
- }
+ ipmi_main_intf->target_addr = target_addr;
+ ipmi_main_intf->target_lun = target_lun ;
+ ipmi_main_intf->target_channel = target_channel ;
- if ( target_addr > 0 && (target_addr != my_addr) ) {
- /* need to open the interface first */
- if (ipmi_main_intf->open != NULL)
- ipmi_main_intf->open(ipmi_main_intf);
+ ipmi_main_intf->transit_addr = transit_addr;
+ ipmi_main_intf->transit_channel = transit_channel;
- ipmi_main_intf->target_addr = target_addr;
- if (transit_addr > 0) {
- ipmi_main_intf->transit_addr = transit_addr;
- ipmi_main_intf->transit_channel = transit_channel;
- } else {
- ipmi_main_intf->transit_addr = ipmi_main_intf->my_addr;
- }
/* must be admin level to do this over lan */
ipmi_intf_session_set_privlvl(ipmi_main_intf, IPMI_SESSION_PRIV_ADMIN);
- }
+ /* Get the ipmb address of the targeted entity */
+ ipmi_main_intf->target_ipmb_addr =
+ ipmi_picmg_ipmb_address(ipmi_main_intf);
+ lprintf(LOG_DEBUG, "Specified addressing Target %#x:%#x Transit %#x:%#x",
+ ipmi_main_intf->target_addr,
+ ipmi_main_intf->target_channel,
+ ipmi_main_intf->transit_addr,
+ ipmi_main_intf->transit_channel);
+ lprintf(LOG_DEBUG, "Discovered Target IPMB-0 address %#x",
+ ipmi_main_intf->target_ipmb_addr);
+ }
+
+ lprintf(LOG_DEBUG, "Interface address: my_addr %#x "
+ "transit %#x:%#x target %#x:%#x "
+ "ipmb_target %#x\n",
+ ipmi_main_intf->my_addr,
+ ipmi_main_intf->transit_addr,
+ ipmi_main_intf->transit_channel,
+ ipmi_main_intf->target_addr,
+ ipmi_main_intf->target_channel,
+ ipmi_main_intf->target_ipmb_addr);
/* parse local SDR cache if given */
if (sdrcache != NULL) {
@@ -1048,3 +1016,5 @@ ipmi_main(int argc, char ** argv,
return rc;
}
+
+
diff --git a/lib/ipmi_picmg.c b/lib/ipmi_picmg.c
index ba43924..f33adce 100644
--- a/lib/ipmi_picmg.c
+++ b/lib/ipmi_picmg.c
@@ -141,6 +141,10 @@ ipmi_picmg_getaddr(struct ipmi_intf * intf, int argc, char ** argv)
req.msg.netfn = IPMI_NETFN_PICMG;
req.msg.cmd = PICMG_GET_ADDRESS_INFO_CMD;
req.msg.data = msg_data;
+ //
+ // Melanie says to fix this so we don't specify fruid (data_len == 1)
+ // unless it is specified on the command line
+ //
req.msg.data_len = 2;
msg_data[0] = 0; /* picmg identifier */
msg_data[1] = 0; /* default fru id */
@@ -1780,3 +1784,93 @@ ipmi_picmg_main (struct ipmi_intf * intf, int argc, char ** argv)
return rc;
}
+
+uint8_t
+ipmi_picmg_ipmb_address(struct ipmi_intf *intf) {
+ struct ipmi_rq req;
+ struct ipmi_rs *rsp;
+ char msg_data;
+
+ if (!intf->picmg_avail) {
+ return 0;
+ }
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = PICMG_GET_ADDRESS_INFO_CMD;
+ msg_data = 0x00;
+ req.msg.data = &msg_data;
+ req.msg.data_len = 1;
+ msg_data = 0;
+
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp && !rsp->ccode) {
+ return rsp->data[2];
+ }
+ if (rsp) {
+ lprintf(LOG_DEBUG, "Get Address Info failed: %#x %s",
+ rsp->ccode, val2str(rsp->ccode, completion_code_vals));
+ } else {
+ lprintf(LOG_DEBUG, "Get Address Info failed: No Response");
+ }
+ return 0;
+}
+
+uint8_t
+picmg_ipmb_discover(struct ipmi_intf *intf) {
+ /* Check if PICMG extension is available to use the function
+ * GetDeviceLocator to retreive i2c address PICMG hack to set
+ * right IPMB address, If extension is not supported, should
+ * not give any problems
+ * PICMG Extension Version 2.0 (PICMG 3.0 Revision 1.0 ATCA) to
+ * PICMG Extension Version 2.3 (PICMG 3.0 Revision 3.0 ATCA)
+ * PICMG Extension Version 4.1 (PICMG 3.0 Revision 3.0 AMC)
+ */
+
+ /* First, check if PICMG extension is available and supported */
+ struct ipmi_rq req;
+ struct ipmi_rs *rsp;
+ char msg_data;
+
+ if (intf->picmg_avail == 0) {
+ lprintf(LOG_INFO, "Running PICMG GetDeviceLocator" );
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = PICMG_GET_PICMG_PROPERTIES_CMD;
+ msg_data = 0x00;
+ req.msg.data = &msg_data;
+ req.msg.data_len = 1;
+ msg_data = 0;
+
+ lprintf(LOG_DEBUG, "Get PICMG Properties my_addr %#x, transit %#x, target %#x",
+ intf->my_addr, intf->transit_addr, intf->target_addr);
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp && !rsp->ccode) {
+ if ( (rsp->data[0] == 0) &&
+ ((rsp->data[1] & 0x0F) == PICMG_ATCA_MAJOR_VERSION
+ || (rsp->data[1] & 0x0F) == PICMG_AMC_MAJOR_VERSION) ) {
+ intf->picmg_avail = 1;
+ lprintf(LOG_INFO, "Discovered PICMG Extension %d.%d",
+ (rsp->data[1] & 0x0f), (rsp->data[1] >> 4));
+ }
+ } else {
+ if (rsp == NULL) {
+ lprintf(LOG_INFO,"No Response from Get PICMG Properties");
+ } else {
+ lprintf(LOG_INFO,"Error Response %#x from Get PICMG Properities", rsp->ccode);
+ }
+ }
+ }
+ if (intf->picmg_avail == 1) {
+ lprintf(LOG_DEBUG, "Running PICMG Get Address Info");
+ uint8_t addr = ipmi_picmg_ipmb_address(intf);
+ if (addr) {
+ lprintf(LOG_INFO, "Discovered IPMB-0 address = 0x%x", addr);
+ return addr;
+ }
+ } else {
+ lprintf(LOG_INFO,
+ "No PICMG Extenstion discovered, keeping IPMB address %#x",
+ intf->my_addr);
+ }
+ return 0;
+}
diff --git a/lib/ipmi_sdr.c b/lib/ipmi_sdr.c
index a2163e3..03334fb 100644
--- a/lib/ipmi_sdr.c
+++ b/lib/ipmi_sdr.c
@@ -456,13 +456,15 @@ ipmi_sdr_get_sensor_thresholds(struct ipmi_intf *intf, uint8_t sensor,
{
struct ipmi_rq req;
struct ipmi_rs *rsp;
- uint32_t save_addr;
+ uint32_t save_addr = 0;
uint32_t save_channel;
- save_addr = intf->target_addr;
- intf->target_addr = target;
- save_channel = intf->target_channel;
- intf->target_channel = channel;
+ if ( BRIDGE_TO_SENSOR(intf, target, channel) ) {
+ save_addr = intf->target_addr;
+ intf->target_addr = target;
+ save_channel = intf->target_channel;
+ intf->target_channel = channel;
+ }
memset(&req, 0, sizeof (req));
req.msg.netfn = IPMI_NETFN_SE;
@@ -471,8 +473,10 @@ ipmi_sdr_get_sensor_thresholds(struct ipmi_intf *intf, uint8_t sensor,
req.msg.data_len = sizeof (sensor);
rsp = intf->sendrecv(intf, &req);
- intf->target_addr = save_addr;
- intf->target_channel = save_channel;
+ if ( save_addr ) {
+ intf->target_addr = save_addr;
+ intf->target_channel = save_channel;
+ }
return rsp;
}
@@ -493,13 +497,15 @@ ipmi_sdr_get_sensor_hysteresis(struct ipmi_intf *intf, uint8_t sensor,
struct ipmi_rq req;
uint8_t rqdata[2];
struct ipmi_rs *rsp;
- uint32_t save_addr;
+ uint32_t save_addr = 0;
uint32_t save_channel;
- save_addr = intf->target_addr;
- intf->target_addr = target;
- save_channel = intf->target_channel;
- intf->target_channel = channel;
+ if ( BRIDGE_TO_SENSOR(intf, target, channel) ) {
+ save_addr = intf->target_addr;
+ intf->target_addr = target;
+ save_channel = intf->target_channel;
+ intf->target_channel = channel;
+ }
rqdata[0] = sensor;
rqdata[1] = 0xff; /* reserved */
@@ -511,8 +517,10 @@ ipmi_sdr_get_sensor_hysteresis(struct ipmi_intf *intf, uint8_t sensor,
req.msg.data_len = 2;
rsp = intf->sendrecv(intf, &req);
- intf->target_addr = save_addr;
- intf->target_channel = save_channel;
+ if ( save_addr ) {
+ intf->target_addr = save_addr;
+ intf->target_channel = save_channel;
+ }
return rsp;
}
@@ -537,6 +545,7 @@ ipmi_sdr_get_sensor_reading(struct ipmi_intf *intf, uint8_t sensor)
return intf->sendrecv(intf, &req);
}
+
/* ipmi_sdr_get_sensor_reading_ipmb - retrieve a raw sensor reading from ipmb
*
* @intf: ipmi interface
@@ -553,25 +562,15 @@ ipmi_sdr_get_sensor_reading_ipmb(struct ipmi_intf *intf, uint8_t sensor,
{
struct ipmi_rq req;
struct ipmi_rs *rsp;
- uint32_t save_addr;
+ uint32_t save_addr = 0;
uint32_t save_channel;
-#if 0
- /* Enabling this code will cause sensors with an SDR Owner ID
- * not equal to IPMI_BMC_SLAVE_ADDR to be not readable when
- * running over the lanplus interface. The
- * ipmi_sdr_get_sensor_reading function does not update the interface
- * target address or channel, so the failure makes sense. I believe
- * the following code and function being called should be removed.
- */
- if ((strncmp(intf->name, "ipmb", 4)) != 0)
- return ipmi_sdr_get_sensor_reading(intf, sensor);
-#endif
- save_addr = intf->target_addr;
- intf->target_addr = target;
- save_channel = intf->target_channel;
- intf->target_channel = channel;
-
+ if ( BRIDGE_TO_SENSOR(intf, target, channel) ) {
+ save_addr = intf->target_addr;
+ intf->target_addr = target;
+ save_channel = intf->target_channel;
+ intf->target_channel = channel;
+ }
memset(&req, 0, sizeof (req));
req.msg.netfn = IPMI_NETFN_SE;
req.msg.cmd = GET_SENSOR_READING;
@@ -579,8 +578,10 @@ ipmi_sdr_get_sensor_reading_ipmb(struct ipmi_intf *intf, uint8_t sensor,
req.msg.data_len = 1;
rsp = intf->sendrecv(intf, &req);
- intf->target_addr = save_addr;
- intf->target_channel = save_channel;
+ if ( save_addr ) {
+ intf->target_addr = save_addr;
+ intf->target_channel = save_channel;
+ }
return rsp;
}
@@ -600,14 +601,15 @@ ipmi_sdr_get_sensor_event_status(struct ipmi_intf *intf, uint8_t sensor,
{
struct ipmi_rq req;
struct ipmi_rs *rsp;
- uint32_t save_addr;
+ uint32_t save_addr = 0;
uint32_t save_channel;
- save_addr = intf->target_addr;
- intf->target_addr = target;
- save_channel = intf->target_channel;
- intf->target_channel = channel;
-
+ if ( BRIDGE_TO_SENSOR(intf, target, channel) ) {
+ save_addr = intf->target_addr;
+ intf->target_addr = target;
+ save_channel = intf->target_channel;
+ intf->target_channel = channel;
+ }
memset(&req, 0, sizeof (req));
req.msg.netfn = IPMI_NETFN_SE;
req.msg.cmd = GET_SENSOR_EVENT_STATUS;
@@ -615,8 +617,10 @@ ipmi_sdr_get_sensor_event_status(struct ipmi_intf *intf, uint8_t sensor,
req.msg.data_len = 1;
rsp = intf->sendrecv(intf, &req);
- intf->target_addr = save_addr;
- intf->target_channel = save_channel;
+ if ( save_addr ) {
+ intf->target_addr = save_addr;
+ intf->target_channel = save_channel;
+ }
return rsp;
}
@@ -636,13 +640,15 @@ ipmi_sdr_get_sensor_event_enable(struct ipmi_intf *intf, uint8_t sensor,
{
struct ipmi_rq req;
struct ipmi_rs *rsp;
- uint32_t save_addr;
+ uint32_t save_addr = 0;
uint32_t save_channel;
- save_addr = intf->target_addr;
- intf->target_addr = target;
- save_channel = intf->target_channel;
- intf->target_channel = channel;
+ if ( BRIDGE_TO_SENSOR(intf, target, channel) ) {
+ save_addr = intf->target_addr;
+ intf->target_addr = target;
+ save_channel = intf->target_channel;
+ intf->target_channel = channel;
+ }
memset(&req, 0, sizeof (req));
req.msg.netfn = IPMI_NETFN_SE;
@@ -651,8 +657,10 @@ ipmi_sdr_get_sensor_event_enable(struct ipmi_intf *intf, uint8_t sensor,
req.msg.data_len = 1;
rsp = intf->sendrecv(intf, &req);
- intf->target_addr = save_addr;
- intf->target_channel = save_channel;
+ if ( save_addr ) {
+ intf->target_addr = save_addr;
+ intf->target_channel = save_channel;
+ }
return rsp;
}
@@ -2838,6 +2846,8 @@ ipmi_sdr_start(struct ipmi_intf *intf, int use_builtin)
return NULL;
}
if (rsp->ccode > 0) {
+ lprintf(LOG_ERR, "Get Device ID command failed: %#x %s",
+ rsp->ccode, val2str(rsp->ccode, completion_code_vals));
free(itr);
itr = NULL;
return NULL;
diff --git a/lib/ipmi_sel.c b/lib/ipmi_sel.c
index 16c807b..b34499b 100644
--- a/lib/ipmi_sel.c
+++ b/lib/ipmi_sel.c
@@ -309,8 +309,8 @@ ipmi_get_oem(struct ipmi_intf * intf)
return IPMI_OEM_UNKNOWN;
}
if (rsp->ccode > 0) {
- lprintf(LOG_ERR, "Get Device ID command failed: %s",
- val2str(rsp->ccode, completion_code_vals));
+ lprintf(LOG_ERR, "Get Device ID command failed: %#x %s",
+ rsp->ccode, val2str(rsp->ccode, completion_code_vals));
return IPMI_OEM_UNKNOWN;
}
diff --git a/lib/ipmi_sensor.c b/lib/ipmi_sensor.c
index 41276b1..9abac00 100644
--- a/lib/ipmi_sensor.c
+++ b/lib/ipmi_sensor.c
@@ -104,12 +104,13 @@ struct ipmi_rs *
ipmi_sensor_set_sensor_thresholds(struct ipmi_intf *intf,
uint8_t sensor,
uint8_t threshold, uint8_t setting,
- uint8_t target, uint8_t lun)
+ uint8_t target, uint8_t lun, uint8_t channel)
{
struct ipmi_rq req;
static struct sensor_set_thresh_rq set_thresh_rq;
struct ipmi_rs *rsp;
- uint8_t save_addr;
+ uint32_t save_addr = 0;
+ uint32_t save_channel;
memset(&set_thresh_rq, 0, sizeof (set_thresh_rq));
set_thresh_rq.sensor_num = sensor;
@@ -129,9 +130,12 @@ ipmi_sensor_set_sensor_thresholds(struct ipmi_intf *intf,
else
return NULL;
- save_addr = intf->target_addr;
- intf->target_addr = target;
-
+ if (BRIDGE_TO_SENSOR(intf, target, channel)) {
+ save_addr = intf->target_addr;
+ intf->target_addr = target;
+ save_channel = intf->target_channel;
+ intf->target_channel = channel;
+ }
memset(&req, 0, sizeof (req));
req.msg.netfn = IPMI_NETFN_SE;
req.msg.cmd = SET_SENSOR_THRESHOLDS;
@@ -139,7 +143,10 @@ ipmi_sensor_set_sensor_thresholds(struct ipmi_intf *intf,
req.msg.data_len = sizeof (set_thresh_rq);
rsp = intf->sendrecv(intf, &req);
- intf->target_addr = save_addr;
+ if (save_addr) {
+ intf->target_addr = save_addr;
+ intf->target_channel = save_channel;
+ }
return rsp;
}
@@ -463,12 +470,12 @@ static const struct valstr threshold_vals[] = {
static int
__ipmi_sensor_set_threshold(struct ipmi_intf *intf,
uint8_t num, uint8_t mask, uint8_t setting,
- uint8_t target, uint8_t lun)
+ uint8_t target, uint8_t lun, uint8_t channel)
{
struct ipmi_rs *rsp;
rsp = ipmi_sensor_set_sensor_thresholds(intf, num, mask, setting,
- target, lun);
+ target, lun, channel);
if (rsp == NULL) {
lprintf(LOG_ERR, "Error setting threshold");
@@ -625,7 +632,8 @@ ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv)
sensor_num, settingMask,
__ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1),
sdr->record.common->keys.owner_id,
- sdr->record.common->keys.lun);
+ sdr->record.common->keys.lun,
+ sdr->record.common->keys.channel);
settingMask = UPPER_CRIT_SPECIFIED;
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
@@ -636,7 +644,8 @@ ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv)
sensor_num, settingMask,
__ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting2),
sdr->record.common->keys.owner_id,
- sdr->record.common->keys.lun);
+ sdr->record.common->keys.lun,
+ sdr->record.common->keys.channel);
settingMask = UPPER_NON_RECOV_SPECIFIED;
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
@@ -647,7 +656,8 @@ ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv)
sensor_num, settingMask,
__ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting3),
sdr->record.common->keys.owner_id,
- sdr->record.common->keys.lun);
+ sdr->record.common->keys.lun,
+ sdr->record.common->keys.channel);
} else if (allLower) {
settingMask = LOWER_NON_RECOV_SPECIFIED;
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
@@ -658,7 +668,8 @@ ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv)
sensor_num, settingMask,
__ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1),
sdr->record.common->keys.owner_id,
- sdr->record.common->keys.lun);
+ sdr->record.common->keys.lun,
+ sdr->record.common->keys.channel);
settingMask = LOWER_CRIT_SPECIFIED;
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
@@ -669,7 +680,8 @@ ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv)
sensor_num, settingMask,
__ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting2),
sdr->record.common->keys.owner_id,
- sdr->record.common->keys.lun);
+ sdr->record.common->keys.lun,
+ sdr->record.common->keys.channel);
settingMask = LOWER_NON_CRIT_SPECIFIED;
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
@@ -680,7 +692,8 @@ ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv)
sensor_num, settingMask,
__ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting3),
sdr->record.common->keys.owner_id,
- sdr->record.common->keys.lun);
+ sdr->record.common->keys.lun,
+ sdr->record.common->keys.channel);
} else {
/*
@@ -778,7 +791,8 @@ ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv)
sensor_num, settingMask,
__ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1),
sdr->record.common->keys.owner_id,
- sdr->record.common->keys.lun);
+ sdr->record.common->keys.lun,
+ sdr->record.common->keys.channel);
}
return ret;
diff --git a/src/plugins/lanplus/lanplus.c b/src/plugins/lanplus/lanplus.c
index 4288224..dc0e59a 100644
--- a/src/plugins/lanplus/lanplus.c
+++ b/src/plugins/lanplus/lanplus.c
@@ -1356,9 +1356,9 @@ void getIpmiPayloadWireRep(
len = 0;
/* IPMI Message Header -- Figure 13-4 of the IPMI v2.0 spec */
- if ((intf->target_addr == ourAddress) || (!bridgePossible))
+ if ((intf->target_addr == ourAddress) || (!bridgePossible)) {
cs = len;
- else {
+ } else {
bridgedRequest = 1;
if(intf->transit_addr != ourAddress && intf->transit_addr != 0)
@@ -1401,6 +1401,14 @@ void getIpmiPayloadWireRep(
entry->req.msg.target_cmd = entry->req.msg.cmd; /* Save target command */
entry->req.msg.cmd = 0x34; /* (fixup request entry) */
#endif
+// Test that sensors can be read correctly on Channel 7 when doulbe briding on
+// gemini. With this code, the sensors can be read without problem
+// 3/18/2013
+// src/ipmitool -I lanplus -U admin -P admin123 -H 16.85.18.239 -t 0x72 -T
+// 0xa4 -b 7 sdr list all
+// if (intf->target_channel == 0 && intf->target_addr == 0x72) {
+// intf->target_channel = 7;
+// }
msg[len++] = (0x40|intf->target_channel); /* Track request*/
payload->payload_length += 7;
@@ -1409,6 +1417,13 @@ void getIpmiPayloadWireRep(
}
}
+ lprintf(LOG_DEBUG,"%s RqAddr %#x transit %#x:%#x target %#x:%#x "
+ "bridgePossible %d",
+ bridgedRequest ? "Bridging" : "Local",
+ intf->my_addr, intf->transit_addr, intf->transit_channel,
+ intf->target_addr, intf->target_channel,
+ bridgePossible);
+
/* rsAddr */
msg[len++] = intf->target_addr; /* IPMI_BMC_SLAVE_ADDR; */
@@ -3296,6 +3311,7 @@ ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf)
if (rsp == NULL) {
lprintf(LOG_ERR, "Set Session Privilege Level to %s failed",
val2str(privlvl, ipmi_privlvl_vals));
+ bridgePossible = backupBridgePossible;
return -1;
}
if (verbose > 2)
@@ -3305,6 +3321,7 @@ ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf)
lprintf(LOG_ERR, "Set Session Privilege Level to %s failed: %s",
val2str(privlvl, ipmi_privlvl_vals),
val2str(rsp->ccode, completion_code_vals));
+ bridgePossible = backupBridgePossible;
return -1;
}
@@ -3453,13 +3470,14 @@ ipmi_lanplus_open(struct ipmi_intf * intf)
lprintf(LOG_DEBUG, "IPMIv2 / RMCP+ SESSION OPENED SUCCESSFULLY\n");
- bridgePossible = 1;
-
rc = ipmi_set_session_privlvl_cmd(intf);
+
if (rc < 0)
goto fail;
intf->manufacturer_id = ipmi_get_oem(intf);
+ bridgePossible = 1;
+
return intf->fd;
fail:
diff --git a/src/plugins/open/open.c b/src/plugins/open/open.c
index 34cb10c..5567992 100644
--- a/src/plugins/open/open.c
+++ b/src/plugins/open/open.c
@@ -107,12 +107,10 @@ ipmi_openipmi_open(struct ipmi_intf * intf)
/* This is never set to 0, the default is IPMI_BMC_SLAVE_ADDR */
if (intf->my_addr != 0) {
- unsigned int a = intf->my_addr;
- if (ioctl(intf->fd, IPMICTL_SET_MY_ADDRESS_CMD, &a) < 0) {
+ if (intf->set_my_addr(intf, intf->my_addr) < 0) {
lperror(LOG_ERR, "Could not set IPMB address");
return -1;
}
-
lprintf(LOG_DEBUG, "Set IPMB address to 0x%x",
intf->my_addr );
}
@@ -120,6 +118,17 @@ ipmi_openipmi_open(struct ipmi_intf * intf)
intf->manufacturer_id = ipmi_get_oem(intf);
return intf->fd;
}
+static int
+ipmi_openipmi_set_my_addr(struct ipmi_intf *intf, uint8_t addr)
+{
+ unsigned int a = addr;
+ if (ioctl(intf->fd, IPMICTL_SET_MY_ADDRESS_CMD, &a) < 0) {
+ lperror(LOG_ERR, "Could not set IPMB address");
+ return -1;
+ }
+ intf->my_addr = addr;
+ return 0;
+}
static void
ipmi_openipmi_close(struct ipmi_intf * intf)
@@ -179,7 +188,8 @@ ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
ipmb_addr.slave_addr = intf->target_addr;
ipmb_addr.lun = req->msg.lun;
lprintf(LOG_DEBUG, "Sending request to "
- "IPMB target @ 0x%x (from 0x%x)", intf->target_addr,intf->my_addr);
+ "IPMB target @ 0x%x:0x%x (from 0x%x)",
+ intf->target_addr,intf->target_channel, intf->my_addr);
if(intf->transit_addr != 0 && intf->transit_addr != intf->my_addr) {
uint8_t index = 0;
@@ -396,6 +406,7 @@ struct ipmi_intf ipmi_open_intf = {
open: ipmi_openipmi_open,
close: ipmi_openipmi_close,
sendrecv: ipmi_openipmi_send_cmd,
+ set_my_addr: ipmi_openipmi_set_my_addr,
my_addr: IPMI_BMC_SLAVE_ADDR,
target_addr: 0, /* init so -m local_addr does not cause bridging */
};
--
1.7.9.5
--------------040501070004060804090409--
1.7.9.5
--------------040501070004060804090409--