diff -u ipmitool-1.8.11/debian/control ipmitool-1.8.11/debian/control --- ipmitool-1.8.11/debian/control +++ ipmitool-1.8.11/debian/control @@ -1,7 +1,8 @@ Source: ipmitool Section: utils Priority: optional -Maintainer: Matthew Johnson +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: Matthew Johnson Uploaders: Luk Claes Build-Depends: debhelper (>> 5.0.0), libreadline-dev, libncurses-dev, libssl-dev, quilt, autotools-dev Vcs-Browser: http://anonscm.debian.org/gitweb/?p=collab-maint/ipmitool.git @@ -11,7 +12,7 @@ Package: ipmitool Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base -Suggests: openipmi +Recommends: openipmi Description: utility for IPMI control with kernel driver or LAN interface A utility for managing and configuring devices that support the Intelligent Platform Management Interface. IPMI is an open standard diff -u ipmitool-1.8.11/debian/changelog ipmitool-1.8.11/debian/changelog --- ipmitool-1.8.11/debian/changelog +++ ipmitool-1.8.11/debian/changelog @@ -1,3 +1,18 @@ +ipmitool (1.8.11-5ubuntu1) precise; urgency=low + + * Merge from Debian testing (LP: #914920). Remaining changes: + - debian/contol: + + Changed openipmi from Suggests to Recommends + - debian/copyright: + + Add DELL copyright notice. + - Apply a series of 6 patches from upstream's patch tracker to + add DELL specific commands (delloem) + * Drop changes: + - Add armel/armhf support, now Architecture is any + - 101_fix_buf_overflow.patch now in debian + + -- Leo Iannacone Wed, 11 Jan 2012 18:49:15 +0100 + ipmitool (1.8.11-5) unstable; urgency=high * debian/control: Add libncurses-dev build dependency @@ -31,6 +46,51 @@ -- Luk Claes Mon, 19 Sep 2011 19:35:04 +0200 +ipmitool (1.8.11-2ubuntu6) oneiric; urgency=low + + * Add armel/armhf support + + -- Michael Casadevall Wed, 05 Oct 2011 15:04:58 -0700 + +ipmitool (1.8.11-2ubuntu5) oneiric; urgency=low + + * Rebuild for OpenSSL 1.0.0. + + -- Colin Watson Wed, 18 May 2011 00:10:19 +0100 + +ipmitool (1.8.11-2ubuntu4) natty; urgency=low + + * Changed openipmi from Suggests to Recommends to ensure + it's installed too. (LP: #110992) + + -- Jeff Lane Wed, 09 Mar 2011 10:40:28 -0500 + +ipmitool (1.8.11-2ubuntu3) maverick; urgency=low + + * debian/patches/101_fix_buf_overflow.patch: Add patch to fix buffer overflow. + (LP: #633054) + + -- Chuck Short Wed, 08 Sep 2010 09:11:26 -0400 + +ipmitool (1.8.11-2ubuntu2) maverick; urgency=low + + * Actually remove 30_ipmi_delloem.patch this time. + + -- Stefano Rivera Mon, 28 Jun 2010 12:47:48 +0200 + +ipmitool (1.8.11-2ubuntu1) maverick; urgency=low + + [ Lorenzo De Liso ] + * Merge from debian unstable (LP: #598993), remaining changes: + - debian/copyright: + + Add DELL copyright notice. + + [ Stefano Rivera ] + * Replaced 30_ipmi_delloem.patch (never accepted upstream) with a new series + of 6 patches from upstream's patch tracker. + + -- Lorenzo De Liso Sun, 27 Jun 2010 12:26:30 +0200 + ipmitool (1.8.11-2) unstable; urgency=low * Fix password reading (Patch from Kris Popendorf @@ -40,6 +100,19 @@ -- Matthew Johnson Sun, 06 Dec 2009 00:05:49 +0000 +ipmitool (1.8.11-1ubuntu1) karmic; urgency=low + + * Merge from debian unstable, remaining changes: + + debian/control: + - change Maintainer field according to specs. + + debian/patches/30_ipmi_delloem:.patch: + - Rediffed due to version bump. + - Dropped dpatchiness. + + debian/copyright: + - Add DELL copyright notice. + + -- Chuck Short Mon, 23 Mar 2009 00:01:26 +0000 + ipmitool (1.8.11-1) unstable; urgency=low * New upstream release @@ -49,6 +122,21 @@ -- Matthew Johnson Sun, 22 Mar 2009 16:44:06 +0000 +ipmitool (1.8.9-2ubuntu1) jaunty; urgency=low + + * debian/patches/30_ipmi_delloem: + - add DELL specific commands (delloem) + * debian/patches/20_ipmi_ipmi: + - clean up *.orig + * debian/patches/20_ipmi_isol: + - clean up *.orig + * debian/copyright: + - add DELL copyright notice + * debian/control: + - change Maintainer field + + -- Ante Karamatic Wed, 18 Feb 2009 08:48:33 +0100 + ipmitool (1.8.9-2) unstable; urgency=medium * Change pidfile name to the one it actually is. (Closes: #508434) diff -u ipmitool-1.8.11/debian/patches/series ipmitool-1.8.11/debian/patches/series --- ipmitool-1.8.11/debian/patches/series +++ ipmitool-1.8.11/debian/patches/series @@ -5,0 +6,6 @@ +dell_01_basic.patch +dell_02_lcd.patch +dell_03_mac.patch +dell_04_lan.patch +dell_05_poowermonitor.patch +dell_06_manpage.patch only in patch2: unchanged: --- ipmitool-1.8.11.orig/debian/copyright +++ ipmitool-1.8.11/debian/copyright @@ -34,3 +34,31 @@ 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 SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + +Parts of code contributed by DELL: + +Copyright (c) 2006, Dell Inc +All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +- Redistributions 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 Dell Inc nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. only in patch2: unchanged: --- ipmitool-1.8.11.orig/debian/patches/dell_05_poowermonitor.patch +++ ipmitool-1.8.11/debian/patches/dell_05_poowermonitor.patch @@ -0,0 +1,1836 @@ +Description: Part 5 of a set of patches adding Dell OEM support - Power monitor commands +Origin: https://sourceforge.net/tracker/?func=detail&aid=2959606&group_id=95200&atid=610553 +Author: Deepaganesh Paulraj +Last-Update: 2010-06-28 +--- a/include/ipmitool/ipmi_delloem.h ++++ b/include/ipmitool/ipmi_delloem.h +@@ -69,8 +69,12 @@ + #define IPMI_DELL_LCD_ERROR_DISP_VERBOSE 0x02 /* blank*/ + + #define IPMI_DELL_IDRAC_VALIDATOR 0xDD ++#define IPMI_DELL_POWER_CAP_STATUS 0xBA + +- ++#define btuphr 0x01 ++#define watt 0x00 ++#define IPMI_DELL_POWER_CAP 0xEA ++#define percent 0x03 + + /* Not on all Dell servers. If there, use it.*/ + typedef struct _tag_ipmi_dell_lcd_caps +@@ -216,10 +220,94 @@ + #define GET_NIC_SELECTION_CMD (uint8_t)(0x25) + #define GET_ACTIVE_NIC_CMD (uint8_t)(0xc1) + +- +- ++#define POWER_SUPPLY_INFO (uint8_t)(0xb0) ++#define IPMI_ENTITY_ID_POWER_SUPPLY (uint8_t)(0x0a) ++#define SENSOR_STATE_STR_SIZE (uint8_t)(64) ++#define SENSOR_NAME_STR_SIZE (uint8_t)(64) ++ ++typedef struct _ipmi_power_monitor ++{ ++ uint32_t cumStartTime; ++ uint32_t cumReading; ++ uint32_t maxPeakStartTime; ++ uint32_t ampPeakTime; ++ uint16_t ampReading; ++ uint32_t wattPeakTime; ++ uint16_t wattReading; ++} __attribute__ ((packed)) IPMI_POWER_MONITOR; ++ ++ ++typedef struct ipmi_power_consumption_data ++{ ++ uint16_t actualpowerconsumption; ++ uint16_t powerthreshold; ++ uint16_t warningthreshold; ++ uint8_t throttlestate; ++ uint16_t maxpowerconsumption; ++ uint16_t throttlepowerconsumption; ++ uint16_t Resv; ++} __attribute__ ((packed)) IPMI_POWER_CONSUMPTION_DATA; ++ ++ ++typedef struct ipmi_inst_power_consumption_data ++{ ++ uint16_t instanpowerconsumption; ++ uint16_t instanApms; ++ uint16_t resv1; ++ uint8_t resv; ++} __attribute__ ((packed)) IPMI_INST_POWER_CONSUMPTION_DATA; ++ ++typedef struct _ipmi_avgpower_consump_histroy ++{ ++ uint8_t parameterselector; ++ uint16_t lastminutepower; ++ uint16_t lasthourpower; ++ uint16_t lastdaypower; ++ uint16_t lastweakpower; ++ ++} __attribute__ ((packed)) IPMI_AVGPOWER_CONSUMP_HISTORY; ++ ++typedef struct _ipmi_power_consump_histroy ++{ ++ uint8_t parameterselector; ++ uint16_t lastminutepower; ++ uint16_t lasthourpower; ++ uint16_t lastdaypower; ++ uint16_t lastweakpower; ++ uint32_t lastminutepowertime; ++ uint32_t lasthourpowertime; ++ uint32_t lastdaypowertime; ++ uint32_t lastweekpowertime; ++} __attribute__ ((packed)) IPMI_POWER_CONSUMP_HISTORY; ++ ++ ++typedef struct _ipmi_delloem_power_cap ++{ ++ uint8_t parameterselector; ++ uint16_t PowerCap; ++ uint8_t unit; ++ uint16_t MaximumPowerConsmp; ++ uint16_t MinimumPowerConsmp; ++ uint16_t totalnumpowersupp; ++ uint16_t AvailablePower ; ++ uint16_t SystemThrottling; ++ uint16_t Resv; ++} __attribute__ ((packed)) IPMI_POWER_CAP; ++ ++typedef struct _power_headroom ++{ ++ uint16_t instheadroom; ++ uint16_t peakheadroom; ++} __attribute__ ((packed)) POWER_HEADROOM; ++ ++ ++typedef struct _SensorReadingType ++{ ++ uint8_t sensorReading; ++ uint8_t sensorFlags; ++ uint16_t sensorState; ++}SensorReadingType; + + int ipmi_delloem_main(struct ipmi_intf * intf, int argc, char ** argv); + +-#endif /*IPMI_DELLOEM_H*/ +- ++#endif /*IPMI_DELLOEM_H*/ +\ No newline at end of file +--- a/lib/ipmi_delloem.c ++++ b/lib/ipmi_delloem.c +@@ -85,6 +85,11 @@ + volatile uint8_t IMC_Type = IMC_IDRAC_10G; + + ++POWER_HEADROOM powerheadroom; ++ ++uint8_t PowercapSetable_flag=0; ++uint8_t PowercapstatusFlag=0; ++ + static void usage(void); + + static int ipmi_delloem_lcd_main (struct ipmi_intf * intf, int argc, char ** argv); +@@ -133,6 +138,34 @@ + static int ipmi_lan_get_active_nic (struct ipmi_intf* intf); + static void ipmi_lan_usage(void); + ++static int ipmi_delloem_powermonitor_main (struct ipmi_intf * intf, int argc, char ** argv); ++static void ipmi_time_to_str(time_t rawTime, char* strTime); ++static int ipmi_get_sensor_reading(struct ipmi_intf *intf , ++ unsigned char sensorNumber, ++ SensorReadingType* pSensorReadingData); ++static int ipmi_get_power_capstatus_command (struct ipmi_intf * intf); ++static int ipmi_set_power_capstatus_command (struct ipmi_intf * intf,uint8_t val); ++static int ipmi_powermgmt(struct ipmi_intf* intf); ++static int ipmi_powermgmt_clear(struct ipmi_intf* intf,uint8_t clearValue); ++static uint64_t watt_to_btuphr_conversion(uint32_t powerinwatt); ++static uint32_t btuphr_to_watt_conversion(uint64_t powerinbtuphr); ++static int ipmi_get_power_headroom_command (struct ipmi_intf * intf,uint8_t unit); ++static int ipmi_get_power_consumption_data(struct ipmi_intf* intf,uint8_t unit); ++static int ipmi_get_instan_power_consmpt_data(struct ipmi_intf* intf, ++ IPMI_INST_POWER_CONSUMPTION_DATA* instpowerconsumptiondata); ++static void ipmi_print_get_instan_power_Amps_data(IPMI_INST_POWER_CONSUMPTION_DATA instpowerconsumptiondata); ++static int ipmi_print_get_power_consmpt_data(struct ipmi_intf* intf,uint8_t unit); ++static int ipmi_get_avgpower_consmpt_history(struct ipmi_intf* intf,IPMI_AVGPOWER_CONSUMP_HISTORY* pavgpower ); ++static int ipmi_get_peakpower_consmpt_history(struct ipmi_intf* intf,IPMI_POWER_CONSUMP_HISTORY * pstPeakpower); ++static int ipmi_get_minpower_consmpt_history(struct ipmi_intf* intf,IPMI_POWER_CONSUMP_HISTORY * pstMinpower); ++static int ipmi_print_power_consmpt_history(struct ipmi_intf* intf,int unit ); ++static int ipmi_get_power_cap(struct ipmi_intf* intf,IPMI_POWER_CAP* ipmipowercap ); ++static int ipmi_print_power_cap(struct ipmi_intf* intf,uint8_t unit ); ++static int ipmi_set_power_cap(struct ipmi_intf* intf,int unit,int val ); ++static int getpowersupplyfruinfo(struct ipmi_intf *intf, uint8_t id, ++ struct fru_header header, struct fru_info fru); ++static void ipmi_powermonitor_usage(void); ++ + + /***************************************************************** + * Function Name: ipmi_delloem_main +@@ -176,6 +209,11 @@ + { + ipmi_delloem_lan_main (intf,argc,argv); + } ++ /*Powermanagement report processing*/ ++ else if (strncmp(argv[current_arg], "powermonitor\0", 13) == 0) ++ { ++ ipmi_delloem_powermonitor_main (intf,argc,argv); ++ } + else + { + usage(); +@@ -206,6 +244,7 @@ + lprintf(LOG_NOTICE, " mac"); + if (IsLANSupported()) + lprintf(LOG_NOTICE, " lan"); ++ lprintf(LOG_NOTICE, " powermonitor"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, "For help on individual commands type:"); + lprintf(LOG_NOTICE, "delloem help"); +@@ -2541,6 +2580,1646 @@ + lprintf(LOG_NOTICE, " lan get active"); + lprintf(LOG_NOTICE, " returns the current active NIC (dedicated, LOM1, LOM2, LOM3, LOM4)."); + lprintf(LOG_NOTICE, ""); ++ ++} ++ ++/***************************************************************** ++* Function Name: ipmi_delloem_powermonitor_main ++* ++* Description: This function processes the delloem powermonitor command ++* Input: intf - ipmi interface ++ argc - no of arguments ++ argv - argument string array ++* Output: ++* ++* Return: return code 0 - success ++* -1 - failure ++* ++******************************************************************/ ++ ++static int ipmi_delloem_powermonitor_main (struct ipmi_intf * intf, int argc, char ** argv) ++{ ++ int rc = 0; ++ ++ current_arg++; ++ if (argc == 1) ++ { ++ rc = ipmi_powermgmt(intf); ++ } ++ else if (strncmp(argv[current_arg], "status\0", 7) == 0) ++ { ++ rc = ipmi_powermgmt(intf); ++ } ++ ++ else if (strncmp(argv[current_arg], "clear\0", 6) == 0) ++ { ++ current_arg++; ++ if (argv[current_arg] == NULL) ++ { ++ ipmi_powermonitor_usage(); ++ return -1; ++ } ++ else if (strncmp(argv[current_arg], "peakpower\0", 10) == 0) ++ { ++ rc = ipmi_powermgmt_clear(intf, 1); ++ } ++ else if (strncmp(argv[current_arg], "cumulativepower\0", 16) == 0) ++ { ++ rc = ipmi_powermgmt_clear(intf, 0); ++ } ++ else ++ { ++ ipmi_powermonitor_usage(); ++ return -1; ++ } ++ ++ } ++ ++ ++ else if (strncmp(argv[current_arg], "powerconsumption\0", 17) == 0) ++ { ++ current_arg++; ++ ++ if (argv[current_arg] == NULL) ++ { ++ ++ rc=ipmi_print_get_power_consmpt_data(intf,watt); ++ ++ } ++ else if (strncmp(argv[current_arg], "watt\0", 5) == 0) ++ { ++ ++ rc = ipmi_print_get_power_consmpt_data(intf, watt); ++ } ++ else if (strncmp(argv[current_arg], "btuphr\0", 7) == 0) ++ { ++ rc = ipmi_print_get_power_consmpt_data(intf, btuphr); ++ } ++ else ++ { ++ ipmi_powermonitor_usage(); ++ return -1; ++ } ++ } ++ else if (strncmp(argv[current_arg], "powerconsumptionhistory\0", 23) == 0) ++ { ++ current_arg++; ++ if (argv[current_arg] == NULL) ++ { ++ rc=ipmi_print_power_consmpt_history(intf,watt); ++ ++ } ++ else if (strncmp(argv[current_arg], "watt\0", 5) == 0) ++ { ++ rc = ipmi_print_power_consmpt_history(intf, watt); ++ } ++ else if (strncmp(argv[current_arg], "btuphr\0", 7) == 0) ++ { ++ rc = ipmi_print_power_consmpt_history(intf, btuphr); ++ } ++ else ++ { ++ ipmi_powermonitor_usage(); ++ return -1; ++ } ++ ++ } ++ ++ else if (strncmp(argv[current_arg], "getpowerbudget\0", 15) == 0) ++ { ++ current_arg++; ++ if (argv[current_arg] == NULL) ++ { ++ rc=ipmi_print_power_cap(intf,watt); ++ ++ } ++ else if (strncmp(argv[current_arg], "watt\0", 5) == 0) ++ { ++ rc = ipmi_print_power_cap(intf, watt); ++ } ++ else if (strncmp(argv[current_arg], "btuphr\0", 7) == 0) ++ { ++ rc = ipmi_print_power_cap(intf, btuphr); ++ } ++ else ++ { ++ ipmi_powermonitor_usage(); ++ return -1; ++ } ++ ++ } ++ ++ else if (strncmp(argv[current_arg], "setpowerbudget\0", 15) == 0) ++ { ++ current_arg++; ++ int val; ++ if (argv[current_arg] == NULL) ++ { ++ ipmi_powermonitor_usage(); ++ return -1; ++ } ++ make_int(argv[current_arg],&val); ++ current_arg++; ++ if (argv[current_arg] == NULL) ++ { ++ ipmi_powermonitor_usage(); ++ } ++ else if (strncmp(argv[current_arg], "watt\0", 5) == 0) ++ { ++ rc=ipmi_set_power_cap(intf,watt,val); ++ } ++ else if (strncmp(argv[current_arg], "btuphr\0", 7) == 0) ++ { ++ rc=ipmi_set_power_cap(intf, btuphr,val); ++ } ++ else if (strncmp(argv[current_arg], "percent\0", 8) == 0) ++ { ++ rc=ipmi_set_power_cap(intf,percent,val); ++ } ++ else ++ { ++ ipmi_powermonitor_usage(); ++ return -1; ++ } ++ ++ } ++ ++ else if (strncmp(argv[current_arg], "enablepowercap\0", 15) == 0) ++ { ++ ipmi_set_power_capstatus_command(intf,1); ++ } ++ ++ else if (strncmp(argv[current_arg], "disablepowercap\0", 16) == 0) ++ { ++ ipmi_set_power_capstatus_command(intf,0); ++ } ++ else ++ { ++ ipmi_powermonitor_usage(); ++ return -1; ++ } ++} ++ ++ ++/***************************************************************** ++* Function Name: ipmi_time_to_str ++* ++* Description: This function converts ipmi time format into gmtime format ++* Input: rawTime - ipmi time format ++* Output: strTime - gmtime format ++* ++* Return: ++* ++******************************************************************/ ++ ++static void ++ipmi_time_to_str(time_t rawTime, char* strTime) ++{ ++ struct tm * tm; ++ char *temp; ++ tm = gmtime(&rawTime); ++ ++ temp = asctime(tm); ++ ++ strcpy(strTime,temp); ++} ++ ++/***************************************************************** ++* Function Name: ipmi_get_sensor_reading ++* ++* Description: This function retrieves a raw sensor reading ++* Input: sensorOwner - sensor owner id ++* sensorNumber - sensor id ++* intf - ipmi interface ++* Output: sensorReadingData - ipmi response structure ++* Return: 1 on error ++* 0 if successful ++* ++******************************************************************/ ++static int ++ipmi_get_sensor_reading(struct ipmi_intf *intf , ++ unsigned char sensorNumber, ++ SensorReadingType* pSensorReadingData) ++{ ++ struct ipmi_rq req; ++ struct ipmi_rs * rsp; ++ int rc = 0; ++ uint8_t save_addr; ++ ++ memset(&req, 0, sizeof (req)); ++ req.msg.netfn = IPMI_NETFN_SE; ++ req.msg.lun = 0; ++ req.msg.cmd = GET_SENSOR_READING; ++ req.msg.data = &sensorNumber; ++ req.msg.data_len = 1; ++ ++ if (NULL == pSensorReadingData) ++ return -1; ++ memset(pSensorReadingData,0, sizeof(SensorReadingType)); ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ return 1; ++ } else if (rsp->ccode > 0) { ++ return 1; ++ } ++ ++ memcpy(pSensorReadingData, rsp->data, sizeof(SensorReadingType)); ++ ++ /* if there is an error transmitting ipmi command, return error*/ ++ if (rsp->ccode != 0) { ++ rc = 1; ++ } ++ ++ /* if sensor messages are disabled, return error*/ ++ if ((!(rsp->data[1]& 0xC0)) || ((rsp->data[1] & 0x20))) { ++ rc =1; ++ } ++ return rc; ++} ++ ++ ++/***************************************************************** ++* Function Name: ipmi_get_power_capstatus_command ++* ++* Description: This function gets the power cap status ++* Input: intf - ipmi interface ++* Global: PowercapSetable_flag - power cap status ++* Output: ++* ++* Return: ++* ++******************************************************************/ ++static int ++ipmi_get_power_capstatus_command (struct ipmi_intf * intf) ++{ ++ struct ipmi_rs * rsp = NULL; ++ struct ipmi_rq req = {0}; ++ uint8_t data[2]; ++ ++ req.msg.netfn = 0x30; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_DELL_POWER_CAP_STATUS; ++ req.msg.data_len = 2; ++ req.msg.data = data; ++ data[0] = 01; ++ data[1] = 0xFF; ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, " Error getting powercap status"); ++ return -1; ++ } else if (rsp->ccode > 0) { ++ lprintf(LOG_ERR, " Error getting powercap statusr: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ return -1; ++ } ++ if (rsp->data[0]&0x02) ++ PowercapSetable_flag=1; ++ if(rsp->data[0]&0x01) ++ PowercapstatusFlag=1; ++ return 0; ++} ++ ++/***************************************************************** ++* Function Name: ipmi_set_power_capstatus_command ++* ++* Description: This function sets the power cap status ++* Input: intf - ipmi interface ++* val - power cap status ++* Output: ++* ++* Return: ++* ++******************************************************************/ ++ ++static int ++ipmi_set_power_capstatus_command (struct ipmi_intf * intf,uint8_t val) ++{ ++ struct ipmi_rs * rsp = NULL; ++ struct ipmi_rq req = {0}; ++ uint8_t data[2]; ++ ipmi_get_power_capstatus_command(intf); ++ ++ if (PowercapSetable_flag!=1) ++ { ++ lprintf(LOG_ERR, " Can not set powercap on this system"); ++ return -1; ++ } ++ req.msg.netfn = 0x30; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_DELL_POWER_CAP_STATUS; ++ req.msg.data_len = 2; ++ req.msg.data = data; ++ ++ data[0] = 00; ++ data[1] = val; ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, " Error setting powercap status"); ++ return -1; ++ } else if (rsp->ccode > 0) { ++ lprintf(LOG_ERR, " Error setting powercap statusr: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ return -1; ++ } ++ ++ return 0; + } + + ++ ++/***************************************************************** ++* Function Name: ipmi_powermgmt ++* ++* Description: This function print the powermonitor details ++* Input: intf - ipmi interface ++* Output: ++* ++* Return: ++* ++******************************************************************/ ++static int ipmi_powermgmt(struct ipmi_intf* intf) ++{ ++ time_t now; ++ struct tm* tm; ++ char* dte; ++ ++ struct ipmi_rs * rsp; ++ struct ipmi_rq req; ++ uint8_t msg_data[2]; ++ uint32_t cumStartTimeConv; ++ uint32_t cumReadingConv; ++ uint32_t maxPeakStartTimeConv; ++ uint32_t ampPeakTimeConv; ++ uint16_t ampReadingConv; ++ uint32_t wattPeakTimeConv; ++ uint32_t wattReadingConv; ++ uint32_t bmctimeconv; ++ uint32_t * bmctimeconvval; ++ ++ IPMI_POWER_MONITOR* pwrMonitorInfo; ++ ++ ++ char cumStartTime[26]; ++ char maxPeakStartTime[26]; ++ char ampPeakTime[26]; ++ char wattPeakTime[26]; ++ char bmctime[26]; ++ ++ float cumReading; ++ int ampReading; ++ int wattReading; ++ int ampReadingRemainder; ++ ++ now = time(0); ++ tm = gmtime(&now); ++ dte = asctime(tm); ++ ++ memset(&req, 0, sizeof(req)); ++ req.msg.netfn = IPMI_NETFN_STORAGE; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_CMD_GET_SEL_TIME; ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, " Error getting BMC time info.\n"); ++ return -1; ++ } ++ if (rsp->ccode != 0) { ++ printf("Error getting power management information, return code %x\n", rsp->ccode); ++ return -1; ++ } ++ bmctimeconvval=(uint32_t*)rsp->data; ++ bmctimeconv=*bmctimeconvval; ++ ++ /* get powermanagement info*/ ++ req.msg.netfn = 0x30; ++ req.msg.lun = 0x0; ++ req.msg.cmd = 0x9c; ++ req.msg.data = msg_data; ++ req.msg.data_len = 2; ++ ++ memset(msg_data, 0, 2); ++ msg_data[0] = 0x07; ++ msg_data[1] = 0x01; ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, " Error getting power management information.\n"); ++ return -1; ++ } ++ if ((rsp->ccode == 0xc1)||(rsp->ccode == 0xcb)) { ++ lprintf(LOG_ERR, " Error getting power management information: Command not supported on this system."); ++ return -1; ++ }else if (rsp->ccode != 0) { ++ printf("Error getting power management information, return code %x\n", rsp->ccode); ++ return -1; ++ } ++ ++ ++ ++ pwrMonitorInfo = (IPMI_POWER_MONITOR*)rsp->data; ++ ++ cumStartTimeConv = pwrMonitorInfo->cumStartTime; ++ cumReadingConv = pwrMonitorInfo->cumReading; ++ maxPeakStartTimeConv = pwrMonitorInfo->maxPeakStartTime; ++ ampPeakTimeConv = pwrMonitorInfo->ampPeakTime; ++ ampReadingConv = pwrMonitorInfo->ampReading; ++ wattPeakTimeConv = pwrMonitorInfo->wattPeakTime; ++ wattReadingConv = pwrMonitorInfo->wattReading; ++ ++ ipmi_time_to_str(cumStartTimeConv, cumStartTime); ++ ++ ipmi_time_to_str(maxPeakStartTimeConv, maxPeakStartTime); ++ ipmi_time_to_str(ampPeakTimeConv, ampPeakTime); ++ ipmi_time_to_str(wattPeakTimeConv, wattPeakTime); ++ ipmi_time_to_str(bmctimeconv, bmctime); ++ ++ ++ ++ now = time(0); ++ ++ int round; ++ int round2; ++ int remainder; ++ ++ ++ remainder = (cumReadingConv % 1000); ++ cumReadingConv = cumReadingConv / 1000; ++ remainder = (remainder + 50) / 100; ++ ++ ampReading = ampReadingConv; ++ ampReadingRemainder = ampReading%10; ++ ampReading = ampReading/10; ++ ++ wattReading = wattReadingConv; ++ ++ printf("Power Tracking Statistics\n"); ++ printf("Statistic : Cumulative Energy Consumption\n"); ++ printf("Start Time : %s", cumStartTime); ++ printf("Finish Time : %s", bmctime); ++ printf("Reading : %d.%d kWh\n\n", cumReadingConv, remainder); ++ ++ printf("Statistic : System Peak Power\n"); ++ printf("Start Time : %s", maxPeakStartTime); ++ printf("Peak Time : %s", wattPeakTime); ++ printf("Peak Reading : %d W\n\n", wattReading); ++ ++ printf("Statistic : System Peak Amperage\n"); ++ printf("Start Time : %s", maxPeakStartTime); ++ printf("Peak Time : %s", ampPeakTime); ++ printf("Peak Reading : %d.%d A\n", ampReading, ampReadingRemainder); ++ ++ ++ return 0; ++ ++} ++/***************************************************************** ++* Function Name: ipmi_powermgmt_clear ++* ++* Description: This function clears peakpower / cumulativepower value ++* Input: intf - ipmi interface ++* clearValue - peakpower / cumulativepower ++* Output: ++* ++* Return: ++* ++******************************************************************/ ++static int ++ipmi_powermgmt_clear(struct ipmi_intf* intf,uint8_t clearValue) ++{ ++ struct ipmi_rs * rsp; ++ struct ipmi_rq req; ++ uint8_t clearType; ++ uint8_t msg_data[3]; ++ ++ if (clearValue) { ++ clearType = 2; ++ } else { ++ clearType = 1; ++ } ++ ++ /* clear powermanagement info*/ ++ req.msg.netfn = 0x30; ++ req.msg.lun = 0; ++ req.msg.cmd = 0x9d; ++ req.msg.data = msg_data; ++ req.msg.data_len = 3; ++ ++ ++ memset(msg_data, 0, 3); ++ msg_data[0] = 0x07; ++ msg_data[1] = 0x01; ++ msg_data[2] = clearType; ++ ++ ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, " Error clearing power values.\n"); ++ return -1; ++ } else if (rsp->ccode == 0xc1) { ++ lprintf(LOG_ERR, " Error clearing power values, command not supported on this system.\n"); ++ return -1; ++ } else if (rsp->ccode != 0){ ++ lprintf(LOG_ERR, " Error clearing power values: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ return -1; ++ } ++ ++} ++ ++/***************************************************************** ++* Function Name: watt_to_btuphr_conversion ++* ++* Description: This function converts the power value in watt to btuphr ++* Input: powerinwatt - power in watt ++* ++* Output: power in btuphr ++* ++* Return: ++* ++******************************************************************/ ++static uint64_t watt_to_btuphr_conversion(uint32_t powerinwatt) ++{ ++ uint64_t powerinbtuphr; ++ powerinbtuphr=(3.413*powerinwatt); ++ ++ return(powerinbtuphr); ++ ++ ++} ++ ++/***************************************************************** ++* Function Name: btuphr_to_watt_conversion ++* ++* Description: This function converts the power value in btuphr to watt ++* Input: powerinbtuphr - power in btuphr ++* ++* Output: power in watt ++* ++* Return: ++* ++******************************************************************/ ++static uint32_t btuphr_to_watt_conversion(uint64_t powerinbtuphr) ++{ ++ uint32_t powerinwatt; ++ /*returning the floor value*/ ++ powerinwatt= (powerinbtuphr/3.413); ++ return (powerinwatt); ++} ++ ++/***************************************************************** ++* Function Name: ipmi_get_power_headroom_command ++* ++* Description: This function prints the Power consumption information ++* Input: intf - ipmi interface ++* unit - watt / btuphr ++* Output: ++* ++* Return: ++* ++******************************************************************/ ++static int ipmi_get_power_headroom_command (struct ipmi_intf * intf,uint8_t unit) ++{ ++ struct ipmi_rs * rsp = NULL; ++ struct ipmi_rq req = {0}; ++ uint64_t peakpowerheadroombtuphr; ++ uint64_t instantpowerhearoom; ++ ++ req.msg.netfn = 0x30; ++ req.msg.lun = 0; ++ req.msg.cmd = 0xBB; ++ req.msg.data_len = 0; ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, " Error getting power headroom status"); ++ return -1; ++ } else if ((rsp->ccode == 0xc1)||(rsp->ccode == 0xcb)){ ++ lprintf(LOG_ERR, " Error getting power headroom status: Command not supported on this system "); ++ return -1; ++ } else if (rsp->ccode > 0) { ++ lprintf(LOG_ERR, " Error getting power headroom status: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ return -1; ++ } ++ if(verbose>1) ++ printf("power headroom Data : %x %x %x %x ", ++ /*need to look into */ rsp->data[0], rsp->data[1], rsp->data[2], rsp->data[3]); ++ powerheadroom= *(( POWER_HEADROOM *)rsp->data); ++ ++ printf ("Headroom\n\r"); ++ printf ("Statistic Reading\n\r"); ++ ++ if(unit == btuphr) ++ { ++ peakpowerheadroombtuphr=watt_to_btuphr_conversion(powerheadroom.peakheadroom); ++ instantpowerhearoom= watt_to_btuphr_conversion(powerheadroom.instheadroom); ++ ++ printf ("System Instantaneous Headroom : %d BTU/hr\n",instantpowerhearoom); ++ printf ("System Peak Headroom : %d BTU/hr\n",peakpowerheadroombtuphr); ++ } ++ else ++ { ++ printf ("System Instantaneous Headroom : %d W\n",powerheadroom.instheadroom); ++ printf ("System Peak Headroom : %d W\n",powerheadroom.peakheadroom); ++ } ++ ++ return 0; ++} ++ ++ ++ ++/***************************************************************** ++* Function Name: ipmi_get_power_consumption_data ++* ++* Description: This function updates the instant Power consumption information ++* Input: intf - ipmi interface ++* Output: power consumption current reading ++* Assumption value will be in Watt. ++* ++* Return: ++* ++******************************************************************/ ++static int ipmi_get_power_consumption_data(struct ipmi_intf* intf,uint8_t unit) ++{ ++ int rc = 0; ++ SensorReadingType sensorReadingData; ++ ++ int i; ++ ++ struct ipmi_rs * rsp=NULL; ++ struct sdr_record_list *sdr; ++ int readingbtuphr=0; ++ int warning_threshbtuphr=0; ++ int failuer_thresbtuphr=0; ++ int status=0; ++ int sensor_number = 0; ++ ++ ++ sdr = ipmi_sdr_find_sdr_byid(intf, "System Level"); ++ if (NULL ==sdr) ++ { ++ printf ("Error : Can not access the System Level sensor data \n\n"); ++ return -1; ++ } ++ ++ sensor_number = sdr->record.full->keys.sensor_num; ++ ipmi_get_sensor_reading (intf,sensor_number,&sensorReadingData); ++ ++ rsp = ipmi_sdr_get_sensor_thresholds(intf, ++ sdr->record.full->keys.sensor_num, ++ sdr->record.full->keys.owner_id, ++ sdr->record.full->keys.lun); ++ ++ if (rsp != NULL && rsp->ccode == 0) ++ { ++ readingbtuphr=sdr_convert_sensor_reading ++ (sdr->record.full, sensorReadingData.sensorReading); ++ warning_threshbtuphr=sdr_convert_sensor_reading ++ (sdr->record.full, rsp->data[4]); ++ failuer_thresbtuphr=sdr_convert_sensor_reading ++ (sdr->record.full, rsp->data[5]); ++ ++ printf ("System Board System Level\n\r"); ++ if (unit==btuphr) ++ { ++ readingbtuphr= watt_to_btuphr_conversion(readingbtuphr); ++ warning_threshbtuphr= watt_to_btuphr_conversion(warning_threshbtuphr); ++ failuer_thresbtuphr= watt_to_btuphr_conversion( failuer_thresbtuphr); ++ ++ printf ("Reading : %d BTU/hr\n",readingbtuphr); ++ printf ("Warning threshold : %d BTU/hr\n",warning_threshbtuphr); ++ printf ("Failure threshold : %d BTU/hr\n",failuer_thresbtuphr); ++ } ++ else ++ { ++ printf ("Reading : %d W \n",readingbtuphr); ++ printf ("Warning threshold : %d W \n",(warning_threshbtuphr)); ++ printf ("Failure threshold : %d W \n",(failuer_thresbtuphr)); ++ } ++ } ++ else ++ { ++ printf ("Error : Can not access the System Level sensor data \n\n"); ++ return -1; ++ } ++ return status; ++} ++ ++ ++ ++ ++/***************************************************************** ++* Function Name: ipmi_get_instan_power_consmpt_data ++* ++* Description: This function updates the instant Power consumption information ++* Input: intf - ipmi interface ++* Output: instpowerconsumptiondata - instant Power consumption information ++* ++* Return: ++* ++******************************************************************/ ++ ++static int ipmi_get_instan_power_consmpt_data(struct ipmi_intf* intf, ++ IPMI_INST_POWER_CONSUMPTION_DATA* instpowerconsumptiondata) ++{ ++ ++ struct ipmi_rs * rsp; ++ struct ipmi_rq req={0}; ++ ++ uint8_t msg_data[2]; ++ ++ ++ /*get instantaneous power consumption command*/ ++ req.msg.netfn = 0x30; ++ req.msg.lun = 0; ++ req.msg.cmd = 0xb3; ++ ++ req.msg.data = msg_data; ++ req.msg.data_len = 2; ++ ++ ++ ++ memset(msg_data, 0, 2); ++ ++ msg_data[0] = 0x0A; ++ msg_data[1] = 0x00; ++ ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, " Error getting instantaneous power consumption data .\n"); ++ ++ return -1; ++ } else if ((rsp->ccode == 0xc1)||(rsp->ccode == 0xcb)) { ++ lprintf(LOG_ERR, " Error getting instantaneous power consumption data: Command not supported on this system."); ++ return -1; ++ } else if (rsp->ccode != 0){ ++ lprintf(LOG_ERR, " Error getting instantaneous power consumption data: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ ++ return -1; ++ } ++ ++ * instpowerconsumptiondata = * ( (IPMI_INST_POWER_CONSUMPTION_DATA*) (rsp->data)); ++ ++ return 0; ++ ++ ++} ++ ++ ++/***************************************************************** ++* Function Name: ipmi_print_get_instan_power_Amps_data ++* ++* Description: This function prints the instant Power consumption information ++* Input: instpowerconsumptiondata - instant Power consumption information ++* Output: ++* ++* Return: ++* ++******************************************************************/ ++static void ipmi_print_get_instan_power_Amps_data(IPMI_INST_POWER_CONSUMPTION_DATA instpowerconsumptiondata) ++{ ++ uint16_t intampsval=0; ++ uint16_t decimalampsval=0; ++ ++ ++ if (instpowerconsumptiondata.instanApms>0) ++ { ++ decimalampsval=(instpowerconsumptiondata.instanApms%10); ++ intampsval=instpowerconsumptiondata.instanApms/10; ++ } ++ printf("\nAmperage value: %d.%d A \n",intampsval,decimalampsval); ++} ++/***************************************************************** ++* Function Name: ipmi_print_get_power_consmpt_data ++* ++* Description: This function prints the Power consumption information ++* Input: intf - ipmi interface ++* unit - watt / btuphr ++* Output: ++* ++* Return: ++* ++******************************************************************/ ++static int ipmi_print_get_power_consmpt_data(struct ipmi_intf* intf,uint8_t unit) ++{ ++ ++ int rc = 0; ++ int i; ++ uint16_t inputwattageL=0; ++ int sensorIndex = 0; ++ ++ uint32_t readingbtuphr; ++ uint32_t warning_threshbtuphr; ++ uint32_t failuer_thresbtuphr; ++ IPMI_INST_POWER_CONSUMPTION_DATA instpowerconsumptiondata = {0,0,0,0}; ++ ++ printf ("\nPower consumption information\n"); ++ ++ ++ rc=ipmi_get_power_consumption_data(intf,unit); ++ if (-1 == rc) ++ return rc; ++ ++ rc=ipmi_get_instan_power_consmpt_data(intf,&instpowerconsumptiondata); ++ if (-1 == rc) ++ return rc; ++ ++ ipmi_print_get_instan_power_Amps_data(instpowerconsumptiondata); ++ ++ ++ rc=ipmi_get_power_headroom_command(intf,unit); ++ ++ if (-1 == rc) ++ return rc; ++ ++ return rc; ++ ++ ++} ++ ++ ++/***************************************************************** ++* Function Name: ipmi_get_avgpower_consmpt_history ++* ++* Description: This function updates the average power consumption information ++* Input: intf - ipmi interface ++* Output: pavgpower- average power consumption information ++* ++* Return: ++* ++******************************************************************/ ++static int ipmi_get_avgpower_consmpt_history(struct ipmi_intf* intf,IPMI_AVGPOWER_CONSUMP_HISTORY* pavgpower ) ++{ ++ struct ipmi_rs * rsp = NULL; ++ struct ipmi_rq req = {0}; ++ uint8_t data[4]; ++ ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_GET_SYS_INFO; ++ req.msg.data_len = 4; ++ req.msg.data = data; ++ data[0] = 0; ++ data[1] = 0xeb; ++ data[2] = 0; ++ data[3] = 0; ++ ++ rsp = intf->sendrecv(intf, &req); ++ ++ if (rsp == NULL) ++ { ++ lprintf(LOG_ERR, " Error getting average power consumption history data .\n"); ++ return -1; ++ } ++ else if ((rsp->ccode == 0xc1)||(rsp->ccode == 0xcb)) ++ { ++ lprintf(LOG_ERR, " Error getting average power consumption history data: Command not supported on this system."); ++ return -1; ++ } ++ else if (rsp->ccode != 0) ++ { ++ lprintf(LOG_ERR, " Error getting average power consumption historydata: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ ++ return -1; ++ } ++ ++ if (verbose > 1) ++ { ++ printf("Average power consumption history Data :%x %x %x %x %x %x %x\n\n", ++ rsp->data[0], rsp->data[1], rsp->data[2], rsp->data[3], ++ rsp->data[4], rsp->data[5], rsp->data[6], rsp->data[7]); ++ ++ } ++ ++ *pavgpower = *( (IPMI_AVGPOWER_CONSUMP_HISTORY*) rsp->data); ++ ++ return 0; ++} ++ ++/***************************************************************** ++* Function Name: ipmi_get_peakpower_consmpt_history ++* ++* Description: This function updates the peak power consumption information ++* Input: intf - ipmi interface ++* Output: pavgpower- peak power consumption information ++* ++* Return: ++* ++******************************************************************/ ++static int ipmi_get_peakpower_consmpt_history(struct ipmi_intf* intf,IPMI_POWER_CONSUMP_HISTORY * pstPeakpower) ++{ ++ ++ struct ipmi_rs * rsp = NULL; ++ struct ipmi_rq req = {0}; ++ uint8_t data[4]; ++ ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_GET_SYS_INFO; ++ req.msg.data_len = 4; ++ req.msg.data = data; ++ data[0] = 0; ++ data[1] = 0xec; ++ data[2] = 0; ++ data[3] = 0; ++ ++ rsp = intf->sendrecv(intf, &req); ++ ++ if (rsp == NULL) ++ { ++ lprintf(LOG_ERR, " Error getting peak power consumption history data .\n"); ++ return -1; ++ } ++ else if ((rsp->ccode == 0xc1)||(rsp->ccode == 0xcb)) ++ { ++ lprintf(LOG_ERR, " Error getting peak power consumption history data: Command not supported on this system."); ++ return -1; ++ } ++ else if (rsp->ccode != 0) ++ { ++ lprintf(LOG_ERR, " Error getting peak power consumption history data: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ return -1; ++ } ++ ++ if (verbose > 1) ++ { ++ printf("Peak power consmhistory Data : %x %x %x %x %x %x %x %x %x %x\n %x %x %x %x %x %x %x %x %x %x %x %x %x\n\n", ++ rsp->data[0], rsp->data[1], rsp->data[2], rsp->data[3], ++ rsp->data[4], rsp->data[5], rsp->data[6], rsp->data[7], ++ rsp->data[8], rsp->data[9], rsp->data[10], rsp->data[11], ++ rsp->data[12], rsp->data[13], rsp->data[14], rsp->data[15], ++ rsp->data[16], rsp->data[17], rsp->data[18], rsp->data[19], ++ rsp->data[20], rsp->data[21], rsp->data[22], rsp->data[23] ++ ); ++ ++ } ++ *pstPeakpower =* ((IPMI_POWER_CONSUMP_HISTORY*)rsp->data); ++ return 0; ++} ++ ++ ++/***************************************************************** ++* Function Name: ipmi_get_minpower_consmpt_history ++* ++* Description: This function updates the peak power consumption information ++* Input: intf - ipmi interface ++* Output: pavgpower- peak power consumption information ++* ++* Return: ++* ++******************************************************************/ ++static int ipmi_get_minpower_consmpt_history(struct ipmi_intf* intf,IPMI_POWER_CONSUMP_HISTORY * pstMinpower) ++{ ++ ++ struct ipmi_rs * rsp = NULL; ++ struct ipmi_rq req = {0}; ++ uint8_t data[4]; ++ ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_GET_SYS_INFO; ++ req.msg.data_len = 4; ++ req.msg.data = data; ++ data[0] = 0; ++ data[1] = 0xed; ++ data[2] = 0; ++ data[3] = 0; ++ ++ rsp = intf->sendrecv(intf, &req); ++ ++ if (rsp == NULL) ++ { ++ lprintf(LOG_ERR, " Error getting peak power consumption history data .\n"); ++ return -1; ++ } ++ else if ((rsp->ccode == 0xc1)||(rsp->ccode == 0xcb)) ++ { ++ lprintf(LOG_ERR, " Error getting peak power consumption history data: Command not supported on this system."); ++ return -1; ++ } ++ else if (rsp->ccode != 0) ++ { ++ lprintf(LOG_ERR, " Error getting peak power consumption history data: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ return -1; ++ } ++ ++ if (verbose > 1) ++ { ++ printf("Peak power consmhistory Data : %x %x %x %x %x %x %x %x %x %x\n %x %x %x %x %x %x %x %x %x %x %x %x %x\n\n", ++ rsp->data[0], rsp->data[1], rsp->data[2], rsp->data[3], ++ rsp->data[4], rsp->data[5], rsp->data[6], rsp->data[7], ++ rsp->data[8], rsp->data[9], rsp->data[10], rsp->data[11], ++ rsp->data[12], rsp->data[13], rsp->data[14], rsp->data[15], ++ rsp->data[16], rsp->data[17], rsp->data[18], rsp->data[19], ++ rsp->data[20], rsp->data[21], rsp->data[22], rsp->data[23] ++ ); ++ ++ } ++ *pstMinpower =* ((IPMI_POWER_CONSUMP_HISTORY*)rsp->data); ++ return 0; ++} ++ ++ ++ ++/***************************************************************** ++* Function Name: ipmi_print_power_consmpt_history ++* ++* Description: This function print the average and peak power consumption information ++* Input: intf - ipmi interface ++* unit - watt / btuphr ++* Output: ++* ++* Return: ++* ++******************************************************************/ ++static int ipmi_print_power_consmpt_history(struct ipmi_intf* intf,int unit ) ++{ ++ ++ char timestr[30]; ++ ++ uint32_t lastminutepeakpower; ++ uint32_t lasthourpeakpower; ++ uint32_t lastdaypeakpower; ++ uint32_t lastweekpeakpower; ++ ++ IPMI_AVGPOWER_CONSUMP_HISTORY avgpower; ++ IPMI_POWER_CONSUMP_HISTORY stMinpower; ++ IPMI_POWER_CONSUMP_HISTORY stPeakpower; ++ ++ uint64_t tempbtuphrconv; ++ uint16_t temp; ++ int rc=0; ++ ++ ++ rc= ipmi_get_avgpower_consmpt_history(intf,&avgpower); ++ if (-1 == rc) ++ return rc; ++ ++ rc= ipmi_get_peakpower_consmpt_history(intf,&stPeakpower); ++ if (-1 == rc) ++ return rc; ++ ++ rc= ipmi_get_minpower_consmpt_history(intf,&stMinpower); ++ if (-1 == rc) ++ return rc; ++ ++ ++ if(rc==0) ++ { ++ printf ("Power Consumption History\n\r\n\r"); ++ /* The fields are alligned manually changing the spaces will alter the alignment*/ ++ printf ("Statistic Last Minute Last Hour Last Day Last Week\n\r\n\r"); ++ ++ if (unit ==btuphr) ++ { ++ printf ("Average Power Consumption "); ++ tempbtuphrconv=watt_to_btuphr_conversion(avgpower.lastminutepower); ++ printf ("%4d BTU/hr ",tempbtuphrconv); ++ tempbtuphrconv=watt_to_btuphr_conversion(avgpower.lasthourpower); ++ printf ("%4d BTU/hr ",tempbtuphrconv); ++ tempbtuphrconv=watt_to_btuphr_conversion(avgpower.lastdaypower); ++ printf ("%4d BTU/hr ",tempbtuphrconv); ++ tempbtuphrconv=watt_to_btuphr_conversion(avgpower.lastweakpower); ++ printf ("%4d BTU/hr\n\r",tempbtuphrconv); ++ ++ printf ("Max Power Consumption "); ++ tempbtuphrconv=watt_to_btuphr_conversion(stPeakpower.lastminutepower); ++ printf ("%4d BTU/hr ",tempbtuphrconv); ++ tempbtuphrconv=watt_to_btuphr_conversion(stPeakpower.lasthourpower); ++ printf ("%4d BTU/hr ",tempbtuphrconv); ++ tempbtuphrconv=watt_to_btuphr_conversion(stPeakpower.lastdaypower); ++ printf ("%4d BTU/hr ",tempbtuphrconv); ++ tempbtuphrconv=watt_to_btuphr_conversion(stPeakpower.lastweakpower); ++ printf ("%4d BTU/hr\n\r",tempbtuphrconv); ++ ++ printf ("Min Power Consumption "); ++ tempbtuphrconv=watt_to_btuphr_conversion(stMinpower.lastminutepower); ++ printf ("%4d BTU/hr ",tempbtuphrconv); ++ tempbtuphrconv=watt_to_btuphr_conversion(stMinpower.lasthourpower); ++ printf ("%4d BTU/hr ",tempbtuphrconv); ++ tempbtuphrconv=watt_to_btuphr_conversion(stMinpower.lastdaypower); ++ printf ("%4d BTU/hr ",tempbtuphrconv); ++ tempbtuphrconv=watt_to_btuphr_conversion(stMinpower.lastweakpower); ++ printf ("%4d BTU/hr\n\r\n\r",tempbtuphrconv); ++ ++ } ++ else ++ { ++ ++ printf ("Average Power Consumption "); ++ tempbtuphrconv=(avgpower.lastminutepower); ++ printf ("%4d W ",tempbtuphrconv); ++ tempbtuphrconv=(avgpower.lasthourpower); ++ printf ("%4d W ",tempbtuphrconv); ++ tempbtuphrconv=(avgpower.lastdaypower); ++ printf ("%4d W ",tempbtuphrconv); ++ tempbtuphrconv=(avgpower.lastweakpower); ++ printf ("%4d W \n\r",tempbtuphrconv); ++ ++ printf ("Max Power Consumption "); ++ tempbtuphrconv=(stPeakpower.lastminutepower); ++ printf ("%4d W ",tempbtuphrconv); ++ tempbtuphrconv=(stPeakpower.lasthourpower); ++ printf ("%4d W ",tempbtuphrconv); ++ tempbtuphrconv=(stPeakpower.lastdaypower); ++ printf ("%4d W ",tempbtuphrconv); ++ tempbtuphrconv=(stPeakpower.lastweakpower); ++ printf ("%4d W \n\r",tempbtuphrconv); ++ ++ printf ("Min Power Consumption "); ++ tempbtuphrconv=(stMinpower.lastminutepower); ++ printf ("%4d W ",tempbtuphrconv); ++ tempbtuphrconv=(stMinpower.lasthourpower); ++ printf ("%4d W ",tempbtuphrconv); ++ tempbtuphrconv=(stMinpower.lastdaypower); ++ printf ("%4d W ",tempbtuphrconv); ++ tempbtuphrconv=(stMinpower.lastweakpower); ++ printf ("%4d W \n\r\n\r",tempbtuphrconv); ++ } ++ ++ lastminutepeakpower=stPeakpower.lastminutepowertime; ++ lasthourpeakpower=stPeakpower.lasthourpowertime; ++ lastdaypeakpower=stPeakpower.lastdaypowertime; ++ lastweekpeakpower=stPeakpower.lastweekpowertime; ++ ++ printf ("Max Power Time\n\r"); ++ ipmi_time_to_str(lastminutepeakpower, timestr); ++ printf ("Last Minute : %s",timestr); ++ ipmi_time_to_str(lasthourpeakpower, timestr); ++ printf ("Last Hour : %s",timestr); ++ ipmi_time_to_str(lastdaypeakpower, timestr); ++ printf ("Last Day : %s",timestr); ++ ipmi_time_to_str(lastweekpeakpower, timestr); ++ printf ("Last Week : %s",timestr); ++ ++ ++ lastminutepeakpower=stMinpower.lastminutepowertime; ++ lasthourpeakpower=stMinpower.lasthourpowertime; ++ lastdaypeakpower=stMinpower.lastdaypowertime; ++ lastweekpeakpower=stMinpower.lastweekpowertime; ++ ++ printf ("Min Power Time\n\r"); ++ ipmi_time_to_str(lastminutepeakpower, timestr); ++ printf ("Last Minute : %s",timestr); ++ ipmi_time_to_str(lasthourpeakpower, timestr); ++ printf ("Last Hour : %s",timestr); ++ ipmi_time_to_str(lastdaypeakpower, timestr); ++ printf ("Last Day : %s",timestr); ++ ipmi_time_to_str(lastweekpeakpower, timestr); ++ printf ("Last Week : %s",timestr); ++ ++ } ++ ++} ++ ++ ++ ++/***************************************************************** ++* Function Name: ipmi_get_power_cap ++* ++* Description: This function updates the power cap information ++* Input: intf - ipmi interface ++* Output: ipmipowercap - power cap information ++* ++* Return: ++* ++******************************************************************/ ++ ++static int ipmi_get_power_cap(struct ipmi_intf* intf,IPMI_POWER_CAP* ipmipowercap ) ++{ ++ struct ipmi_rs * rsp=NULL; ++ struct ipmi_rq req={0}; ++ uint64_t tempbtuphrconv; ++ uint8_t data[4]; ++ ++ /* power supply rating command*/ ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_GET_SYS_INFO; ++ req.msg.data_len = 4; ++ req.msg.data = data; ++ ++ data[0] = 0; ++ data[1] = IPMI_DELL_POWER_CAP; ++ data[2] = 0; ++ data[3] = 0; ++ ++ ++ rsp = intf->sendrecv(intf, &req); ++ ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, " Error getting power cap .\n"); ++ if (verbose > 1){ ++ printf("power cap Data :%x %x %x %x %x %x %x %x %x %x ", ++ rsp->data[1], rsp->data[2], rsp->data[3], ++ rsp->data[4], rsp->data[5], rsp->data[6], rsp->data[7], ++ rsp->data[8], rsp->data[9], rsp->data[10],rsp->data[11]); ++ } ++ return -1; ++ ++ } else if ((rsp->ccode == 0xc1)||(rsp->ccode == 0xcb)) { ++ ++ lprintf(LOG_ERR, " Error getting power cap: Command not supported on this system."); ++ if (verbose > 1){ ++ printf("power cap Data :%x %x %x %x %x %x %x %x %x %x ", ++ rsp->data[1], rsp->data[2], rsp->data[3], ++ rsp->data[4], rsp->data[5], rsp->data[6], rsp->data[7], ++ rsp->data[8], rsp->data[9], rsp->data[10],rsp->data[11]); ++ ++ } ++ return -1; ++ } else if (rsp->ccode != 0){ ++ lprintf(LOG_ERR, " Error getting power cap: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ if (verbose > 1){ ++ printf("power cap Data :%x %x %x %x %x %x %x %x %x %x ", ++ rsp->data[1], rsp->data[2], rsp->data[3], ++ rsp->data[4], rsp->data[5], rsp->data[6], rsp->data[7], ++ rsp->data[8], rsp->data[9], rsp->data[10],rsp->data[11]); ++ } ++ return -1; ++ } ++ if (verbose > 1){ ++ printf("power cap Data :%x %x %x %x %x %x %x %x %x %x ", ++ rsp->data[1], rsp->data[2], rsp->data[3], ++ rsp->data[4], rsp->data[5], rsp->data[6], rsp->data[7], ++ rsp->data[8], rsp->data[9], rsp->data[10],rsp->data[11]); ++ ++ } ++ ++ * ipmipowercap = *((IPMI_POWER_CAP*)(rsp->data)); ++ ++ return 0; ++} ++ ++/***************************************************************** ++* Function Name: ipmi_print_power_cap ++* ++* Description: This function print the power cap information ++* Input: intf - ipmi interface ++* unit - watt / btuphr ++* Output: ++* Return: ++* ++******************************************************************/ ++static int ipmi_print_power_cap(struct ipmi_intf* intf,uint8_t unit ) ++{ ++ uint64_t tempbtuphrconv; ++ int rc; ++ IPMI_POWER_CAP ipmipowercap; ++ ++ rc=ipmi_get_power_cap(intf,&ipmipowercap); ++ ++ ++ if (rc==0) ++ { ++ if (unit ==btuphr){ ++ tempbtuphrconv=watt_to_btuphr_conversion(ipmipowercap.MaximumPowerConsmp); ++ printf ("Maximum power: %d BTU/hr\n",tempbtuphrconv); ++ tempbtuphrconv=watt_to_btuphr_conversion(ipmipowercap.MinimumPowerConsmp); ++ printf ("Minimum power: %d BTU/hr\n",tempbtuphrconv); ++ tempbtuphrconv=watt_to_btuphr_conversion(ipmipowercap.PowerCap); ++ printf ("Power cap : %d BTU/hr\n",tempbtuphrconv); ++ }else{ ++ ++ printf ("Maximum power: %d Watt\n",ipmipowercap.MaximumPowerConsmp); ++ printf ("Minimum power: %d Watt\n",ipmipowercap.MinimumPowerConsmp); ++ printf ("Power cap : %d Watt\n",ipmipowercap.PowerCap); ++ } ++ } ++ return rc; ++ ++} ++ ++/***************************************************************** ++* Function Name: ipmi_set_power_cap ++* ++* Description: This function updates the power cap information ++* Input: intf - ipmi interface ++* unit - watt / btuphr ++* val - new power cap value ++* Output: ++* Return: ++* ++******************************************************************/ ++static int ipmi_set_power_cap(struct ipmi_intf* intf,int unit,int val ) ++{ ++ struct ipmi_rs *rsp = NULL; ++ struct ipmi_rq req={0};; ++ uint8_t data[13]; ++ uint16_t powercapval; ++ uint64_t maxpowerbtuphr; ++ uint64_t maxpowerbtuphr1; ++ uint64_t minpowerbtuphr; ++ int rc; ++ IPMI_POWER_CAP ipmipowercap; ++ ++ ipmi_get_power_capstatus_command(intf); ++ if (PowercapSetable_flag!=1) ++ { ++ lprintf(LOG_ERR, " Can not set powercap on this system"); ++ return -1; ++ } ++ else if(PowercapstatusFlag!=1) ++ { ++ lprintf(LOG_ERR, " Power cap set feature is not enabled"); ++ return -1; ++ } ++ ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_GET_SYS_INFO; ++ req.msg.data_len = 4; ++ memset(data, 0, 4); ++ req.msg.data = data; ++ ++ data[0] = 0; ++ data[1] = IPMI_DELL_POWER_CAP; ++ data[2] = 0; ++ data[3] = 0; ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) ++ { ++ lprintf(LOG_ERR, " Error getting power cap .\n"); ++ if (verbose > 1) ++ { ++ printf("power cap Data :%x %x %x %x %x %x %x %x %x %x ", ++ rsp->data[1], rsp->data[2], rsp->data[3], ++ rsp->data[4], rsp->data[5], rsp->data[6], rsp->data[7], ++ rsp->data[8], rsp->data[9], rsp->data[10],rsp->data[11]); ++ } ++ return -1; ++ ++ } ++ else if (rsp->ccode == 0xc1) ++ { ++ ++ lprintf(LOG_ERR, " Error getting power cap, command not supported on this system.\n"); ++ if (verbose > 1){ ++ printf("power cap Data :%x %x %x %x %x %x %x %x %x %x ", ++ rsp->data[1], rsp->data[2], rsp->data[3], ++ rsp->data[4], rsp->data[5], rsp->data[6], rsp->data[7], ++ rsp->data[8], rsp->data[9], rsp->data[10],rsp->data[11]); ++ ++ } ++ return -1; ++ } ++ else if (rsp->ccode != 0) ++ { ++ lprintf(LOG_ERR, " Error getting power cap: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ if (verbose > 1) ++ { ++ printf("power cap Data :%x %x %x %x %x %x %x %x %x %x ", ++ rsp->data[1], rsp->data[2], rsp->data[3], ++ rsp->data[4], rsp->data[5], rsp->data[6], rsp->data[7], ++ rsp->data[8], rsp->data[9], rsp->data[10],rsp->data[11]); ++ } ++ return -1; ++ } ++ if (verbose > 1) ++ { ++ printf("power cap Data :%x %x %x %x %x %x %x %x %x %x ", ++ rsp->data[1], rsp->data[2], rsp->data[3], ++ rsp->data[4], rsp->data[5], rsp->data[6], rsp->data[7], ++ rsp->data[8], rsp->data[9], rsp->data[10],rsp->data[11]); ++ ++ } ++ ++ ipmipowercap.PowerCap=((rsp->data[1]<<8)+rsp->data[2]); ++ ipmipowercap.unit=rsp->data[3]; ++ ipmipowercap.MaximumPowerConsmp=((rsp->data[4]<<8)+rsp->data[5]); ++ ipmipowercap.MinimumPowerConsmp=((rsp->data[6]<<8)+rsp->data[7]); ++ ++ memset(data, 0, 13); ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_SET_SYS_INFO; ++ req.msg.data_len = 13; ++ req.msg.data = data; ++ data[0] = IPMI_DELL_POWER_CAP; ++ powercapval=val; ++ ++ ++ data[1] = (powercapval&0XFF); ++ data[2] = ((powercapval&0XFF00)>>8); ++ data[3] = unit; ++ ++ data[4]=((ipmipowercap.MaximumPowerConsmp&0xFF)); ++ data[5]=((ipmipowercap.MaximumPowerConsmp&0xFF00)>>8); ++ data[6]=((ipmipowercap.MinimumPowerConsmp&0xFF)); ++ data[7]=((ipmipowercap.MinimumPowerConsmp&0xFF00)>>8); ++ data[8]=(ipmipowercap.totalnumpowersupp); ++ data[9]=((ipmipowercap.AvailablePower&0xFF)); ++ data[10]=((ipmipowercap.AvailablePower&0xFF00)>>8); ++ data[11]=(ipmipowercap.SystemThrottling); ++ data[12]=0x00; ++ ++ ipmipowercap.MaximumPowerConsmp = BSWAP_16(ipmipowercap.MaximumPowerConsmp); ++ ipmipowercap.MinimumPowerConsmp = BSWAP_16(ipmipowercap.MinimumPowerConsmp); ++ ipmipowercap.PowerCap = BSWAP_16(ipmipowercap.PowerCap); ++ if(unit==btuphr) ++ { ++ val = btuphr_to_watt_conversion(val); ++ ++ } ++ else if(unit ==percent) ++ { ++ if((val <1)||(val>100)) ++ { ++ lprintf(LOG_ERR, " Cap value is out of boundary conditon it should be between 0 - 100"); ++ return -1; ++ } ++ val =( (val*(ipmipowercap.MaximumPowerConsmp -ipmipowercap.MinimumPowerConsmp))/100)+ipmipowercap.MinimumPowerConsmp; ++ lprintf(LOG_ERR, " Cap value in percentage is %d ",val); ++ data[1] = (val&0XFF); ++ data[2] = ((val&0XFF00)>>8); ++ data[3] = watt; ++ } ++ if(((valipmipowercap.MaximumPowerConsmp))&&(unit==watt)) ++ { ++ lprintf(LOG_ERR, " Cap value is out of boundary conditon it should be between %d - %d", ++ ipmipowercap.MinimumPowerConsmp,ipmipowercap.MaximumPowerConsmp); ++ return -1; ++ } ++ else if(((valipmipowercap.MaximumPowerConsmp))&&(unit==btuphr)) ++ { ++ minpowerbtuphr= watt_to_btuphr_conversion(ipmipowercap.MinimumPowerConsmp); ++ maxpowerbtuphr=watt_to_btuphr_conversion(ipmipowercap.MaximumPowerConsmp); ++ maxpowerbtuphr1= watt_to_btuphr_conversion(ipmipowercap.MaximumPowerConsmp); ++ lprintf(LOG_ERR, " Cap value is out of boundary conditon it should be between %d", ++ minpowerbtuphr); ++ lprintf(LOG_ERR, " -%d", ++ maxpowerbtuphr1); ++ ++ return -1; ++ } ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) ++ { ++ lprintf(LOG_ERR, " Error setting power cap"); ++ return -1; ++ } ++ else if (rsp->ccode > 0) ++ { ++ lprintf(LOG_ERR, " Error setting power cap: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ return -1; ++ } ++ if (verbose > 1) ++ { ++ printf("CC for setpowercap :%d ",rsp->ccode); ++ } ++ return 0; ++} ++ ++/***************************************************************** ++* Function Name: getpowersupplyfruinfo ++* ++* Description: This function retrieves the FRU header ++* Input: intf - ipmi interface ++* header - watt / btuphr ++* fru - FRU information ++* Output: header - FRU header ++* Return: ++* ++******************************************************************/ ++static int getpowersupplyfruinfo(struct ipmi_intf *intf, uint8_t id, ++ struct fru_header header, struct fru_info fru) ++{ ++ struct ipmi_rs * rsp; ++ struct ipmi_rq req; ++ ++ uint8_t msg_data[4]; ++ ++ memset(&fru, 0, sizeof(struct fru_info)); ++ memset(&header, 0, sizeof(struct fru_header)); ++ ++ /* ++ * get info about this FRU ++ */ ++ memset(msg_data, 0, 4); ++ msg_data[0] = id; ++ ++ memset(&req, 0, sizeof(req)); ++ req.msg.netfn = IPMI_NETFN_STORAGE; ++ req.msg.lun = 0; ++ req.msg.cmd = GET_FRU_INFO; ++ req.msg.data = msg_data; ++ req.msg.data_len = 1; ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ printf(" Device not present (No Response)\n"); ++ return -1; ++ } ++ if (rsp->ccode > 0) { ++ printf(" Device not present (%s)\n", ++ val2str(rsp->ccode, completion_code_vals)); ++ return -1; ++ } ++ ++ fru.size = (rsp->data[1] << 8) | rsp->data[0]; ++ fru.access = rsp->data[2] & 0x1; ++ ++ lprintf(LOG_DEBUG, "fru.size = %d bytes (accessed by %s)", ++ fru.size, fru.access ? "words" : "bytes"); ++ ++ if (fru.size < 1) { ++ lprintf(LOG_ERR, " Invalid FRU size %d", fru.size); ++ return -1; ++ } ++ ++ /* ++ * retrieve the FRU header ++ */ ++ msg_data[0] = id; ++ msg_data[1] = 0; ++ msg_data[2] = 0; ++ msg_data[3] = 8; ++ ++ memset(&req, 0, sizeof(req)); ++ req.msg.netfn = IPMI_NETFN_STORAGE; ++ req.msg.lun = 0; ++ req.msg.cmd = GET_FRU_DATA; ++ req.msg.data = msg_data; ++ req.msg.data_len = 4; ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ printf(" Device not present (No Response)\n"); ++ return 1; ++ } ++ if (rsp->ccode > 0) { ++ printf(" Device not present (%s)\n", ++ val2str(rsp->ccode, completion_code_vals)); ++ return 1; ++ } ++ ++ if (verbose > 1) ++ printbuf(rsp->data, rsp->data_len, "FRU DATA"); ++ ++ memcpy(&header, rsp->data + 1, 8); ++ ++ ++ ++} ++ ++/***************************************************************** ++* Function Name: ipmi_powermonitor_usage ++* ++* Description: This function prints help message for powermonitor command ++* Input: ++* Output: ++* ++* Return: ++* ++******************************************************************/ ++static void ++ipmi_powermonitor_usage(void) ++{ ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, " powermonitor"); ++ lprintf(LOG_NOTICE, " Shows power tracking statistics "); ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, " powermonitor clear cumulativepower"); ++ lprintf(LOG_NOTICE, " Reset cumulative power reading"); ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, " powermonitor clear peakpower"); ++ lprintf(LOG_NOTICE, " Reset peak power reading"); ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, " powermonitor powerconsumption"); ++ lprintf(LOG_NOTICE, " Displays power consumption in "); ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, " powermonitor powerconsumptionhistory "); ++ lprintf(LOG_NOTICE, " Displays power consumption history "); ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, " powermonitor getpowerbudget"); ++ lprintf(LOG_NOTICE, " Displays power cap in "); ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, " powermonitor setpowerbudget "); ++ lprintf(LOG_NOTICE, " Allows user to set the power cap in "); ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, " powermonitor enablepowercap "); ++ lprintf(LOG_NOTICE, " To enable set power cap"); ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, " powermonitor disablepowercap "); ++ lprintf(LOG_NOTICE, " To disable set power cap"); ++ lprintf(LOG_NOTICE, ""); ++ ++} ++ ++ ++ ++ only in patch2: unchanged: --- ipmitool-1.8.11.orig/debian/patches/dell_02_lcd.patch +++ ipmitool-1.8.11/debian/patches/dell_02_lcd.patch @@ -0,0 +1,1762 @@ +Description: Part 2 of a set of patches adding Dell OEM support - LCD commands +Origin: https://sourceforge.net/tracker/?func=detail&aid=2959603&group_id=95200&atid=610553 +Author: Deepaganesh Paulraj +Last-Update: 2010-06-28 +--- a/include/ipmitool/ipmi_delloem.h ++++ b/include/ipmitool/ipmi_delloem.h +@@ -35,6 +35,116 @@ + + #pragma pack(1) + ++#define MIN(a,b) ((a) < (b) ? (a) : (b)) ++#define MAX(a,b) ((a) > (b) ? (a) : (b)) ++ ++ ++/* IPMI 2.0 command for system information*/ ++#define IPMI_SET_SYS_INFO 0x58 ++#define IPMI_GET_SYS_INFO 0x59 ++ ++/* Dell selector for LCD control - get and set unless specified */ ++#define IPMI_DELL_LCD_STRING_SELECTOR 0xC1 /* RW get/set the user string */ ++#define IPMI_DELL_LCD_CONFIG_SELECTOR 0xC2 /* RW set to user/default/none */ ++#define IPMI_DELL_LCD_GET_CAPS_SELECTOR 0xCF /* RO use when available*/ ++#define IPMI_DELL_LCD_STRINGEX_SELECTOR 0xD0 /* RW get/set the user string use first when available*/ ++#define IPMI_DELL_LCD_STATUS_SELECTOR 0xE7 /* LCD string when config set to default.*/ ++#define IPMI_DELL_PLATFORM_MODEL_NAME_SELECTOR 0xD1 /* LCD string when config set to default.*/ ++ ++/* Dell defines for picking which string to use */ ++#define IPMI_DELL_LCD_CONFIG_USER_DEFINED 0x00 /* use string set by user*/ ++#define IPMI_DELL_LCD_CONFIG_DEFAULT 0x01 /* use platform model name*/ ++#define IPMI_DELL_LCD_CONFIG_NONE 0x02 /* blank*/ ++#define IPMI_DELL_LCD_iDRAC_IPV4ADRESS 0x04 /* use string set by user*/ ++#define IPMI_DELL_LCD_IDRAC_MAC_ADDRESS 0x08 /* use platform model name*/ ++#define IPMI_DELL_LCD_OS_SYSTEM_NAME 0x10 /* blank*/ ++ ++#define IPMI_DELL_LCD_SERVICE_TAG 0x20 /* use string set by user*/ ++#define IPMI_DELL_LCD_iDRAC_IPV6ADRESS 0x40 /* use string set by user*/ ++#define IPMI_DELL_LCD_AMBEINT_TEMP 0x80 /* use platform model name*/ ++#define IPMI_DELL_LCD_SYSTEM_WATTS 0x100 /* blank*/ ++#define IPMI_DELL_LCD_ASSET_TAG 0x200 ++ ++#define IPMI_DELL_LCD_ERROR_DISP_SEL 0x01 /* use platform model name*/ ++#define IPMI_DELL_LCD_ERROR_DISP_VERBOSE 0x02 /* blank*/ ++ ++#define IPMI_DELL_IDRAC_VALIDATOR 0xDD ++ ++ ++ ++/* Not on all Dell servers. If there, use it.*/ ++typedef struct _tag_ipmi_dell_lcd_caps ++{ ++ uint8_t parm_rev; /* 0x11 for IPMI 2.0 */ ++ uint8_t char_set; /* always 1 for printable ASCII 0x20-0x7E */ ++ uint8_t number_lines; /* 0-4, 1 for 9G. 10G tbd */ ++ uint8_t max_chars[4]; /* 62 for triathlon, 0 if not present (glacier) */ ++ /* [0] is max chars for line 1 */ ++}IPMI_DELL_LCD_CAPS; ++ ++#define IPMI_DELL_LCD_STRING_LENGTH_MAX 62 /* Valid for 9G. Glacier ??. */ ++#define IPMI_DELL_LCD_STRING1_SIZE 14 ++#define IPMI_DELL_LCD_STRINGN_SIZE 16 ++ ++ ++ ++typedef struct _tag_ipmi_dell_lcd_string ++{ ++ uint8_t parm_rev; /* 0x11 for IPMI 2.0 */ ++ uint8_t data_block_selector; /* 16-byte data block number to access, 0 based.*/ ++ union ++ { ++ struct ++ { ++ uint8_t encoding : 4; /* 0 is printable ASCII 7-bit */ ++ uint8_t length; /* 0 to max chars from lcd caps */ ++ uint8_t data[IPMI_DELL_LCD_STRING1_SIZE]; /* not zero terminated. */ ++ }selector_0_string; ++ uint8_t selector_n_data[IPMI_DELL_LCD_STRINGN_SIZE]; ++ }lcd_string; ++} __attribute__ ((packed)) IPMI_DELL_LCD_STRING; ++ ++/* Only found on servers with more than 1 line. Use if available. */ ++typedef struct _tag_ipmi_dell_lcd_stringex ++{ ++ uint8_t parm_rev; /* 0x11 for IPMI 2.0 */ ++ uint8_t line_number; /* LCD line number 1 to 4 */ ++ uint8_t data_block_selector; /* 16-byte data block number to access, 0 based.*/ ++ union ++ { ++ struct ++ { ++ uint8_t encoding : 4; /* 0 is printable ASCII 7-bit */ ++ uint8_t length; /* 0 to max chars from lcd caps */ ++ uint8_t data[IPMI_DELL_LCD_STRING1_SIZE]; /* not zero terminated. */ ++ } selector_0_string; ++ uint8_t selector_n_data[IPMI_DELL_LCD_STRINGN_SIZE]; ++ } lcd_string; ++} __attribute__ ((packed)) IPMI_DELL_LCD_STRINGEX; ++ ++ ++typedef struct _lcd_status ++{ ++ char vKVM_status; ++ char lock_status; ++ char Resv1; ++ char Resv; ++} __attribute__ ((packed)) LCD_STATUS; ++ ++typedef struct _lcd_mode ++{ ++ uint8_t parametersel; ++ uint32_t lcdmode; ++ uint16_t lcdquallifier; ++ uint32_t capabilites; ++ uint8_t error_display; ++ uint8_t Resv; ++} __attribute__ ((packed)) LCD_MODE; ++ ++ ++ ++ ++ + + int ipmi_delloem_main(struct ipmi_intf * intf, int argc, char ** argv); + +--- a/lib/ipmi_delloem.c ++++ b/lib/ipmi_delloem.c +@@ -49,15 +49,60 @@ + #include + #include + #include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + /*------------ipmi headers------------------*/ + + ++ + /*--------------time header-----------------*/ + #include + ++ + static int current_arg =0; ++uint8_t iDRAC_FLAG=0; ++LCD_MODE lcd_mode; ++static uint8_t LcdSupported=0; ++ + static void usage(void); + ++static int ipmi_delloem_lcd_main (struct ipmi_intf * intf, int argc, char ** argv); ++static int ipmi_lcd_get_platform_model_name (struct ipmi_intf * intf,char* lcdstring, ++ uint8_t max_length,uint8_t field_type); ++static int ipmi_idracvalidator_command (struct ipmi_intf * intf); ++static int ipmi_lcd_get_configure_command_wh (struct ipmi_intf * intf); ++static int ipmi_lcd_get_configure_command (struct ipmi_intf * intf,uint8_t *command); ++static int ipmi_lcd_set_configure_command (struct ipmi_intf * intf, int command); ++static int ipmi_lcd_set_configure_command_wh (struct ipmi_intf * intf, uint32_t mode, ++ uint16_t lcdquallifier,uint8_t errordisp); ++static int ipmi_lcd_get_single_line_text (struct ipmi_intf * intf, char* lcdstring, uint8_t max_length); ++static int ipmi_lcd_get_info_wh(struct ipmi_intf * intf); ++static int ipmi_lcd_get_info(struct ipmi_intf * intf); ++static int ipmi_lcd_get_status_val(struct ipmi_intf * intf, LCD_STATUS* lcdstatus); ++static int IsLCDSupported (); ++static void CheckLCDSupport(struct ipmi_intf * intf); ++static void ipmi_lcd_status_print( LCD_STATUS lcdstatus); ++static int ipmi_lcd_get_status(struct ipmi_intf * intf ); ++static int ipmi_lcd_set_kvm(struct ipmi_intf * intf, char status); ++static int ipmi_lcd_set_lock(struct ipmi_intf * intf, char lock); ++static int ipmi_lcd_set_single_line_text (struct ipmi_intf * intf, char * text); ++static int ipmi_lcd_set_text(struct ipmi_intf * intf, char * text, int line_number); ++static int ipmi_lcd_configure_wh (struct ipmi_intf * intf, uint32_t mode , ++ uint16_t lcdquallifier, uint8_t errordisp, ++ int8_t line_number, char * text); ++static int ipmi_lcd_configure (struct ipmi_intf * intf, int command, ++ int8_t line_number, char * text); ++static void ipmi_lcd_usage(void); + + /***************************************************************** + * Function Name: ipmi_delloem_main +@@ -78,6 +123,8 @@ + { + int rc = 0; + ++ ipmi_idracvalidator_command(intf); ++ CheckLCDSupport (intf); + + if (argc == 0 || strncmp(argv[0], "help\0", 5) == 0) + { +@@ -85,10 +132,18 @@ + return 0; + } + ++ if (IsLCDSupported() && (0 ==strncmp(argv[current_arg], "lcd\0", 4)) ) ++ { ++ ipmi_delloem_lcd_main (intf,argc,argv); ++ } ++ else ++ { ++ usage(); ++ return -1; ++ } + return rc; + } + +- + /***************************************************************** + * Function Name: usage + * +@@ -106,9 +161,1546 @@ + lprintf(LOG_NOTICE, "usage: delloem [option...]"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, "commands:"); ++ if (IsLCDSupported()) ++ lprintf(LOG_NOTICE, " lcd"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, "For help on individual commands type:"); + lprintf(LOG_NOTICE, "delloem help"); + + } + ++/***************************************************************** ++* Function Name: ipmi_delloem_lcd_main ++* ++* Description: This function processes the delloem lcd command ++* Input: intf - ipmi interface ++ argc - no of arguments ++ argv - argument string array ++* Output: ++* ++* Return: return code 0 - success ++* -1 - failure ++* ++******************************************************************/ ++ ++static int ipmi_delloem_lcd_main (struct ipmi_intf * intf, int argc, char ** argv) ++{ ++ int rc = 0; ++ ++ current_arg++; ++ if (argc < current_arg) ++ { ++ usage(); ++ return -1; ++ } ++ ++ ++ /* ipmitool delloem lcd info*/ ++ if (argc == 1) ++ { ++ ipmi_lcd_usage(); ++ } ++ else if (strncmp(argv[current_arg], "info\0", 5) == 0) ++ { ++ if(iDRAC_FLAG==1) ++ rc = ipmi_lcd_get_info_wh(intf); ++ else ++ rc = ipmi_lcd_get_info(intf); ++ } ++ else if (strncmp(argv[current_arg], "status\0", 7) == 0) ++ { ++ rc = ipmi_lcd_get_status(intf); ++ } ++ /* ipmitool delloem lcd set*/ ++ else if (strncmp(argv[current_arg], "set\0", 4) == 0) ++ { ++ uint8_t line_number = 0; ++ current_arg++; ++ if (argc <= current_arg) ++ { ++ ipmi_lcd_usage(); ++ return -1; ++ } ++ if (strncmp(argv[current_arg], "line\0", 5) == 0) ++ { ++ current_arg++; ++ if (argc <= current_arg) {usage();return -1;} ++ line_number = (uint8_t)strtoul(argv[current_arg], NULL, 0); ++ current_arg++; ++ if (argc <= current_arg) {usage();return -1;} ++ } ++ if ((strncmp(argv[current_arg], "mode\0", 5) == 0)&&(iDRAC_FLAG==1)) ++ { ++ current_arg++; ++ if (argc <= current_arg) ++ { ++ ipmi_lcd_usage(); ++ return -1; ++ } ++ if (argv[current_arg] == NULL) ++ { ++ ipmi_lcd_usage(); ++ return -1; ++ } ++ if (strncmp(argv[current_arg], "none\0", 5) == 0) ++ { ++ rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_CONFIG_NONE,0xFF,0XFF, 0, NULL); ++ } ++ else if (strncmp(argv[current_arg], "modelname\0", 10) == 0) ++ { ++ rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_CONFIG_DEFAULT,0xFF,0XFF, 0, NULL); ++ } ++ else if (strncmp(argv[current_arg], "userdefined\0", 12) == 0) ++ { ++ current_arg++; ++ if (argc <= current_arg) ++ { ++ ipmi_lcd_usage();return -1; ++ } ++ rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_CONFIG_USER_DEFINED,0xFF,0XFF, line_number, argv[current_arg]); ++ } ++ else if (strncmp(argv[current_arg], "ipv4address\0", 12) == 0) ++ { ++ rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_iDRAC_IPV4ADRESS ,0xFF,0XFF, 0, NULL); ++ } ++ else if (strncmp(argv[current_arg], "macaddress\0", 11) == 0) ++ { ++ rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_IDRAC_MAC_ADDRESS,0xFF,0XFF, 0, NULL); ++ } ++ else if (strncmp(argv[current_arg], "systemname\0", 11) == 0) ++ { ++ rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_OS_SYSTEM_NAME,0xFF,0XFF, 0, NULL); ++ } ++ else if (strncmp(argv[current_arg], "servicetag\0", 11) == 0) ++ { ++ rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_SERVICE_TAG, 0xFF,0XFF,0, NULL); ++ } ++ else if (strncmp(argv[current_arg], "ipv6address\0", 12) == 0) ++ { ++ rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_iDRAC_IPV6ADRESS ,0xFF,0XFF, 0, NULL); ++ } ++ else if (strncmp(argv[current_arg], "ambienttemp\0", 12) == 0) ++ { ++ rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_AMBEINT_TEMP, 0xFF,0XFF,0, NULL); ++ ++ } ++ else if (strncmp(argv[current_arg], "systemwatt\0", 11) == 0) ++ { ++ rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_SYSTEM_WATTS , 0xFF,0XFF,0, NULL); ++ ++ } ++ else if (strncmp(argv[current_arg], "assettag\0", 9) == 0) ++ { ++ rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_ASSET_TAG , 0xFF,0XFF,0, NULL); ++ ++ } ++ else if (strncmp(argv[current_arg], "help\0", 5) == 0) ++ { ++ ipmi_lcd_usage(); ++ } ++ else ++ { ++ ipmi_lcd_usage(); ++ } ++ } ++ else if ((strncmp(argv[current_arg], "lcdqualifier\0", 13)== 0) &&(iDRAC_FLAG==1) ) ++ { ++ ++ current_arg++; ++ if (argc <= current_arg) ++ { ++ ipmi_lcd_usage(); ++ return -1; ++ } ++ if (argv[current_arg] == NULL) ++ { ++ ipmi_lcd_usage(); ++ return -1; ++ } ++ ++ if (strncmp(argv[current_arg], "watt\0", 5) == 0) { ++ ++ ++ rc = ipmi_lcd_configure_wh (intf, 0xFF,0x00,0XFF, 0, NULL); ++ } ++ else if (strncmp(argv[current_arg], "btuphr\0",7) == 0) { ++ rc = ipmi_lcd_configure_wh (intf, 0xFF,0x01,0XFF, 0, NULL); ++ ++ } else if (strncmp(argv[current_arg], "celsius\0", 8) == 0) { ++ rc = ipmi_lcd_configure_wh (intf, 0xFF,0x02,0xFF, 0, NULL); ++ } else if (strncmp(argv[current_arg], "fahrenheit", 11) == 0) { ++ rc = ipmi_lcd_configure_wh (intf, 0xFF,0x03,0xFF, 0, NULL); ++ ++ }else if (strncmp(argv[current_arg], "help\0", 5) == 0) { ++ ipmi_lcd_usage(); ++ } ++ else { ++ ipmi_lcd_usage(); ++ } ++ } ++ else if( (strncmp(argv[current_arg], "errordisplay\0", 13) == 0)&&(iDRAC_FLAG==1)) ++ { ++ ++ current_arg++; ++ if (argc <= current_arg) ++ { ++ ipmi_lcd_usage(); ++ return -1; ++ } ++ if (argv[current_arg] == NULL) ++ { ++ ipmi_lcd_usage(); ++ return -1; ++ } ++ ++ if (strncmp(argv[current_arg], "sel\0", 4) == 0) ++ { ++ rc = ipmi_lcd_configure_wh (intf, 0xFF,0xFF,IPMI_DELL_LCD_ERROR_DISP_SEL , 0, NULL); ++ } ++ else if (strncmp(argv[current_arg], "simple\0", 7) == 0) ++ { ++ rc = ipmi_lcd_configure_wh (intf, 0xFF,0xFF,IPMI_DELL_LCD_ERROR_DISP_VERBOSE , 0, NULL); ++ ++ } ++ else if (strncmp(argv[current_arg], "help\0", 5) == 0) ++ { ++ ipmi_lcd_usage(); ++ } ++ else ++ { ++ ipmi_lcd_usage(); ++ } ++ } ++ ++ else if ((strncmp(argv[current_arg], "none\0", 5) == 0)&&(iDRAC_FLAG==0)) ++ { ++ rc = ipmi_lcd_configure (intf, IPMI_DELL_LCD_CONFIG_NONE, 0, NULL); ++ } ++ else if ((strncmp(argv[current_arg], "default\0", 8) == 0)&&(iDRAC_FLAG==0)) ++ { ++ rc = ipmi_lcd_configure (intf, IPMI_DELL_LCD_CONFIG_DEFAULT, 0, NULL); ++ ++ } ++ else if ((strncmp(argv[current_arg], "custom\0", 7) == 0)&&(iDRAC_FLAG==0)) ++ { ++ current_arg++; ++ if (argc <= current_arg) ++ { ++ ipmi_lcd_usage(); ++ return -1; ++ } ++ rc = ipmi_lcd_configure (intf, IPMI_DELL_LCD_CONFIG_USER_DEFINED, line_number, argv[current_arg]); ++ } ++ ++ else if (strncmp(argv[current_arg], "vkvm\0", 5) == 0) ++ { ++ current_arg++; ++ if (argc <= current_arg) ++ { ++ ipmi_lcd_usage(); ++ return -1; ++ } ++ ++ if (strncmp(argv[current_arg], "active\0", 7) == 0) ++ { ++ rc = ipmi_lcd_set_kvm (intf, 1); ++ } ++ else if (strncmp(argv[current_arg], "inactive\0", 9)==0) ++ { ++ rc = ipmi_lcd_set_kvm (intf, 0); ++ ++ } ++ else if (strncmp(argv[current_arg], "help\0", 5) == 0) ++ { ++ ipmi_lcd_usage(); ++ } ++ else ++ { ++ ipmi_lcd_usage(); ++ } ++ ++ } ++ else if (strncmp(argv[current_arg], "frontpanelaccess\0", 17) == 0) ++ { ++ current_arg++; ++ if (argc <= current_arg) ++ { ++ ipmi_lcd_usage(); ++ return -1; ++ } ++ if (strncmp(argv[current_arg], "viewandmodify\0", 14) == 0) ++ { ++ rc = ipmi_lcd_set_lock (intf, 0); ++ } ++ else if (strncmp(argv[current_arg], "viewonly\0", 9)==0) ++ { ++ rc = ipmi_lcd_set_lock (intf, 1); ++ ++ } ++ else if (strncmp(argv[current_arg], "disabled\0", 9)==0) ++ { ++ rc = ipmi_lcd_set_lock (intf, 2); ++ ++ } ++ else if (strncmp(argv[current_arg], "help\0", 5) == 0) ++ { ++ ipmi_lcd_usage(); ++ } ++ else ++ { ++ ipmi_lcd_usage(); ++ } ++ ++ } ++ else if( (strncmp(argv[current_arg], "help\0", 5) == 0)&&(iDRAC_FLAG==0)) ++ { ++ ipmi_lcd_usage(); ++ } ++ else ++ { ++ ipmi_lcd_usage(); ++ return -1; ++ } ++ } ++ else ++ { ++ ipmi_lcd_usage(); ++ return -1; ++ } ++ ++} ++ ++ ++ ++/***************************************************************** ++* Function Name: ipmi_lcd_get_platform_model_name ++* ++* Description: This function retrieves the platform model name, or any other parameter ++* which stores data in the same format ++* Input: intf - pointer to interface ++* max_length - length of the platform model string ++* field_type - either hostname / platform model ++* Output: lcdstring - hostname / platform model string ++* ++* Return: ++* ++******************************************************************/ ++static int ++ipmi_lcd_get_platform_model_name (struct ipmi_intf * intf, ++ char* lcdstring, ++ uint8_t max_length, ++ uint8_t field_type) ++{ ++ struct ipmi_rs * rsp = NULL; ++ struct ipmi_rq req = {0}; ++ uint8_t data[4]; ++ IPMI_DELL_LCD_STRING * lcdstringblock; ++ int lcdstring_len = 0; ++ int bytes_copied = 0; ++ ++ int ii; ++ ++ for (ii = 0; ii < 4; ii++) ++ { ++ int bytes_to_copy; ++ ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_GET_SYS_INFO; ++ req.msg.data_len = 4; ++ req.msg.data = data; ++ data[0] = 0; /* get parameter*/ ++ data[1] = field_type; ++ data[2] = ii; ++ data[3] = 0; ++ ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, " Error getting platform model name"); ++ } else if (rsp->ccode > 0) { ++ lprintf(LOG_ERR, " Error getting platform model name: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ } ++ ++ lcdstringblock = (IPMI_DELL_LCD_STRING *) (void *) rsp->data; ++ ++ /* first block is different - 14 bytes*/ ++ if (0 == ii) { ++ lcdstring_len = lcdstringblock->lcd_string.selector_0_string.length; ++ ++ lcdstring_len = MIN (lcdstring_len,max_length); ++ ++ bytes_to_copy = MIN(lcdstring_len, IPMI_DELL_LCD_STRING1_SIZE); ++ memcpy (lcdstring, lcdstringblock->lcd_string.selector_0_string.data, bytes_to_copy); ++ } else { ++ int string_offset; ++ ++ bytes_to_copy = MIN(lcdstring_len - bytes_copied, IPMI_DELL_LCD_STRINGN_SIZE); ++ if (bytes_to_copy < 1) ++ break; ++ string_offset = IPMI_DELL_LCD_STRING1_SIZE + IPMI_DELL_LCD_STRINGN_SIZE * (ii-1); ++ memcpy (lcdstring+string_offset, lcdstringblock->lcd_string.selector_n_data, bytes_to_copy); ++ } ++ ++ ++ bytes_copied += bytes_to_copy; ++ ++ if (bytes_copied >= lcdstring_len) ++ ++ break; ++ } ++ ++} ++ ++/***************************************************************** ++* Function Name: ipmi_idracvalidator_command ++* ++* Description: This function returns the iDRAC6 type ++* Input: intf - ipmi interface ++* Output: ++* ++* Return: iDRAC6 type 1 - whoville ++* 0 - others ++* ++******************************************************************/ ++ ++static int ++ipmi_idracvalidator_command (struct ipmi_intf * intf) ++{ ++ struct ipmi_rs * rsp = NULL; ++ struct ipmi_rq req = {0}; ++ uint8_t data[4]; ++ ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_GET_SYS_INFO; ++ req.msg.data_len = 4; ++ req.msg.data = data; ++ data[0] = 0; ++ data[1] = IPMI_DELL_IDRAC_VALIDATOR; ++ data[2] = 2; ++ data[3] = 0; ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ /*lprintf(LOG_ERR, " Error getting IMC type"); */ ++ return -1; ++ } else if (rsp->ccode > 0) { ++ /*lprintf(LOG_ERR, " Error getting IMC type: %s", ++ val2str(rsp->ccode, completion_code_vals)); */ ++ return -1; ++ } ++ if( (0x0A == rsp->data[10]) || (0x0D ==rsp->data[10]) ) ++ { ++ iDRAC_FLAG=1; ++ } ++ else ++ { ++ iDRAC_FLAG=0; ++ } ++ ++ return 0; ++} ++ ++/***************************************************************** ++* Function Name: ipmi_lcd_get_configure_command_wh ++* ++* Description: This function returns current lcd configuration for Dell OEM LCD command ++* Input: intf - ipmi interface ++* Global: lcd_mode - lcd mode setting ++* Output: ++* ++* Return: returns the current lcd configuration ++* 0 = User defined ++* 1 = Default ++* 2 = None ++* ++******************************************************************/ ++static int ++ipmi_lcd_get_configure_command_wh (struct ipmi_intf * intf) ++{ ++ struct ipmi_rs * rsp = NULL; ++ struct ipmi_rq req = {0}; ++ uint8_t data[4]; ++ ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_GET_SYS_INFO; ++ req.msg.data_len = 4; ++ req.msg.data = data; ++ data[0] = 0; ++ data[1] = IPMI_DELL_LCD_CONFIG_SELECTOR; ++ data[2] = 0; ++ data[3] = 0; ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, " Error getting LCD configuration"); ++ return -1; ++ }else if ((rsp->ccode == 0xc1)||(rsp->ccode == 0xcb)){ ++ ++ lprintf(LOG_ERR, " Error getting LCD configuration: Command not supported on this system."); ++ ++ } else if (rsp->ccode > 0) { ++ lprintf(LOG_ERR, " Error getting LCD configuration: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ return -1; ++ } ++ ++ lcd_mode= *((LCD_MODE*)(rsp->data)); ++ return 0; ++} ++ ++ ++/***************************************************************** ++* Function Name: ipmi_lcd_get_configure_command ++* ++* Description: This function returns current lcd configuration for Dell OEM LCD command ++* Input: intf - ipmi interface ++* Output: command - user defined / default / none / ipv4 / mac address / ++ system name / service tag / ipv6 / temp / system watt / asset tag ++* ++* Return: ++* ++******************************************************************/ ++ ++static int ++ipmi_lcd_get_configure_command (struct ipmi_intf * intf, ++ uint8_t *command) ++{ ++ struct ipmi_rs * rsp = NULL; ++ struct ipmi_rq req = {0}; ++ uint8_t data[4]; ++ ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_GET_SYS_INFO; ++ req.msg.data_len = 4; ++ req.msg.data = data; ++ data[0] = 0; ++ data[1] = IPMI_DELL_LCD_CONFIG_SELECTOR; ++ data[2] = 0; ++ data[3] = 0; ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) ++ { ++ lprintf(LOG_ERR, " Error getting LCD configuration"); ++ return -1; ++ } ++ else if ((rsp->ccode == 0xc1)||(rsp->ccode == 0xcb)) ++ { ++ lprintf(LOG_ERR, " Error getting LCD configuration: Command not supported on this system."); ++ return -1; ++ } ++ else if (rsp->ccode > 0) ++ { ++ lprintf(LOG_ERR, " Error getting LCD configuration: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ return -1; ++ } ++ ++ /* rsp->data[0] is the rev */ ++ *command = rsp->data[1]; ++ ++ return 0; ++} ++ ++/***************************************************************** ++* Function Name: ipmi_lcd_set_configure_command ++* ++* Description: This function updates current lcd configuration ++* Input: intf - ipmi interface ++* command - user defined / default / none / ipv4 / mac address / ++* system name / service tag / ipv6 / temp / system watt / asset tag ++* Output: ++* Return: ++* ++******************************************************************/ ++ ++static int ++ipmi_lcd_set_configure_command (struct ipmi_intf * intf, int command) ++{ ++#define LSCC_DATA_LEN 2 ++ ++ struct ipmi_rs * rsp = NULL; ++ struct ipmi_rq req = {0}; ++ uint8_t data[2]; ++ ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_SET_SYS_INFO; ++ req.msg.data_len = 2; ++ req.msg.data = data; ++ data[0] = IPMI_DELL_LCD_CONFIG_SELECTOR; ++ data[1] = command; /* command - custom, default, none */ ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) ++ { ++ lprintf(LOG_ERR, " Error setting LCD configuration"); ++ return -1; ++ } ++ else if ((rsp->ccode == 0xc1)||(rsp->ccode == 0xcb)) ++ { ++ lprintf(LOG_ERR, " Error setting LCD configuration: Command not supported on this system."); ++ ++ } ++ else if (rsp->ccode > 0) ++ { ++ lprintf(LOG_ERR, " Error setting LCD configuration: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ ++/***************************************************************** ++* Function Name: ipmi_lcd_set_configure_command ++* ++* Description: This function updates current lcd configuration ++* Input: intf - ipmi interface ++* mode - user defined / default / none ++* lcdquallifier - lcd quallifier id ++* errordisp - error number ++* Output: ++* Return: ++* ++******************************************************************/ ++static int ++ipmi_lcd_set_configure_command_wh (struct ipmi_intf * intf, ++ uint32_t mode, ++ uint16_t lcdquallifier, ++ uint8_t errordisp) ++{ ++#define LSCC_DATA_LEN 2 ++ ++ struct ipmi_rs * rsp = NULL; ++ struct ipmi_rq req = {0}; ++ uint8_t data[13]; ++ ++ ipmi_lcd_get_configure_command_wh(intf); ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_SET_SYS_INFO; ++ req.msg.data_len = 13; ++ req.msg.data = data; ++ data[0] = IPMI_DELL_LCD_CONFIG_SELECTOR; ++ ++ if(mode!=0xFF) ++ { ++ ++ data[1] = mode&0xFF; /* command - custom, default, none*/ ++ data[2]=(mode&0xFF00)>>8; ++ data[3]=(mode&0xFF0000)>>16; ++ data[4]=(mode&0xFF000000)>>24; ++ } ++ else ++ { ++ data[1] = (lcd_mode.lcdmode)&0xFF; /* command - custom, default, none*/ ++ data[2]=((lcd_mode.lcdmode)&0xFF00)>>8; ++ data[3]=((lcd_mode.lcdmode)&0xFF0000)>>16; ++ data[4]=((lcd_mode.lcdmode)&0xFF000000)>>24; ++ } ++ ++ if(lcdquallifier!=0xFF) ++ { ++ if(lcdquallifier==0x01) ++ { ++ data[5] =(lcd_mode.lcdquallifier)|0x01; /* command - custom, default, none*/ ++ ++ } ++ else if(lcdquallifier==0x00) ++ { ++ data[5] =(lcd_mode.lcdquallifier)&0xFE; /* command - custom, default, none*/ ++ } ++ else if (lcdquallifier==0x03) ++ { ++ data[5] =(lcd_mode.lcdquallifier)|0x02; /* command - custom, default, none*/ ++ } ++ else if (lcdquallifier==0x02) ++ { ++ data[5] =(lcd_mode.lcdquallifier)&0xFD; ++ } ++ } ++ else ++ { ++ data[5]=lcd_mode.lcdquallifier; ++ } ++ if(errordisp!=0xFF) ++ { ++ data[11]=errordisp; ++ } ++ else ++ { ++ data[11]=lcd_mode.error_display; ++ } ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) ++ { ++ lprintf(LOG_ERR, " Error setting LCD configuration"); ++ return -1; ++ } ++ else if ((rsp->ccode == 0xc1)||(rsp->ccode == 0xcb)) ++ { ++ lprintf(LOG_ERR, " Error setting LCD configuration: Command not supported on this system."); ++ } ++ else if (rsp->ccode > 0) ++ { ++ lprintf(LOG_ERR, " Error setting LCD configuration: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ ++ ++/***************************************************************** ++* Function Name: ipmi_lcd_get_single_line_text ++* ++* Description: This function updates current lcd configuration ++* Input: intf - ipmi interface ++* lcdstring - new string to be updated ++* max_length - length of the string ++* Output: ++* Return: ++* ++******************************************************************/ ++ ++static int ++ipmi_lcd_get_single_line_text (struct ipmi_intf * intf, char* lcdstring, uint8_t max_length) ++{ ++ struct ipmi_rs * rsp = NULL; ++ struct ipmi_rq req = {0}; ++ uint8_t data[4]; ++ IPMI_DELL_LCD_STRING * lcdstringblock; ++ int lcdstring_len = 0; ++ int bytes_copied = 0; ++ int ii; ++ ++ for (ii = 0; ii < 4; ii++) { ++ int bytes_to_copy; ++ ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_GET_SYS_INFO; ++ req.msg.data_len = 4; ++ req.msg.data = data; ++ data[0] = 0; /* get parameter*/ ++ data[1] = IPMI_DELL_LCD_STRING_SELECTOR; ++ data[2] = ii; /* block selector*/ ++ data[3] = 00; /* set selector (n/a)*/ ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, " Error getting text data"); ++ return -1; ++ } else if (rsp->ccode > 0) { ++ lprintf(LOG_ERR, " Error getting text data: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ return -1; ++ } ++ ++ lcdstringblock = (IPMI_DELL_LCD_STRING *) (void *) rsp->data; ++ ++ /* first block is different - 14 bytes*/ ++ if (0 == ii) ++ { ++ lcdstring_len = lcdstringblock->lcd_string.selector_0_string.length; ++ ++ if (lcdstring_len < 1 || lcdstring_len > max_length) ++ break; ++ ++ bytes_to_copy = MIN(lcdstring_len, IPMI_DELL_LCD_STRING1_SIZE); ++ memcpy (lcdstring, lcdstringblock->lcd_string.selector_0_string.data, bytes_to_copy); ++ } ++ else ++ { ++ int string_offset; ++ ++ bytes_to_copy = MIN(lcdstring_len - bytes_copied, IPMI_DELL_LCD_STRINGN_SIZE); ++ if (bytes_to_copy < 1) ++ break; ++ string_offset = IPMI_DELL_LCD_STRING1_SIZE + IPMI_DELL_LCD_STRINGN_SIZE * (ii-1); ++ memcpy (lcdstring+string_offset, lcdstringblock->lcd_string.selector_n_data, bytes_to_copy); ++ } ++ ++ bytes_copied += bytes_to_copy; ++ if (bytes_copied >= lcdstring_len) ++ break; ++ } ++ return 0; ++} ++ ++/***************************************************************** ++* Function Name: ipmi_lcd_get_info_wh ++* ++* Description: This function prints current lcd configuration for whoville platform ++* Input: intf - ipmi interface ++* Output: ++* Return: ++* ++******************************************************************/ ++ ++static int ++ipmi_lcd_get_info_wh(struct ipmi_intf * intf) ++ ++{ ++ struct ipmi_rs * rsp = NULL; ++ struct ipmi_rq req = {0}; ++ uint8_t data[4]; ++ uint8_t command = 0; ++ IPMI_DELL_LCD_CAPS* lcd_caps; ++ char lcdstring[IPMI_DELL_LCD_STRING_LENGTH_MAX+1] = {0}; ++ int rc; ++ ++ ++ printf("LCD info\n"); ++ ++ if (ipmi_lcd_get_configure_command_wh (intf) != 0) ++ { ++ return -1; ++ } ++ else ++ { ++ if (lcd_mode.lcdmode== IPMI_DELL_LCD_CONFIG_DEFAULT) ++ { ++ char text[IPMI_DELL_LCD_STRING_LENGTH_MAX+1] = {0}; ++ ++ ipmi_lcd_get_platform_model_name(intf, text, ++ IPMI_DELL_LCD_STRING_LENGTH_MAX, ++ IPMI_DELL_PLATFORM_MODEL_NAME_SELECTOR); ++ ++ if (text == NULL) ++ return -1; ++ printf(" Setting:Model name\n"); ++ printf(" Line 1: %s\n", text); ++ } ++ else if (lcd_mode.lcdmode == IPMI_DELL_LCD_CONFIG_NONE) ++ { ++ printf(" Setting: none\n"); ++ } ++ else if (lcd_mode.lcdmode == IPMI_DELL_LCD_CONFIG_USER_DEFINED) ++ { ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_GET_SYS_INFO; ++ req.msg.data_len = 4; ++ req.msg.data = data; ++ data[0] = 0; /* get parameter*/ ++ data[1] = IPMI_DELL_LCD_GET_CAPS_SELECTOR; ++ data[2] = 0; /* set selector (n/a)*/ ++ data[3] = 0; /* block selector (n/a)*/ ++ ++ printf(" Setting: User defined\n"); ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) ++ { ++ lprintf(LOG_ERR, " Error getting LCD capabilities."); ++ return -1; ++ } ++ else if ((rsp->ccode == 0xc1)||(rsp->ccode == 0xcb)) ++ { ++ lprintf(LOG_ERR, " Error getting LCD capabilities: Command not supported on this system."); ++ } ++ else if (rsp->ccode > 0) ++ { ++ lprintf(LOG_ERR, " Error getting LCD capabilities: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ return -1; ++ } ++ ++ lcd_caps = (IPMI_DELL_LCD_CAPS *)rsp->data; ++ if (lcd_caps->number_lines > 0) ++ { ++ memset(lcdstring, 0, IPMI_DELL_LCD_STRING_LENGTH_MAX+1); ++ ++ rc = ipmi_lcd_get_single_line_text (intf, lcdstring, lcd_caps->max_chars[0]); ++ printf(" Text: %s\n", lcdstring); ++ } ++ else ++ { ++ printf(" No lines to show\n"); ++ } ++ } ++ else if (lcd_mode.lcdmode == IPMI_DELL_LCD_iDRAC_IPV4ADRESS) ++ { ++ printf(" Setting: IPV4 Address\n"); ++ } ++ else if (lcd_mode.lcdmode == IPMI_DELL_LCD_IDRAC_MAC_ADDRESS) ++ { ++ printf(" Setting: MAC Address\n"); ++ } ++ else if (lcd_mode.lcdmode == IPMI_DELL_LCD_OS_SYSTEM_NAME) ++ { ++ printf(" Setting: OS System Name\n"); ++ } ++ else if (lcd_mode.lcdmode == IPMI_DELL_LCD_SERVICE_TAG) ++ { ++ printf(" Setting: System Tag\n"); ++ } ++ else if (lcd_mode.lcdmode == IPMI_DELL_LCD_iDRAC_IPV6ADRESS) ++ { ++ printf(" Setting: IPV6 Address\n"); ++ } ++ else if (lcd_mode.lcdmode == IPMI_DELL_LCD_AMBEINT_TEMP) ++ { ++ printf(" Setting: Ambient Temp\n"); ++ if(lcd_mode.lcdquallifier&0x02) ++ printf(" Unit: F\n"); ++ else ++ printf(" Unit: C\n"); ++ } ++ else if (lcd_mode.lcdmode == IPMI_DELL_LCD_SYSTEM_WATTS) ++ { ++ printf(" Setting: System Watts\n"); ++ ++ if(lcd_mode.lcdquallifier&0x01) ++ printf(" Unit: BTU/hr\n"); ++ else ++ printf(" Unit: Watt\n"); ++ ++ } ++ if(lcd_mode.error_display==IPMI_DELL_LCD_ERROR_DISP_SEL) ++ printf(" Error Display: SEL\n"); ++ else if(lcd_mode.error_display==IPMI_DELL_LCD_ERROR_DISP_VERBOSE) ++ printf(" Error Display: Simple\n"); ++ } ++ ++ return 0; ++} ++ ++/***************************************************************** ++* Function Name: ipmi_lcd_get_info ++* ++* Description: This function prints current lcd configuration for platform other than whoville ++* Input: intf - ipmi interface ++* Output: ++* Return: ++* ++******************************************************************/ ++static int ipmi_lcd_get_info(struct ipmi_intf * intf) ++{ ++ struct ipmi_rs * rsp = NULL; ++ struct ipmi_rq req = {0}; ++ uint8_t data[4]; ++ IPMI_DELL_LCD_CAPS * lcd_caps; ++ uint8_t command = 0; ++ char lcdstring[IPMI_DELL_LCD_STRING_LENGTH_MAX+1] = {0}; ++ int rc; ++ ++ printf("LCD info\n"); ++ ++ if (ipmi_lcd_get_configure_command (intf, &command) != 0) ++ { ++ return -1; ++ } ++ else ++ { ++ if (command == IPMI_DELL_LCD_CONFIG_DEFAULT) ++ { ++ memset (lcdstring,0,IPMI_DELL_LCD_STRING_LENGTH_MAX+1); ++ ++ ipmi_lcd_get_platform_model_name(intf, lcdstring, IPMI_DELL_LCD_STRING_LENGTH_MAX, ++ IPMI_DELL_PLATFORM_MODEL_NAME_SELECTOR); ++ ++ printf(" Setting: default\n"); ++ printf(" Line 1: %s\n", lcdstring); ++ } ++ else if (command == IPMI_DELL_LCD_CONFIG_NONE) ++ { ++ printf(" Setting: none\n"); ++ } ++ else if (command == IPMI_DELL_LCD_CONFIG_USER_DEFINED) ++ { ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_GET_SYS_INFO; ++ req.msg.data_len = 4; ++ req.msg.data = data; ++ data[0] = 0; /* get parameter */ ++ data[1] = IPMI_DELL_LCD_GET_CAPS_SELECTOR; ++ data[2] = 0; /* set selector (n/a) */ ++ data[3] = 0; /* block selector (n/a) */ ++ ++ printf(" Setting: custom\n"); ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) ++ { ++ lprintf(LOG_ERR, " Error getting LCD capabilities."); ++ return -1; ++ } ++ else if ((rsp->ccode == 0xc1)||(rsp->ccode == 0xcb)) ++ { ++ lprintf(LOG_ERR, " Error getting LCD capabilities: Command not supported on this system."); ++ } ++ else if (rsp->ccode > 0) ++ { ++ lprintf(LOG_ERR, " Error getting LCD capabilities: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ return -1; ++ } ++ ++ lcd_caps = (IPMI_DELL_LCD_CAPS *)(void *)rsp->data; ++ if (lcd_caps->number_lines > 0) ++ { ++ memset (lcdstring,0,IPMI_DELL_LCD_STRING_LENGTH_MAX+1); ++ rc = ipmi_lcd_get_single_line_text (intf, lcdstring, lcd_caps->max_chars[0]); ++ printf(" Text: %s\n", lcdstring); ++ } ++ else ++ { ++ printf(" No lines to show\n"); ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++/***************************************************************** ++* Function Name: ipmi_lcd_get_status_val ++* ++* Description: This function gets current lcd configuration ++* Input: intf - ipmi interface ++* Output: lcdstatus - KVM Status & Lock Status ++* Return: ++* ++******************************************************************/ ++ ++static int ++ipmi_lcd_get_status_val(struct ipmi_intf * intf, LCD_STATUS* lcdstatus) ++{ ++ struct ipmi_rs * rsp = NULL; ++ struct ipmi_rq req = {0}; ++ uint8_t data[4]; ++ ++ ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_GET_SYS_INFO; ++ req.msg.data_len = 4; ++ req.msg.data = data; ++ data[0] = 0; /* get parameter */ ++ data[1] = IPMI_DELL_LCD_STATUS_SELECTOR; ++ data[2] = 0; /* block selector */ ++ data[3] = 0; ++ /* set selector (n/a) */ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) ++ { ++ lprintf(LOG_ERR, " Error getting LCD Status"); ++ return -1; ++ } ++ else if ((rsp->ccode == 0xc1)||(rsp->ccode == 0xcb)) ++ { ++ lprintf(LOG_ERR, " Error getting LCD status: Command not supported on this system."); ++ return -1; ++ } ++ else if (rsp->ccode > 0) ++ { ++ lprintf(LOG_ERR, " Error getting LCD Status: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ return -1; ++ } ++ ++ /*lcdstatus= (LCD_STATUS* ) rsp->data; */ ++ ++ lcdstatus->vKVM_status=rsp->data[1]; ++ lcdstatus->lock_status=rsp->data[2]; ++ ++ return 0; ++} ++ ++ ++/***************************************************************** ++* Function Name: IsLCDSupported ++* ++* Description: This function returns whether lcd supported or not ++* Input: ++* Output: ++* Return: ++* ++******************************************************************/ ++static int IsLCDSupported () ++{ ++ return LcdSupported; ++} ++ ++/***************************************************************** ++* Function Name: CheckLCDSupport ++* ++* Description: This function checks whether lcd supported or not ++* Input: intf - ipmi interface ++* Output: ++* Return: ++* ++******************************************************************/ ++static void CheckLCDSupport(struct ipmi_intf * intf) ++{ ++ struct ipmi_rs * rsp = NULL; ++ struct ipmi_rq req = {0}; ++ uint8_t data[4]; ++ ++ LcdSupported = 0; ++ ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_GET_SYS_INFO; ++ req.msg.data_len = 4; ++ req.msg.data = data; ++ data[0] = 0; /* get parameter */ ++ data[1] = IPMI_DELL_LCD_STATUS_SELECTOR; ++ data[2] = 0; /* block selector */ ++ data[3] = 0; ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) ++ { ++ return; ++ } ++ else if ((rsp->ccode == 0xc1)||(rsp->ccode == 0xcb)) ++ { ++ return; ++ } ++ else if (rsp->ccode > 0) ++ { ++ return; ++ } ++ LcdSupported = 1; ++ ++} ++ ++/***************************************************************** ++* Function Name: ipmi_lcd_status_print ++* ++* Description: This function prints current lcd configuration KVM Status & Lock Status ++* Input: lcdstatus - KVM Status & Lock Status ++* Output: ++* Return: ++* ++******************************************************************/ ++ ++static void ipmi_lcd_status_print( LCD_STATUS lcdstatus) ++{ ++ switch (lcdstatus.vKVM_status) ++ { ++ case 0x00: ++ printf("LCD KVM Status :Inactive\n"); ++ break; ++ case 0x01: ++ printf("LCD KVM Status :Active\n"); ++ break; ++ default: ++ printf("LCD KVM Status :Invalid Status\n"); ++ ++ break; ++ } ++ ++ switch (lcdstatus.lock_status) ++ { ++ case 0x00: ++ printf("LCD lock Status :View and modify\n"); ++ break; ++ case 0x01: ++ printf("LCD lock Status :View only\n"); ++ break; ++ case 0x02: ++ printf("LCD lock Status :disabled\n"); ++ break; ++ default: ++ printf("LCD lock Status :Invalid\n"); ++ break; ++ } ++ ++} ++ ++/***************************************************************** ++* Function Name: ipmi_lcd_get_status ++* ++* Description: This function gets current lcd KVM active status & lcd access mode ++* Input: intf - ipmi interface ++* Output: ++* Return: -1 on error ++* 0 if successful ++* ++******************************************************************/ ++static int ++ipmi_lcd_get_status(struct ipmi_intf * intf ) ++{ ++ int rc=0; ++ LCD_STATUS lcdstatus; ++ ++ rc =ipmi_lcd_get_status_val( intf, &lcdstatus); ++ if (rc <0) ++ return -1; ++ ipmi_lcd_status_print(lcdstatus); ++ ++ return rc; ++ ++} ++ ++/***************************************************************** ++* Function Name: ipmi_lcd_set_kvm ++* ++* Description: This function sets lcd KVM active status ++* Input: intf - ipmi interface ++* status - Inactive / Active ++* Output: ++* Return: -1 on error ++* 0 if successful ++* ++******************************************************************/ ++static int ++ipmi_lcd_set_kvm(struct ipmi_intf * intf, char status) ++{ ++#define LSCC_DATA_LEN 2 ++ LCD_STATUS lcdstatus; ++ int rc=0; ++ struct ipmi_rs * rsp = NULL; ++ struct ipmi_rq req = {0}; ++ uint8_t data[5]; ++ rc=ipmi_lcd_get_status_val(intf,&lcdstatus); ++ if (rc < 0) ++ return -1; ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_SET_SYS_INFO; ++ req.msg.data_len = 5; ++ req.msg.data = data; ++ data[0] = IPMI_DELL_LCD_STATUS_SELECTOR; ++ data[1] = status; /* active- incative*/ ++ data[2] = lcdstatus.lock_status; /* full-veiw-locked */ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, " Error setting LCD status"); ++ rc= -1; ++ }else if ((rsp->ccode == 0xc1)||(rsp->ccode == 0xcb)) { ++ lprintf(LOG_ERR, " Error getting LCD status: Command not supported on this system."); ++ return -1; ++ } else if (rsp->ccode > 0) { ++ lprintf(LOG_ERR, " Error setting LCD status: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ ++ rc= -1; ++ } ++ ++ return rc; ++} ++ ++/***************************************************************** ++* Function Name: ipmi_lcd_set_lock ++* ++* Description: This function sets lcd access mode ++* Input: intf - ipmi interface ++* lock - View and modify / View only / Diabled ++* Output: ++* Return: -1 on error ++* 0 if successful ++* ++******************************************************************/ ++static int ++ipmi_lcd_set_lock(struct ipmi_intf * intf, char lock) ++{ ++#define LSCC_DATA_LEN 2 ++ LCD_STATUS lcdstatus; ++ int rc =0; ++ struct ipmi_rs * rsp = NULL; ++ struct ipmi_rq req = {0}; ++ uint8_t data[5]; ++ rc=ipmi_lcd_get_status_val(intf,&lcdstatus); ++ if (rc < 0) ++ return -1; ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_SET_SYS_INFO; ++ req.msg.data_len = 5; ++ req.msg.data = data; ++ data[0] = IPMI_DELL_LCD_STATUS_SELECTOR; ++ data[1] = lcdstatus.vKVM_status; /* active- incative */ ++ data[2] = lock; /* full- veiw-locked */ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) ++ { ++ lprintf(LOG_ERR, " Error setting LCD status"); ++ rc= -1; ++ } ++ if ((rsp->ccode == 0xc1)||(rsp->ccode == 0xcb)) ++ { ++ lprintf(LOG_ERR, " Error getting LCD status: Command not supported on this system."); ++ return -1; ++ } ++ else if (rsp->ccode > 0) ++ { ++ lprintf(LOG_ERR, " Error setting LCD status: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ ++ rc= -1; ++ } ++ ++ return rc; ++} ++ ++/***************************************************************** ++* Function Name: ipmi_lcd_set_single_line_text ++* ++* Description: This function sets lcd line text ++* Input: intf - ipmi interface ++* text - lcd string ++* Output: ++* Return: -1 on error ++* 0 if successful ++* ++******************************************************************/ ++ ++static int ++ipmi_lcd_set_single_line_text (struct ipmi_intf * intf, char * text) ++{ ++ struct ipmi_rs * rsp = NULL; ++ struct ipmi_rq req = {0}; ++ uint8_t data[18]; ++ int bytes_to_store = strlen(text); ++ int bytes_stored = 0; ++ int ii; ++ int rc = 0; ++ if (bytes_to_store>IPMI_DELL_LCD_STRING_LENGTH_MAX) ++ { ++ lprintf(LOG_ERR, " Out of range Max limit is 62 characters"); ++ return 1; ++ ++ } ++ else ++ { ++ bytes_to_store = MIN(bytes_to_store, IPMI_DELL_LCD_STRING_LENGTH_MAX); ++ for (ii = 0; ii < 4; ii++) { ++ /*first block, 2 bytes parms and 14 bytes data*/ ++ if (0 == ii) { ++ int size_of_copy = ++ MIN((bytes_to_store - bytes_stored), IPMI_DELL_LCD_STRING1_SIZE); ++ if (size_of_copy < 0) /* allow 0 string length*/ ++ break; ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_SET_SYS_INFO; ++ req.msg.data_len = size_of_copy + 4; /* chars, selectors and sizes*/ ++ req.msg.data = data; ++ data[0] = IPMI_DELL_LCD_STRING_SELECTOR; ++ data[1] = ii; /* block number to use (0)*/ ++ data[2] = 0; /*string encoding*/ ++ data[3] = bytes_to_store; /* total string length*/ ++ memcpy (data+4, text+bytes_stored, size_of_copy); ++ bytes_stored += size_of_copy; ++ } else { ++ int size_of_copy = ++ MIN((bytes_to_store - bytes_stored), IPMI_DELL_LCD_STRINGN_SIZE); ++ if (size_of_copy <= 0) ++ break; ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_SET_SYS_INFO; ++ req.msg.data_len = size_of_copy + 2; ++ req.msg.data = data; ++ data[0] = IPMI_DELL_LCD_STRING_SELECTOR; ++ data[1] = ii; /* block number to use (1,2,3)*/ ++ memcpy (data+2, text+bytes_stored, size_of_copy); ++ bytes_stored += size_of_copy; ++ } ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, " Error setting text data"); ++ rc = -1; ++ } else if (rsp->ccode > 0) { ++ lprintf(LOG_ERR, " Error setting text data: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ rc = -1; ++ } ++ } ++ } ++ return rc; ++} ++ ++/***************************************************************** ++* Function Name: ipmi_lcd_set_text ++* ++* Description: This function sets lcd line text ++* Input: intf - ipmi interface ++* text - lcd string ++* line_number- line number ++ ++* Output: ++* Return: -1 on error ++* 0 if successful ++* ++******************************************************************/ ++ ++static int ++ipmi_lcd_set_text(struct ipmi_intf * intf, char * text, int line_number) ++{ ++ int rc = 0; ++ ++ struct ipmi_rs * rsp = NULL; ++ struct ipmi_rq req = {0}; ++ uint8_t data[4]; ++ IPMI_DELL_LCD_CAPS * lcd_caps; ++ ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.lun = 0; ++ req.msg.cmd = IPMI_GET_SYS_INFO; ++ req.msg.data_len = 4; ++ req.msg.data = data; ++ data[0] = 0; /* get parameter*/ ++ data[1] = IPMI_DELL_LCD_GET_CAPS_SELECTOR; ++ data[2] = 0; /* set selector (n/a)*/ ++ data[3] = 0; /* block selector (n/a)*/ ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) ++ { ++ lprintf(LOG_ERR, " Error getting LCD capabilities"); ++ return -1; ++ } ++ else if (rsp->ccode > 0) ++ { ++ lprintf(LOG_ERR, " Error getting LCD capabilities: %s", ++ val2str(rsp->ccode, completion_code_vals)); ++ ++ return -1; ++ } ++ ++ lcd_caps = (IPMI_DELL_LCD_CAPS *)(void *)rsp->data; ++ ++ if (lcd_caps->number_lines > 0) { ++ rc = ipmi_lcd_set_single_line_text (intf, text); ++ } else { ++ lprintf(LOG_ERR, "LCD does not have any lines that can be set"); ++ rc = -1; ++ } ++ ++ ++ return rc; ++} ++ ++/***************************************************************** ++* Function Name: ipmi_lcd_configure_wh ++* ++* Description: This function updates the current lcd configuration ++* Input: intf - ipmi interface ++* lcdquallifier- lcd quallifier ++* errordisp - error number ++* line_number-line number ++* text - lcd string ++* Output: ++* Return: -1 on error ++* 0 if successful ++* ++******************************************************************/ ++ ++static int ++ipmi_lcd_configure_wh (struct ipmi_intf * intf, uint32_t mode , ++ uint16_t lcdquallifier, uint8_t errordisp, ++ int8_t line_number, char * text) ++{ ++ int rc = 0; ++ ++ ++ if (IPMI_DELL_LCD_CONFIG_USER_DEFINED == mode) ++ /* Any error was reported earlier. */ ++ rc = ipmi_lcd_set_text(intf, text, line_number); ++ ++ ++ if (rc == 0) ++ ++ rc = ipmi_lcd_set_configure_command_wh (intf, mode ,lcdquallifier,errordisp); ++ ++ return rc; ++} ++ ++ ++/***************************************************************** ++* Function Name: ipmi_lcd_configure ++* ++* Description: This function updates the current lcd configuration ++* Input: intf - ipmi interface ++* command- lcd command ++* line_number-line number ++* text - lcd string ++* Output: ++* Return: -1 on error ++* 0 if successful ++* ++******************************************************************/ ++ ++static int ++ipmi_lcd_configure (struct ipmi_intf * intf, int command, ++ int8_t line_number, char * text) ++{ ++ int rc = 0; ++ ++ if (IPMI_DELL_LCD_CONFIG_USER_DEFINED == command) ++ rc = ipmi_lcd_set_text(intf, text, line_number); ++ ++ if (rc == 0) ++ rc = ipmi_lcd_set_configure_command (intf, command); ++ ++ return rc; ++} ++ ++ ++/***************************************************************** ++* Function Name: ipmi_lcd_usage ++* ++* Description: This function prints help message for lcd command ++* Input: ++* Output: ++* ++* Return: ++* ++******************************************************************/ ++ ++static void ++ipmi_lcd_usage(void) ++{ ++ lprintf(LOG_NOTICE, ""); ++ if(iDRAC_FLAG==0) ++ { ++ lprintf(LOG_NOTICE, " lcd set {none}|{default}|{custom }"); ++ lprintf(LOG_NOTICE, " Set LCD text displayed during non-fault conditions"); ++ } ++ else if(iDRAC_FLAG==1) ++ { ++ lprintf(LOG_NOTICE, " lcd set {mode}|{lcdqualifier}|{errordisplay}"); ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, " lcd set mode {none}|{modelname}|{ipv4address}|{macaddress}|"); ++ lprintf(LOG_NOTICE, " {systemname}|{servicetag}|{ipv6address}|{ambienttemp}"); ++ lprintf(LOG_NOTICE, " {systemwatt }|{assettag}|{userdefined}"); ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, " lcd set lcdqualifier {watt}|{btuphr}|{celsius}|{fahrenheit}"); ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, " lcd set errordisplay {sel}|{simple}"); ++ } ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, " lcd info"); ++ lprintf(LOG_NOTICE, " Show LCD text that is displayed during non-fault conditions"); ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, " lcd set vkvm{active}|{inactive}"); ++ lprintf(LOG_NOTICE, " Set vKVM active and inactive, message will be displayed on lcd"); ++ lprintf(LOG_NOTICE, " when vKVM is active and vKVM session is in progress"); ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, " lcd set frontpanelaccess {viewandmodify}|{viewonly}|{disabled}"); ++ lprintf(LOG_NOTICE, " Set LCD mode to view and modify, view only or disabled "); ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, " lcd status"); ++ lprintf(LOG_NOTICE, " Show LCD Status for vKVM display"); ++ lprintf(LOG_NOTICE, " and Front Panel access mode {viewandmodify}|{viewonly}|{disabled} "); ++ lprintf(LOG_NOTICE, ""); ++} only in patch2: unchanged: --- ipmitool-1.8.11.orig/debian/patches/dell_04_lan.patch +++ ipmitool-1.8.11/debian/patches/dell_04_lan.patch @@ -0,0 +1,354 @@ +Description: Part 4 of a set of patches adding Dell OEM support - LAN commands +Origin: https://sourceforge.net/tracker/?func=detail&aid=2959605&group_id=95200&atid=610553 +Author: Deepaganesh Paulraj +Last-Update: 2010-06-28 +--- a/include/ipmitool/ipmi_delloem.h ++++ b/include/ipmitool/ipmi_delloem.h +@@ -211,6 +211,14 @@ + #define IDRAC_NIC_NUMBER (uint8_t)(0x8) + + #define TOTAL_N0_NICS_INDEX (uint8_t)(0x1) ++ ++#define SET_NIC_SELECTION_CMD (uint8_t)(0x24) ++#define GET_NIC_SELECTION_CMD (uint8_t)(0x25) ++#define GET_ACTIVE_NIC_CMD (uint8_t)(0xc1) ++ ++ ++ ++ + int ipmi_delloem_main(struct ipmi_intf * intf, int argc, char ** argv); + + #endif /*IPMI_DELLOEM_H*/ +--- a/lib/ipmi_delloem.c ++++ b/lib/ipmi_delloem.c +@@ -70,6 +70,11 @@ + + #define DELL_OEM_NETFN (uint8_t)(0x30) + #define GET_IDRAC_VIRTUAL_MAC (uint8_t)(0xC9) ++#define INVALID -1 ++#define SHARED 0 ++#define SHARED_WITH_FAILOVER_LOM2 1 ++#define DEDICATED 2 ++#define SHARED_WITH_FAILOVER_ALL_LOMS 3 + + static int current_arg =0; + uint8_t iDRAC_FLAG=0; +@@ -120,6 +125,14 @@ + static int ipmi_macinfo (struct ipmi_intf* intf, uint8_t NicNum); + static void ipmi_mac_usage(void); + ++static int ipmi_delloem_lan_main (struct ipmi_intf * intf, int argc, char ** argv); ++static int IsLANSupported (); ++static int get_nic_selection_mode (int current_arg, char ** argv); ++static int ipmi_lan_set_nic_selection (struct ipmi_intf* intf, uint8_t nic_selection); ++static int ipmi_lan_get_nic_selection (struct ipmi_intf* intf); ++static int ipmi_lan_get_active_nic (struct ipmi_intf* intf); ++static void ipmi_lan_usage(void); ++ + + /***************************************************************** + * Function Name: ipmi_delloem_main +@@ -158,6 +171,11 @@ + { + ipmi_delloem_mac_main (intf,argc,argv); + } ++ /* lan address*/ ++ else if (IsLANSupported() && strncmp(argv[current_arg], "lan\0", 4) == 0) ++ { ++ ipmi_delloem_lan_main (intf,argc,argv); ++ } + else + { + usage(); +@@ -186,6 +204,8 @@ + if (IsLCDSupported()) + lprintf(LOG_NOTICE, " lcd"); + lprintf(LOG_NOTICE, " mac"); ++ if (IsLANSupported()) ++ lprintf(LOG_NOTICE, " lan"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, "For help on individual commands type:"); + lprintf(LOG_NOTICE, "delloem help"); +@@ -1747,6 +1767,7 @@ + static int ipmi_delloem_mac_main (struct ipmi_intf * intf, int argc, char ** argv) + { + int rc = 0; ++ + current_arg++; + if (argc == 1) + { +@@ -2252,3 +2273,274 @@ + lprintf(LOG_NOTICE, " Shows the MAC address of specified LOM. 0-7 System LOM, 8- DRAC/iDRAC."); + lprintf(LOG_NOTICE, ""); + } ++ ++/***************************************************************** ++* Function Name: ipmi_delloem_lan_main ++* ++* Description: This function processes the delloem lan command ++* Input: intf - ipmi interface ++ argc - no of arguments ++ argv - argument string array ++* Output: ++* ++* Return: return code 0 - success ++* -1 - failure ++* ++******************************************************************/ ++ ++static int ipmi_delloem_lan_main (struct ipmi_intf * intf, int argc, char ** argv) ++{ ++ int rc = 0; ++ ++ int nic_selection = 0; ++ current_arg++; ++ if (argv[current_arg] == NULL) ++ { ++ ipmi_lan_usage(); ++ return -1; ++ } ++ else if (strncmp(argv[current_arg], "set\0", 4) == 0) ++ { ++ current_arg++; ++ if (argv[current_arg] == NULL) ++ { ++ ipmi_lan_usage(); ++ return -1; ++ } ++ nic_selection = get_nic_selection_mode(current_arg,argv); ++ ++ ++ if (INVALID == nic_selection) ++ { ++ ipmi_lan_usage(); ++ return -1; ++ } ++ rc = ipmi_lan_set_nic_selection(intf,nic_selection); ++ return 0; ++ } ++ else if (strncmp(argv[current_arg], "get\0", 4) == 0) ++ { ++ current_arg++; ++ if (argv[current_arg] == NULL) ++ { ++ rc = ipmi_lan_get_nic_selection(intf); ++ return rc; ++ } ++ else if (strncmp(argv[current_arg], "active\0", 7) == 0) ++ { ++ rc = ipmi_lan_get_active_nic(intf); ++ return rc; ++ } ++ else ++ { ++ ipmi_lan_usage(); ++ } ++ ++ } ++ else ++ { ++ ipmi_lan_usage(); ++ } ++} ++ ++ ++static int IsLANSupported () ++{ ++ if (IMC_IDRAC_11G_MODULAR == IMC_Type) ++ return 0; ++ return 1; ++} ++ ++char NIC_Selection_Mode_String [4] [50] = { "shared", ++"shared with failover lom2", ++"dedicated", ++"shared with Failover all loms" ++}; ++ ++ ++char AciveLOM_String [5] [10] = {"dedicated","LOM1","LOM2","LOM3","LOM4" }; ++ ++ ++ ++ ++static int get_nic_selection_mode (int current_arg, char ** argv) ++{ ++ int nic_selection_mode = 0; ++ if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "dedicated\0", 10)) ++ { ++ return DEDICATED; ++ } ++ if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "shared\0", 7)) ++ { ++ if (NULL == argv[current_arg+1] ) ++ return SHARED; ++ } ++ current_arg++; ++ if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "with\0", 5)) ++ { ++ } ++ else ++ return INVALID; ++ ++ current_arg++; ++ if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "failover\0", 9)) ++ { ++ } ++ else ++ return INVALID; ++ ++ current_arg++; ++ if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "lom2\0", 5)) ++ { ++ return SHARED_WITH_FAILOVER_LOM2; ++ } ++ else if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "all\0", 4)) ++ { ++ } ++ else ++ return INVALID; ++ ++ current_arg++; ++ if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "loms\0", 5)) ++ { ++ return SHARED_WITH_FAILOVER_ALL_LOMS; ++ } ++ ++ return INVALID; ++ ++} ++ ++ ++static int ipmi_lan_set_nic_selection (struct ipmi_intf* intf, uint8_t nic_selection) ++{ ++ struct ipmi_rs * rsp; ++ struct ipmi_rq req; ++ ++ uint8_t msg_data[30]; ++ uint8_t input_length=0; ++ uint8_t j; ++ ++ input_length = 0; ++ ++ msg_data[input_length++] = nic_selection; ++ ++ req.msg.netfn = DELL_OEM_NETFN; ++ req.msg.lun = 0; ++ req.msg.cmd = SET_NIC_SELECTION_CMD; ++ req.msg.data = msg_data; ++ req.msg.data_len = input_length; ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) ++ { ++ lprintf(LOG_ERR, " Error in setting nic selection"); ++ return -1; ++ } ++ else if (rsp->ccode > 0) ++ { ++ lprintf(LOG_ERR, " Error in setting nic selection (%s) \n", ++ val2str(rsp->ccode, completion_code_vals) ); ++ return -1; ++ } ++ printf("configured successfully"); ++ ++ return 0; ++} ++ ++static int ipmi_lan_get_nic_selection (struct ipmi_intf* intf) ++{ ++ uint8_t nic_selection=-1; ++ ++ struct ipmi_rs * rsp; ++ struct ipmi_rq req; ++ ++ uint8_t msg_data[30]; ++ uint8_t input_length=0; ++ uint8_t j; ++ ++ input_length = 0; ++ ++ req.msg.netfn = DELL_OEM_NETFN; ++ req.msg.lun = 0; ++ req.msg.cmd = GET_NIC_SELECTION_CMD; ++ req.msg.data = msg_data; ++ req.msg.data_len = input_length; ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) ++ { ++ lprintf(LOG_ERR, " Error in getting nic selection"); ++ return -1; ++ } ++ else if (rsp->ccode > 0) ++ { ++ lprintf(LOG_ERR, " Error in getting nic selection (%s) \n", ++ val2str(rsp->ccode, completion_code_vals) ); ++ return -1; ++ } ++ nic_selection = rsp->data[0]; ++ ++ printf ("\n%s",NIC_Selection_Mode_String[nic_selection]); ++ ++ return 0; ++} ++ ++static int ipmi_lan_get_active_nic (struct ipmi_intf* intf) ++{ ++ uint8_t active_nic=0; ++ ++ struct ipmi_rs * rsp; ++ struct ipmi_rq req; ++ ++ uint8_t msg_data[30]; ++ uint8_t input_length=0; ++ uint8_t j; ++ ++ input_length = 0; ++ ++ msg_data[input_length++] = 0; /*Get Status*/ ++ msg_data[input_length++] = 0; /*Reserved*/ ++ msg_data[input_length++] = 0; /*Reserved*/ ++ ++ req.msg.netfn = DELL_OEM_NETFN; ++ req.msg.lun = 0; ++ req.msg.cmd = GET_ACTIVE_NIC_CMD; ++ req.msg.data = msg_data; ++ req.msg.data_len = input_length; ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) ++ { ++ lprintf(LOG_ERR, " Error in getting Active LOM Status"); ++ return -1; ++ } ++ else if (rsp->ccode > 0) ++ { ++ lprintf(LOG_ERR, " Error in getting Active LOM Status (%s) \n", ++ val2str(rsp->ccode, completion_code_vals) ); ++ return -1; ++ } ++ active_nic = rsp->data[0]; ++ if (active_nic < 5) ++ printf ("\n%s",AciveLOM_String[active_nic]); ++ ++ return 0; ++} ++ ++ ++static void ++ipmi_lan_usage(void) ++{ ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, " lan set "); ++ lprintf(LOG_NOTICE, " sets the NIC Selection Mode (dedicated, shared, shared with failover lom2, shared with Failover all loms)."); ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, " lan get "); ++ lprintf(LOG_NOTICE, " returns the current NIC Selection Mode (dedicated, shared, shared with failover lom2, shared with Failover all loms)."); ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, " lan get active"); ++ lprintf(LOG_NOTICE, " returns the current active NIC (dedicated, LOM1, LOM2, LOM3, LOM4)."); ++ lprintf(LOG_NOTICE, ""); ++} ++ ++ only in patch2: unchanged: --- ipmitool-1.8.11.orig/debian/patches/dell_03_mac.patch +++ ipmitool-1.8.11/debian/patches/dell_03_mac.patch @@ -0,0 +1,680 @@ +Description: Part 3 of a set of patches adding Dell OEM support - MAC commands +Origin: https://sourceforge.net/tracker/?func=detail&aid=2959604&group_id=95200&atid=610553 +Author: Deepaganesh Paulraj +Last-Update: 2010-06-28 +--- a/include/ipmitool/ipmi_delloem.h ++++ b/include/ipmitool/ipmi_delloem.h +@@ -141,11 +141,76 @@ + uint8_t Resv; + } __attribute__ ((packed)) LCD_MODE; + ++#define PARAM_REV_OFFSET (uint8_t)(0x1) + ++#define LOM_MACTYPE_ETHERNET 0 ++#define LOM_MACTYPE_ISCSI 1 ++#define LOM_MACTYPE_RESERVED 3 + ++#define LOM_ETHERNET_ENABLED 0 ++#define LOM_ETHERNET_DISABLED 1 ++#define LOM_ETHERNET_PLAYINGDEAD 2 ++#define LOM_ETHERNET_RESERVED 3 + ++#define LOM_ACTIVE 1 ++#define LOM_INACTIVE 0 + ++#define MACADDRESSLENGH 6 ++#define MAX_LOM 8 + ++ ++#define APP_NETFN (uint8_t)(0x6) ++ ++ ++#define GET_SYSTEM_INFO_CMD (uint8_t)(0x59) ++#define EMB_NIC_MAC_ADDRESS_11G (uint8_t)(0xDA) ++#define EMB_NIC_MAC_ADDRESS_9G_10G (uint8_t)(0xCB) ++ ++#define IMC_IDRAC_10G (uint8_t) (0x08) ++#define IMC_CMC (uint8_t) (0x09) ++#define IMC_IDRAC_11G_MONOLITHIC (uint8_t) (0x0A) ++#define IMC_IDRAC_11G_MODULAR (uint8_t) (0x0B) ++#define IMC_UNUSED (uint8_t) (0x0C) ++#define IMC_MASER_LITE_BMC (uint8_t) (0x0D) ++ ++ ++ ++typedef struct ++{ ++ unsigned int BladSlotNumber : 4; ++ unsigned int MacType : 2; ++ unsigned int EthernetStatus : 2; ++ unsigned int NICNumber : 5; ++ unsigned int Reserved : 3; ++ uint8_t MacAddressByte[MACADDRESSLENGH]; ++} LOMMacAddressType; ++ ++ ++typedef struct ++{ ++ LOMMacAddressType LOMMacAddress [MAX_LOM]; ++} EmbeddedNICMacAddressType; ++ ++typedef struct ++{ ++ uint8_t MacAddressByte[MACADDRESSLENGH]; ++} MacAddressType; ++ ++typedef struct ++{ ++ MacAddressType MacAddress [MAX_LOM]; ++} EmbeddedNICMacAddressType_10G; ++ ++ ++ ++#define TRANSPORT_NETFN (uint8_t)(0xc) ++#define GET_LAN_PARAM_CMD (uint8_t)(0x02) ++#define MAC_ADDR_PARAM (uint8_t)(0x05) ++#define LAN_CHANNEL_NUMBER (uint8_t)(0x01) ++ ++#define IDRAC_NIC_NUMBER (uint8_t)(0x8) ++ ++#define TOTAL_N0_NICS_INDEX (uint8_t)(0x1) + int ipmi_delloem_main(struct ipmi_intf * intf, int argc, char ** argv); + + #endif /*IPMI_DELLOEM_H*/ +--- a/lib/ipmi_delloem.c ++++ b/lib/ipmi_delloem.c +@@ -68,12 +68,18 @@ + /*--------------time header-----------------*/ + #include + ++#define DELL_OEM_NETFN (uint8_t)(0x30) ++#define GET_IDRAC_VIRTUAL_MAC (uint8_t)(0xC9) + + static int current_arg =0; + uint8_t iDRAC_FLAG=0; + LCD_MODE lcd_mode; + static uint8_t LcdSupported=0; + ++ ++volatile uint8_t IMC_Type = IMC_IDRAC_10G; ++ ++ + static void usage(void); + + static int ipmi_delloem_lcd_main (struct ipmi_intf * intf, int argc, char ** argv); +@@ -104,6 +110,17 @@ + int8_t line_number, char * text); + static void ipmi_lcd_usage(void); + ++static int ipmi_delloem_mac_main (struct ipmi_intf * intf, int argc, char ** argv); ++static int make_int(const char *str, int *value); ++static void InitEmbeddedNICMacAddressValues (); ++static int ipmi_macinfo_drac_idrac_virtual_mac(struct ipmi_intf* intf,uint8_t NicNum); ++static int ipmi_macinfo_drac_idrac_mac(struct ipmi_intf* intf,uint8_t NicNum); ++static int ipmi_macinfo_10g (struct ipmi_intf* intf, uint8_t NicNum); ++static int ipmi_macinfo_11g (struct ipmi_intf* intf, uint8_t NicNum); ++static int ipmi_macinfo (struct ipmi_intf* intf, uint8_t NicNum); ++static void ipmi_mac_usage(void); ++ ++ + /***************************************************************** + * Function Name: ipmi_delloem_main + * +@@ -136,6 +153,11 @@ + { + ipmi_delloem_lcd_main (intf,argc,argv); + } ++ /* mac address*/ ++ else if (strncmp(argv[current_arg], "mac\0", 4) == 0) ++ { ++ ipmi_delloem_mac_main (intf,argc,argv); ++ } + else + { + usage(); +@@ -163,6 +185,7 @@ + lprintf(LOG_NOTICE, "commands:"); + if (IsLCDSupported()) + lprintf(LOG_NOTICE, " lcd"); ++ lprintf(LOG_NOTICE, " mac"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, "For help on individual commands type:"); + lprintf(LOG_NOTICE, "delloem help"); +@@ -599,7 +622,8 @@ + { + iDRAC_FLAG=0; + } +- ++ IMC_Type = rsp->data[10]; ++ + return 0; + } + +@@ -1704,3 +1728,527 @@ + lprintf(LOG_NOTICE, " and Front Panel access mode {viewandmodify}|{viewonly}|{disabled} "); + lprintf(LOG_NOTICE, ""); + } ++ ++/***************************************************************** ++* Function Name: ipmi_delloem_mac_main ++* ++* Description: This function processes the delloem mac command ++* Input: intf - ipmi interface ++ argc - no of arguments ++ argv - argument string array ++* Output: ++* ++* Return: return code 0 - success ++* -1 - failure ++* ++******************************************************************/ ++ ++ ++static int ipmi_delloem_mac_main (struct ipmi_intf * intf, int argc, char ** argv) ++{ ++ int rc = 0; ++ current_arg++; ++ if (argc == 1) ++ { ++ rc = ipmi_macinfo(intf, 0xff); ++ } ++ else if (strncmp(argv[current_arg], "list\0", 5) == 0) ++ { ++ rc = ipmi_macinfo(intf, 0xff); ++ } ++ else if (strncmp(argv[current_arg], "get\0", 4) == 0) ++ { ++ current_arg++; ++ if (argv[current_arg] == NULL) ++ { ++ ipmi_mac_usage(); ++ return -1; ++ } ++ int currIdInt; ++ make_int(argv[current_arg],&currIdInt); ++ if(currIdInt>8) ++ { ++ lprintf(LOG_ERR, "Invalid NIC number. The NIC number should be between 0-8\n"); ++ ipmi_mac_usage(); ++ return -1; ++ } ++ rc = ipmi_macinfo(intf, currIdInt); ++ } ++ else ++ { ++ ipmi_mac_usage(); ++ } ++ ++} ++ ++ ++/***************************************************************** ++* Function Name: make_int ++* ++* Description: This function convert string into integer ++* Input: str - decimal number string ++* Output: value - integer value ++* Return: ++* ++******************************************************************/ ++static int make_int(const char *str, int *value) ++{ ++ char *tmp=NULL; ++ *value = strtol(str,&tmp,0); ++ if ( tmp-str != strlen(str) ) ++ { ++ return -1; ++ } ++ return 0; ++} ++ ++ ++ ++ ++ ++EmbeddedNICMacAddressType EmbeddedNICMacAddress; ++ ++EmbeddedNICMacAddressType_10G EmbeddedNICMacAddress_10G; ++ ++static void InitEmbeddedNICMacAddressValues () ++{ ++ uint8_t i; ++ uint8_t j; ++ ++ ++ for (i=0;isendrecv(intf, &req); ++ if (rsp == NULL) ++ { ++ return -1; ++ } ++ if (rsp->ccode > 0) ++ { ++ return -1; ++ } ++ memcpy(VirtualMacAddress,((rsp->data)+VIRTUAL_MAC_OFFSET),MACADDRESSLENGH); ++ ++ for (i=0;isendrecv(intf, &req); ++ if (rsp == NULL) ++ { ++ lprintf(LOG_ERR, " Error in getting MAC Address"); ++ return -1; ++ } ++ if (rsp->ccode > 0) ++ { ++ lprintf(LOG_ERR, " Error in getting MAC Address (%s) \n", ++ val2str(rsp->ccode, completion_code_vals) ); ++ return -1; ++ } ++ ++ memcpy(iDRAC6MacAddressByte,((rsp->data)+PARAM_REV_OFFSET),MACADDRESSLENGH); ++ ++ if (IMC_IDRAC_10G == IMC_Type) ++ printf ("\n\rDRAC MAC Address "); ++ else ++ printf ("\n\riDRAC6 MAC Address "); ++ ++ for (j=0;j<5;j++) ++ printf("%02x:",iDRAC6MacAddressByte[j]); ++ printf("%02x",iDRAC6MacAddressByte[j]); ++ ++ printf ("\n\r"); ++ } ++ return 0; ++} ++ ++ ++/***************************************************************** ++* Function Name: ipmi_macinfo_10g ++* ++* Description: This function retrieves the mac address of LOMs ++* Input: intf - ipmi interface ++ NicNum - NIC number ++* Output: ++* Return: ++* ++******************************************************************/ ++ ++static int ipmi_macinfo_10g (struct ipmi_intf* intf, uint8_t NicNum) ++{ ++ struct ipmi_rs * rsp; ++ struct ipmi_rq req; ++ ++ uint8_t msg_data[30]; ++ uint8_t input_length=0; ++ ++ uint8_t j; ++ uint8_t i; ++ uint8_t rc; ++ ++ uint8_t Total_No_NICs = 0; ++ ++ ++ InitEmbeddedNICMacAddressValues (); ++ ++ memset(msg_data, 0, sizeof(msg_data)); ++ input_length = 0; ++ msg_data[input_length++] = 0x00; /* Get Parameter Command */ ++ msg_data[input_length++] = EMB_NIC_MAC_ADDRESS_9G_10G; /* OEM Param */ ++ ++ msg_data[input_length++] = 0x00; ++ msg_data[input_length++] = 0x00; ++ ++ memset(&req, 0, sizeof(req)); ++ ++ req.msg.netfn = APP_NETFN; ++ req.msg.lun = 0; ++ req.msg.cmd = GET_SYSTEM_INFO_CMD; ++ req.msg.data = msg_data; ++ ++ ++ req.msg.data_len = input_length; ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, " Error in getting MAC Address"); ++ return -1; ++ } ++ if (rsp->ccode > 0) { ++ lprintf(LOG_ERR, " Error in getting MAC Address (%s) \n", ++ val2str(rsp->ccode, completion_code_vals) ); ++ return -1; ++ } ++ ++ Total_No_NICs = (uint8_t) rsp->data[0+PARAM_REV_OFFSET]; /* Byte 1: Total Number of Embedded NICs */ ++ ++ if (IDRAC_NIC_NUMBER != NicNum) ++ { ++ if (0xff == NicNum) ++ { ++ printf ("\n\rSystem LOMs"); ++ } ++ printf("\n\rNIC Number\tMAC Address\n\r"); ++ ++ ++ memcpy(&EmbeddedNICMacAddress_10G,((rsp->data)+PARAM_REV_OFFSET+TOTAL_N0_NICS_INDEX),Total_No_NICs* MACADDRESSLENGH); ++ ++ ++ /*Read the LOM type and Mac Addresses */ ++ ++ for (i=0;isendrecv(intf, &req); ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, " Error in getting MAC Address"); ++ return -1; ++ } ++ if (rsp->ccode > 0) { ++ lprintf(LOG_ERR, " Error in getting MAC Address (%s) \n", ++ val2str(rsp->ccode, completion_code_vals) ); ++ return -1; ++ } ++ ++ len = 8; /*eigher 8 or 16 */ ++ maxlen = (uint8_t) rsp->data[0+PARAM_REV_OFFSET]; ++ loop_count = maxlen / len; ++ ++ if (IDRAC_NIC_NUMBER != NicNum) ++ { ++ if (0xff == NicNum) ++ { ++ printf ("\n\rSystem LOMs"); ++ } ++ printf("\n\rNIC Number\tMAC Address\t\tStatus\n\r"); ++ ++ ++ /*Read the LOM type and Mac Addresses */ ++ offset=0; ++ for (i=0;isendrecv(intf, &req); ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, " Error in getting MAC Address"); ++ return -1; ++ } ++ if (rsp->ccode > 0) { ++ lprintf(LOG_ERR, " Error in getting MAC Address (%s) \n", ++ val2str(rsp->ccode, completion_code_vals) ); ++ return -1; ++ ++ } ++ ++ memcpy(&(EmbeddedNICMacAddress.LOMMacAddress[i]),((rsp->data)+PARAM_REV_OFFSET),len); ++ ++ ++ if (LOM_MACTYPE_ETHERNET == EmbeddedNICMacAddress.LOMMacAddress[i].MacType) ++ { ++ ++ if ( (0xff==NicNum) || (NicNum == EmbeddedNICMacAddress.LOMMacAddress[i].NICNumber) ) ++ { ++ printf ("\n\r%d",EmbeddedNICMacAddress.LOMMacAddress[i].NICNumber); ++ printf ("\t\t"); ++ for (j=0;j<5;j++) ++ printf("%02x:",EmbeddedNICMacAddress.LOMMacAddress[i].MacAddressByte[j]); ++ printf("%02x",EmbeddedNICMacAddress.LOMMacAddress[i].MacAddressByte[j]); ++ ++ if (LOM_ETHERNET_ENABLED == EmbeddedNICMacAddress.LOMMacAddress[i].EthernetStatus) ++ printf ("\tEnabled"); ++ else ++ printf ("\tDisabled"); ++ } ++ } ++ ++ } ++ printf ("\n\r"); ++ ++ } ++ ++ ipmi_macinfo_drac_idrac_mac(intf,NicNum); ++ ++ return 0; ++ ++} ++ ++ ++ ++/***************************************************************** ++* Function Name: ipmi_macinfo ++* ++* Description: This function retrieves the mac address of LOMs ++* Input: intf - ipmi interface ++* Output: ++* Return: ++* ++******************************************************************/ ++ ++static int ipmi_macinfo (struct ipmi_intf* intf, uint8_t NicNum) ++{ ++ if (IMC_IDRAC_10G == IMC_Type) ++ { ++ return ipmi_macinfo_10g (intf,NicNum); ++ } ++ else if (IMC_IDRAC_11G_MODULAR == IMC_Type || IMC_IDRAC_11G_MONOLITHIC== IMC_Type ) ++ { ++ return ipmi_macinfo_11g (intf,NicNum); ++ } ++ else ++ { ++ lprintf(LOG_ERR, " Error in getting MAC Address : Not supported platform"); ++ return 0; ++ } ++} ++ ++ ++/***************************************************************** ++* Function Name: ipmi_mac_usage ++* ++* Description: This function prints help message for mac command ++* Input: ++* Output: ++* ++* Return: ++* ++******************************************************************/ ++ ++static void ++ipmi_mac_usage(void) ++{ ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, " mac list"); ++ lprintf(LOG_NOTICE, " Lists the MAC address of LOMs"); ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, " mac get "); ++ lprintf(LOG_NOTICE, " Shows the MAC address of specified LOM. 0-7 System LOM, 8- DRAC/iDRAC."); ++ lprintf(LOG_NOTICE, ""); ++} only in patch2: unchanged: --- ipmitool-1.8.11.orig/debian/patches/101_fix_buf_overflow.patch +++ ipmitool-1.8.11/debian/patches/101_fix_buf_overflow.patch @@ -0,0 +1,12 @@ +diff -Naurp ipmitool-1.8.11.orig//lib/ipmi_tsol.c ipmitool-1.8.11//lib/ipmi_tsol.c +--- ipmitool-1.8.11.orig//lib/ipmi_tsol.c 2009-02-25 15:38:52.000000000 -0500 ++++ ipmitool-1.8.11//lib/ipmi_tsol.c 2010-09-08 09:10:24.611519035 -0400 +@@ -385,7 +385,7 @@ ipmi_tsol_main(struct ipmi_intf * intf, + socklen_t mylen; + char *recvip = NULL; + char out_buff[IPMI_BUF_SIZE * 8], in_buff[IPMI_BUF_SIZE]; +- char buff[IPMI_BUF_SIZE + 4]; ++ char buff[IPMI_BUF_SIZE * 8 + 4]; + int fd_socket, result, i; + int out_buff_fill, in_buff_fill; + int ip1, ip2, ip3, ip4; only in patch2: unchanged: --- ipmitool-1.8.11.orig/debian/patches/dell_01_basic.patch +++ ipmitool-1.8.11/debian/patches/dell_01_basic.patch @@ -0,0 +1,620 @@ +Description: Part 1 of a set of patches adding Dell OEM support - Patchset foundations +Origin: https://sourceforge.net/tracker/?func=detail&aid=2959602&group_id=95200&atid=610553 +Author: Deepaganesh Paulraj +Last-Update: 2010-06-28 +--- a/configure ++++ b/configure +@@ -24310,7 +24310,7 @@ + fi + fi; + +- ++ac_config_files="$ac_config_files Makefile doc/Makefile contrib/Makefile control/Makefile control/pkginfo control/prototype control/rpmmacros control/ipmitool.spec lib/Makefile include/Makefile include/ipmitool/Makefile src/Makefile src/plugins/Makefile src/plugins/lan/Makefile src/plugins/lanplus/Makefile src/plugins/open/Makefile src/plugins/free/Makefile src/plugins/imb/Makefile src/plugins/bmc/Makefile src/plugins/lipmi/Makefile" + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling + See \`config.log' for more details." >&5 +--- a/doc/ipmitool.1 ++++ b/doc/ipmitool.1 +@@ -219,6 +219,7 @@ + shell Launch interactive IPMI shell + exec Run list of commands from file + set Set runtime variable for shell and exec ++ delloem Manage Dell OEM Extensions + echo Used to echo lines to stdout in scripts + ekanalyzer run FRU-Ekeying analyzer using FRU files + +--- /dev/null ++++ b/include/ipmitool/ipmi_delloem.h +@@ -0,0 +1,42 @@ ++/**************************************************************************** ++Copyright (c) 2008, Dell Inc ++All rights reserved. ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions are met: ++- Redistributions of source code must retain the above copyright notice, ++this list of conditions and the following disclaimer. ++ ++- Redistributions 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 Dell Inc nor the names of its contributors ++may be used to endorse or promote products derived from this software ++without specific prior written permission. ++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++POSSIBILITY OF SUCH DAMAGE. ++ ++ ++*****************************************************************************/ ++#ifndef IPMI_DELLOEM_H ++#define IPMI_DELLOEM_H ++ ++#if HAVE_CONFIG_H ++# include ++#endif ++ ++#pragma pack(1) ++ ++ ++int ipmi_delloem_main(struct ipmi_intf * intf, int argc, char ** argv); ++ ++#endif /*IPMI_DELLOEM_H*/ ++ +--- a/include/ipmitool/Makefile.am ++++ b/include/ipmitool/Makefile.am +@@ -37,5 +37,5 @@ + ipmi_strings.h ipmi_constants.h ipmi_user.h ipmi_pef.h \ + ipmi_oem.h ipmi_isol.h ipmi_sunoem.h ipmi_picmg.h \ + ipmi_fwum.h ipmi_main.h ipmi_tsol.h ipmi_firewall.h \ +- ipmi_kontronoem.h ipmi_ekanalyzer.h ipmi_gendev.h ++ ipmi_kontronoem.h ipmi_delloem.h ipmi_ekanalyzer.h ipmi_gendev.h + +--- a/include/ipmitool/Makefile.in ++++ b/include/ipmitool/Makefile.in +@@ -216,7 +216,7 @@ + ipmi_strings.h ipmi_constants.h ipmi_user.h ipmi_pef.h \ + ipmi_oem.h ipmi_isol.h ipmi_sunoem.h ipmi_picmg.h \ + ipmi_fwum.h ipmi_main.h ipmi_tsol.h ipmi_firewall.h \ +- ipmi_kontronoem.h ipmi_ekanalyzer.h ipmi_gendev.h ++ ipmi_kontronoem.h ipmi_delloem.h ipmi_ekanalyzer.h ipmi_gendev.h + + all: all-am + +--- /dev/null ++++ b/lib/ipmi_delloem.c +@@ -0,0 +1,114 @@ ++/****************************************************************** ++Copyright (c) 2008, Dell Inc ++All rights reserved. ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions are met: ++- Redistributions of source code must retain the above copyright notice, ++this list of conditions and the following disclaimer. ++ ++- Redistributions 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 Dell Inc nor the names of its contributors ++may be used to endorse or promote products derived from this software ++without specific prior written permission. ++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++POSSIBILITY OF SUCH DAMAGE. ++ ++ ++******************************************************************/ ++/* ++* Thursday Oct 7 17:30:12 2009 ++* ++* ++* This code implements a dell OEM proprietary commands. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++/*------------ipmi headers------------------*/ ++ ++ ++/*--------------time header-----------------*/ ++#include ++ ++static int current_arg =0; ++static void usage(void); ++ ++ ++/***************************************************************** ++* Function Name: ipmi_delloem_main ++* ++* Description: This function processes the delloem command ++* Input: intf - ipmi interface ++ argc - no of arguments ++ argv - argument string array ++* Output: ++* ++* Return: return code 0 - success ++* -1 - failure ++* ++******************************************************************/ ++ ++int ++ipmi_delloem_main(struct ipmi_intf * intf, int argc, char ** argv) ++{ ++ int rc = 0; ++ ++ ++ if (argc == 0 || strncmp(argv[0], "help\0", 5) == 0) ++ { ++ usage(); ++ return 0; ++ } ++ ++ return rc; ++} ++ ++ ++/***************************************************************** ++* Function Name: usage ++* ++* Description: This function prints help message for delloem command ++* Input: ++* Output: ++* ++* Return: ++* ++******************************************************************/ ++ ++static void usage(void) ++{ ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, "usage: delloem [option...]"); ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, "commands:"); ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, "For help on individual commands type:"); ++ lprintf(LOG_NOTICE, "delloem help"); ++ ++} ++ +--- a/lib/ipmi_event.c ++++ b/lib/ipmi_event.c +@@ -95,10 +95,11 @@ + + chmed = ipmi_current_channel_medium(intf); + if (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) { +- /* system interface, need extra generator ID */ +- req.msg.data_len = 8; +- rqdata[0] = 0x20; +- memcpy(rqdata+1, emsg, sizeof(struct platform_event_msg)); ++ /* system interface, need extra generator ID */ ++ req.msg.data_len = 8; ++ /* Valid system software ID The bit [0] of SWID must be 1b */ ++ rqdata[0] = (0x20 <<1) | 0x1; ++ memcpy(rqdata+1, emsg, sizeof(struct platform_event_msg)); + } + else { + req.msg.data_len = 7; +--- a/lib/ipmi_main.c ++++ b/lib/ipmi_main.c +@@ -73,11 +73,12 @@ + #endif + + #ifdef ENABLE_ALL_OPTIONS +-# define OPTION_STRING "I:hVvcgsEKao:H:d:P:f:U:p:C:L:A:t:T:m:S:l:b:B:e:k:y:O:" ++# define OPTION_STRING "I:hVvcgsEKao:H:d:P:f:U:p:C:L:A:t:T:m:S:l:b:B:e:k:x:y:O:" + #else + # define OPTION_STRING "I:hVvcH:f:U:p:d:S:" + #endif + ++int xoptionselected =0; + extern int verbose; + extern int csv_output; + extern const struct valstr ipmi_privlvl_vals[]; +@@ -230,6 +231,7 @@ + lprintf(LOG_NOTICE, " -e char Set SOL escape character"); + lprintf(LOG_NOTICE, " -C ciphersuite Cipher suite to be used by lanplus interface"); + lprintf(LOG_NOTICE, " -k key Use Kg key for IPMIv2 authentication"); ++ lprintf(LOG_NOTICE, " -x key Use Kg key in hex value"); + lprintf(LOG_NOTICE, " -y hex_key Use hexadecimal-encoded Kg key for IPMIv2 authentication"); + lprintf(LOG_NOTICE, " -L level Remote session privilege level [default=ADMINISTRATOR]"); + lprintf(LOG_NOTICE, " Append a '+' to use name/privilege lookup in RAKP1"); +@@ -254,6 +256,34 @@ + ipmi_cmd_print(cmdlist); + } + ++char IsHexValue (char ch) ++{ ++ if ( (ch >= '0' && ch <='9') || ++ (ch >= 'a' && ch <='f') || ++ (ch >= 'A' && ch <='F') ++ ) ++ { ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/* ++Input - a valid hex value. ++Output - 0x0 to 0xF ++*/ ++char AsciiToHex (char ch) ++{ ++ if (ch >='a') ++ return ch-'a'+10; ++ if (ch >='A') ++ return ch-'A'+10; ++ if (ch >= '0') ++ return ch-'0'; ++ return ch; ++} ++ + /* ipmi_parse_hex - convert hexadecimal numbers to ascii string + * Input string must be composed of two-characer hexadecimal numbers. + * There is no separator between the numbers. Each number results in one character +@@ -352,7 +382,14 @@ + char * sdrcache = NULL; + unsigned char * kgkey = NULL; + char * seloem = NULL; +- int port = 0; ++ #define ENCRYPTION_KEY_ASCII_LENGTH 40 ++ #define ENCRYPTION_KEY_HEX_LENGTH 20 ++ ++ char kgkeyhexbuf[ENCRYPTION_KEY_ASCII_LENGTH+1]; ++ char kgkeybuf[ENCRYPTION_KEY_HEX_LENGTH+1]; ++ char nibble; ++ ++ int port = 0,k,m; + int devnum = 0; + int cipher_suite_id = 3; /* See table 22-19 of the IPMIv2 spec */ + int argflag, i, found; +@@ -363,6 +400,7 @@ + progname = strrchr(argv[0], '/'); + progname = ((progname == NULL) ? argv[0] : progname+1); + ++ xoptionselected = 0; + while ((argflag = getopt(argc, (char **)argv, OPTION_STRING)) != -1) + { + switch (argflag) { +@@ -392,7 +430,7 @@ + goto out_free; + break; + case 'V': +- printf("%s version %s\n", progname, VERSION); ++ printf("%s version %s.dell19\n", progname, VERSION); + rc = 0; + goto out_free; + break; +@@ -449,6 +487,45 @@ + goto out_free; + } + break; ++ case 'x': ++ xoptionselected = 1; ++ kgkey = strdup(optarg); ++ ++ if (kgkey == NULL) { ++ lprintf(LOG_ERR, "%s: malloc failure", progname); ++ goto out_free; ++ } ++ if (strlen(kgkey) != ENCRYPTION_KEY_ASCII_LENGTH) ++ { ++ lprintf(LOG_ERR, "This option supports kg key. The key string size should be 40 characters."); ++ goto out_free; ++ } ++ ++ for (k=0;k MAX_USER_PASSWORD_LENGTH) ++ { ++ printf("\nMaximum password length is 20 characters."); ++ goto out_free; ++ } + + /* Prevent password snooping with ps */ + i = strlen(optarg); +@@ -661,8 +744,12 @@ + ipmi_intf_session_set_username(intf, username); + if (password != NULL) + ipmi_intf_session_set_password(intf, password); +- if (kgkey != NULL) +- ipmi_intf_session_set_kgkey(intf, kgkey); ++ if (1 == xoptionselected) ++ if (kgkey != NULL) ++ ipmi_intf_session_set_kgkey(intf, kgkeybuf); ++ else ++ if (kgkey != NULL) ++ ipmi_intf_session_set_kgkey(intf, kgkey); + if (port > 0) + ipmi_intf_session_set_port(intf, port); + if (authtype >= 0) +--- a/lib/Makefile.am ++++ b/lib/Makefile.am +@@ -38,7 +38,8 @@ + ipmi_session.c ipmi_strings.c ipmi_user.c ipmi_raw.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_hpmfwupg.c ipmi_sdradd.c ipmi_ekanalyzer.c ipmi_gendev.c\ ++ipmi_delloem.c + + libipmitool_la_LDFLAGS = -export-dynamic + libipmitool_la_LIBADD = -lm +--- a/lib/Makefile.in ++++ b/lib/Makefile.in +@@ -46,6 +46,8 @@ + + SOURCES = $(libipmitool_la_SOURCES) + ++SOURCES = $(libipmitool_la_SOURCES) ++ + srcdir = @srcdir@ + top_srcdir = @top_srcdir@ + VPATH = @srcdir@ +@@ -86,8 +88,8 @@ + ipmi_user.lo ipmi_raw.lo ipmi_oem.lo ipmi_isol.lo \ + ipmi_sunoem.lo ipmi_fwum.lo ipmi_picmg.lo ipmi_main.lo \ + ipmi_tsol.lo ipmi_firewall.lo ipmi_kontronoem.lo \ +- ipmi_hpmfwupg.lo ipmi_sdradd.lo ipmi_ekanalyzer.lo \ +- ipmi_gendev.lo ++ ipmi_hpmfwupg.lo ipmi_sdradd.lo ipmi_ekanalyzer.lo\ ++ ipmi_delloem.lo ipmi_gendev.lo + libipmitool_la_OBJECTS = $(am_libipmitool_la_OBJECTS) + DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) + depcomp = $(SHELL) $(top_srcdir)/depcomp +@@ -239,7 +241,8 @@ + ipmi_session.c ipmi_strings.c ipmi_user.c ipmi_raw.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_hpmfwupg.c ipmi_sdradd.c ipmi_ekanalyzer.c ipmi_gendev.c\ ++ipmi_delloem.c + + libipmitool_la_LDFLAGS = -export-dynamic + libipmitool_la_LIBADD = -lm +--- a/src/ipmitool.c ++++ b/src/ipmitool.c +@@ -61,6 +61,7 @@ + #include + #include + #include ++#include + #include + + #ifdef HAVE_CONFIG_H +@@ -105,6 +106,7 @@ + { ipmi_picmg_main, "picmg", "Run a PICMG/ATCA extended cmd"}, + { ipmi_fwum_main, "fwum", "Update IPMC using Kontron OEM Firmware Update Manager" }, + { ipmi_firewall_main,"firewall","Configure Firmware Firewall" }, ++ { ipmi_delloem_main, "delloem", "OEM Commands for Dell systems" }, + #ifdef HAVE_READLINE + { ipmi_shell_main, "shell", "Launch interactive IPMI shell" }, + #endif +--- a/src/Makefile.in ++++ b/src/Makefile.in +@@ -46,6 +46,8 @@ + + SOURCES = $(ipmievd_SOURCES) $(ipmitool_SOURCES) + ++SOURCES = $(ipmievd_SOURCES) $(ipmitool_SOURCES) ++ + srcdir = @srcdir@ + top_srcdir = @top_srcdir@ + VPATH = @srcdir@ +--- a/src/plugins/bmc/Makefile.in ++++ b/src/plugins/bmc/Makefile.in +@@ -46,6 +46,8 @@ + + SOURCES = $(libintf_bmc_la_SOURCES) + ++SOURCES = $(libintf_bmc_la_SOURCES) ++ + srcdir = @srcdir@ + top_srcdir = @top_srcdir@ + VPATH = @srcdir@ +--- a/src/plugins/free/Makefile.in ++++ b/src/plugins/free/Makefile.in +@@ -16,6 +16,8 @@ + + SOURCES = $(libintf_free_la_SOURCES) + ++SOURCES = $(libintf_free_la_SOURCES) ++ + srcdir = @srcdir@ + top_srcdir = @top_srcdir@ + VPATH = @srcdir@ +--- a/src/plugins/imb/Makefile.in ++++ b/src/plugins/imb/Makefile.in +@@ -46,6 +46,8 @@ + + SOURCES = $(libintf_imb_la_SOURCES) + ++SOURCES = $(libintf_imb_la_SOURCES) ++ + srcdir = @srcdir@ + top_srcdir = @top_srcdir@ + VPATH = @srcdir@ +--- a/src/plugins/ipmi_intf.c ++++ b/src/plugins/ipmi_intf.c +@@ -255,9 +255,10 @@ + + if (kgkey == NULL) + return; ++ memcpy(intf->session->v2_data.kg, kgkey, IPMI_KG_BUFFER_SIZE); + +- memcpy(intf->session->v2_data.kg, kgkey, +- __min(strlen(kgkey), IPMI_KG_BUFFER_SIZE)); ++ /*memcpy(intf->session->v2_data.kg, kgkey, ++ __min(strlen(kgkey), IPMI_KG_BUFFER_SIZE));*/ + } + + void +--- a/src/plugins/lan/Makefile.in ++++ b/src/plugins/lan/Makefile.in +@@ -46,6 +46,8 @@ + + SOURCES = $(libintf_lan_la_SOURCES) + ++SOURCES = $(libintf_lan_la_SOURCES) ++ + srcdir = @srcdir@ + top_srcdir = @top_srcdir@ + VPATH = @srcdir@ +--- a/src/plugins/lanplus/lanplus_crypt.c ++++ b/src/plugins/lanplus/lanplus_crypt.c +@@ -42,6 +42,7 @@ + #include "lanplus_crypt_impl.h" + + ++extern int xoptionselected; + + /* + * lanplus_rakp2_hmac_matches +@@ -463,7 +464,7 @@ + int input_buffer_length, i; + uint8_t * input_key; + uint32_t mac_length; +- ++ uint8_t invalid_encryption_key; + + memset(session->v2_data.sik, 0, IPMI_SIK_BUFFER_SIZE); + +@@ -535,7 +536,26 @@ + /* We will be hashing with Kuid */ + input_key = session->authcode; + } ++ if (1==xoptionselected) ++ { ++ input_key = session->v2_data.kg; + ++ invalid_encryption_key = 1; ++ for (i=0;iauthcode; ++ } ++ } + + if (verbose >= 2) + printbuf((const uint8_t *)input_buffer, input_buffer_length, "session integrity key input"); +--- a/src/plugins/lanplus/Makefile.in ++++ b/src/plugins/lanplus/Makefile.in +@@ -46,6 +46,8 @@ + + SOURCES = $(libintf_lanplus_la_SOURCES) + ++SOURCES = $(libintf_lanplus_la_SOURCES) ++ + srcdir = @srcdir@ + top_srcdir = @top_srcdir@ + VPATH = @srcdir@ +--- a/src/plugins/lipmi/Makefile.in ++++ b/src/plugins/lipmi/Makefile.in +@@ -46,6 +46,8 @@ + + SOURCES = $(libintf_lipmi_la_SOURCES) + ++SOURCES = $(libintf_lipmi_la_SOURCES) ++ + srcdir = @srcdir@ + top_srcdir = @top_srcdir@ + VPATH = @srcdir@ +--- a/src/plugins/Makefile.in ++++ b/src/plugins/Makefile.in +@@ -46,6 +46,8 @@ + + SOURCES = $(libintf_la_SOURCES) + ++SOURCES = $(libintf_la_SOURCES) ++ + srcdir = @srcdir@ + top_srcdir = @top_srcdir@ + VPATH = @srcdir@ +--- a/src/plugins/open/Makefile.in ++++ b/src/plugins/open/Makefile.in +@@ -46,6 +46,8 @@ + + SOURCES = $(libintf_open_la_SOURCES) + ++SOURCES = $(libintf_open_la_SOURCES) ++ + srcdir = @srcdir@ + top_srcdir = @top_srcdir@ + VPATH = @srcdir@ only in patch2: unchanged: --- ipmitool-1.8.11.orig/debian/patches/dell_06_manpage.patch +++ ipmitool-1.8.11/debian/patches/dell_06_manpage.patch @@ -0,0 +1,221 @@ +Description: This patch provides man page updates for the 5 patches uploaded earlier. +Origin: https://sourceforge.net/tracker/?func=detail&aid=3002588&group_id=95200&atid=610553 +Author: Manjunath A. Pattanshetti +Last-Update: 2010-06-28 +--- a/doc/ipmitool.1 ++++ b/doc/ipmitool.1 +@@ -822,6 +822,214 @@ + cards or two modules. + .RE + .RE ++ ++.TP ++\fIdelloem\fP ++.RS ++.br ++ ++The delloem commands provide information on Dell-specific features. ++.TP ++\fIlcd\fP ++.RS ++.br ++\fBset {mode}\fR| ++.br ++\fB{lcdqualifier}\fR|\fB{errordisplay}\fR ++.RS ++.br ++ ++Allows you to set the LCD mode and user-defined string. ++.RE ++.TP ++\fIlcd set mode\fP ++.RS ++.br ++\fB{none}\fR|\fB{modelname}\fR| ++.br ++\fB{ipv4address}\fR|\fB{macaddress}\fR| ++.br ++\fB{systemname}\fR|\fB{servicetag}\fR| ++.br ++\fB{ipv6address}\fR|\fB{ambienttemp}\fR| ++.br ++\fB{systemwatt}\fR|\fB{assettag}\fR| ++.br ++\fB{userdefined}\fR ++.RS ++.br ++ ++Allows you to set the LCD display mode to any of the preceding parameters. ++.RE ++.RE ++.TP ++\fIlcd set lcdqualifier\fP ++.RS ++.br ++\fB{watt}\fR|\fB{btuphr}\fR| ++.br ++\fB{celsius}\fR|\fB{fahrenheit}\fR ++.RS ++.br ++ ++Allows you to set the unit for the system ambient temperature mode. ++.RE ++.RE ++.TP ++\fIlcd set errordisplay\fP ++.RS ++.br ++\fB{sel}\fR|\fB{simple}\fR ++.RS ++.br ++ ++Allows you to set the error display. ++.RE ++.RE ++.RE ++.TP ++\fIlcd info\fP ++.RS ++.br ++ ++Displays the LCD screen information. ++.RE ++.TP ++\fIlcd set vkvm\fP ++.RS ++\fB{active}\fR|\fB{inactive}\fR ++.RS ++.br ++ ++Allows you to set the vKVM status to active or inactive. When it is active and session is in progress, a message appears on LCD. ++.RE ++.RE ++.TP ++\fIlcd status\fP ++.RS ++.br ++ ++Displays the LCD status for vKVM display active or inactive and Front Panel access mode (viewandmodify, view-only or disabled). ++.RE ++.TP ++\fImac\fP ++.RS ++.br ++ ++Displays the information about the system NICs. ++.TP ++\fImac list\fP ++.RS ++.br ++ ++Displays the NIC MAC address and status of all NICs. It also displays the DRAC/iDRAC MAC address. ++.RE ++.TP ++\fImac get\fP ++.RS ++\fB\fR ++.RS ++.br ++ ++Displays the selected NICs MAC address and status. ++.RE ++.RE ++.RE ++.TP ++\fIlan set\fP ++.RS ++\fB\fR ++.br ++ ++Sets the NIC selection mode (dedicated, shared, shared with failover LOM2, shared with failover all LOMs). ++.RE ++.TP ++\fIlan get\fP ++.br ++ ++Returns the current NIC selection mode (dedicated, shared, shared with failover LOM2, shared with failover all LOMs). ++.TP ++\fIlan get active\fP ++.br ++ ++Returns the current active NIC (dedicated, LOM1, LOM2, LOM3 or LOM4). ++.TP ++\fIpowermonitor\fP ++.RS ++.br ++ ++Displays power tracking statistics. ++.RE ++.TP ++\fIpowermonitor clear cumulativepower\fP ++.RS ++.br ++ ++Reset cumulative power reading. ++.RE ++.TP ++\fIpowermonitor clear peakpower\fP ++.RS ++.br ++ ++Reset peak power reading. ++.RE ++.TP ++\fIpowermonitor powerconsumption\fP ++.RS ++\fB\fR|\fB\fR ++.RS ++.br ++ ++Displays the power consumption in watt or btuphr. ++.RE ++.RE ++.TP ++\fIpowermonitor powerconsumptionhistory\fP ++.RS ++\fB\fR|\fB\fR ++.RS ++.br ++ ++Displays the power consumption history in watt or btuphr. ++.RE ++.RE ++.TP ++\fIpowermonitor getpowerbudget\fP ++.RS ++\fB\fR|\fB\fR ++.RS ++.br ++ ++Displays the power cap in watt or btuphr. ++.RE ++.RE ++.TP ++\fIpowermonitor setpowerbudget\fP ++.RS ++\fB\fR\fB\fR ++.RS ++.br ++ ++Allows you to set the power cap in watt, BTU/hr or percentage. ++.RE ++.RE ++.TP ++\fIpowermonitor enablepowercap\fP ++.RS ++.br ++ ++Enables set power cap. ++.RE ++.TP ++\fIpowermonitor disablepowercap\fP ++.RS ++.br ++ ++Disables set power cap. ++.RE ++.RE ++ + .TP + \fIevent\fP + .RS