mirror of
https://github.com/ipmitool/ipmitool.git
synced 2025-05-10 18:47:22 +00:00
"Bridging fixes for PICMG Platforms. Interface is always opened prior to
first IPMI request. Addition of macro to determine necessity of sensor bridging and PICMG target address discover. See ID: 3611226"
This commit is contained in:
parent
cf6740b3f6
commit
72dd3edde4
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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 */
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user