Hi Dmitry,

I've attached an update patch which removes the need to close/re-open the 
interface when
the PICMG discovered IPMB address is found to be different than the IPMB 
address used to
open the interface.    A new per interface function was added to enable setting 
the IPMB
address (if the interface supports it), and the OpenIPMI interface was modified 
to provide this
interface.  See the patch for details.

In putting together the BRIDGE_TO_SENSOR macro, I was working under the 
assumption that channel
0 was always used to identify the primary IPMB Channel (per the IPMI 
specification).  This
is why I first qualify that the SDR sensor record channel is equal to zero 
before I compare the
target_ipmb_addr (which is only set on PICMG platforms), with the SDR sensor 
record address.
This comparison is intended to be true when the sensor is on an IPMB and the 
target IPMB (as returned
by PICMG Get Address Info) matches the sensor address.    If this is the case, 
then this sensor does
not require any extra bridging beyond what was used to address the SDR 
repository (PICMG
platforms only).    If you would like me to explicitly run time verify in the 
macro that this condition is PICMG
only, I can qualify it with intf->picmg_avail in addition to the 
target_ipmb_addr test.

The second condition in the BRIDGE_TO_SENSOR macro simply looks to see if the 
sensor record
address and channel exactly match the argument specified target address and channel 
(-t <address>
-b <channel>).   If this is true, then the sensor does not require any extra 
bridging beyond what
was used to address the SDR repository (any platform).    This second condition 
check doesn't change
the current logic from what exists today, it just clarifies the case in which 
no extra bridging is
necessary beyond what was specified on the ipmitool command line.   If this 
test really confuses folks, it
could be removed.

NOTE: With the code that currently exists today in ipmitool, the address of the 
sensor from the SDR repository
always overwrites the interface target address and target channel prior to 
accessing the sensor
via the interface sendrecv routine.     Then in the interface sendrecv 
routines, bridging requests will be
built using the target address (target_addr) and channel (target_channel) if 
the target_addr doesn't match the
interface address (my_addr).

I did not intend to change how sensors are addressed via bridging on non PICMG 
platforms.

Thanks in Advance,
Jim

-- Jim Mankovich | jm...@hp.com (US Mountain Time) --

On 4/16/2013 11:58 PM, Dmitry Bazhenov wrote:
Hello, Jim,

Please, see my comments mixed in.

17.04.2013 2:21, Jim Mankovich пишет:
Dmitry,

See my comments below.

Thanks,
Jim

-- Jim Mankovich | jm...@hp.com (US Mountain Time) --

On 4/15/2013 11:01 PM, Dmitry Bazhenov wrote:
Hello, Jim,

Your approach has technical and logical flaws.

In technical part, all interface drivers shall be ensured to use
correct IPMB address when establishing or closing session/interface.
This especially regards to LAN and LAN+ drivers. Since some library
functionality may close and re-open the interface during its work (as
does HPM.1), this may cause problems. Also, a correct address must be
used for bridging (when composing a Send Message request).
I did not intended to do anything which would invalidate using "correct
IPMB when establishing or closing session/interface.   But, I did need
to close/re-open to connect to the discovered IPMB address when I ran
across the issue with OpenIPMI.   See my answer to your specific
question associated with OpenIPMI  below.

Understood. But, still, there is an issue with the Send Message request when 
performing bridging or double bridging using the LAN interfaces. Though, it is 
a separate issue.



In logical part, when bridging is used, we must perform the address
retrieval procedure not only on the IPMC on which the interface was
opened, but on the target IPMC as well. And the second acquired
address must be used in sensor owner ID comparison to decide if
bridging is required or not. It might be, if double bridging is used
to access the target IPMC, that sensor values are unreachable.
Using the second acquired address for sensor owner ID comparison for
bridging was my intent with the change I made.  Did you see something
that indicated this was not what I was doing?    Also, the channel
number has to be used in the comparison as well since it is part of
addressing identified in the sensor entries in the SDR repository.

You're right. I have missed it at the first time.

But still, there are issues with checking if bridging is needed:

First: in my opinion, the channel comparison is wrong in the BRIDGE_TO_SENSOR 
macro. The local channel number on the target IPMC may not match with the channel 
number used to access the target IPMC (intf->target_channel).

For example, for PICMG-defined Carrier IPMC, the channel for accessing an AMC 
module is 7, while for the AMC module, the same channel is 0.

I understand that it is likely for PICMG systems that the first check in the 
macro succeeds and the second check does not really matter.
But I am not sure that there will be no problem with other system types.

Second, the target address and channel substitution may be wrong too. This works 
only if intf->target_channel can be used to access the sensor owner, but it may 
not be the case. So, in some situation, additional bridging step is needed. If a 
double bridging is already used, such sensors may not be even reachable.

However, I can not imaging systems where such situation is possible. So, this 
is rather theoretical issue.


Also, since not all IPMCs are PICMG-based, it maybe not correct to use
the Get Address Info command for the target IPMC address retrieval. It
is better to fetch the Management Controller Locator record instead
(implement this retrieval in ipmi_sdr.c or ipmi_sensor.c).

I could certainly do this on non PICMG-based systems, but isn't it
possible that there could be more than one Management Controller Locator
record in the target SDR repository?   If there can be more than one,
how do you know which one to use?

There can be several MC locators for non-PICMG systems. PICMG-systems contain 
only one MC locator and several FRU Device locators for subsidiary FRUs.

I suggest fetching the target_ipmb_addr only for PICMG-based systems.



And regarding to the OpenIPMI interface driver. Is it possible to set
another IPMC address without closing and re-opening interface? Other
interface drivers seem not require such procedure.
The OpenIPMI interface has the ability to set the address vial
IPMICTL_SET_MY_ADDRESS_CMD, and I believe this could be used to avoid
the close/re-open.   Did your fix to resolve bridging issues work
correctly with OpenIPMI?

We do not actively use the OpenIPMI driver, so we are not aware of its issues.
My point is that no other interface drivers need this additional close/open. 
So, it might be worth to do it only for the OpenIPMI interface.

No more comments.

Regards,
Dmitry

Regards,
Dmitry

15.04.2013 23:12, Jim Mankovich пишет:
Hi Dmitry,

I have a similar approach to what you outlined, but I did not find the
need to do
anything different the the "-m" command line switch.   I've attached a
patch I've
been using to resolve the issue I was having and would appreciate any
feedback you
might have on my approach.    The patch is for the CVS ipmitool source
code at TOB
this morning.

I changed ipmi_main() to always open the interface using either 0x20 or
the address
specified with the "-m" switch.   With the code as it exists today, open
is sometimes
done in main and sometimes done when the first IPMI request is made.
I found the
defer of the open quire problematic, so I changed the code to always do
the open prior
to the first IPMI request.    After the initial open, I use the PICMG
get address info to
get the IPMB-0 address.   If I was able to discover an address, I close
and re-open
the interface with the discovered IPMB-0 address as I found this was
necessary to make
sure that the open ipmi driver had the correct address of the target
IPMB-0.   Then, if bridging is
specified with "-t" and/or "-T", I get the bridge target IPMB-0 address
and store that away to
determine when bridging is necessary for sensors identified in the SDR
repository accessed via
the bridging command line arguments.

Thanks,
Jim

-- Jim Mankovich | jm...@hp.com (US Mountain Time) --

On 4/15/2013 9:05 AM, Dmitry Bazhenov wrote:
Hello, Jim,

Your understanding is correct. Moreover, we already have a patch which
solves the issue (in our local IPMITool repo). We are going to submit
the patch for this issue shortly.

And to the topic raised.

The sensor owner ID in the SDR in my opinion shall match with the IPMC
slave address on the primary IPMB bus (channel #0).

Since there are cases when the IPMC accessed from other channels (than
channel #0), like LAN, the slave address of the IPMC on that channel
may
not match with the primary IPMB address.

We solved this problem as follows:
- introduced a BMC address which can be overridden by "-m" command-line
parameter (default valuse is 20h). This address is used to access the
IPMC on which a session to establish a session (for LAN).
- then using Get PICMG Properties to check whether the board is a
PICMG-based system.
- use either Get Address Info for FRU #0 or fetch the Management
Controller Locator Record to query the IPMC slave address on the
primary
IPMB.
- store the fetched slave address. it then used to match the sensor
owner ID to decide if the bridging to sensor is required on not.
- for the case when bridging is used, the stored slave address is used
to compose the Send Message command is return address.

Regards,
Dmitry

15.04.2013 20:47, Jim Mankovich пишет:
All,

I've been digging into various issue associated with ipmitool bridging
on a PICMG

system and I wouldappreciate some help with understanding what the
actual intended

use of the bridging command line arguments was.   There are two
different bridging

argument specifications, -t target_address/-b target_channel (single
bridge), and

-T transit_address/-B transit_channel (dual bridge).

When only -t is specified, single level bridging will be used to read
the SDR repository

if the address specified by -t is not equivalent to the ipmitool
identified IPMB-0 address.

Note: The ipmitool identified IPMB-0 address is either the default of
0x20, or specified

on the command line via the -m address switch, or discovered via PICMG
get address

info.

In addition to -t, you may also specify a transit address via -T.If a
transit address is

specified, dual bridging will be used to read the SDR
repository(via the
transit address

to get to the target identified via -t).   The specification of a
transit address without a

target address is meaningless as the transit address is not used
unless
there is a target

address specification with -t.

Does my description agree with your understanding of these switches
and
their use?

Now, in addition to bridging to read the SDR repository, bridging will
also occur to access

an individual sensor if the sensor owner id identified in the SDR
repository does not match

the ipmitool identified IPMB-0 address.    This bridging will override
the specified target address

identified via the -t switch, but will make use of the transit address
(and dual bridge) when

both -t and -T are specified.

This bridging implementation has issues on the PICMG system I have
been
using when

addressing sensors whose owner id and channel specification in the SDR
repository do

not identify the exact same addressing that was used to read the SDR
repository.

For example:If a sensor identified in an SDR repository resides on
IPMB-0 (channel 0),

but the SDR repository was accessed via bridging on IPMB-L (channel
7),
the sensor can't

be accessed with the current code because the sensor will be addressed
via bridging using

channel 0 (from the SDR repository)instead of channel 7 (from the -b
channel specification).

The problem is that when using bridging to access an SDR
repository, the
bridged SDR

repository destination may actually identify another IPMB-0 at the
bridged destination.

If this is the case, then the sensor can simply be read using the same
bridging as was

used to read the SDR repository.

On PICMG compliant systems, this issue can be resolved by getting the
IPMB-0 address

of the target and compare this target IPMB-0 address with the sensor
owner id/channel

number from the SDR repository.If the sensor owner id is equal to the
target IPMB-0

address and the sensor channel is 0, then the sensor can be accessed
using the same

addressing as was used to address the SDR repository.


I have some ipmitool changes in the works which resolve the sensor
bridging issue
I've described, but I need some insight from someone more familiar
with
PICMG and
sensor bridging to make sure my analysis of the problem I'm seeing is
correct.

Thanks in advance,
Jim

--
-- Jim Mankovich |jm...@hp.com  (US Mountain Time) --



------------------------------------------------------------------------------


Precog is a next-generation analytics platform capable of advanced
analytics on semi-structured data. The platform includes APIs for
building
apps and a phenomenal toolset for data science. Developers can use
our toolset for easy data analysis & visualization. Get a free
account!
http://www2.precog.com/precogplatform/slashdotnewsletter



_______________________________________________
Ipmitool-devel mailing list
Ipmitool-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ipmitool-devel

------------------------------------------------------------------------------


Precog is a next-generation analytics platform capable of advanced
analytics on semi-structured data. The platform includes APIs for
building
apps and a phenomenal toolset for data science. Developers can use
our toolset for easy data analysis & visualization. Get a free account!
http://www2.precog.com/precogplatform/slashdotnewsletter
_______________________________________________
Ipmitool-devel mailing list
Ipmitool-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ipmitool-devel







>From fa4857c8d253ac367d5044903f7c15bc8434aa62 Mon Sep 17 00:00:00 2001
From: Jim Mankovich <jm...@hp.com>
Date: Wed, 17 Apr 2013 10:20:02 -0600
Subject: [PATCH] PICMG Sensor Bridging Update 1


Signed-off-by: Jim Mankovich <jm...@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 */
 };
-- 
1.7.9.5

------------------------------------------------------------------------------
Precog is a next-generation analytics platform capable of advanced
analytics on semi-structured data. The platform includes APIs for building
apps and a phenomenal toolset for data science. Developers can use
our toolset for easy data analysis & visualization. Get a free account!
http://www2.precog.com/precogplatform/slashdotnewsletter
_______________________________________________
Ipmitool-devel mailing list
Ipmitool-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ipmitool-devel

Reply via email to