diff --git a/ipmitool/doc/ipmitool.1 b/ipmitool/doc/ipmitool.1 index 1befd67..2445004 100644 --- a/ipmitool/doc/ipmitool.1 +++ b/ipmitool/doc/ipmitool.1 @@ -123,8 +123,9 @@ Force session privilege level. Can be CALLBACK, USER, OPERATOR, ADMINISTRATOR. Default is ADMINISTRATOR. .TP \fB\-m\fR <\fIlocal_address\fP> -Set the local IPMB address. The default is 0x20 and there -should be no need to change it for normal operation. +Set the local IPMB address. The local address defaults to 0x20 +or is auto discovered on PICMG platforms when -m is not specified. +There should be no need to change the local address for normal operation. .TP \fB\-N\fR <\fIsec\fP> Specify nr. of seconds between retransmissions of lan/lanplus messages. diff --git a/ipmitool/include/ipmitool/ipmi_intf.h b/ipmitool/include/ipmitool/ipmi_intf.h index 8b5b6f6..270f92d 100644 --- a/ipmitool/include/ipmitool/ipmi_intf.h +++ b/ipmitool/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/ipmitool/include/ipmitool/ipmi_picmg.h b/ipmitool/include/ipmitool/ipmi_picmg.h index 5f73be2..3d70454 100644 --- a/ipmitool/include/ipmitool/ipmi_picmg.h +++ b/ipmitool/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_discover(struct ipmi_intf *intf); +uint8_t ipmi_picmg_ipmb_address(struct ipmi_intf *intf); #endif diff --git a/ipmitool/include/ipmitool/ipmi_sdr.h b/ipmitool/include/ipmitool/ipmi_sdr.h index 0f168d2..724d0cd 100644 --- a/ipmitool/include/ipmitool/ipmi_sdr.h +++ b/ipmitool/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/ipmitool/lib/ipmi_fru.c b/ipmitool/lib/ipmi_fru.c index af366d8..aaf2e5e 100644 --- a/ipmitool/lib/ipmi_fru.c +++ b/ipmitool/lib/ipmi_fru.c @@ -3106,7 +3106,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) @@ -3146,14 +3147,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/ipmitool/lib/ipmi_main.c b/ipmitool/lib/ipmi_main.c index cc04b51..b8da60d 100644 --- a/ipmitool/lib/ipmi_main.c +++ b/ipmitool/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,94 +872,83 @@ 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 ; - - /* setup destination channel if given */ - ipmi_main_intf->target_channel = target_channel ; - ipmi_main_intf->devnum = devnum; - /* 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; + /* Open the interface with the specified or default IPMB 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); - /* 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"); - } + /* + * Attempt picmg discovery of the actual interface address unless + * the users specified an address. + * Address specification always overrides discovery + */ + if (picmg_discover(ipmi_main_intf) && !arg_addr) { + lprintf(LOG_DEBUG, "Running PICMG Get Address Info"); + addr = ipmi_picmg_ipmb_address(ipmi_main_intf); + lprintf(LOG_INFO, "Discovered IPMB-0 address 0x%x", addr); } - 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); + /* + * 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) { + /* + * Only set the interface address on interfaces which support + * it + */ + (void) ipmi_main_intf->set_my_addr(ipmi_main_intf, addr); + } - 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; + /* 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 ; + + ipmi_main_intf->transit_addr = transit_addr; + ipmi_main_intf->transit_channel = transit_channel; + + /* 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); + if (ipmi_main_intf->target_ipmb_addr) { + lprintf(LOG_INFO, "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) { ipmi_sdr_list_cache_fromfile(ipmi_main_intf, sdrcache); @@ -1048,3 +1029,5 @@ ipmi_main(int argc, char ** argv, return rc; } + + diff --git a/ipmitool/lib/ipmi_picmg.c b/ipmitool/lib/ipmi_picmg.c index ba43924..b303752 100644 --- a/ipmitool/lib/ipmi_picmg.c +++ b/ipmitool/lib/ipmi_picmg.c @@ -1780,3 +1780,83 @@ 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_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) { + 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_INFO, "Running 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 == 0) { + lprintf(LOG_INFO, "No PICMG Extenstion discovered"); + } + return intf->picmg_avail; +} diff --git a/ipmitool/lib/ipmi_sdr.c b/ipmitool/lib/ipmi_sdr.c index 88af447..89357f3 100644 --- a/ipmitool/lib/ipmi_sdr.c +++ b/ipmitool/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/ipmitool/lib/ipmi_sel.c b/ipmitool/lib/ipmi_sel.c index 490f33d..d8ced54 100644 --- a/ipmitool/lib/ipmi_sel.c +++ b/ipmitool/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/ipmitool/lib/ipmi_sensor.c b/ipmitool/lib/ipmi_sensor.c index 41276b1..9abac00 100644 --- a/ipmitool/lib/ipmi_sensor.c +++ b/ipmitool/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/ipmitool/src/plugins/lanplus/lanplus.c b/ipmitool/src/plugins/lanplus/lanplus.c index 4288224..d2aca7f 100644 --- a/ipmitool/src/plugins/lanplus/lanplus.c +++ b/ipmitool/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) @@ -1409,6 +1409,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 +3303,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 +3313,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 +3462,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/ipmitool/src/plugins/open/open.c b/ipmitool/src/plugins/open/open.c index 34cb10c..5567992 100644 --- a/ipmitool/src/plugins/open/open.c +++ b/ipmitool/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 */ };