From a7f89980e5b3f4b9a74c70dbc5ffe8aabd28be28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sun, 6 Jul 2014 18:04:32 +0200 Subject: Imported Upstream version 2.9.3 --- util/ipicmg.c | 1911 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1911 insertions(+) create mode 100644 util/ipicmg.c (limited to 'util/ipicmg.c') diff --git a/util/ipicmg.c b/util/ipicmg.c new file mode 100644 index 0000000..c549151 --- /dev/null +++ b/util/ipicmg.c @@ -0,0 +1,1911 @@ +/* + * ipicmg.c + * + * This module handles PICMG extended IPMI commands. + * + * Change History: + * 06/03/2010 ARCress - new, included in source tree + * 08/15/2011 ARCress - updated with PICMG 2.3 + * + *---------------------------------------------------------------------- + * Copyright (c) 2010 Kontron. All right reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Kontron, or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. + * THE COPYRIGHT HOLDER AND ITS LICENSORS SHALL NOT BE LIABLE + * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING + * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL THE + * COPYRIGHT HOLDER OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR + * DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR + * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF + * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, + * EVEN IF COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + *---------------------------------------------------------------------- + */ +#ifdef WIN32 +#include +#include +#include +#include +#include "getopt.h" +#else +#include +#include +#include +#if defined(HPUX) +/* getopt is defined in stdio.h */ +#elif defined(MACOS) +/* getopt is defined in unistd.h */ +#include +#else +#include +#endif +#endif +#include "ipmicmd.h" +#include "ipicmg.h" + +/* Misc PICMG defines */ +#define PICMG_EXTENSION_ATCA_MAJOR_VERSION 2 +#define PICMG_EXTENSION_AMC0_MAJOR_VERSION 4 +#define PICMG_EXTENSION_UTCA_MAJOR_VERSION 5 + + +#define PICMG_EKEY_MODE_QUERY 0 +#define PICMG_EKEY_MODE_PRINT_ALL 1 +#define PICMG_EKEY_MODE_PRINT_ENABLED 2 +#define PICMG_EKEY_MODE_PRINT_DISABLED 3 + +#define PICMG_EKEY_MAX_CHANNEL 16 +#define PICMG_EKEY_MAX_FABRIC_CHANNEL 15 +#define PICMG_EKEY_MAX_INTERFACE 3 + +#define PICMG_EKEY_AMC_MAX_CHANNEL 16 +#define PICMG_EKEY_AMC_MAX_DEVICE 15 /* 4 bits */ + +/* Global data */ +static char * progname = "ipicmg"; +static char * progver = "2.93"; +static char fdebug = 0; +static char fset_mc = 0; +static uint8_t g_bus = PUBLIC_BUS; +static uint8_t g_sa = BMC_SA; +static uint8_t g_lun = BMC_LUN; +static uint8_t g_addrtype = ADDR_SMI; +static uint8_t g_fruid = 0; +static unsigned char PicmgExtMajorVersion; + +typedef enum picmg_bused_resource_mode { + PICMG_BUSED_RESOURCE_SUMMARY, +} t_picmg_bused_resource_mode ; + + +typedef enum picmg_card_type { + PICMG_CARD_TYPE_CPCI, + PICMG_CARD_TYPE_ATCA, + PICMG_CARD_TYPE_AMC, + PICMG_CARD_TYPE_RESERVED +} t_picmg_card_type ; + +/* This is the version of the PICMG Extenstion */ +static t_picmg_card_type PicmgCardType = PICMG_CARD_TYPE_RESERVED; + +const struct valstr picmg_frucontrol_vals[] = { + { 0, "Cold Reset" }, + { 1, "Warm Reset" }, + { 2, "Graceful Reboot" }, + { 3, "Issue Diagnostic Interrupt" }, + { 4, "Quiesce" }, + { 5, NULL }, +}; + +const struct valstr picmg_clk_family_vals[] = { + { 0x00, "Unspecified" }, + { 0x01, "SONET/SDH/PDH" }, + { 0x02, "Reserved for PCI Express" }, + { 0x03, "Reserved" }, /* from 03h to C8h */ + { 0xC9, "Vendor defined clock family" }, /* from C9h to FFh */ + { 0x00, NULL }, +}; + +const struct oemvalstr picmg_clk_accuracy_vals[] = { + { 0x01, 10, "PRS" }, + { 0x01, 20, "STU" }, + { 0x01, 30, "ST2" }, + { 0x01, 40, "TNC" }, + { 0x01, 50, "ST3E" }, + { 0x01, 60, "ST3" }, + { 0x01, 70, "SMC" }, + { 0x01, 80, "ST4" }, + { 0x01, 90, "DUS" }, + { 0x02, 0xE0, "PCI Express Generation 2" }, + { 0x02, 0xF0, "PCI Express Generation 1" }, + { 0xffffff, 0x00, NULL } +}; + +const struct oemvalstr picmg_clk_resource_vals[] = { + { 0x0, 0, "On-Carrier Device 0" }, + { 0x0, 1, "On-Carrier Device 1" }, + { 0x1, 1, "AMC Site 1 - A1" }, + { 0x1, 2, "AMC Site 1 - A2" }, + { 0x1, 3, "AMC Site 1 - A3" }, + { 0x1, 4, "AMC Site 1 - A4" }, + { 0x1, 5, "AMC Site 1 - B1" }, + { 0x1, 6, "AMC Site 1 - B2" }, + { 0x1, 7, "AMC Site 1 - B3" }, + { 0x1, 8, "AMC Site 1 - B4" }, + { 0x2, 0, "ATCA Backplane" }, + { 0xffffff, 0x00, NULL } +}; + +const struct oemvalstr picmg_clk_id_vals[] = { + { 0x0, 0, "Clock 0" }, + { 0x0, 1, "Clock 1" }, + { 0x0, 2, "Clock 2" }, + { 0x0, 3, "Clock 3" }, + { 0x0, 4, "Clock 4" }, + { 0x0, 5, "Clock 5" }, + { 0x0, 6, "Clock 6" }, + { 0x0, 7, "Clock 7" }, + { 0x0, 8, "Clock 8" }, + { 0x0, 9, "Clock 9" }, + { 0x0, 10, "Clock 10" }, + { 0x0, 11, "Clock 11" }, + { 0x0, 12, "Clock 12" }, + { 0x0, 13, "Clock 13" }, + { 0x0, 14, "Clock 14" }, + { 0x0, 15, "Clock 15" }, + { 0x1, 1, "TCLKA" }, + { 0x1, 2, "TCLKB" }, + { 0x1, 3, "TCLKC" }, + { 0x1, 4, "TCLKD" }, + { 0x1, 5, "FLCKA" }, + { 0x2, 1, "CLK1A" }, + { 0x2, 2, "CLK1A" }, + { 0x2, 3, "CLK1A" }, + { 0x2, 4, "CLK1A" }, + { 0x2, 5, "CLK1A" }, + { 0x2, 6, "CLK1A" }, + { 0x2, 7, "CLK1A" }, + { 0x2, 8, "CLK1A" }, + { 0x2, 9, "CLK1A" }, + { 0xffffff, 0x00, NULL } +}; + +const struct valstr picmg_busres_id_vals[] = { + { 0x0, "Metallic Test Bus pair #1" }, + { 0x1, "Metallic Test Bus pair #2" }, + { 0x2, "Synch clock group 1 (CLK1)" }, + { 0x3, "Synch clock group 2 (CLK2)" }, + { 0x4, "Synch clock group 3 (CLK3)" }, + { 0x5, NULL } +}; +const struct valstr picmg_busres_board_cmd_vals[] = { + { 0x0, "Query" }, + { 0x1, "Release" }, + { 0x2, "Force" }, + { 0x3, "Bus Free" }, + { 0x4, NULL } +}; + +const struct valstr picmg_busres_shmc_cmd_vals[] = { + { 0x0, "Request" }, + { 0x1, "Relinquish" }, + { 0x2, "Notify" }, + { 0x3, NULL } +}; + +const struct oemvalstr picmg_busres_board_status_vals[] = { + { 0x0, 0x0, "In control" }, + { 0x0, 0x1, "No control" }, + { 0x1, 0x0, "Ack" }, + { 0x1, 0x1, "Refused" }, + { 0x1, 0x2, "No control" }, + { 0x2, 0x0, "Ack" }, + { 0x2, 0x1, "No control" }, + { 0x3, 0x0, "Accept" }, + { 0x3, 0x1, "Not Needed" }, + { 0xffffff, 0x00, NULL } +}; + +const struct oemvalstr picmg_busres_shmc_status_vals[] = { + { 0x0, 0x0, "Grant" }, + { 0x0, 0x1, "Busy" }, + { 0x0, 0x2, "Defer" }, + { 0x0, 0x3, "Deny" }, + + { 0x1, 0x0, "Ack" }, + { 0x1, 0x1, "Error" }, + + { 0x2, 0x0, "Ack" }, + { 0x2, 0x1, "Error" }, + { 0x2, 0x2, "Deny" }, + + { 0xffffff, 0x00, NULL } +}; + +void +ipmi_picmg_help (void) +{ + printf(" properties - get PICMG properties\n"); + printf(" frucontrol - FRU control\n"); + printf(" addrinfo - get address information\n"); + printf(" activate - activate a FRU\n"); + printf(" deactivate - deactivate a FRU\n"); + printf(" policy get - get the FRU activation policy\n"); + printf(" policy set - set the FRU activation policy\n"); + printf(" portstate get - get port state \n"); + printf(" portstate getdenied - get all denied[disabled] port description\n"); + printf(" portstate getgranted - get all granted[enabled] port description\n"); + printf(" portstate getall - get all port state description\n"); + printf(" portstate set - set port state \n"); + printf(" amcportstate get - get port state \n"); + printf(" amcportstate set - set port state \n"); + printf(" led prop - get led properties\n"); + printf(" led cap - get led color capabilities\n"); + printf(" led get - get led state\n"); + printf(" led set - set led state\n"); + printf(" power get - get power level info\n"); + printf(" power set - set power level\n"); + printf(" clk get - get clk state\n"); + printf(" clk getdenied - get all(up to 16) denied[disabled] clock descriptions\n"); + printf(" clk getgranted - get all(up to 16) granted[enabled] clock descriptions\n"); + printf(" clk getall - get all(up to 16) clock descriptions\n"); + printf(" clk set - set clk state\n"); + printf(" busres summary - display brief bused resource status info \n"); +} + +struct sAmcAddrMap { + unsigned char ipmbLAddr; + char* amcBayId; + unsigned char siteNum; +} amcAddrMap[] = { + {0xFF, "reserved", 0}, + {0x72, "A1" , 1}, + {0x74, "A2" , 2}, + {0x76, "A3" , 3}, + {0x78, "A4" , 4}, + {0x7A, "B1" , 5}, + {0x7C, "B2" , 6}, + {0x7E, "B3" , 7}, + {0x80, "B4" , 8}, + {0x82, "reserved", 0}, + {0x84, "reserved", 0}, + {0x86, "reserved", 0}, + {0x88, "reserved", 0}, +}; + +int +ipmi_picmg_getaddr(void * intf, int argc, char ** argv) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + unsigned char msg_data[5]; + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_GET_ADDRESS_INFO_CMD; + req.msg.data = msg_data; + req.msg.data_len = 2; + msg_data[0] = 0; /* picmg identifier */ + msg_data[1] = 0; /* default fru id */ + + if(argc > 0) { + msg_data[1] = (uint8_t)strtoul(argv[0], NULL,0); /* FRU ID */ + } + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error getting address information CC: 0x%02x\n", rv); + return rv; + } + + printf("Hardware Address : 0x%02x\n", rsp[1]); + printf("IPMB-0 Address : 0x%02x\n", rsp[2]); + printf("FRU ID : 0x%02x\n", rsp[4]); + printf("Site ID : 0x%02x\n", rsp[5]); + + printf("Site Type : "); + switch (rsp[6]) { + case PICMG_ATCA_BOARD: + printf("ATCA board\n"); + break; + case PICMG_POWER_ENTRY: + printf("Power Entry Module\n"); + break; + case PICMG_SHELF_FRU: + printf("Shelf FRU\n"); + break; + case PICMG_DEDICATED_SHMC: + printf("Dedicated Shelf Manager\n"); + break; + case PICMG_FAN_TRAY: + printf("Fan Tray\n"); + break; + case PICMG_FAN_FILTER_TRAY: + printf("Fan Filter Tray\n"); + break; + case PICMG_ALARM: + printf("Alarm module\n"); + break; + case PICMG_AMC: + printf("AMC"); + printf(" -> IPMB-L Address: 0x%02x\n", amcAddrMap[rsp[5]].ipmbLAddr); + break; + case PICMG_PMC: + printf("PMC\n"); + break; + case PICMG_RTM: + printf("RTM\n"); + break; + default: + if (rsp[6] >= 0xc0 && rsp[6] <= 0xcf) { + printf("OEM\n"); + } else { + printf("unknown\n"); + } + } + + return 0; +} + +int +ipmi_picmg_properties(void * intf, int show ) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + unsigned char PicmgExtMajorVersion; + struct ipmi_rq req; + unsigned char msg_data; + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_GET_PICMG_PROPERTIES_CMD; + req.msg.data = &msg_data; + req.msg.data_len = 1; + msg_data = 0; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error %d getting picmg properties\n", rv); + return rv; + } + + if( show ) + { + printf("PICMG identifier : 0x%02x\n", rsp[0]); + printf("PICMG Ext. Version : %i.%i\n", rsp[1]&0x0f, + (rsp[1]&0xf0) >> 4); + printf("Max FRU Device ID : 0x%02x\n", rsp[2]); + printf("FRU Device ID : 0x%02x\n", rsp[3]); + } + + /* We cache the major extension version ... + to know how to format some commands */ + PicmgExtMajorVersion = rsp[1]&0x0f; + + if( PicmgExtMajorVersion == PICMG_CPCI_MAJOR_VERSION ) { + PicmgCardType = PICMG_CARD_TYPE_CPCI; + } + else if( PicmgExtMajorVersion == PICMG_ATCA_MAJOR_VERSION) { + PicmgCardType = PICMG_CARD_TYPE_ATCA; + } + else if( PicmgExtMajorVersion == PICMG_AMC_MAJOR_VERSION) { + PicmgCardType = PICMG_CARD_TYPE_AMC; + } + + return 0; +} + + + +#define PICMG_FRU_DEACTIVATE (unsigned char) 0x00 +#define PICMG_FRU_ACTIVATE (unsigned char) 0x01 + +int +ipmi_picmg_fru_activation(void * intf, int argc, char ** argv, unsigned char state) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + + struct picmg_set_fru_activation_cmd cmd; + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_FRU_ACTIVATION_CMD; + req.msg.data = (unsigned char*) &cmd; + req.msg.data_len = 3; + + cmd.picmg_id = 0; /* PICMG identifier */ + cmd.fru_id = atob(argv[0]); /* FRU ID */ + cmd.fru_state = state; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error %d on activation/deactivation of FRU\n",rv); + return rv; + } + if (rsp[0] != 0x00) { + printf("Error, invalid response\n"); + } + + return 0; +} + + +int +ipmi_picmg_fru_activation_policy_get(void * intf, int argc, char ** argv) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + + unsigned char msg_data[4]; + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_GET_FRU_POLICY_CMD; + req.msg.data = msg_data; + req.msg.data_len = 2; + + msg_data[0] = 0; /* PICMG identifier */ + msg_data[1] = atob(argv[0]); /* FRU ID */ + + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + if (rv < 0) printf("no response\n"); + else printf("returned Completion Code 0x%02x\n", rv); + return rv; + } + + printf(" %s\n", ((rsp[1] & 0x01) == 0x01) ? + "activation locked" : "activation not locked"); + printf(" %s\n", ((rsp[1] & 0x02) == 0x02) ? + "deactivation locked" : "deactivation not locked"); + + return 0; +} + +int +ipmi_picmg_fru_activation_policy_set(void * intf, int argc, char ** argv) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + + unsigned char msg_data[4]; + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_SET_FRU_POLICY_CMD; + req.msg.data = msg_data; + req.msg.data_len = 4; + + msg_data[0] = 0; /* PICMG identifier */ + msg_data[1] = atob(argv[0]); /* FRU ID */ + msg_data[2] = atob(argv[1])& 0x03; /* FRU act policy mask */ + msg_data[3] = atob(argv[2])& 0x03; /* FRU act policy set bits */ + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + if (rv < 0) printf("no response\n"); + else printf("returned Completion Code 0x%02x\n", rv); + return rv; + } + + return 0; +} + +#define PICMG_MAX_LINK_PER_CHANNEL 4 + +int +ipmi_picmg_portstate_get(void * intf, int interfc, uchar channel, int mode) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + unsigned char msg_data[4]; + struct fru_picmgext_link_desc* d; /* descriptor pointer for rec. data */ + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_GET_PORT_STATE_CMD; + req.msg.data = msg_data; + req.msg.data_len = 2; + + msg_data[0] = 0x00; /* PICMG identifier */ + msg_data[1] = (interfc & 0x3)<<6; /* interface */ + msg_data[1] |= (channel & 0x3F); /* channel number */ + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + if (rv < 0) printf("no response\n"); + else if( mode == PICMG_EKEY_MODE_QUERY ) + printf("returned Completion Code 0x%02x\n", rv); + return rv; + } + + if (rsp_len >= 6) { + int index; + /* add support for more than one link per channel */ + for(index=0;index (1+ (index*5))){ + d = (struct fru_picmgext_link_desc *) &(rsp[1 + (index*5)]); + + if + ( + mode == PICMG_EKEY_MODE_PRINT_ALL + || + mode == PICMG_EKEY_MODE_QUERY + || + ( + mode == PICMG_EKEY_MODE_PRINT_ENABLED + && + rsp[5 + (index*5) ] == 0x01 + ) + || + ( + mode == PICMG_EKEY_MODE_PRINT_DISABLED + && + rsp[5 + (index*5) ] == 0x00 + ) + ) + { + printf(" Link Grouping ID: 0x%02x\n", d->grouping); + printf(" Link Type Extension: 0x%02x\n", d->ext); + printf(" Link Type: 0x%02x ", d->type); + if (d->type == 0 || d->type == 0xff) + { + printf("Reserved %d\n",d->type); + } + else if (d->type >= 0x06 && d->type <= 0xef) + { + printf("Reserved %d\n",d->type); + } + else if (d->type >= 0xf0 && d->type <= 0xfe) + { + printf("OEM GUID Definition %d\n",d->type); + } + else + { + switch (d->type) + { + case FRU_PICMGEXT_LINK_TYPE_BASE: + printf("PICMG 3.0 Base Interface 10/100/1000\n"); + break; + case FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET: + printf("PICMG 3.1 Ethernet Fabric Interface\n"); + break; + case FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND: + printf("PICMG 3.2 Infiniband Fabric Interface\n"); + break; + case FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR: + printf("PICMG 3.3 Star Fabric Interface\n"); + break; + case FRU_PICMGEXT_LINK_TYPE_PCIE: + printf("PCI Express Fabric Interface\n"); + break; + default: + printf("Invalid\n"); + break; + } + } + printf(" Link Designator: \n"); + printf(" Port Flag: 0x%02x\n", d->desig_port); + printf(" Interface: 0x%02x - ", d->desig_if); + switch (d->desig_if) + { + case FRU_PICMGEXT_DESIGN_IF_BASE: + printf("Base Interface\n"); + break; + case FRU_PICMGEXT_DESIGN_IF_FABRIC: + printf("Fabric Interface\n"); + break; + case FRU_PICMGEXT_DESIGN_IF_UPDATE_CHANNEL: + printf("Update Channel\n"); + break; + case FRU_PICMGEXT_DESIGN_IF_RESERVED: + printf("Reserved\n"); + break; + default: + printf("Invalid"); + break; + } + printf(" Channel Number: 0x%02x\n", d->desig_channel); + printf(" STATE: %s\n", + ( rsp[5 +(index*5)] == 0x01) ?"enabled":"disabled"); + printf("\n"); + } + } + } + } + else + { + printf("Unexpected answer len %d, can't print result\n",rsp_len); + } + + return 0; +} + + +int +ipmi_picmg_portstate_set(void * intf, int interfc, uchar channel, + uchar port, int type, int typeext, int group, int enable) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + unsigned char msg_data[6]; + // struct fru_picmgext_link_desc* d; + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_SET_PORT_STATE_CMD; + req.msg.data = msg_data; + req.msg.data_len = 6; + + msg_data[0] = 0x00; /* PICMG identifier */ + msg_data[1] = (channel & 0x3f) | ((interfc & 3) << 6); + msg_data[2] = (port & 0xf) | ((type & 0xf) << 4); + msg_data[3] = ((type >> 4) & 0xf) | ((typeext & 0xf) << 4); + msg_data[4] = group & 0xff; + msg_data[5] = (unsigned char) (enable & 0x01); /* en/dis */ + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + if (rv < 0) printf("no response\n"); + else printf("returned Completion Code 0x%02x\n", rv); + return rv; + } + + return 0; +} + + + +/* AMC.0 commands */ + +#define PICMG_AMC_MAX_LINK_PER_CHANNEL 4 + +int +ipmi_picmg_amc_portstate_get(void * intf,int device,uchar channel, + int mode) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + + unsigned char msg_data[4]; + + struct fru_picmgext_amc_link_info* d; /* descriptor pointer for rec. data */ + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_AMC_GET_PORT_STATE_CMD; + req.msg.data = msg_data; + + /* FIXME : add check for AMC or carrier device */ + if(device == -1 || PicmgCardType != PICMG_CARD_TYPE_ATCA ){ + req.msg.data_len = 2; /* for amc only channel */ + }else{ + req.msg.data_len = 3; /* for carrier channel and device */ + } + + msg_data[0] = 0x00; /* PICMG identifier */ + msg_data[1] = channel ; + msg_data[2] = (uchar)device ; + + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + if (rv < 0) printf("no response\n"); + else if ( mode == PICMG_EKEY_MODE_QUERY ) + printf("returned Completion Code 0x%02x\n", rv); + return rv; + } + + if (rsp_len >= 5) { + int index; + + /* add support for more than one link per channel */ + for(index=0;index (1+ (index*4))){ + unsigned char type; + unsigned char ext; + unsigned char grouping; + unsigned char port; + unsigned char enabled; + d = (struct fru_picmgext_amc_link_info *)&(rsp[1 + (index*4)]); + + + /* Removed endianness check here, probably not required + as we dont use bitfields */ + port = d->linkInfo[0] & 0x0F; + type = ((d->linkInfo[0] & 0xF0) >> 4 )|(d->linkInfo[1] & 0x0F ); + ext = ((d->linkInfo[1] & 0xF0) >> 4 ); + grouping = d->linkInfo[2]; + + + enabled = rsp[4 + (index*4) ]; + + if + ( + mode == PICMG_EKEY_MODE_PRINT_ALL + || + mode == PICMG_EKEY_MODE_QUERY + || + ( + mode == PICMG_EKEY_MODE_PRINT_ENABLED + && + enabled == 0x01 + ) + || + ( + mode == PICMG_EKEY_MODE_PRINT_DISABLED + && + enabled == 0x00 + ) + ) + { + if(device == -1 || PicmgCardType != PICMG_CARD_TYPE_ATCA ){ + printf(" Link device : AMC\n"); + }else{ + printf(" Link device : 0x%02x\n", device ); + } + + printf(" Link Grouping ID: 0x%02x\n", grouping); + + if (type == 0 || type == 1 ||type == 0xff) + { + printf(" Link Type Extension: 0x%02x\n", ext); + printf(" Link Type: Reserved\n"); + } + else if (type >= 0xf0 && type <= 0xfe) + { + printf(" Link Type Extension: 0x%02x\n", ext); + printf(" Link Type: OEM GUID Definition\n"); + } + else + { + if (type <= FRU_PICMGEXT_AMC_LINK_TYPE_STORAGE ) + { + printf(" Link Type Extension: %s\n", + amc_link_type_ext_str[type][ext]); + printf(" Link Type: %s\n", + amc_link_type_str[type]); + } + else{ + printf(" Link Type Extension: 0x%02x\n", ext); + printf(" Link Type: undefined\n"); + } + } + printf(" Link Designator: \n"); + printf(" Channel Number: 0x%02x\n", channel); + printf(" Port Flag: 0x%02x\n", port ); + printf(" STATE: %s\n", + ( enabled == 0x01 )?"enabled":"disabled"); + printf("\n"); + } + } + } + } + else + { + printf("ipmi_picmg_amc_portstate_get: " + "Unexpected answer, can't print result\n"); + } + + return 0; +} + + +int +ipmi_picmg_amc_portstate_set(void * intf, uchar channel, uchar port, + int type, int typeext, int group, int enable, int device) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + unsigned char msg_data[7]; + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_AMC_SET_PORT_STATE_CMD; + req.msg.data = msg_data; + + msg_data[0] = 0x00; /* PICMG identifier*/ + msg_data[1] = channel; /* channel id */ + msg_data[2] = port & 0xF; /* port flags */ + msg_data[2] |= (type & 0x0F)<<4; /* type */ + msg_data[3] = (type & 0xF0)>>4; /* type */ + msg_data[3] |= (typeext & 0x0F)<<4; /* extension */ + msg_data[4] = (group & 0xFF); /* group */ + msg_data[5] = (enable & 0x01); /* state */ + req.msg.data_len = 6; + + /* device id - only for carrier needed */ + if (device >= 0) { + msg_data[6] = (uchar)device; + req.msg.data_len = 7; + } + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + if (rv < 0) printf("no response\n"); + else printf("returned Completion Code 0x%02x\n", rv); + return rv; + } + + return 0; +} + + +int +ipmi_picmg_get_led_properties(void * intf, int argc, char ** argv) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + + unsigned char msg_data[6]; + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_GET_FRU_LED_PROPERTIES_CMD; + req.msg.data = msg_data; + req.msg.data_len = 2; + + msg_data[0] = 0x00; /* PICMG identifier */ + msg_data[1] = atob(argv[0]); /* FRU-ID */ + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + if (rv < 0) printf("no response\n"); + else printf("returned Completion Code 0x%02x\n", rv); + return rv; + } + + printf("General Status LED Properties: 0x%2x\n\r", rsp[1] ); + printf("App. Specific LED Count: 0x%2x\n\r", rsp[2] ); + + return 0; +} + +int +ipmi_picmg_get_led_capabilities(void * intf, int argc, char ** argv) +{ + int i; + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + + unsigned char msg_data[6]; + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_GET_LED_COLOR_CAPABILITIES_CMD; + req.msg.data = msg_data; + req.msg.data_len = 3; + + msg_data[0] = 0x00; /* PICMG identifier */ + msg_data[1] = atob(argv[0]); /* FRU-ID */ + msg_data[2] = atob(argv[1]); /* LED-ID */ + + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + if (rv < 0) printf("no response\n"); + else printf("returned Completion Code 0x%02x\n", rv); + return rv; + } + + printf("LED Color Capabilities: %02x", rsp[1] ); + for ( i=0 ; i<8 ; i++ ) { + if ( rsp[1] & (0x01 << i) ) { + printf("%s, ", led_color_str[ i ]); + } + } + printf("\n\r"); + + printf("Default LED Color in\n\r"); + printf(" LOCAL control: %s\n\r", led_color_str[ rsp[2] ] ); + printf(" OVERRIDE state: %s\n\r", led_color_str[ rsp[3] ] ); + + return 0; +} + +int +ipmi_picmg_get_led_state(void * intf, int argc, char ** argv) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + + unsigned char msg_data[6]; + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_GET_FRU_LED_STATE_CMD; + req.msg.data = msg_data; + req.msg.data_len = 3; + + msg_data[0] = 0x00; /* PICMG identifier */ + msg_data[1] = atob(argv[0]); /* FRU-ID */ + msg_data[2] = atob(argv[1]); /* LED-ID */ + + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + if (rv < 0) printf("no response\n"); + else printf("returned Completion Code 0x%02x\n", rv); + return rv; + } + + printf("LED states: %x ", rsp[1] ); + if (rsp[1] == 0x1) + printf("[LOCAL CONTROL]\n\r"); + else if (rsp[1] == 0x2) + printf("[OVERRIDE]\n\r"); + else if (rsp[1] == 0x4) + printf("[LAMPTEST]\n\r"); + else + printf("\n\r"); + + printf(" Local Control function: %x ", rsp[2] ); + if (rsp[2] == 0x0) + printf("[OFF]\n\r"); + else if (rsp[2] == 0xff) + printf("[ON]\n\r"); + else + printf("[BLINKING]\n\r"); + + printf(" Local Control On-Duration: %x\n\r", rsp[3] ); + printf(" Local Control Color: %x [%s]\n\r", rsp[4], led_color_str[ rsp[4] ]); + + /* override state or lamp test */ + if (rsp[1] == 0x02) { + printf(" Override function: %x ", rsp[5] ); + if (rsp[2] == 0x0) + printf("[OFF]\n\r"); + else if (rsp[2] == 0xff) + printf("[ON]\n\r"); + else + printf("[BLINKING]\n\r"); + + printf(" Override On-Duration: %x\n\r", rsp[6] ); + printf(" Override Color: %x [%s]\n\r", rsp[7], led_color_str[ rsp[7] ]); + + }else if (rsp[1] == 0x06) { + printf(" Override function: %x ", rsp[5] ); + if (rsp[2] == 0x0) + printf("[OFF]\n\r"); + else if (rsp[2] == 0xff) + printf("[ON]\n\r"); + else + printf("[BLINKING]\n\r"); + printf(" Override On-Duration: %x\n\r", rsp[6] ); + printf(" Override Color: %x [%s]\n\r", rsp[7], led_color_str[ rsp[7] ]); + printf(" Lamp test duration: %x\n\r", rsp[8] ); + } + + return 0; +} + +int +ipmi_picmg_set_led_state(void * intf, int argc, char ** argv) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + + unsigned char msg_data[6]; + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_SET_FRU_LED_STATE_CMD; + req.msg.data = msg_data; + req.msg.data_len = 6; + + msg_data[0] = 0x00; /* PICMG identifier */ + msg_data[1] = atob(argv[0]); /* FRU-ID */ + msg_data[2] = atob(argv[1]); /* LED-ID */ + msg_data[3] = atob(argv[2]); /* LED function */ + msg_data[4] = atob(argv[3]); /* LED on duration */ + msg_data[5] = atob(argv[4]); /* LED color */ + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + if (rv < 0) printf("no response\n"); + else printf("returned Completion Code 0x%02x\n", rv); + return rv; + } + + + return 0; +} + +int +ipmi_picmg_get_power_level(void * intf, int argc, char ** argv) +{ + int i; + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + + unsigned char msg_data[6]; + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_GET_POWER_LEVEL_CMD; + req.msg.data = msg_data; + req.msg.data_len = 3; + + msg_data[0] = 0x00; /* PICMG identifier */ + msg_data[1] = atob(argv[0]); /* FRU-ID */ + msg_data[2] = atob(argv[1]); /* Power type */ + + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + if (rv < 0) printf("no response\n"); + else printf("returned Completion Code 0x%02x\n", rv); + return rv; + } + + printf("Dynamic Power Configuration: %s\n", (rsp[1]&0x80)==0x80?"enabled":"disabled" ); + printf("Actual Power Level: %i\n", (rsp[1] & 0xf)); + printf("Delay to stable Power: %i\n", rsp[2]); + printf("Power Multiplier: %i\n", rsp[3]); + + + for ( i = 1; i+3 < rsp_len ; i++ ) { + printf(" Power Draw %i: %i\n", i, (rsp[i+3]) * rsp[3] / 10); + } + return 0; +} + +int +ipmi_picmg_set_power_level(void * intf, int argc, char ** argv) +{ + // int i; + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + + unsigned char msg_data[6]; + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_SET_POWER_LEVEL_CMD; + req.msg.data = msg_data; + req.msg.data_len = 4; + + msg_data[0] = 0x00; /* PICMG identifier */ + msg_data[1] = atob(argv[0]); /* FRU-ID */ + msg_data[2] = atob(argv[1]); /* power level */ + msg_data[3] = atob(argv[2]); /* present to desired */ + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + if (rv < 0) printf("no response\n"); + else printf("returned Completion Code 0x%02x\n", rv); + return rv; + } + + return 0; +} + +int +ipmi_picmg_bused_resource(void * intf, t_picmg_bused_resource_mode mode) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + + unsigned char msg_data[6]; + memset(&req, 0, sizeof(req)); + + switch ( mode ) { + case PICMG_BUSED_RESOURCE_SUMMARY: + { + t_picmg_busres_resource_id resource; + t_picmg_busres_board_cmd_types cmd =PICMG_BUSRES_BOARD_CMD_QUERY; + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_BUSED_RESOURCE_CMD; + req.msg.data = msg_data; + req.msg.data_len = 3; + + /* IF BOARD + query for all resources + */ + for( resource=PICMG_BUSRES_METAL_TEST_BUS_1;resource<=PICMG_BUSRES_SYNC_CLOCK_GROUP_3;resource+=(t_picmg_busres_resource_id)1 ) { + msg_data[0] = 0x00; /* PICMG identifier */ + msg_data[1] = (unsigned char) cmd; + msg_data[2] = (unsigned char) resource; + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + if (rv < 0) printf("bused resource control: no response\n"); + else printf("bused resource control: returned Completion Code 0x%02x\n",rv); + return rv; + } else { + printf("Resource 0x%02x '%-26s' : 0x%02x [%s] \n" , + resource, val2str(resource,picmg_busres_id_vals), + rsp[1], oemval2str(cmd,rsp[1], + picmg_busres_board_status_vals)); + } + } + } + break; + default: rv = -1; + break; + } + + return rv; +} + +int +ipmi_picmg_fru_control(void * intf, int argc, char ** argv) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + + unsigned char msg_data[6]; + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_FRU_CONTROL_CMD; + req.msg.data = msg_data; + req.msg.data_len = 3; + + msg_data[0] = 0x00; /* PICMG identifier */ + msg_data[1] = atob(argv[0]); /* FRU-ID */ + msg_data[2] = atob(argv[1]); /* control option */ + + printf("FRU Device Id: %d FRU Control Option: %s\n\r", msg_data[1], \ + val2str( msg_data[2], picmg_frucontrol_vals)); + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + if (rv < 0) printf("frucontrol: no response\n"); + else printf("frucontrol: returned Completion Code 0x%02x\n",rv); + return rv; + } else { + printf("frucontrol: ok\n"); + } + + return 0; +} + + +int +ipmi_picmg_clk_get(void * intf, int clk_id,int clk_res,int mode) +{ + // int i; + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + + unsigned char enabled; + unsigned char direction; + + unsigned char msg_data[6]; + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_AMC_GET_CLK_STATE_CMD; + req.msg.data = msg_data; + + msg_data[0] = 0x00; /* PICMG identifier */ + msg_data[1] = clk_id; + + if(clk_res == -1 || PicmgCardType != PICMG_CARD_TYPE_ATCA ){ + req.msg.data_len = 2; /* for amc only channel */ + }else{ + req.msg.data_len = 3; /* for carrier channel and device */ + msg_data[2] = clk_res; + } + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + if (rv < 0) printf("no response\n"); + else printf("returned Completion Code 0x%02x\n", rv); + return rv; + } + + { + enabled = (rsp[1]&0x8)!=0; + direction = (rsp[1]&0x4)!=0; + + if + ( + mode == PICMG_EKEY_MODE_QUERY + || + mode == PICMG_EKEY_MODE_PRINT_ALL + || + ( + mode == PICMG_EKEY_MODE_PRINT_DISABLED + && + enabled == 0 + ) + || + ( + mode == PICMG_EKEY_MODE_PRINT_ENABLED + && + enabled == 1 + ) + ) { + if( PicmgCardType != PICMG_CARD_TYPE_AMC ) { + printf("CLK resource id : %3d [ %s ]\n", clk_res , + oemval2str( ((clk_res>>6)&0x03), (clk_res&0x0F), + picmg_clk_resource_vals)); + } else { + printf("CLK resource id : N/A [ AMC Module ]\n"); + clk_res = 0x40; /* Set */ + } + printf("CLK id : %3d [ %s ]\n", clk_id, + oemval2str( ((clk_res>>6)&0x03), clk_id , + picmg_clk_id_vals)); + + + printf("CLK setting : 0x%02x\n", rsp[1]); + printf(" - state: %s\n", (enabled)?"enabled":"disabled"); + printf(" - direction: %s\n", (direction)?"Source":"Receiver"); + printf(" - PLL ctrl: 0x%x\n", rsp[1]&0x3); + + if(enabled){ + unsigned long freq = 0; + freq = ( rsp[5] << 0 + | rsp[6] << 8 + | rsp[7] << 16 + | rsp[8] << 24 ); + printf(" - Index: %3d\n", rsp[2]); + printf(" - Family: %3d [ %s ]\n", rsp[3], + val2str( rsp[3], picmg_clk_family_vals)); + printf(" - AccLVL: %3d [ %s ]\n", rsp[4], + oemval2str(rsp[3],rsp[4],picmg_clk_accuracy_vals)); + printf(" - Freq: %d\n", freq); + } + } + } + return 0; +} + + +int +ipmi_picmg_clk_set(void * intf, int argc, char ** argv) +{ + // int i; + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + + unsigned char msg_data[11]; + unsigned long freq=0; + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_AMC_SET_CLK_STATE_CMD; + req.msg.data = msg_data; + + msg_data[0] = 0x00; /* PICMG identifier */ + msg_data[1] = (uchar)strtoul(argv[0], NULL,0); /* clk id */ + msg_data[2] = (uchar)strtoul(argv[1], NULL,0); /* clk index */ + msg_data[3] = (uchar)strtoul(argv[2], NULL,0); /* setting */ + msg_data[4] = (uchar)strtoul(argv[3], NULL,0); /* family */ + msg_data[5] = (uchar)strtoul(argv[4], NULL,0); /* acc */ + + freq = strtoul(argv[5], NULL,0); + msg_data[6] = (uchar)((freq >> 0)& 0xFF); /* freq */ + msg_data[7] = (uchar)((freq >> 8)& 0xFF); /* freq */ + msg_data[8] = (uchar)((freq >>16)& 0xFF); /* freq */ + msg_data[9] = (uchar)((freq >>24)& 0xFF); /* freq */ + + req.msg.data_len = 10; + if( PicmgCardType == PICMG_CARD_TYPE_ATCA ) + { + if( argc > 7) + { + req.msg.data_len = 11; + msg_data[10] = (uchar)strtoul(argv[6], NULL,0); /* resource id */ + } + else + { + printf("missing resource id for atca board\n"); + return -1; + } + } + +#if 1 +printf("## ID: %d\n", msg_data[1]); +printf("## index: %d\n", msg_data[2]); +printf("## setting: 0x%02x\n", msg_data[3]); +printf("## family: %d\n", msg_data[4]); +printf("## acc: %d\n", msg_data[5]); +printf("## freq: %d\n", freq ); +printf("## res: %d\n", msg_data[10]); +#endif + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + if (rv < 0) printf("no response\n"); + else printf("returned Completion Code 0x%02x\n", rv); + return rv; + } + + return 0; +} + + +#ifdef METACOMMAND +int i_picmg(int argc, char **argv) +#else +#ifdef WIN32 +int __cdecl +#else +int +#endif +main(int argc, char **argv) +#endif +{ + int rc = 0; + int showProperties = 0; + void *intf = NULL; + int c, i; + char *s1; + + printf("%s ver %s\n", progname,progver); + + while ( (c = getopt( argc, argv,"m:i:T:V:J:EYF:P:N:R:U:Z:x?")) != EOF) + switch (c) { + case 'm': /* specific IPMB MC, 3-byte address, e.g. "409600" */ + g_bus = htoi(&optarg[0]); /*bus/channel*/ + g_sa = htoi(&optarg[2]); /*device slave address*/ + g_lun = htoi(&optarg[4]); /*LUN*/ + g_addrtype = ADDR_IPMB; + if (optarg[6] == 's') { + g_addrtype = ADDR_SMI; s1 = "SMI"; + } else { g_addrtype = ADDR_IPMB; s1 = "IPMB"; } + fset_mc = 1; + ipmi_set_mc(g_bus,g_sa,g_lun,g_addrtype); + printf("Use MC at %s bus=%x sa=%x lun=%x\n", + s1,g_bus,g_sa,g_lun); + break; + case 'i': /*specify a fru id*/ + if (strncmp(optarg,"0x",2) == 0) g_fruid = htoi(&optarg[2]); + else g_fruid = htoi(optarg); + printf("Using FRU ID 0x%02x\n",g_fruid); + break; + case 'x': fdebug = 1; break; /* debug messages */ + case 'N': /* nodename */ + case 'U': /* remote username */ + case 'P': /* remote password */ + case 'R': /* remote password */ + case 'E': /* get password from IPMI_PASSWORD environment var */ + case 'F': /* force driver type */ + case 'T': /* auth type */ + case 'J': /* cipher suite */ + case 'V': /* priv level */ + case 'Y': /* prompt for remote password */ + case 'Z': /* set local MC address */ + parse_lan_options(c,optarg,fdebug); + break; + case '?': + ipmi_picmg_help(); + return ERR_USAGE; + break; + } + for (i = 0; i < optind; i++) { argv++; argc--; } + + /* Get PICMG properties is called to obtain version information */ + if (argc !=0 && !strncmp(argv[0], "properties", 10)) { + showProperties =1; + } + + if (argc == 0 || (!strncmp(argv[0], "help", 4))) { + ipmi_picmg_help(); + return ERR_USAGE; + } + + rc = ipmi_picmg_properties(intf,showProperties); + if (rc < 0) { /*cannot contact MC, so exit*/ + goto do_exit; + } + + /* address info command */ + else if (!strncmp(argv[0], "addrinfo", 8)) { + rc = ipmi_picmg_getaddr(intf, argc-1, &argv[1]); + } + else if (!strncmp(argv[0], "busres", 6)) { + if (argc > 1) { + if (!strncmp(argv[1], "summary", 7)) { + ipmi_picmg_bused_resource(intf, PICMG_BUSED_RESOURCE_SUMMARY ); + } + } else { + printf("usage: busres summary\n"); + } + } + /* fru control command */ + else if (!strncmp(argv[0], "frucontrol", 10)) { + if (argc > 2) { + rc = ipmi_picmg_fru_control(intf, argc-1, &(argv[1])); + } + else { + printf("usage: frucontrol