summaryrefslogtreecommitdiff
path: root/hpiutil/hpifrua.c
diff options
context:
space:
mode:
Diffstat (limited to 'hpiutil/hpifrua.c')
-rw-r--r--hpiutil/hpifrua.c550
1 files changed, 550 insertions, 0 deletions
diff --git a/hpiutil/hpifrua.c b/hpiutil/hpifrua.c
new file mode 100644
index 0000000..ae41a7d
--- /dev/null
+++ b/hpiutil/hpifrua.c
@@ -0,0 +1,550 @@
+/*
+ * hpifrua.c (hpifru.c for HPI_A)
+ *
+ * Author: Bill Barkley & Andy Cress
+ * Copyright (c) 2003-2005 Intel Corporation.
+ *
+ * 04/18/03
+ * 06/09/03 - new CustomField parsing, including SystemGUID
+ * 02/19/04 ARCress - generalized BMC tag parsing, created IsTagBmc()
+ * 05/05/04 ARCress - added OpenHPI Mgt Ctlr tag to IsTagBmc()
+ * 09/22/04 ARCress - inbuff size bigger, check null ptr in fixstr
+ * 01/11/05 ARCress - skip INVENTORY RDRs that return errors
+ * 03/16/05 ARCress - make sure asset tag is BMC for writes
+ */
+/*M*
+Copyright (c) 2003-2005, Intel Corporation
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ a.. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ b.. 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.
+ c.. Neither the name of Intel Corporation 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.
+ *M*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+#include "SaHpi.h"
+
+#define NCT 25
+
+char progver[] = "1.4 HPI-A";
+char progname[] = "hpifru";
+char *chasstypes[NCT] = {
+ "Not Defined", "Other", "Unknown", "Desktop", "Low Profile Desktop",
+ "Pizza Box", "Mini Tower", "Tower", "Portable", "Laptop",
+ "Notebook", "Handheld", "Docking Station", "All in One", "Subnotebook",
+ "Space Saving", "Lunch Box", "Main Server", "Expansion", "SubChassis",
+ "Buss Expansion Chassis", "Peripheral Chassis", "RAID Chassis",
+ "Rack-Mount Chassis", "New"
+};
+int fasset = 0;
+int fdebug = 0;
+int fxdebug = 0;
+int i,j,k = 0;
+SaHpiUint32T buffersize;
+SaHpiUint32T actualsize;
+char *asset_tag;
+char inbuff[2048];
+char outbuff[1024];
+SaHpiInventoryDataT *inv;
+SaHpiInventChassisTypeT chasstype;
+SaHpiInventGeneralDataT *dataptr;
+SaHpiTextBufferT *strptr;
+
+#ifdef ANYINVENT
+static int
+IsTagBmc(char *dstr, int dlen)
+{
+ /* if OpenHPI, always return TRUE for any Inventory RDR */
+ return(1);
+}
+#else
+char bmctag[] = "Basbrd Mgmt Ctlr"; /* see IsTagBmc() */
+char bmctag2[] = "Management Controller"; /* see IsTagBmc() */
+/*
+ * findmatch
+ * returns offset of the match if found, or -1 if not found.
+ */
+static int
+findmatch(char *buffer, int sbuf, char *pattern, int spattern, char figncase)
+{
+ int c, j, imatch;
+ j = 0;
+ imatch = 0;
+ for (j = 0; j < sbuf; j++) {
+ if (sbuf - j < spattern && imatch == 0) return (-1);
+ c = buffer[j];
+ if (c == pattern[imatch]) {
+ imatch++;
+ if (imatch == spattern) return (++j - imatch);
+ } else if (pattern[imatch] == '?') { /*wildcard char*/
+ imatch++;
+ if (imatch == spattern) return (++j - imatch);
+ } else if (figncase == 1) {
+ if ((c & 0x5f) == (pattern[imatch] & 0x5f)) {
+ imatch++;
+ if (imatch == spattern) return (++j - imatch);
+ } else
+ imatch = 0;
+ } else
+ imatch = 0;
+ }
+ return (-1);
+} /*end findmatch */
+
+static int
+IsTagBmc(char *dstr, int dlen)
+{
+ int ret = 0;
+ if (strncmp(dstr, bmctag, sizeof(bmctag)) == 0) /* Sahalee */
+ ret = 1;
+ else if (findmatch(dstr,dlen,"BMC",3,1) >= 0) /* mBMC or other */
+ ret = 1;
+ else if (findmatch(dstr,dlen,bmctag2,sizeof(bmctag2),1) >= 0)
+ ret = 1; /* BMC tag for OpenHPI with ipmi plugin */
+ return(ret);
+}
+#endif
+
+static void
+fixstr(SaHpiTextBufferT *strptr)
+{
+ size_t datalen;
+
+ outbuff[0] = 0;
+ if (strptr == NULL) return;
+ datalen = strptr->DataLength;
+ if (datalen > sizeof(outbuff)) datalen = sizeof(outbuff) - 1;
+ if (datalen != 0) {
+ strncpy ((char *)outbuff, (char *)strptr->Data, datalen);
+ outbuff[datalen] = 0;
+ if (fdebug) {
+ printf("TextBuffer: %s, len=%d, dtype=%x lang=%d\n",
+ outbuff, strptr->DataLength,
+ strptr->DataType, strptr->Language);
+ }
+ }
+}
+
+static void
+prtchassinfo(void)
+{
+ chasstype = (SaHpiInventChassisTypeT)inv->DataRecords[i]->RecordData.ChassisInfo.Type;
+ for (k=0; k<NCT; k++) {
+ if (k == chasstype)
+ printf( "Chassis Type : %s\n", chasstypes[k]);
+ }
+
+ dataptr = (SaHpiInventGeneralDataT *)&inv->DataRecords[i]->RecordData.ChassisInfo.GeneralData;
+ strptr=dataptr->Manufacturer;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Chassis Manufacturer: %s\n", outbuff);
+
+ strptr=dataptr->ProductName;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Chassis Name : %s\n", outbuff);
+
+ strptr=dataptr->ProductVersion;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Chassis Version : %s\n", outbuff);
+
+ strptr=dataptr->ModelNumber;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Chassis Model Number: %s\n", outbuff);
+
+ strptr=dataptr->SerialNumber;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Chassis Serial # : %s\n", outbuff);
+
+ strptr=dataptr->PartNumber;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Chassis Part Number : %s\n", outbuff);
+
+ strptr=dataptr->FileId;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Chassis FRU File ID : %s\n", outbuff);
+
+ strptr=dataptr->AssetTag;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Chassis Asset Tag : %s\n", outbuff);
+ if (dataptr->CustomField[0] != 0)
+ {
+ if (dataptr->CustomField[0]->DataLength != 0)
+ strncpy ((char *)outbuff, (char *)dataptr->CustomField[0]->Data,
+ dataptr->CustomField[0]->DataLength);
+ outbuff[dataptr->CustomField[0]->DataLength] = 0;
+ printf( "Chassis OEM Field : %s\n", outbuff);
+ }
+}
+
+static void
+prtprodtinfo(void)
+{
+ int j;
+ dataptr = (SaHpiInventGeneralDataT *)&inv->DataRecords[i]->RecordData.ProductInfo;
+ strptr=dataptr->Manufacturer;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Product Manufacturer: %s\n", outbuff);
+
+ strptr=dataptr->ProductName;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Product Name : %s\n", outbuff);
+
+ strptr=dataptr->ProductVersion;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Product Version : %s\n", outbuff);
+
+ strptr=dataptr->ModelNumber;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Product Model Number: %s\n", outbuff);
+
+ strptr=dataptr->SerialNumber;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Product Serial # : %s\n", outbuff);
+
+ strptr=dataptr->PartNumber;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Product Part Number : %s\n", outbuff);
+
+ strptr=dataptr->FileId;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Product FRU File ID : %s\n", outbuff);
+
+ strptr=dataptr->AssetTag;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Product Asset Tag : %s\n", outbuff);
+
+ for (j = 0; j < 10; j++) {
+ int ii;
+ if (dataptr->CustomField[j] != NULL) {
+ if ((dataptr->CustomField[j]->DataType == 0) &&
+ (dataptr->CustomField[j]->DataLength == 16)) { /*binary GUID*/
+ printf( "IPMI SystemGUID : ");
+ for (ii=0; ii< dataptr->CustomField[j]->DataLength; ii++)
+ printf("%02x", dataptr->CustomField[j]->Data[ii]);
+ printf("\n");
+ } else { /* other text field */
+ dataptr->CustomField[j]->Data[
+ dataptr->CustomField[j]->DataLength] = 0;
+ if (fdebug) {
+ printf("TextBuffer: %s, len=%d, dtype=%x lang=%d\n",
+ dataptr->CustomField[j]->Data,
+ dataptr->CustomField[j]->DataLength,
+ dataptr->CustomField[j]->DataType,
+ dataptr->CustomField[j]->Language);
+ }
+ printf( "Product OEM Field : %s\n",
+ dataptr->CustomField[j]->Data);
+ }
+ } else /* NULL pointer */
+ break;
+ } /*end for*/
+}
+
+static void
+prtboardinfo(void)
+{
+ dataptr = (SaHpiInventGeneralDataT *)&inv->DataRecords[i]->RecordData.BoardInfo;
+ strptr=dataptr->Manufacturer;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Board Manufacturer : %s\n", outbuff);
+
+ strptr=dataptr->ProductName;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Board Product Name : %s\n", outbuff);
+
+ strptr=dataptr->ModelNumber;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Board Model Number : %s\n", outbuff);
+
+ strptr=dataptr->PartNumber;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Board Part Number : %s\n", outbuff);
+
+ strptr=dataptr->ProductVersion;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Board Version : %s\n", outbuff);
+
+ strptr=dataptr->SerialNumber;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Board Serial # : %s\n", outbuff);
+
+ strptr=dataptr->FileId;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Board FRU File ID : %s\n", outbuff);
+
+ strptr=dataptr->AssetTag;
+ fixstr((SaHpiTextBufferT *)strptr);
+ printf( "Board Asset Tag : %s\n", outbuff);
+
+ if (dataptr->CustomField[0] != 0)
+ {
+ if (dataptr->CustomField[0]->DataLength != 0)
+ strncpy ((char *)outbuff, (char *)dataptr->CustomField[0]->Data,
+ dataptr->CustomField[0]->DataLength);
+ outbuff[dataptr->CustomField[0]->DataLength] = 0;
+ printf( "Board OEM Field : %s\n", outbuff);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int prodrecindx=0;
+ int asset_len=0;
+ int c;
+ SaErrorT rv;
+ SaHpiVersionT hpiVer;
+ SaHpiSessionIdT sessionid;
+ SaHpiRptInfoT rptinfo;
+ SaHpiRptEntryT rptentry;
+ SaHpiEntryIdT rptentryid;
+ SaHpiEntryIdT nextrptentryid;
+ SaHpiEntryIdT entryid;
+ SaHpiEntryIdT nextentryid;
+ SaHpiResourceIdT resourceid;
+ SaHpiRdrT rdr;
+ SaHpiEirIdT eirid;
+
+ printf("%s ver %s\n",progname,progver);
+
+ while ( (c = getopt( argc, argv,"a:xz?")) != EOF )
+ switch(c) {
+ case 'z': fxdebug = 1; /* fall thru to include next setting */
+ case 'x': fdebug = 1; break;
+ case 'a':
+ fasset = 1;
+ if (optarg)
+ {
+ asset_tag = (char *)strdup(optarg);
+ asset_len = strlen(optarg);
+ }
+ /*
+ printf( "String Length = %d\n", asset_len);
+ printf( "String Length = %d\n", strlen(optarg));
+ */
+ break;
+ default:
+ printf("Usage: %s [-x] [-a asset_tag]\n", progname);
+ printf(" -a Sets the asset tag\n");
+ printf(" -x Display debug messages\n");
+ printf(" -z Display extra debug messages\n");
+ exit(1);
+ }
+ inv = (SaHpiInventoryDataT *)&inbuff[0];
+ rv = saHpiInitialize(&hpiVer);
+ if (rv != SA_OK) {
+ printf("saHpiInitialize error %d\n",rv);
+ exit(-1);
+ }
+ rv = saHpiSessionOpen(SAHPI_DEFAULT_DOMAIN_ID,&sessionid,NULL);
+ if (rv != SA_OK) {
+ printf("saHpiSessionOpen error %d\n",rv);
+ exit(-1);
+ }
+
+ rv = saHpiResourcesDiscover(sessionid);
+ if (fxdebug) printf("saHpiResourcesDiscover rv = %d\n",rv);
+ rv = saHpiRptInfoGet(sessionid,&rptinfo);
+ if (fxdebug) printf("saHpiRptInfoGet rv = %d\n",rv);
+ if (fdebug) printf("RptInfo: UpdateCount = %x, UpdateTime = %lx\n",
+ rptinfo.UpdateCount, (unsigned long)rptinfo.UpdateTimestamp);
+
+ /* walk the RPT list */
+ rptentryid = SAHPI_FIRST_ENTRY;
+ while ((rv == SA_OK) && (rptentryid != SAHPI_LAST_ENTRY))
+ {
+ rv = saHpiRptEntryGet(sessionid,rptentryid,&nextrptentryid,&rptentry);
+ if (rv != SA_OK) printf("RptEntryGet: rv = %d\n",rv);
+ if (rv == SA_OK)
+ {
+ /* walk the RDR list for this RPT entry */
+ entryid = SAHPI_FIRST_ENTRY;
+ /* OpenHPI sometimes has bad RPT DataLength here. */
+ rptentry.ResourceTag.Data[rptentry.ResourceTag.DataLength] = 0;
+ resourceid = rptentry.ResourceId;
+ printf("Resource Tag: %s\n", rptentry.ResourceTag.Data);
+ if (fdebug) printf("rptentry[%d] resourceid=%d\n", rptentryid,resourceid);
+ while ((rv == SA_OK) && (entryid != SAHPI_LAST_ENTRY))
+ {
+ rv = saHpiRdrGet(sessionid,resourceid, entryid,&nextentryid, &rdr);
+ if (fxdebug) printf("saHpiRdrGet[%d] rv = %d\n",entryid,rv);
+ if (rv == SA_OK)
+ {
+ if (rdr.RdrType == SAHPI_INVENTORY_RDR)
+ {
+ /*type 3 includes inventory records*/
+ eirid = rdr.RdrTypeUnion.InventoryRec.EirId;
+ rdr.IdString.Data[rdr.IdString.DataLength] = 0;
+ if (fdebug) printf( "RDR[%d]: Inventory, type=%d num=%d %s\n",
+ rdr.RecordId, rdr.RdrType, eirid, rdr.IdString.Data);
+ else printf("RDR[%d]: %s \n",rdr.RecordId,rdr.IdString.Data);
+
+ buffersize = sizeof(inbuff);
+ if (fdebug) printf("BufferSize=%d InvenDataRecSize=%d\n",
+ buffersize, sizeof(inbuff));
+ /* Always get inventory data, not just for BMC */
+ /* if ( IsTagBmc(rdr.IdString.Data, rdr.IdString.DataLength) ) */
+ {
+ memset(inv,0,buffersize);
+ if (fdebug) printf("InventoryDataRead (%d, %d, %d, %d, %p, %d)\n",
+ sessionid, resourceid, eirid, buffersize, inv,
+ actualsize);
+
+ rv = saHpiEntityInventoryDataRead( sessionid, resourceid,
+ eirid, buffersize, inv, &actualsize);
+ if (fdebug) {
+ printf("saHpiEntityInventoryDataRead[%d] rv = %d\n",eirid,rv);
+ printf("buffersize = %d, ActualSize=%d\n",
+ buffersize,actualsize);
+ }
+ if (rv == SA_OK || rv == -2000) // (0 - buffersize))
+ {
+ /* Walk thru the list of inventory data */
+ for (i=0; inv->DataRecords[i] != NULL; i++)
+ {
+ if (fdebug) printf( "Record index=%d type=%x len=%d\n",
+ i, inv->DataRecords[i]->RecordType,
+ inv->DataRecords[i]->DataLength);
+ if (inv->Validity == SAHPI_INVENT_DATA_VALID)
+ {
+ switch (inv->DataRecords[i]->RecordType)
+ {
+ case SAHPI_INVENT_RECTYPE_INTERNAL_USE:
+ if (fdebug) printf( "Internal Use\n");
+ break;
+ case SAHPI_INVENT_RECTYPE_PRODUCT_INFO:
+ if (fdebug) printf( "Product Info\n");
+ prodrecindx = i;
+ prtprodtinfo();
+ break;
+ case SAHPI_INVENT_RECTYPE_CHASSIS_INFO:
+ if (fdebug) printf( "Chassis Info\n");
+ prtchassinfo();
+ break;
+ case SAHPI_INVENT_RECTYPE_BOARD_INFO:
+ if (fdebug) printf( "Board Info\n");
+ prtboardinfo();
+ break;
+ case SAHPI_INVENT_RECTYPE_OEM:
+ if (fdebug) printf( "OEM Record\n");
+ break;
+ default:
+ printf(" Invalid Invent Rec Type =%x\n",
+ inv->DataRecords[i]->RecordType);
+ break;
+ }
+ }
+ }
+ /* Cannot guarantee writable unless it is the BMC. */
+ if (IsTagBmc(rdr.IdString.Data,rdr.IdString.DataLength)
+ && (fasset == 1))
+ { /* handle asset tag */
+ SaHpiTextBufferT aTag;
+ if (fdebug) printf( "Inventory = %s\n", rdr.IdString.Data);
+ /* prodrecindx contains index for Prod Rec Type */
+ dataptr = (SaHpiInventGeneralDataT *)
+ &inv->DataRecords[prodrecindx]->RecordData.ProductInfo;
+ dataptr->AssetTag = &aTag;
+ strptr=dataptr->AssetTag;
+ strptr->DataType = SAHPI_TL_TYPE_LANGUAGE;
+ strptr->Language = SAHPI_LANG_ENGLISH;
+ strptr->DataLength = (SaHpiUint8T)asset_len;
+ strncpy( (char *)strptr->Data, (char *)asset_tag,asset_len);
+ strptr->Data[asset_len] = 0;
+
+ printf( "Writing new asset tag: %s\n",(char *)strptr->Data);
+ rv = saHpiEntityInventoryDataWrite( sessionid,
+ resourceid, eirid, inv);
+ printf("Return Write Status = %d\n", rv);
+
+ if (rv == SA_OK)
+ {
+ printf ("Good write - re-reading!\n");
+ rv = saHpiEntityInventoryDataRead( sessionid, resourceid,
+ eirid, buffersize, inv, &actualsize);
+ if (fxdebug) printf(
+ "saHpiEntityInventoryDataRead[%d] rv = %d\n", eirid, rv);
+ if (fdebug) printf("ActualSize=%d\n", actualsize);
+ if (rv == SA_OK)
+ {
+ /* Walk thru the list of inventory data */
+ for (i=0; inv->DataRecords[i] != NULL; i++)
+ {
+ if (inv->Validity == SAHPI_INVENT_DATA_VALID)
+ {
+ if (fdebug) printf( "Index = %d type=%x len=%d\n",
+ i, inv->DataRecords[i]->RecordType,
+ inv->DataRecords[i]->DataLength);
+ switch (inv->DataRecords[i]->RecordType)
+ {
+ case SAHPI_INVENT_RECTYPE_INTERNAL_USE:
+ if (fdebug) printf( "Internal Use\n");
+ break;
+ case SAHPI_INVENT_RECTYPE_PRODUCT_INFO:
+ if (fdebug) printf( "Product Info\n");
+ prtprodtinfo();
+ break;
+ case SAHPI_INVENT_RECTYPE_CHASSIS_INFO:
+ if (fdebug) printf( "Chassis Info\n");
+ prtchassinfo();
+ break;
+ case SAHPI_INVENT_RECTYPE_BOARD_INFO:
+ if (fdebug) printf( "Board Info\n");
+ prtboardinfo();
+ break;
+ case SAHPI_INVENT_RECTYPE_OEM:
+ if (fdebug) printf( "OEM Record\n");
+ break;
+ default:
+ printf(" Invalid Invent Rec Type =%x\n",
+ inv->DataRecords[i]->RecordType);
+ break;
+ }
+ }
+ }
+ } /*re-walk the inventory record list */
+ } /* Good write - re-read */
+ } /* check asset tag flag */
+ } else {
+ /* It is an Inventory RDR, but gets error reading FRU. */
+ if (fdebug) printf("\tinventory read error, rv=%d\n", rv);
+ rv = 0; /* keep trying another RDR */
+ entryid = nextentryid;
+ continue;
+ }
+ }
+ } /* Inventory Data Records - Type 3 */
+ entryid = nextentryid;
+ }
+ }
+ rptentryid = nextrptentryid;
+ }
+ }
+ rv = saHpiSessionClose(sessionid);
+ rv = saHpiFinalize();
+ exit(0);
+}
+ /* end hpifru.c */