"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:
Jim Mankovich 2013-05-06 14:08:56 +00:00
parent cf6740b3f6
commit 72dd3edde4
12 changed files with 313 additions and 169 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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

View File

@ -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,

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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:

View File

@ -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 */
};