Compare commits

...

15 Commits

Author SHA1 Message Date
be7917f9f5 Changes Integrated since 1.8.14RC2 2014-05-05 07:26:36 -06:00
a7d3bda08d ID: 311 man page update for new sunoem commands 2014-05-05 06:58:08 -06:00
d531785a23 ID: 280 - man page cleanup 2014-04-29 09:38:11 -06:00
eeeb973e39 Make comment about 'source offset' explicit 2014-04-26 14:43:30 +02:00
166ae1da23 ID: 308 - "fru edit" no longer works for non-zero fields
1. Warnings about "FRU Area Length" based on uninitialized (malloc'd) memory
contents (due to fru->max_read_size not being initialized, left at 0) and
fru_data not being zeroed after malloc() in ipmi_fru_set_field_string().

2. "fru edit" commands for any field index other than 0 would fail (with "Field
not found !" error) due to a couple offset and length calculation errors (for
all the supported "area" types) in ipmi_fru_set_field_string().

3. "fru edit" commands would corrupt the FRU Inventory Area due to incorrect
"source offset" value being specified in write_fru_area() call in
impi_fru_set_field_string().

Commit for Rob Swindell
2014-04-25 20:48:40 +02:00
4f0967779e ID: 310 - lanplus retry regression
The lanplus driver for has a bug in ipmi_lanplus_open_session(). There is
an extra and undesired check for a null response (timeout). As a result, it
returns 1 to the caller. The result of this is an occasional assertion. Commit
mends this.

Commit for Pat Donlin
2014-04-25 20:40:36 +02:00
9d88837ef3 Add ticket IDs, if we have one 2014-04-18 06:39:09 +02:00
824c0ed4a0 Add hpm2.h to list of distributed include files 2014-04-17 14:01:22 -06:00
7ea04d8f77 Update ChangeLog for 1.8.14RC2 changes 2014-04-17 13:28:54 -06:00
8d5e8fcf7a Incorrect byteswap in SOL maximum payload code
max_inbound_payload_size, max_outbound_payload_size and port are
assembled byte by byte using shifts. This works correctly in both
little and big endian and doing a subsequent byte swap is wrong.

To highlight this issue I dumped the values on a big endian machine:

max_inbound_payload_size 51200
max_outbound_payload_size 51200
port 28418

And after this fix:

max_inbound_payload_size 200
max_outbound_payload_size 200
port 623

Signed-off-by: Zdenek Styblik <stybla@turnovfree.net>
2014-04-12 15:13:25 +02:00
2c7526be6b Fix build error in HPM.2 code
lib/hpm2.c uses BSWAP_16 without including ipmitool/bswap.h.

Signed-off-by: Zdenek Styblik <stybla@turnovfree.net>
2014-04-12 15:08:39 +02:00
a88db0d181 ID: 300 - new sunoem functionality
Main changes include:

 * direct connection to ILOM command line interface
 * ability to add/delete ssh keys fot ILOM users
 * ability to set ILOM properties
 * ability to retrieve various logs from SP
 * removal of obsolete/non-functioning code and other misc changes

Commit for Martin Hovorka of Oracle
2014-04-09 21:24:05 +02:00
42aba7eb4f ID: 144 - Fix 'dcmi power set_limit action <value>'
From the ticket:
(v1.8.12) "dcmi power set_limit action <value>" (where <value> is either
"sel_logging" or "power_off") does not actually send the "Set Power Limit"
command (so no change to the power limit policy is made).

This was caused by all atoi(), strtol(), strtoul() calls being replaced. This
patch should fix it.

Commit for Holger Liebig
2014-04-08 15:24:55 +02:00
23e9340b49 ID:302 - HPM.2 long message support
This patch adds basic long message support for PICMG-based systems according to
the HPM.2 specification.
It also introduces APIs for setting inbound and outbound messages sizes per
selected interface.
This APIs are used in LAN and LAN+ interfaces to set autonomously detected
inbound and outbound message sizes.
The newly introduced APIs also replace the existing message size detection code
in several ipmitool commands in order to leverage the advantages of long message
support (HPM.1 upgrade, SDR acquring, FRU inventory read and write).
The Kontron-specific long message support is moved under a OEM option.

Commit for Dmitry Bazhenov
2014-04-08 15:18:50 +02:00
707d77ffbc Add new SEL entries for ipmi 2.0 rev 1.1
Signed-off-by: Jordan Hargrave <jordan_hargrave@dell.com>
Signed-off-by: Zdenek Styblik <stybla@turnovfree.net>
2014-04-05 11:38:08 +02:00
23 changed files with 2917 additions and 426 deletions

View File

@ -1,4 +1,4 @@
version 1.8.14 2014-03-28
version 1.8.14 2014-05-05
* ID: 299 - openipmi plugin writes zero to wrong byte
* ID: 301 - Add OS/Hypervisor installation status events
* ID: 298 - fix LANplus retry
@ -23,12 +23,22 @@ version 1.8.14 2014-03-28
* ID: 90 - Add options to chassis bootparam set bootflag
* ID: 292 -Properly handle plugin non-zero target adddress with -t
* Numerous Fixes based on running Coverity
* Use TIOCFLUSH if TCFLSH is missing to get the serial plugin building on Hurd.
* Disable imb and open plugins by default on Hurd. The platform lack the required kernel support.
* Change serial plugin to only try to disable the IUCLC serial line flag on platforms supporting it. Fixes build problem on Hurd and FreeBSD.
* Add support for enabling/disabling PEF policy entries
* Use TIOCFLUSH if TCFLSH is missing to get the serial plugin building on
Hurd.
* Disable imb and open plugins by default on Hurd. The platform lack
the required kernel support.
* Change serial plugin to only try to disable the IUCLC serial line flag on
platforms supporting it. Fixes build problem on Hurd and FreeBSD.
* PA: 83 - Revised IPv6 patch
* FR: 24 - Exchange OS Name Hostname BMC URL during startup
* ID: 304 - Incorect byteswap in SOL maximum payload
* ID: 303 - Fix build error in HPM.2 code
* ID: 300 - new sunoem functionality
* ID: 144 - Fix 'dcmi power set_limit action <value>'
* ID: 302 - HPM.2 long message support
* ID: 309 - Add new SEL entries for ipmi 2.0 rev 1.1
* ID: 280 - man page cleanup
* ID: 311 - man page update for new sunoem commands
version 1.8.13 2013-09-09
* ID: 3611905 - Direct Serial Basic/Terminal Mode Interface drivers

View File

@ -154,9 +154,6 @@ 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\-M\fR <\fIaddress\fP>
Set transit local address for bridge request. (dual bridge)
.TP
\fB\-N\fR <\fIsec\fP>
Specify nr. of seconds between retransmissions of lan/lanplus messages.
Defaults are 2 seconds for lan and 1 second for lanplus interfaces.
@ -2975,10 +2972,19 @@ number. The default is 1.
This command may be used to read SPD (Serial Presence Detect) data using the
I2C Master Write\-Read IPMI command.
.TP
.TP
\fIsunoem\fP
.RS
.TP
.TP
\fIcli\fP [<\fBcommand string\fR> ...]
.br
Execute the service processor command line interface commands.
Without any command string, an interactive session is started
in the service processor command line environ ment. If a
command string is specified, the command string is executed
on the service processor and the connection is closed.
.TP
\fIled\fP
.RS
@ -2987,65 +2993,139 @@ on a Sun Microsystems server. Use 'sdr list generic' to get a
list of devices that are controllable LEDs. The \fIledtype\fP
parameter is optional and not necessary to provide on the command
line unless it is required by hardware.
.TP
.TP
\fIget\fP <\fBsensorid\fR> [<\fBledtype\fR>]
Get status of a particular LED described by a Generic Device Locator
record in the SDR. A sensorid of \fIall\fP will get the status
of all available LEDS.
.TP
.TP
\fIset\fP <\fBsensorid\fR> <\fBledmode\fR> [<\fBledtype\fR>]
Set status of a particular LED described by a Generic Device Locator
record in the SDR. A sensorid of \fIall\fP will set the status
of all available LEDS to the specified \fIledmode\fP and \fIledtype\fP.
.TP
.TP
LED Mode is required for set operations:
.br
.br
\fIOFF\fP Off
.br
.br
\fION\fP Steady On
.br
.br
\fISTANDBY\fP 100ms on 2900ms off blink rate
.br
.br
\fISLOW\fP 1HZ blink rate
.br
.br
\fIFAST\fP 4HZ blink rate
.TP
.TP
LED Type is optional:
.br
.br
\fIOK2RM\fP Ok to Remove
.br
.br
\fISERVICE\fP Service Required
.br
.br
\fIACT\fP Activity
.br
.br
\fILOCATE\fP Locate
.RE
.TP
\fIfan\fP \fIspeed\fP <0-100>
.TP
\fInacname\fP <\fBipmi name\fR>
.br
Set system fan speed (PWM duty cycle).
.RS
.TP
Return the full NAC name of a target identified by ipmi name.
.TP
\fIping\fP <\fBcount\fR> [<\fBq\fR>]
.br
Send and receive count packets. Each packet is 64 bytes.
q - Quiet. Displays output only at the start and end of the process.
.TP
\fIgetval\fP <\fBproperty name\fR>
.br
Returns value of specified ILOM property.
.TP
\fIsetval\fP <\fBproperty name\fR> <\fBproperty value\fR> [<\fBtimeout\fR>]
.br
Sets value of ILOM property. If timeout is not specified, the
default value is 5 seconds. NOTE: setval must be executed locally on host!
.TP
\fIsshkey\fP
.RS
.TP
.TP
\fIset\fP <\fBuserid\fR> <\fBkeyfile\fR>
This command will allow you to specify an SSH key to use for a particular
user on the Service Processor. This key will be used for CLI logins to
the SP and not for IPMI sessions. View available users and their userids
user on the Service Processor. This key will be used for CLI logins to
the SP and not for IPMI sessions. View available users and their userids
with the 'user list' command.
.TP
.TP
\fIdel\fP <\fBuserid\fR>
This command will delete the SSH key for a specified userid.
.RE
.TP
\fIversion\fP
.br
Display the version of ILOM firmware.
.TP
\fIgetfile\fP <\fBfile identifier\fR> <\fBdestination file name\fR>
.br
This command will return various files from service processor and store them
in specified destination file. Note that some files may not be present or
be supported by your SP.
.br
.RS
File identifiers:
.RS
.br
\fISSH_PUBKEYS\fP
.br
\fIDIAG_PASSED\fP
.br
\fIDIAG_FAILED\fP
.br
\fIDIAG_END_TIME\fP
.br
\fIDIAG_INVENTORY\fP
.br
\fIDIAG_TEST_LOG\fP
.br
\fIDIAG_START_TIME\fP
.br
\fIDIAG_UEFI_LOG\fP
.br
\fIDIAG_TEST_LOG\fP
.br
\fIDIAG_LAST_LOG\fP
.br
\fIDIAG_LAST_CMD\fP
.RE
.RE
.TP
\fIgetbehavior\fP <\fBfeature identifier\fR>
.br
This command will test if various ILOM features are enabled.
.br
.RS
Feature identifiers:
.RS
.br
\fISUPPORTS_SIGNED_PACKAGES\fP
.br
\fIREQUIRES_SIGNED_PACKAGES\fP
.RE
.RE
.RE
.TP
\fItsol\fP
.RS

View File

@ -30,7 +30,7 @@
MAINTAINERCLEANFILES = Makefile.in
noinst_HEADERS = log.h bswap.h helper.h ipmi.h ipmi_cc.h ipmi_intf.h \
noinst_HEADERS = log.h bswap.h hpm2.h helper.h ipmi.h ipmi_cc.h ipmi_intf.h \
ipmi_chassis.h ipmi_entity.h ipmi_fru.h ipmi_hpmfwupg.h ipmi_lanp.h \
ipmi_sdr.h ipmi_sel.h ipmi_sol.h ipmi_mc.h ipmi_raw.h \
ipmi_channel.h ipmi_sensor.h ipmi_event.h ipmi_session.h \

86
include/ipmitool/hpm2.h Normal file
View File

@ -0,0 +1,86 @@
/*
* Copyright (c) 2012 Pigeon Point Systems. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Pigeon Point Systems nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
* PIGEON POINT SYSTEMS ("PPS") AND ITS LICENSORS SHALL NOT BE LIABLE
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
* PPS OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
* OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
* LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF PPS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
#include <stdint.h>
#include <ipmitool/ipmi_intf.h>
/* Global HPM.2 defines */
#define HPM2_REVISION 0x01
#define HPM3_REVISION 0x01
#define HPM2_LAN_PARAMS_REV 0x01
#define HPM2_SOL_PARAMS_REV 0x01
#define HPM3_LAN_PARAMS_REV 0x01
/* HPM.2 capabilities */
#define HPM2_CAPS_SOL_EXTENSION 0x01
#define HPM2_CAPS_PACKET_TRACE 0x02
#define HPM2_CAPS_EXT_MANAGEMENT 0x04
#define HPM2_CAPS_VERSION_SENSOR 0x08
#define HPM2_CAPS_DYNAMIC_SESSIONS 0x10
#if HAVE_PRAGMA_PACK
# pragma pack(push, 1)
#endif
/* HPM.2 LAN attach capabilities */
struct hpm2_lan_attach_capabilities {
uint8_t hpm2_revision_id;
uint16_t lan_channel_mask;
uint8_t hpm2_caps;
uint8_t hpm2_lan_params_start;
uint8_t hpm2_lan_params_rev;
uint8_t hpm2_sol_params_start;
uint8_t hpm2_sol_params_rev;
} ATTRIBUTE_PACKING;
/* HPM.2 LAN channel capabilities */
struct hpm2_lan_channel_capabilities {
uint8_t capabilities;
uint8_t attach_type;
uint8_t bandwidth_class;
uint16_t max_inbound_pld_size;
uint16_t max_outbound_pld_size;
} ATTRIBUTE_PACKING;
#if HAVE_PRAGMA_PACK
# pragma pack(pop)
#endif
/* HPM.2 command assignments */
#define HPM2_GET_LAN_ATTACH_CAPABILITIES 0x3E
extern int hpm2_get_capabilities(struct ipmi_intf * intf,
struct hpm2_lan_attach_capabilities * caps);
extern int hpm2_get_lan_channel_capabilities(struct ipmi_intf * intf,
uint8_t hpm2_lan_params_start,
struct hpm2_lan_channel_capabilities * caps);
extern int hpm2_detect_max_payload_size(struct ipmi_intf * intf);

View File

@ -180,7 +180,8 @@ struct ipmi_intf {
uint8_t target_channel;
uint32_t transit_addr;
uint8_t transit_channel;
uint8_t channel_buf_size;
uint16_t max_request_data_size;
uint16_t max_response_data_size;
uint8_t devnum;
@ -193,6 +194,8 @@ struct ipmi_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);
void (*set_max_request_data_size)(struct ipmi_intf * intf, uint16_t size);
void (*set_max_response_data_size)(struct ipmi_intf * intf, uint16_t size);
};
struct ipmi_intf * ipmi_intf_load(char * name);

View File

@ -327,6 +327,8 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
{ 0x07, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Disabled" },
{ 0x07, 0x09, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Terminator presence detected" },
{ 0x07, 0x0a, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Throttled" },
{ 0x07, 0x0b, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Uncorrectable machine check exception" },
{ 0x07, 0x0c, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Correctable machine check error" },
{ 0x08, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Presence detected" },
{ 0x08, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Failure detected" },
@ -337,7 +339,10 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
{ 0x08, 0x06, 0x00, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Config Error: Vendor Mismatch" },
{ 0x08, 0x06, 0x01, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Config Error: Revision Mismatch" },
{ 0x08, 0x06, 0x02, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Config Error: Processor Missing" },
{ 0x08, 0x06, 0x03, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Config Error: Power Supply Rating Mismatch" },
{ 0x08, 0x06, 0x04, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Config Error: Voltage Rating Mismatch" },
{ 0x08, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Config Error" },
{ 0x08, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Power Supply Inactive" },
{ 0x09, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Unit", "Power off/down" },
{ 0x09, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Unit", "Power cycle" },
@ -361,6 +366,7 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
{ 0x0c, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Configuration Error" },
{ 0x0c, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Spare" },
{ 0x0c, 0x09, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Throttled" },
{ 0x0c, 0x0a, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Critical Overtemperature" },
{ 0x0d, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Drive Present" },
{ 0x0d, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Drive Fault" },
@ -480,6 +486,7 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
{ 0x13, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Bus Uncorrectable error" },
{ 0x13, 0x09, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Fatal NMI" },
{ 0x13, 0x0a, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Bus Fatal Error" },
{ 0x13, 0x0b, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Bus Degraded" },
{ 0x14, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Button", "Power Button pressed" },
{ 0x14, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Button", "Sleep Button pressed" },
@ -492,6 +499,7 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
{ 0x17, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Add-in Card", NULL },
{ 0x18, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Chassis", NULL },
{ 0x19, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Chip Set", NULL },
{ 0x19, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Chip Set", "Thermal Trip" },
{ 0x1a, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Other FRU", NULL },
{ 0x1b, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Cable/Interconnect", "Connected" },

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -39,19 +39,35 @@
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_sdr.h>
#define IPMI_NETFN_SUNOEM 0x2e
#define IPMI_NETFN_SUNOEM 0x2e
#define IPMI_SUNOEM_SET_SSH_KEY 0x01
#define IPMI_SUNOEM_DEL_SSH_KEY 0x02
#define IPMI_SUNOEM_GET_HEALTH_STATUS 0x10
#define IPMI_SUNOEM_SET_FAN_SPEED 0x20
#define IPMI_SUNOEM_LED_GET 0x21
#define IPMI_SUNOEM_LED_SET 0x22
#define IPMI_SUNOEM_SET_SSH_KEY 0x01
#define IPMI_SUNOEM_DEL_SSH_KEY 0x02
#define IPMI_SUNOEM_GET_HEALTH_STATUS 0x10
#define IPMI_SUNOEM_CLI 0x19
#define IPMI_SUNOEM_SET_FAN_SPEED 0x20
#define IPMI_SUNOEM_LED_GET 0x21
#define IPMI_SUNOEM_LED_SET 0x22
#define IPMI_SUNOEM_ECHO 0x23
#define IPMI_SUNOEM_VERSION 0x24
#define IPMI_SUNOEM_NACNAME 0x29
#define IPMI_SUNOEM_GETVAL 0x2A
#define IPMI_SUNOEM_SETVAL 0x2C
#define IPMI_SUNOEM_SENSOR_SET 0x3A
#define IPMI_SUNOEM_SET_FAN_MODE 0x41
#define IPMI_SUNOEM_CORE_TUNNEL 0x44
/*
* Error codes of sunoem functions
*/
typedef enum {
SUNOEM_EC_SUCCESS = 0,
SUNOEM_EC_INVALID_ARG = 1,
SUNOEM_EC_BMC_NOT_RESPONDING = 2,
SUNOEM_EC_BMC_CCODE_NONZERO = 3
} sunoem_ec_t;
int ipmi_sunoem_main(struct ipmi_intf *, int, char **);
struct ipmi_rs * sunoem_led_get(struct ipmi_intf * intf, struct sdr_record_generic_locator * dev, int ledtype);
struct ipmi_rs * sunoem_led_set(struct ipmi_intf * intf, struct sdr_record_generic_locator * dev, int ledtype, int ledmode);
#endif /*IPMI_SUNOEM_H*/

View File

@ -39,7 +39,7 @@ libipmitool_la_SOURCES = helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_pef.c \
ipmi_oem.c ipmi_isol.c ipmi_sunoem.c ipmi_fwum.c ipmi_picmg.c \
ipmi_main.c ipmi_tsol.c ipmi_firewall.c ipmi_kontronoem.c \
ipmi_hpmfwupg.c ipmi_sdradd.c ipmi_ekanalyzer.c ipmi_gendev.c \
ipmi_ime.c ipmi_delloem.c ipmi_dcmi.c \
ipmi_ime.c ipmi_delloem.c ipmi_dcmi.c hpm2.c \
../src/plugins/lan/md5.c ../src/plugins/lan/md5.h
libipmitool_la_LDFLAGS = -export-dynamic

289
lib/hpm2.c Normal file
View File

@ -0,0 +1,289 @@
/*
* Copyright (c) 2012 Pigeon Point Systems. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Pigeon Point Systems nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
* PIGEON POINT SYSTEMS ("PPS") AND ITS LICENSORS SHALL NOT BE LIABLE
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
* PPS OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
* OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
* LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF PPS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
#include <ipmitool/hpm2.h>
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/log.h>
#include <ipmitool/bswap.h>
#if HAVE_PRAGMA_PACK
# pragma pack(push, 1)
#endif
/* HPM.x Get Capabilities request */
struct hpmx_cmd_get_capabilities_rq {
uint8_t picmg_id;
uint8_t hpmx_id;
} ATTRIBUTE_PACKING;
/* HPM.2 Get Capabilities response */
struct hpm2_cmd_get_capabilities_rp {
uint8_t picmg_id;
struct hpm2_lan_attach_capabilities caps;
} ATTRIBUTE_PACKING;
#if HAVE_PRAGMA_PACK
# pragma pack(pop)
#endif
/* IPMI Get LAN Configuration Parameters command */
#define IPMI_LAN_GET_CONFIG 0x02
int hpm2_get_capabilities(struct ipmi_intf * intf,
struct hpm2_lan_attach_capabilities * caps)
{
struct ipmi_rq req;
struct ipmi_rs * rsp;
struct hpmx_cmd_get_capabilities_rq rq;
/* reset result */
memset(caps, 0, sizeof(struct hpm2_lan_attach_capabilities));
/* prepare request */
rq.picmg_id = 0;
rq.hpmx_id = 2;
/* prepare request */
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_PICMG;
req.msg.cmd = HPM2_GET_LAN_ATTACH_CAPABILITIES;
req.msg.data = (uint8_t *)&rq;
req.msg.data_len = sizeof(rq);
/* send */
rsp = intf->sendrecv(intf, &req);
if (!rsp) {
lprintf(LOG_NOTICE, "Error sending request.");
return -1;
}
if (rsp->ccode == 0xC1) {
lprintf(LOG_DEBUG, "IPM Controller is not HPM.2 compatible");
return rsp->ccode;
} else if (rsp->ccode) {
lprintf(LOG_NOTICE, "Get HPM.x Capabilities request failed,"
" compcode = %x", rsp->ccode);
return rsp->ccode;
}
/* check response length */
if (rsp->data_len < 2 || rsp->data_len > 10) {
lprintf(LOG_NOTICE, "Bad response length, len=%d", rsp->data_len);
return -1;
}
/* check HPM.x identifier */
if (rsp->data[1] != 2) {
lprintf(LOG_NOTICE, "Bad HPM.x ID, id=%d", rsp->data[1]);
return rsp->ccode;
}
/*
* this hardly can happen, since completion code is already checked.
* but check for safety
*/
if (rsp->data_len < 4) {
lprintf(LOG_NOTICE, "Bad response length, len=%d", rsp->data_len);
return -1;
}
/* copy HPM.2 capabilities */
memcpy(caps, rsp->data + 2, rsp->data_len - 2);
#if WORDS_BIGENDIAN
/* swap bytes to convert from little-endian format */
caps->lan_channel_mask = BSWAP_16(caps->lan_channel_mask);
#endif
/* check HPM.2 revision */
if (caps->hpm2_revision_id != HPM2_REVISION) {
lprintf(LOG_NOTICE, "Bad HPM.2 revision, rev=%d",
caps->hpm2_revision_id);
return -1;
}
if (!caps->lan_channel_mask) {
return -1;
}
/* check response length */
if (rsp->data_len < 8) {
lprintf(LOG_NOTICE, "Bad response length, len=%d", rsp->data_len);
return -1;
}
/* check HPM.2 LAN parameters start */
if (caps->hpm2_lan_params_start < 0xC0) {
lprintf(LOG_NOTICE, "Bad HPM.2 LAN params start, start=%x",
caps->hpm2_lan_params_start);
return -1;
}
/* check HPM.2 LAN parameters revision */
if (caps->hpm2_lan_params_rev != HPM2_LAN_PARAMS_REV) {
lprintf(LOG_NOTICE, "Bad HPM.2 LAN params revision, rev=%d",
caps->hpm2_lan_params_rev);
return -1;
}
/* check for HPM.2 SOL extension */
if (!(caps->hpm2_caps & HPM2_CAPS_SOL_EXTENSION)) {
/* no further checks */
return 0;
}
/* check response length */
if (rsp->data_len < 10) {
lprintf(LOG_NOTICE, "Bad response length, len=%d", rsp->data_len);
return -1;
}
/* check HPM.2 SOL parameters start */
if (caps->hpm2_sol_params_start < 0xC0) {
lprintf(LOG_NOTICE, "Bad HPM.2 SOL params start, start=%x",
caps->hpm2_sol_params_start);
return -1;
}
/* check HPM.2 SOL parameters revision */
if (caps->hpm2_sol_params_rev != HPM2_SOL_PARAMS_REV) {
lprintf(LOG_NOTICE, "Bad HPM.2 SOL params revision, rev=%d",
caps->hpm2_sol_params_rev);
return -1;
}
return 0;
}
int hpm2_get_lan_channel_capabilities(struct ipmi_intf * intf,
uint8_t hpm2_lan_params_start,
struct hpm2_lan_channel_capabilities * caps)
{
struct ipmi_rq req;
struct ipmi_rs * rsp;
uint8_t rq[4];
/* reset result */
memset(caps, 0, sizeof(struct hpm2_lan_channel_capabilities));
/* prepare request */
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_TRANSPORT;
req.msg.cmd = IPMI_LAN_GET_CONFIG;
req.msg.data = (uint8_t *)&rq;
req.msg.data_len = sizeof(rq);
/* prepare request data */
rq[0] = 0xE; /* sending channel */
rq[1] = hpm2_lan_params_start; /* HPM.2 Channel Caps */
rq[2] = rq[3] = 0;
/* send */
rsp = intf->sendrecv(intf, &req);
if (rsp) {
lprintf(LOG_NOTICE, "Error sending request");
return -1;
}
if (rsp->ccode == 0x80) {
lprintf(LOG_DEBUG, "HPM.2 Channel Caps parameter is not supported");
return rsp->ccode;
} else if (rsp->ccode) {
lprintf(LOG_NOTICE, "Get LAN Configuration Parameters request failed,"
" compcode = %x", rsp->ccode);
return rsp->ccode;
}
/* check response length */
if (rsp->data_len != sizeof (struct hpm2_lan_channel_capabilities) + 1) {
lprintf(LOG_NOTICE, "Bad response length, len=%d", rsp->data_len);
return -1;
}
/* check parameter revision */
if (rsp->data[0] != HPM2_LAN_PARAMS_REV) {
lprintf(LOG_NOTICE, "Bad HPM.2 LAN parameter revision, rev=%d",
rsp->data[0]);
return -1;
}
/* copy parameter data */
memcpy(caps, &rsp->data[1], sizeof (struct hpm2_lan_channel_capabilities));
#if WORDS_BIGENDIAN
/* swap bytes to convert from little-endian format */
caps->max_inbound_pld_size = BSWAP_16(caps->max_inbound_pld_size);
caps->max_outbound_pld_size = BSWAP_16(caps->max_outbound_pld_size);
#endif
return 0;
}
int hpm2_detect_max_payload_size(struct ipmi_intf * intf)
{
struct hpm2_lan_attach_capabilities attach_caps;
struct hpm2_lan_channel_capabilities channel_caps;
int err;
/* query HPM.2 support */
err = hpm2_get_capabilities(intf, &attach_caps);
/* check if HPM.2 is supported */
if (err != 0 || !attach_caps.lan_channel_mask) {
return err;
}
/* query channel capabilities */
err = hpm2_get_lan_channel_capabilities(intf,
attach_caps.hpm2_lan_params_start, &channel_caps);
/* check if succeeded */
if (err != 0) {
return err;
}
/* update request and response sizes */
ipmi_intf_set_max_request_data_size(intf,
channel_caps.max_inbound_pld_size - 7);
ipmi_intf_set_max_response_data_size(intf,
channel_caps.max_outbound_pld_size - 8);
/* print debug info */
lprintf(LOG_DEBUG, "Set maximum request size to %d\n"
"Set maximum response size to %d",
intf->max_request_data_size, intf->max_response_data_size);
return 0;
}

View File

@ -187,18 +187,60 @@ const struct dcmi_cmd dcmi_pwrmgmt_vals[] = {
/* set power limit commands */
const struct dcmi_cmd dcmi_pwrmgmt_set_usage_vals[] = {
{ 0x00, "action", " <sel_logging | power_off>" },
{ 0x00, "action", " <no_action | sel_logging | power_off>" },
{ 0x01, "limit", " <number in Watts>" },
{ 0x02, "correction", "<number in milliseconds>" },
{ 0x03, "sample", " <number in seconds>" },
{ 0xFF, NULL, NULL }
};
/* power management/get action commands */
const struct dcmi_cmd dcmi_pwrmgmt_get_action_vals[] = {
{ 0x00, "No Action", ""},
{ 0x01, "Hard Power Off & Log Event to SEL", ""},
{ 0x02, "OEM reserved (02h)", ""},
{ 0x03, "OEM reserved (03h)", ""},
{ 0x04, "OEM reserved (04h)", ""},
{ 0x05, "OEM reserved (05h)", ""},
{ 0x06, "OEM reserved (06h)", ""},
{ 0x07, "OEM reserved (07h)", ""},
{ 0x08, "OEM reserved (08h)", ""},
{ 0x09, "OEM reserved (09h)", ""},
{ 0x0a, "OEM reserved (0ah)", ""},
{ 0x0b, "OEM reserved (0bh)", ""},
{ 0x0c, "OEM reserved (0ch)", ""},
{ 0x0d, "OEM reserved (0dh)", ""},
{ 0x0e, "OEM reserved (0eh)", ""},
{ 0x0f, "OEM reserved (0fh)", ""},
{ 0x10, "OEM reserved (10h)", ""},
{ 0x11, "Log Event to SEL", ""},
{ 0xFF, NULL, NULL }
};
/* power management/set action commands */
const struct dcmi_cmd dcmi_pwrmgmt_action_vals[] = {
{ 0x00, "No Action", "" },
{ 0x01, "Hard Power Off & Log Event to SEL", "" },
{ 0x11, "Log Event to SEL", "" },
{ 0x00, "no_action", "No Action"},
{ 0x01, "power_off", "Hard Power Off & Log Event to SEL"},
{ 0x11, "sel_logging", "Log Event to SEL"},
{ 0x02, "oem_02", "OEM reserved (02h)"},
{ 0x03, "oem_03", "OEM reserved (03h)"},
{ 0x04, "oem_04", "OEM reserved (04h)"},
{ 0x05, "oem_05", "OEM reserved (05h)"},
{ 0x06, "oem_06", "OEM reserved (06h)"},
{ 0x07, "oem_07", "OEM reserved (07h)"},
{ 0x08, "oem_08", "OEM reserved (08h)"},
{ 0x09, "oem_09", "OEM reserved (09h)"},
{ 0x0a, "oem_0a", "OEM reserved (0ah)"},
{ 0x0b, "oem_0b", "OEM reserved (0bh)"},
{ 0x0c, "oem_0c", "OEM reserved (0ch)"},
{ 0x0d, "oem_0d", "OEM reserved (0dh)"},
{ 0x0e, "oem_0e", "OEM reserved (0eh)"},
{ 0x0f, "oem_0f", "OEM reserved (0fh)"},
{ 0x10, "oem_10", "OEM reserved (10h)"},
{ 0xFF, NULL, NULL }
};
@ -481,7 +523,7 @@ ipmi_dcmi_prnt_oobDiscover(struct ipmi_intf * intf)
intf->abort = 1;
intf->session->sol_data.sequence_number = 1;
if (ipmi_intf_socket_connect(intf) == -1) {
if (ipmi_intf_socket_connect (intf) == -1) {
lprintf(LOG_ERR, "Could not open socket!");
return -1;
}
@ -1425,7 +1467,7 @@ ipmi_dcmi_pwr_prnt_glimit(struct ipmi_intf * intf)
(realCc == 0) ?
"Power Limit Active" : "No Active Power Limit");
printf(" Exception actions: %s\n",
val2str2(val.action, dcmi_pwrmgmt_action_vals));
val2str2(val.action, dcmi_pwrmgmt_get_action_vals));
printf(" Power Limit: %i Watts\n", val.limit);
printf(" Correction time: %i milliseconds\n", val.correction);
printf(" Sampling period: %i seconds\n", val.sample);
@ -1456,12 +1498,6 @@ ipmi_dcmi_pwr_slimit(struct ipmi_intf * intf, const char * option,
uint32_t lvalue = 0;
int i;
if (str2uint(value, &lvalue) != 0) {
lprintf(LOG_ERR, "Given %s '%s' is invalid.",
option, value);
return (-1);
}
rsp = ipmi_dcmi_pwr_glimit(intf); /* get the power limit settings */
# if 0
{
@ -1499,39 +1535,124 @@ ipmi_dcmi_pwr_slimit(struct ipmi_intf * intf, const char * option,
* sample period in seconds *
* val.sample = *(uint16_t*)(&rsp->data[12]);
*/
lprintf(LOG_INFO,
"DCMI IN Limit=%d Correction=%d Action=%d Sample=%d\n",
val.limit, val.correction, val.action, val.sample);
switch (str2val2(option, dcmi_pwrmgmt_set_usage_vals)) {
case 0x00:
/* action */
switch (str2val2(value, dcmi_pwrmgmt_action_vals)) {
case 0x00:
/* no_action */
val.action = 0;
break;
case 0x01:
/* power_off */
val.action = 1;
break;
case 0x02:
/* OEM reserved action */
val.action = 0x02;
break;
case 0x03:
/* OEM reserved action */
val.action = 0x03;
break;
case 0x04:
/* OEM reserved action */
val.action = 0x04;
break;
case 0x05:
/* OEM reserved action */
val.action = 0x05;
break;
case 0x06:
/* OEM reserved action */
val.action = 0x06;
break;
case 0x07:
/* OEM reserved action */
val.action = 0x07;
break;
case 0x08:
/* OEM reserved action */
val.action = 0x08;
break;
case 0x09:
/* OEM reserved action */
val.action = 0x09;
break;
case 0x0a:
/* OEM reserved action */
val.action = 0x0a;
break;
case 0x0b:
/* OEM reserved action */
val.action = 0x0b;
break;
case 0x0c:
/* OEM reserved action */
val.action = 0x0c;
break;
case 0x0d:
/* OEM reserved action */
val.action = 0x0d;
break;
case 0x0e:
/* OEM reserved action */
val.action = 0x0e;
break;
case 0x0f:
/* OEM reserved action */
val.action = 0x0f;
break;
case 0x10:
/* OEM reserved action */
val.action = 0x10;
break;
case 0x11:
/* sel_logging*/
val.action = 0x11;
break;
case 0xFF:
/* error - not a string we knew what to do with */
lprintf(LOG_ERR, "Given %s '%s' is invalid.",
option, value);
return -1;
}
break;
case 0x01:
/* limit */
if (str2uint(value, &lvalue) != 0) {
lprintf(LOG_ERR, "Given %s '%s' is invalid.",
option, value);
return (-1);
}
val.limit = *(uint16_t*)(&lvalue);
break;
case 0x02:
/* correction */
if (str2uint(value, &lvalue) != 0) {
lprintf(LOG_ERR, "Given %s '%s' is invalid.",
option, value);
return (-1);
}
val.correction = *(uint32_t*)(&lvalue);
break;
case 0x03:
/* sample */
if (str2uint(value, &lvalue) != 0) {
lprintf(LOG_ERR, "Given %s '%s' is invalid.",
option, value);
return (-1);
}
val.sample = *(uint16_t*)(&lvalue);
break;
case 0xff:
/* no valid options */
return -1;
}
lprintf(LOG_INFO, "DCMI OUT Limit=%d Correction=%d Action=%d Sample=%d\n", val.limit, val.correction, val.action, val.sample);
msg_data[0] = val.grp_id; /* Group Extension Identification */
msg_data[1] = 0x00; /* reserved */
@ -1696,6 +1817,10 @@ ipmi_dcmi_main(struct ipmi_intf * intf, int argc, char **argv)
/* action */
switch (str2val2(argv[2], dcmi_pwrmgmt_action_vals)) {
case 0x00:
/* no_action */
data[4] = 0x00;
break;
case 0x01:
/* power_off */
data[4] = 0x01;
@ -1706,6 +1831,8 @@ ipmi_dcmi_main(struct ipmi_intf * intf, int argc, char **argv)
break;
case 0xFF:
/* error - not a string we knew what to do with */
lprintf(LOG_ERR, "Given Action '%s' is invalid.",
argv[2]);
return -1;
}
/* limit */

View File

@ -454,12 +454,25 @@ write_fru_area(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
/* initialize request size only once */
if (fru->max_write_size == 0) {
if (intf->channel_buf_size != 0) {
/* subtract 1 byte for FRU ID an 2 bytes for offset */
fru->max_write_size = intf->channel_buf_size - 3;
uint16_t max_rq_size = ipmi_intf_get_max_request_data_size(intf);
/* validate lower bound of the maximum request data size */
if (max_rq_size <= 3) {
lprintf(LOG_ERROR, "Maximum request size is too small to send "
"a write request");
return -1;
}
/*
* Write FRU Info command returns the number of written bytes in
* a single byte field.
*/
if (max_rq_size - 3 > 255) {
/* Limit the max write size with 255 bytes. */
fru->max_write_size = 255;
} else {
/* subtract 1 byte for FRU ID an 2 bytes for offset */
fru->max_write_size = 32 - 3;
fru->max_write_size = max_rq_size - 3;
}
/* check word access */
@ -611,8 +624,25 @@ read_fru_area(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
req.msg.data_len = 4;
if (fru->max_read_size == 0) {
/* subtract 1 byte for completion code and 1 for byte count */
fru->max_read_size = 32 - 2;
uint16_t max_rs_size = ipmi_intf_get_max_response_data_size(intf) - 1;
/* validate lower bound of the maximum response data size */
if (max_rs_size <= 1) {
lprintf(LOG_ERROR, "Maximum response size is too small to send "
"a read request");
return -1;
}
/*
* Read FRU Info command may read up to 255 bytes of data.
*/
if (max_rs_size - 1 > 255) {
/* Limit the max read size with 255 bytes. */
fru->max_read_size = 255;
} else {
/* subtract 1 byte for bytes count */
fru->max_read_size = max_rs_size - 1;
}
/* check word access */
if (fru->access) {
@ -4687,22 +4717,22 @@ f_type, uint8_t f_index, char *f_string)
if (f_type == 'c' ) {
header_offset = (header.offset.chassis * 8);
read_fru_area(intf ,&fru, fruId, header_offset , 3 , fru_data);
fru_field_offset = (header.offset.chassis * 8) + 3;
fru_section_len = *(fru_data + header_offset + 1) * 8;
fru_field_offset = 3;
fru_section_len = *(fru_data + 1) * 8;
}
/* Board type field */
else if (f_type == 'b' ) {
header_offset = (header.offset.board * 8);
read_fru_area(intf ,&fru, fruId, header_offset , 3 , fru_data);
fru_field_offset = (header.offset.board * 8) + 6;
fru_section_len = *(fru_data + header_offset + 1) * 8;
fru_field_offset = 6;
fru_section_len = *(fru_data + 1) * 8;
}
/* Product type field */
else if (f_type == 'p' ) {
header_offset = (header.offset.product * 8);
read_fru_area(intf ,&fru, fruId, header_offset , 3 , fru_data);
fru_field_offset = (header.offset.product * 8) + 3;
fru_section_len = *(fru_data + header_offset + 1) * 8;
fru_field_offset = 3;
fru_section_len = *(fru_data + 1) * 8;
}
else
{
@ -4752,8 +4782,8 @@ f_type, uint8_t f_index, char *f_string)
checksum = (~checksum) + 1;
fru_data[header_offset + fru_section_len - 1] = checksum;
/* Write the updated section to the FRU data */
if( write_fru_area(intf, &fru, fruId, header_offset,
/* Write the updated section to the FRU data; source offset => 0 */
if( write_fru_area(intf, &fru, fruId, 0,
header_offset, fru_section_len, fru_data) < 0 )
{
printf("Write to FRU data failed.\n");

View File

@ -1072,38 +1072,6 @@ HpmfwupgUpgradeStage(struct ipmi_intf *intf,
return rc;
}
int
get_max_rq_data_size(struct ipmi_intf *intf)
{
int bufLength;
/* Check if we receive size in parameters */
if(intf->channel_buf_size != 0) {
/* Plan for overhead */
if (intf->target_addr == intf->my_addr) {
bufLength = intf->channel_buf_size - 9;
} else {
bufLength = intf->channel_buf_size - 11;
}
} else if (strstr(intf->name,"lan") != NULL) {
/* Find max buffer length according the connection
* parameters
*/
bufLength = HPMFWUPG_SEND_DATA_COUNT_LAN - 2;
if (intf->transit_addr != intf->my_addr
&& intf->transit_addr != 0) {
bufLength -= 8;
}
} else if (strstr(intf->name,"open") != NULL
&& intf->target_addr == intf->my_addr) {
bufLength = HPMFWUPG_SEND_DATA_COUNT_KCS - 2;
} else if (intf->target_channel == 7) {
bufLength = HPMFWUPG_SEND_DATA_COUNT_IPMBL;
} else {
bufLength = HPMFWUPG_SEND_DATA_COUNT_IPMB;
}
return bufLength;
}
int
HpmFwupgActionUploadFirmware(struct HpmfwupgComponentBitMask components,
struct HpmfwupgUpgradeCtx *pFwupgCtx,
@ -1138,6 +1106,8 @@ HpmFwupgActionUploadFirmware(struct HpmfwupgComponentBitMask components,
unsigned char mode = 0;
unsigned char componentId = 0x00;
unsigned char componentIdByte = 0x00;
uint16_t max_rq_size;
/* Save component ID on which the upload is done */
componentIdByte = components.ComponentBits.byte;
while ((componentIdByte>>= 1) != 0) {
@ -1150,8 +1120,19 @@ HpmFwupgActionUploadFirmware(struct HpmfwupgComponentBitMask components,
pDataInitial = ((unsigned char *)pFwImage
+ sizeof(struct HpmfwupgFirmwareImage));
pData = pDataInitial;
/* Find max buffer length according the connection parameters */
bufLength = get_max_rq_data_size(intf);
max_rq_size = ipmi_intf_get_max_request_data_size(intf);
/* validate lower bound of max request size */
if (max_rq_size <= sizeof(struct HpmfwupgUploadFirmwareBlockReq)) {
lprintf(LOG_ERROR, "Maximum request size is too small to "
"send a upload request.");
return HPMFWUPG_ERROR;
}
bufLength = max_rq_size - sizeof(struct HpmfwupgUploadFirmwareBlockReq);
/* Get firmware length */
firmwareLength = pFwImage->length[0];
firmwareLength|= (pFwImage->length[1] << 8) & 0xff00;
@ -1178,8 +1159,7 @@ HpmFwupgActionUploadFirmware(struct HpmfwupgComponentBitMask components,
if (!skip) {
HpmDisplayUpgrade(0,0,1,0);
/* Initialize parameters */
uploadCmd.req = malloc(get_max_rq_data_size(intf)
+ sizeof(struct HpmfwupgUploadFirmwareBlockReq));
uploadCmd.req = malloc(max_rq_size);
if (!uploadCmd.req) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
return HPMFWUPG_ERROR;

View File

@ -982,13 +982,15 @@ ipmi_main(int argc, char ** argv,
}
/* Enable Big Buffer when requested */
ipmi_main_intf->channel_buf_size = 0;
if ( my_long_packet_size != 0 ) {
printf("Setting large buffer to %i\n", my_long_packet_size);
if (ipmi_kontronoem_set_large_buffer( ipmi_main_intf, my_long_packet_size ) == 0)
{
/* Enable Big Buffer when requested */
if (!ipmi_oem_active(ipmi_main_intf, "kontron") ||
ipmi_kontronoem_set_large_buffer(ipmi_main_intf,
my_long_packet_size ) == 0) {
printf("Setting large buffer to %i\n", my_long_packet_size);
my_long_packet_set = 1;
ipmi_main_intf->channel_buf_size = my_long_packet_size;
ipmi_intf_set_max_request_data_size(ipmi_main_intf,
my_long_packet_size);
}
}
@ -1002,8 +1004,10 @@ ipmi_main(int argc, char ** argv,
rc = ipmi_cmd_run(ipmi_main_intf, NULL, 0, NULL);
if (my_long_packet_set == 1) {
/* Restore defaults */
ipmi_kontronoem_set_large_buffer( ipmi_main_intf, 0 );
if (ipmi_oem_active(ipmi_main_intf, "kontron")) {
/* Restore defaults */
ipmi_kontronoem_set_large_buffer( ipmi_main_intf, 0 );
}
}
/* clean repository caches */

View File

@ -67,6 +67,10 @@ static struct ipmi_oem_handle ipmi_oem_list[] = {
name: "i82571spt",
desc: "Intel 82571 MAC with integrated RMCP+ support in super pass-through mode",
},
{
name: "kontron",
desc: "Kontron OEM big buffer support"
},
{ 0 }
};

View File

@ -59,7 +59,7 @@
extern int verbose;
static int use_built_in; /* Uses DeviceSDRs instead of SDRR */
static int sdr_max_read_len = GET_SDR_ENTIRE_RECORD;
static int sdr_max_read_len = 0;
static int sdr_extended = 0;
static long sdriana = 0;
@ -3024,6 +3024,17 @@ ipmi_sdr_get_record(struct ipmi_intf * intf, struct sdr_get_rs * header,
req.msg.data = (uint8_t *) & sdr_rq;
req.msg.data_len = sizeof (sdr_rq);
/* check if max length is null */
if ( sdr_max_read_len == 0 ) {
/* get maximum response size */
sdr_max_read_len = ipmi_intf_get_max_response_data_size(intf) - 2;
/* cap the number of bytes to read */
if (sdr_max_read_len > 0xFE) {
sdr_max_read_len = 0xFE;
}
}
/* read SDR record with partial reads
* because a full read usually exceeds the maximum
* transport buffer size. (completion code 0xca)

View File

@ -1830,17 +1830,6 @@ ipmi_sol_activate(struct ipmi_intf * intf, int looptest, int interval,
(ap_rsp.payload_udp_port[1] << 8) |
ap_rsp.payload_udp_port[0];
#if WORDS_BIGENDIAN
intf->session->sol_data.max_inbound_payload_size =
BSWAP_16(intf->session->sol_data.max_inbound_payload_size);
intf->session->sol_data.max_outbound_payload_size =
BSWAP_16(intf->session->sol_data.max_outbound_payload_size);
intf->session->sol_data.port =
BSWAP_16(intf->session->sol_data.port);
#endif
intf->session->timeout = 1;

File diff suppressed because it is too large Load Diff

View File

@ -53,6 +53,8 @@
#include <ipmitool/ipmi_sdr.h>
#include <ipmitool/log.h>
#define IPMI_DEFAULT_PAYLOAD_SIZE 25
#ifdef IPMI_INTF_OPEN
extern struct ipmi_intf ipmi_open_intf;
#endif
@ -497,3 +499,153 @@ ipmi_intf_socket_connect(struct ipmi_intf * intf)
}
#endif
uint16_t
ipmi_intf_get_max_request_data_size(struct ipmi_intf * intf)
{
int16_t size;
size = intf->max_request_data_size;
/* check if request size is not specified */
if (!size) {
/*
* The IPMB standard overall message length for <20>non -bridging<6E>
* messages is specified as 32 bytes, maximum, including slave
* address. This sets the upper limit for typical IPMI messages.
* With the exception of messages used for bridging messages to
* other busses or interfaces (e.g. Master Write-Read and Send Message)
* IPMI messages should be designed to fit within this 32-byte maximum.
* In order to support bridging, the Master Write -Read and Send Message
* commands are allowed to exceed the 32-byte maximum transaction on IPMB
*/
size = IPMI_DEFAULT_PAYLOAD_SIZE;
/* check if message is forwarded */
if (intf->target_addr && intf->target_addr != intf->my_addr) {
/* add Send Message request size */
size += 8;
}
}
/* check if message is forwarded */
if (intf->target_addr && intf->target_addr != intf->my_addr) {
/* subtract send message request size */
size -= 8;
/*
* Check that forwarded request size is not greater
* than the default payload size.
*/
if (size > IPMI_DEFAULT_PAYLOAD_SIZE) {
size = IPMI_DEFAULT_PAYLOAD_SIZE;
}
/* check for double bridging */
if (intf->transit_addr && intf->transit_addr != intf->target_addr) {
/* subtract inner send message request size */
size -= 8;
}
}
/* check for underflow */
if (size < 0) {
return 0;
}
return size;
}
uint16_t
ipmi_intf_get_max_response_data_size(struct ipmi_intf * intf)
{
int16_t size;
size = intf->max_response_data_size;
/* check if response size is not specified */
if (!size) {
/*
* The IPMB standard overall message length for <20>non -bridging<6E>
* messages is specified as 32 bytes, maximum, including slave
* address. This sets the upper limit for typical IPMI messages.
* With the exception of messages used for bridging messages to
* other busses or interfaces (e.g. Master Write-Read and Send Message)
* IPMI messages should be designed to fit within this 32-byte maximum.
* In order to support bridging, the Master Write -Read and Send Message
* commands are allowed to exceed the 32-byte maximum transaction on IPMB
*/
size = IPMI_DEFAULT_PAYLOAD_SIZE; /* response length with subtracted header and checksum byte */
/* check if message is forwarded */
if (intf->target_addr && intf->target_addr != intf->my_addr) {
/* add Send Message header size */
size += 7;
}
}
/* check if message is forwarded */
if (intf->target_addr && intf->target_addr != intf->my_addr) {
/*
* Some IPMI controllers like PICMG AMC Carriers embed responses
* to the forwarded messages into the Send Message response.
* In order to be sure that the response is not truncated,
* subtract the internal message header size.
*/
size -= 8;
/*
* Check that forwarded response is not greater
* than the default payload size.
*/
if (size > IPMI_DEFAULT_PAYLOAD_SIZE) {
size = IPMI_DEFAULT_PAYLOAD_SIZE;
}
/* check for double bridging */
if (intf->transit_addr && intf->transit_addr != intf->target_addr) {
/* subtract inner send message header size */
size -= 8;
}
}
/* check for underflow */
if (size < 0) {
return 0;
}
return size;
}
void
ipmi_intf_set_max_request_data_size(struct ipmi_intf * intf, uint16_t size)
{
if (size < IPMI_DEFAULT_PAYLOAD_SIZE) {
lprintf(LOG_ERR, "Request size is too small (%d), leave default size",
size);
return;
}
if (intf->set_max_request_data_size) {
intf->set_max_request_data_size(intf, size);
} else {
intf->max_request_data_size = size;
}
}
void
ipmi_intf_set_max_response_data_size(struct ipmi_intf * intf, uint16_t size)
{
if (size < IPMI_DEFAULT_PAYLOAD_SIZE - 1) {
lprintf(LOG_ERR, "Response size is too small (%d), leave default size",
size);
return;
}
if (intf->set_max_response_data_size) {
intf->set_max_response_data_size(intf, size);
} else {
intf->max_response_data_size = size;
}
}

View File

@ -52,6 +52,7 @@
#include <ipmitool/ipmi_oem.h>
#include <ipmitool/ipmi_strings.h>
#include <ipmitool/ipmi_constants.h>
#include <ipmitool/hpm2.h>
#if HAVE_CONFIG_H
# include <config.h>
@ -67,6 +68,13 @@
#define IPMI_LAN_PORT 0x26f
#define IPMI_LAN_CHANNEL_E 0x0e
/*
* LAN interface is required to support 45 byte request transactions and
* 42 byte response transactions.
*/
#define IPMI_LAN_MAX_REQUEST_SIZE 38 /* 45 - 7 */
#define IPMI_LAN_MAX_RESPONSE_SIZE 34 /* 42 - 8 */
extern const struct valstr ipmi_privlvl_vals[];
extern const struct valstr ipmi_authtype_session_vals[];
extern int verbose;
@ -88,6 +96,8 @@ static int ipmi_lan_send_rsp(struct ipmi_intf * intf, struct ipmi_rs * rsp);
static int ipmi_lan_open(struct ipmi_intf * intf);
static void ipmi_lan_close(struct ipmi_intf * intf);
static int ipmi_lan_ping(struct ipmi_intf * intf);
static void ipmi_lan_set_max_rq_data_size(struct ipmi_intf * intf, uint16_t size);
static void ipmi_lan_set_max_rp_data_size(struct ipmi_intf * intf, uint16_t size);
struct ipmi_intf ipmi_lan_intf = {
name: "lan",
@ -100,6 +110,8 @@ struct ipmi_intf ipmi_lan_intf = {
recv_sol: ipmi_lan_recv_sol,
send_sol: ipmi_lan_send_sol,
keepalive: ipmi_lan_keepalive,
set_max_request_data_size: ipmi_lan_set_max_rq_data_size,
set_max_response_data_size: ipmi_lan_set_max_rp_data_size,
target_addr: IPMI_BMC_SLAVE_ADDR,
};
@ -2055,6 +2067,10 @@ ipmi_lan_open(struct ipmi_intf * intf)
}
intf->manufacturer_id = ipmi_get_oem(intf);
/* automatically detect interface request and response sizes */
hpm2_detect_max_payload_size(intf);
return intf->fd;
}
@ -2067,5 +2083,30 @@ ipmi_lan_setup(struct ipmi_intf * intf)
return -1;
}
memset(intf->session, 0, sizeof(struct ipmi_session));
/* setup default LAN maximum request and response sizes */
intf->max_request_data_size = IPMI_LAN_MAX_REQUEST_SIZE;
intf->max_response_data_size = IPMI_LAN_MAX_RESPONSE_SIZE;
return 0;
}
static void
ipmi_lan_set_max_rq_data_size(struct ipmi_intf * intf, uint16_t size)
{
if (size + 7 > 0xFF) {
size = 0xFF - 7;
}
intf->max_request_data_size = size;
}
static void
ipmi_lan_set_max_rp_data_size(struct ipmi_intf * intf, uint16_t size)
{
if (size + 8 > 0xFF) {
size = 0xFF - 8;
}
intf->max_response_data_size = size;
}

View File

@ -55,6 +55,7 @@
#include <ipmitool/ipmi_channel.h>
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_strings.h>
#include <ipmitool/hpm2.h>
#include <ipmitool/bswap.h>
#include <openssl/rand.h>
@ -65,6 +66,13 @@
#include "rmcp.h"
#include "asf.h"
/*
* LAN interface is required to support 45 byte request transactions and
* 42 byte response transactions.
*/
#define IPMI_LAN_MAX_REQUEST_SIZE 38 /* 45 - 7 */
#define IPMI_LAN_MAX_RESPONSE_SIZE 34 /* 42 - 8 */
extern const struct valstr ipmi_rakp_return_codes[];
extern const struct valstr ipmi_priv_levels[];
extern const struct valstr ipmi_auth_algorithms[];
@ -112,8 +120,10 @@ static int check_sol_packet_for_new_data(
static void ack_sol_packet(
struct ipmi_intf * intf,
struct ipmi_rs * rsp);
static void ipmi_lanp_set_max_rq_data_size(struct ipmi_intf * intf, uint16_t size);
static void ipmi_lanp_set_max_rp_data_size(struct ipmi_intf * intf, uint16_t size);
static uint8_t bridgePossible = 0;
static uint8_t bridgePossible = 0;
struct ipmi_intf ipmi_lanplus_intf = {
name: "lanplus",
@ -125,6 +135,8 @@ struct ipmi_intf ipmi_lanplus_intf = {
recv_sol: ipmi_lanplus_recv_sol,
send_sol: ipmi_lanplus_send_sol,
keepalive: ipmi_lanplus_keepalive,
set_max_request_data_size: ipmi_lanp_set_max_rq_data_size,
set_max_response_data_size: ipmi_lanp_set_max_rp_data_size,
target_addr: IPMI_BMC_SLAVE_ADDR,
};
@ -2870,17 +2882,13 @@ ipmi_lanplus_open_session(struct ipmi_intf * intf)
free(msg);
msg = NULL;
if (!rsp) {
lprintf(LOG_WARNING, "Error sending open session message.");
return -1;
}
if (verbose)
lanplus_dump_open_session_response(rsp);
if (rsp == NULL ) {
lprintf(LOG_DEBUG, "Timeout in open session response message.");
return 2;
}
if (verbose)
lanplus_dump_open_session_response(rsp);
if (rsp->payload.open_session_response.rakp_return_code !=
IPMI_RAKP_STATUS_NO_ERRORS)
{
@ -3473,6 +3481,9 @@ ipmi_lanplus_open(struct ipmi_intf * intf)
intf->manufacturer_id = ipmi_get_oem(intf);
bridgePossible = 1;
/* automatically detect interface request and response sizes */
hpm2_detect_max_payload_size(intf);
return intf->fd;
fail:
@ -3624,5 +3635,46 @@ static int ipmi_lanplus_setup(struct ipmi_intf * intf)
return -1;
}
memset(intf->session, 0, sizeof(struct ipmi_session));
/* setup default LAN maximum request and response sizes */
intf->max_request_data_size = IPMI_LAN_MAX_REQUEST_SIZE;
intf->max_response_data_size = IPMI_LAN_MAX_RESPONSE_SIZE;
return 0;
}
static void ipmi_lanp_set_max_rq_data_size(struct ipmi_intf * intf, uint16_t size)
{
if (intf->session->cipher_suite_id == 3) {
/*
* encrypted payload can only be multiple of 16 bytes
*/
size &= ~15;
/*
* decrement payload size on confidentiality header size
* plus minimal confidentiality trailer size
*/
size -= (16 + 1);
}
intf->max_request_data_size = size;
}
static void ipmi_lanp_set_max_rp_data_size(struct ipmi_intf * intf, uint16_t size)
{
if (intf->session->cipher_suite_id == 3) {
/*
* encrypted payload can only be multiple of 16 bytes
*/
size &= ~15;
/*
* decrement payload size on confidentiality header size
* plus minimal confidentiality trailer size
*/
size -= (16 + 1);
}
intf->max_response_data_size = size;
}

View File

@ -65,6 +65,22 @@
# include "open.h"
#endif
/**
* Maximum input message size for KCS/SMIC is 40 with 2 utility bytes and
* 38 bytes of data.
* Maximum input message size for BT is 42 with 4 utility bytes and
* 38 bytes of data.
*/
#define IPMI_OPENIPMI_MAX_RQ_DATA_SIZE 38
/**
* Maximum output message size for KCS/SMIC is 38 with 2 utility bytes, a byte
* for completion code and 35 bytes of data.
* Maximum output message size for BT is 40 with 4 utility bytes, a byte
* for completion code and 35 bytes of data.
*/
#define IPMI_OPENIPMI_MAX_RS_DATA_SIZE 35
extern int verbose;
static int
@ -401,9 +417,19 @@ ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
return &rsp;
}
int ipmi_openipmi_setup(struct ipmi_intf * intf)
{
/* set default payload size */
intf->max_request_data_size = IPMI_OPENIPMI_MAX_RQ_DATA_SIZE;
intf->max_response_data_size = IPMI_OPENIPMI_MAX_RS_DATA_SIZE;
return 0;
}
struct ipmi_intf ipmi_open_intf = {
name: "open",
desc: "Linux OpenIPMI Interface",
setup: ipmi_openipmi_setup,
open: ipmi_openipmi_open,
close: ipmi_openipmi_close,
sendrecv: ipmi_openipmi_send_cmd,

View File

@ -189,6 +189,10 @@ serial_bm_setup(struct ipmi_intf * intf)
return -1;
}
memset(intf->session, 0, sizeof(struct ipmi_session));
/* setup default LAN maximum request and response sizes */
intf->max_request_data_size = SERIAL_BM_MAX_RQ_SIZE;
intf->max_response_data_size = SERIAL_BM_MAX_RS_SIZE;
return 0;
}

View File

@ -894,6 +894,10 @@ ipmi_serial_term_setup(struct ipmi_intf * intf)
}
memset(intf->session, 0, sizeof(struct ipmi_session));
/* setup default LAN maximum request and response sizes */
intf->max_request_data_size = IPMI_SERIAL_MAX_RQ_SIZE;
intf->max_response_data_size = IPMI_SERIAL_MAX_RS_SIZE;
return 0;
}