mirror of
https://github.com/ipmitool/ipmitool.git
synced 2025-05-11 02:57:22 +00:00
New FRU get OEM record command
This commit is contained in:
parent
c0e63cefbb
commit
b97d1b74e2
@ -73,6 +73,7 @@ static int ipmi_fru_get_multirec_from_file(char * pFileName, uint8_t * pBufArea,
|
|||||||
static int ipmi_fru_get_multirec_size_from_file(char * pFileName, uint32_t * pSize, uint32_t * pOffset);
|
static int ipmi_fru_get_multirec_size_from_file(char * pFileName, uint32_t * pSize, uint32_t * pOffset);
|
||||||
static void ipmi_fru_get_adjust_size_from_buffer(uint8_t * pBufArea, uint32_t *pSize);
|
static void ipmi_fru_get_adjust_size_from_buffer(uint8_t * pBufArea, uint32_t *pSize);
|
||||||
static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length);
|
static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length);
|
||||||
|
|
||||||
static int ipmi_fru_set_field_string(struct ipmi_intf * intf, unsigned
|
static int ipmi_fru_set_field_string(struct ipmi_intf * intf, unsigned
|
||||||
char fruId, uint8_t f_type, uint8_t f_index, char *f_string);
|
char fruId, uint8_t f_type, uint8_t f_index, char *f_string);
|
||||||
static void
|
static void
|
||||||
@ -325,7 +326,7 @@ build_fru_bloc(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
|
|||||||
//printf("Bloc Size : %i\n", h->len);
|
//printf("Bloc Size : %i\n", h->len);
|
||||||
//printf("\n");
|
//printf("\n");
|
||||||
i += h->len + sizeof (struct fru_multirec_header);
|
i += h->len + sizeof (struct fru_multirec_header);
|
||||||
} while (!(h->format & 0x80));
|
} while (!(h->format & 0x80) && ( last_off < fru->size));
|
||||||
|
|
||||||
lprintf(LOG_DEBUG ,"Multi-Record area ends at: %i (%xh)",i,i);
|
lprintf(LOG_DEBUG ,"Multi-Record area ends at: %i (%xh)",i,i);
|
||||||
|
|
||||||
@ -416,13 +417,14 @@ build_fru_bloc(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
|
|||||||
printf("\n");*/
|
printf("\n");*/
|
||||||
|
|
||||||
i += h->len + sizeof (struct fru_multirec_header);
|
i += h->len + sizeof (struct fru_multirec_header);
|
||||||
} while (!(h->format & 0x80));
|
|
||||||
|
} while (!(h->format & 0x80) && ( bloc_count < num_bloc ) );
|
||||||
|
|
||||||
lprintf(LOG_DEBUG ,"Multi-Record area ends at: %i (%xh)",i,i);
|
lprintf(LOG_DEBUG ,"Multi-Record area ends at: %i (%xh)",i,i);
|
||||||
/* If last bloc size was defined and is not until the end, create a
|
/* If last bloc size was defined and is not until the end, create a
|
||||||
last bloc with the remaining unused space */
|
last bloc with the remaining unused space */
|
||||||
|
|
||||||
if(fru->size > i)
|
if((fru->size > i) && (bloc_count < num_bloc))
|
||||||
{
|
{
|
||||||
// Bloc for remaining space
|
// Bloc for remaining space
|
||||||
p_bloc[bloc_count].start = i;
|
p_bloc[bloc_count].start = i;
|
||||||
@ -431,7 +433,6 @@ build_fru_bloc(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
|
|||||||
bloc_count ++;
|
bloc_count ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
free(fru_data);
|
free(fru_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,11 +461,6 @@ build_fru_bloc(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
|
|||||||
lprintf(LOG_DEBUG ,"Bloc Size : %i\n", p_bloc[counter].size);
|
lprintf(LOG_DEBUG ,"Bloc Size : %i\n", p_bloc[counter].size);
|
||||||
lprintf(LOG_DEBUG ,"\n");
|
lprintf(LOG_DEBUG ,"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(* ptr_number_bloc) = num_bloc;
|
(* ptr_number_bloc) = num_bloc;
|
||||||
@ -555,7 +551,7 @@ write_fru_area(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
|
|||||||
{
|
{
|
||||||
lprintf(LOG_INFO,"Writing %d bytes", (req.msg.data_len-3));
|
lprintf(LOG_INFO,"Writing %d bytes", (req.msg.data_len-3));
|
||||||
}
|
}
|
||||||
else
|
else if(found_bloc != 0xFFFF)
|
||||||
{
|
{
|
||||||
lprintf(LOG_INFO,"Writing %d bytes (Bloc #%i: %s)",
|
lprintf(LOG_INFO,"Writing %d bytes (Bloc #%i: %s)",
|
||||||
(req.msg.data_len-3),
|
(req.msg.data_len-3),
|
||||||
@ -584,11 +580,11 @@ write_fru_area(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
|
|||||||
|
|
||||||
if(protected_bloc == 0)
|
if(protected_bloc == 0)
|
||||||
{
|
{
|
||||||
|
lprintf(LOG_INFO,"Wrote %d bytes", writeLength);
|
||||||
off += writeLength; // Write OK, bloc not protected, continue
|
off += writeLength; // Write OK, bloc not protected, continue
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
if(found_bloc != 0xffff)
|
if(found_bloc != 0xffff)
|
||||||
{
|
{
|
||||||
// Bloc protected, advise user and jump over protected bloc
|
// Bloc protected, advise user and jump over protected bloc
|
||||||
@ -1466,7 +1462,7 @@ int ipmi_fru_query_new_value(uint8_t *data,int offset, size_t len)
|
|||||||
*
|
*
|
||||||
* IANA : 15000 (Kontron)
|
* IANA : 15000 (Kontron)
|
||||||
* RECORD ID : 3
|
* RECORD ID : 3
|
||||||
* RECORD VERSION: 0
|
* RECORD VERSION: 0 (or 1)
|
||||||
*
|
*
|
||||||
* I would have like to put that stuff in an OEM specific file, but apart for
|
* I would have like to put that stuff in an OEM specific file, but apart for
|
||||||
* the record format information, all commands are really standard 'FRU' command
|
* the record format information, all commands are really standard 'FRU' command
|
||||||
@ -1483,7 +1479,8 @@ int ipmi_fru_query_new_value(uint8_t *data,int offset, size_t len)
|
|||||||
*/
|
*/
|
||||||
#define OEM_KONTRON_INFORMATION_RECORD 3
|
#define OEM_KONTRON_INFORMATION_RECORD 3
|
||||||
|
|
||||||
#define OEM_KONTRON_COMPLETE_ARG_COUNT 12
|
#define EDIT_OEM_KONTRON_COMPLETE_ARG_COUNT 12
|
||||||
|
#define GET_OEM_KONTRON_COMPLETE_ARG_COUNT 5
|
||||||
/*
|
/*
|
||||||
./src/ipmitool fru edit 0
|
./src/ipmitool fru edit 0
|
||||||
oem 15000 3 0 name instance FIELD1 FIELD2 FIELD3 crc32
|
oem 15000 3 0 name instance FIELD1 FIELD2 FIELD3 crc32
|
||||||
@ -1501,8 +1498,12 @@ int ipmi_fru_query_new_value(uint8_t *data,int offset, size_t len)
|
|||||||
#define OEM_KONTRON_CRC32_ARG_POS 11
|
#define OEM_KONTRON_CRC32_ARG_POS 11
|
||||||
|
|
||||||
#define OEM_KONTRON_FIELD_SIZE 8
|
#define OEM_KONTRON_FIELD_SIZE 8
|
||||||
|
#define OEM_KONTRON_VERSION_FIELD_SIZE 10
|
||||||
|
|
||||||
typedef struct OemKontronInformationRecord{
|
#ifdef HAVE_PRAGMA_PACK
|
||||||
|
#pragma pack(1)
|
||||||
|
#endif
|
||||||
|
typedef struct OemKontronInformationRecordV0{
|
||||||
uint8_t field1TypeLength;
|
uint8_t field1TypeLength;
|
||||||
uint8_t field1[OEM_KONTRON_FIELD_SIZE];
|
uint8_t field1[OEM_KONTRON_FIELD_SIZE];
|
||||||
uint8_t field2TypeLength;
|
uint8_t field2TypeLength;
|
||||||
@ -1511,7 +1512,146 @@ typedef struct OemKontronInformationRecord{
|
|||||||
uint8_t field3[OEM_KONTRON_FIELD_SIZE];
|
uint8_t field3[OEM_KONTRON_FIELD_SIZE];
|
||||||
uint8_t crcTypeLength;
|
uint8_t crcTypeLength;
|
||||||
uint8_t crc32[OEM_KONTRON_FIELD_SIZE];
|
uint8_t crc32[OEM_KONTRON_FIELD_SIZE];
|
||||||
}tOemKontronInformationRecord;
|
}tOemKontronInformationRecordV0;
|
||||||
|
#ifdef HAVE_PRAGMA_PACK
|
||||||
|
#pragma pack(0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_PRAGMA_PACK
|
||||||
|
#pragma pack(1)
|
||||||
|
#endif
|
||||||
|
typedef struct OemKontronInformationRecordV1{
|
||||||
|
uint8_t field1TypeLength;
|
||||||
|
uint8_t field1[OEM_KONTRON_VERSION_FIELD_SIZE];
|
||||||
|
uint8_t field2TypeLength;
|
||||||
|
uint8_t field2[OEM_KONTRON_FIELD_SIZE];
|
||||||
|
uint8_t field3TypeLength;
|
||||||
|
uint8_t field3[OEM_KONTRON_FIELD_SIZE];
|
||||||
|
uint8_t crcTypeLength;
|
||||||
|
uint8_t crc32[OEM_KONTRON_FIELD_SIZE];
|
||||||
|
}tOemKontronInformationRecordV1;
|
||||||
|
#ifdef HAVE_PRAGMA_PACK
|
||||||
|
#pragma pack(0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
./src/ipmitool fru get 0 oem iana 3
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void ipmi_fru_oemkontron_get( int argc, char ** argv,uint8_t * fru_data,
|
||||||
|
int off,int len,
|
||||||
|
struct fru_multirec_header *h,
|
||||||
|
struct fru_multirec_oem_header *oh)
|
||||||
|
{
|
||||||
|
static int badParams=FALSE;
|
||||||
|
int start = off;
|
||||||
|
int offset = start;
|
||||||
|
int length = len;
|
||||||
|
int i;
|
||||||
|
offset += sizeof(struct fru_multirec_oem_header);
|
||||||
|
|
||||||
|
if(!badParams){
|
||||||
|
/* the 'OEM' field is already checked in caller */
|
||||||
|
if( argc > OEM_KONTRON_SUBCOMMAND_ARG_POS ){
|
||||||
|
if(strncmp("oem", argv[OEM_KONTRON_SUBCOMMAND_ARG_POS],3)){
|
||||||
|
printf("usage: fru get <id> <oem>\r\n");
|
||||||
|
badParams = TRUE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( argc<GET_OEM_KONTRON_COMPLETE_ARG_COUNT ){
|
||||||
|
printf("usage: oem <iana> <recordid>\r\n");
|
||||||
|
printf("usage: oem 15000 3\r\n");
|
||||||
|
badParams = TRUE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!badParams){
|
||||||
|
|
||||||
|
if(oh->record_id == OEM_KONTRON_INFORMATION_RECORD ) {
|
||||||
|
|
||||||
|
uint8_t version;
|
||||||
|
|
||||||
|
printf("Kontron OEM Information Record\n");
|
||||||
|
version = oh->record_version;
|
||||||
|
|
||||||
|
int blockstart;
|
||||||
|
uint8_t blockCount;
|
||||||
|
uint8_t blockIndex=0;
|
||||||
|
|
||||||
|
unsigned int matchInstance = 0;
|
||||||
|
unsigned int instance = atoi( argv[OEM_KONTRON_INSTANCE_ARG_POS]);
|
||||||
|
|
||||||
|
blockCount = fru_data[offset++];
|
||||||
|
|
||||||
|
for(blockIndex=0;blockIndex<blockCount;blockIndex++){
|
||||||
|
void * pRecordData;
|
||||||
|
uint8_t nameLen;
|
||||||
|
|
||||||
|
blockstart = offset;
|
||||||
|
nameLen = ( fru_data[offset++] &= 0x3F );
|
||||||
|
printf(" Name: %*.*s\n",nameLen, nameLen, (const char *)(fru_data+offset));
|
||||||
|
|
||||||
|
offset+=nameLen;
|
||||||
|
|
||||||
|
pRecordData = &fru_data[offset];
|
||||||
|
|
||||||
|
printf(" Record Version: %d\n", version);
|
||||||
|
if( version == 0 )
|
||||||
|
{
|
||||||
|
printf(" Version: %*.*s\n",
|
||||||
|
OEM_KONTRON_FIELD_SIZE,
|
||||||
|
OEM_KONTRON_FIELD_SIZE,
|
||||||
|
((tOemKontronInformationRecordV0 *) pRecordData)->field1);
|
||||||
|
printf(" Build Date: %*.*s\n",
|
||||||
|
OEM_KONTRON_FIELD_SIZE,
|
||||||
|
OEM_KONTRON_FIELD_SIZE,
|
||||||
|
((tOemKontronInformationRecordV0 *) pRecordData)->field2);
|
||||||
|
printf(" Update Date: %*.*s\n",
|
||||||
|
OEM_KONTRON_FIELD_SIZE,
|
||||||
|
OEM_KONTRON_FIELD_SIZE,
|
||||||
|
((tOemKontronInformationRecordV0 *) pRecordData)->field3);
|
||||||
|
printf(" Checksum: %*.*s\n\n",
|
||||||
|
OEM_KONTRON_FIELD_SIZE,
|
||||||
|
OEM_KONTRON_FIELD_SIZE,
|
||||||
|
((tOemKontronInformationRecordV0 *) pRecordData)->crc32);
|
||||||
|
matchInstance++;
|
||||||
|
offset+= sizeof(tOemKontronInformationRecordV0);
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
else if ( version == 1 )
|
||||||
|
{
|
||||||
|
printf(" Version: %*.*s\n",
|
||||||
|
OEM_KONTRON_VERSION_FIELD_SIZE,
|
||||||
|
OEM_KONTRON_VERSION_FIELD_SIZE,
|
||||||
|
((tOemKontronInformationRecordV1 *) pRecordData)->field1);
|
||||||
|
printf(" Build Date: %*.*s\n",
|
||||||
|
OEM_KONTRON_FIELD_SIZE,
|
||||||
|
OEM_KONTRON_FIELD_SIZE,
|
||||||
|
((tOemKontronInformationRecordV1 *) pRecordData)->field2);
|
||||||
|
printf(" Update Date: %*.*s\n",
|
||||||
|
OEM_KONTRON_FIELD_SIZE,
|
||||||
|
OEM_KONTRON_FIELD_SIZE,
|
||||||
|
((tOemKontronInformationRecordV1 *) pRecordData)->field3);
|
||||||
|
printf(" Checksum: %*.*s\n\n",
|
||||||
|
OEM_KONTRON_FIELD_SIZE,
|
||||||
|
OEM_KONTRON_FIELD_SIZE,
|
||||||
|
((tOemKontronInformationRecordV1 *) pRecordData)->crc32);
|
||||||
|
matchInstance++;
|
||||||
|
offset+= sizeof(tOemKontronInformationRecordV1);
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf (" Unsupported version %d\n",version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int ipmi_fru_oemkontron_edit( int argc, char ** argv,uint8_t * fru_data,
|
static int ipmi_fru_oemkontron_edit( int argc, char ** argv,uint8_t * fru_data,
|
||||||
int off,int len,
|
int off,int len,
|
||||||
@ -1535,7 +1675,7 @@ static int ipmi_fru_oemkontron_edit( int argc, char ** argv,uint8_t * fru_data,
|
|||||||
return hasChanged;
|
return hasChanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( argc<OEM_KONTRON_COMPLETE_ARG_COUNT ){
|
if( argc<EDIT_OEM_KONTRON_COMPLETE_ARG_COUNT ){
|
||||||
printf("usage: oem <iana> <recordid> <format> <args...>\r\n");
|
printf("usage: oem <iana> <recordid> <format> <args...>\r\n");
|
||||||
printf("usage: oem 15000 3 0 <name> <instance> <field1>"\
|
printf("usage: oem 15000 3 0 <name> <instance> <field1>"\
|
||||||
" <field2> <field3> <crc32>\r\n");
|
" <field2> <field3> <crc32>\r\n");
|
||||||
@ -1545,8 +1685,9 @@ static int ipmi_fru_oemkontron_edit( int argc, char ** argv,uint8_t * fru_data,
|
|||||||
if( atoi(argv[OEM_KONTRON_RECORDID_ARG_POS])
|
if( atoi(argv[OEM_KONTRON_RECORDID_ARG_POS])
|
||||||
== OEM_KONTRON_INFORMATION_RECORD){
|
== OEM_KONTRON_INFORMATION_RECORD){
|
||||||
for(i=OEM_KONTRON_VERSION_ARG_POS;i<=OEM_KONTRON_CRC32_ARG_POS;i++){
|
for(i=OEM_KONTRON_VERSION_ARG_POS;i<=OEM_KONTRON_CRC32_ARG_POS;i++){
|
||||||
if(strlen(argv[i]) != OEM_KONTRON_FIELD_SIZE ){
|
if( (strlen(argv[i]) != OEM_KONTRON_FIELD_SIZE) &&
|
||||||
printf("error: version fields must have a %d caracters\r\n",
|
(strlen(argv[i]) != OEM_KONTRON_VERSION_FIELD_SIZE)) {
|
||||||
|
printf("error: version fields must have %d characters\r\n",
|
||||||
OEM_KONTRON_FIELD_SIZE);
|
OEM_KONTRON_FIELD_SIZE);
|
||||||
badParams = TRUE;
|
badParams = TRUE;
|
||||||
return hasChanged;
|
return hasChanged;
|
||||||
@ -1558,12 +1699,13 @@ static int ipmi_fru_oemkontron_edit( int argc, char ** argv,uint8_t * fru_data,
|
|||||||
if(!badParams){
|
if(!badParams){
|
||||||
|
|
||||||
if(oh->record_id == OEM_KONTRON_INFORMATION_RECORD ) {
|
if(oh->record_id == OEM_KONTRON_INFORMATION_RECORD ) {
|
||||||
|
uint8_t formatVersion = (uint8_t)atoi( argv[OEM_KONTRON_FORMAT_ARG_POS]);
|
||||||
uint8_t version;
|
uint8_t version;
|
||||||
|
|
||||||
printf(" Kontron OEM Information Record\n");
|
printf(" Kontron OEM Information Record\n");
|
||||||
version = oh->record_version;
|
version = oh->record_version;
|
||||||
|
|
||||||
if( version == 0 ){
|
if( version == formatVersion ){
|
||||||
int blockstart;
|
int blockstart;
|
||||||
uint8_t blockCount;
|
uint8_t blockCount;
|
||||||
uint8_t blockIndex=0;
|
uint8_t blockIndex=0;
|
||||||
@ -1571,53 +1713,95 @@ static int ipmi_fru_oemkontron_edit( int argc, char ** argv,uint8_t * fru_data,
|
|||||||
unsigned int matchInstance = 0;
|
unsigned int matchInstance = 0;
|
||||||
unsigned int instance = atoi( argv[OEM_KONTRON_INSTANCE_ARG_POS]);
|
unsigned int instance = atoi( argv[OEM_KONTRON_INSTANCE_ARG_POS]);
|
||||||
|
|
||||||
|
|
||||||
blockCount = fru_data[offset++];
|
blockCount = fru_data[offset++];
|
||||||
printf(" blockCount: %d\n",blockCount);
|
printf(" blockCount: %d\n",blockCount);
|
||||||
|
|
||||||
for(blockIndex=0;blockIndex<blockCount;blockIndex++){
|
for(blockIndex=0;blockIndex<blockCount;blockIndex++){
|
||||||
tOemKontronInformationRecord *recordData;
|
void * pRecordData;
|
||||||
uint8_t nameLen;
|
uint8_t nameLen;
|
||||||
|
|
||||||
blockstart = offset;
|
blockstart = offset;
|
||||||
|
|
||||||
nameLen = ( fru_data[offset++] &= 0x3F );
|
nameLen = ( fru_data[offset++] & 0x3F );
|
||||||
|
|
||||||
if(!strncmp((char *)argv[OEM_KONTRON_NAME_ARG_POS],
|
if( version == 0 || version == 1 )
|
||||||
(const char *)(fru_data+offset),nameLen)&& (matchInstance == instance)){
|
{
|
||||||
|
if(!strncmp((char *)argv[OEM_KONTRON_NAME_ARG_POS],
|
||||||
|
(const char *)(fru_data+offset),nameLen)&& (matchInstance == instance)){
|
||||||
|
|
||||||
printf ("Found : %s\n",argv[OEM_KONTRON_NAME_ARG_POS]);
|
printf ("Found : %s\n",argv[OEM_KONTRON_NAME_ARG_POS]);
|
||||||
offset+=nameLen;
|
offset+=nameLen;
|
||||||
|
|
||||||
recordData = ( tOemKontronInformationRecord *)
|
pRecordData = &fru_data[offset];
|
||||||
&fru_data[offset];
|
|
||||||
|
|
||||||
memcpy( recordData->field1 ,
|
if( version == 0 )
|
||||||
argv[OEM_KONTRON_VERSION_ARG_POS] ,
|
{
|
||||||
|
memcpy( ((tOemKontronInformationRecordV0 *)
|
||||||
|
pRecordData)->field1 ,
|
||||||
|
argv[OEM_KONTRON_VERSION_ARG_POS] ,
|
||||||
OEM_KONTRON_FIELD_SIZE);
|
OEM_KONTRON_FIELD_SIZE);
|
||||||
memcpy( recordData->field2 ,
|
memcpy( ((tOemKontronInformationRecordV0 *)
|
||||||
|
pRecordData)->field2 ,
|
||||||
argv[OEM_KONTRON_BUILDDATE_ARG_POS],
|
argv[OEM_KONTRON_BUILDDATE_ARG_POS],
|
||||||
OEM_KONTRON_FIELD_SIZE);
|
OEM_KONTRON_FIELD_SIZE);
|
||||||
memcpy( recordData->field3 ,
|
memcpy( ((tOemKontronInformationRecordV0 *)
|
||||||
|
pRecordData)->field3 ,
|
||||||
argv[OEM_KONTRON_UPDATEDATE_ARG_POS],
|
argv[OEM_KONTRON_UPDATEDATE_ARG_POS],
|
||||||
OEM_KONTRON_FIELD_SIZE);
|
OEM_KONTRON_FIELD_SIZE);
|
||||||
memcpy( recordData->crc32 ,
|
memcpy( ((tOemKontronInformationRecordV0 *)
|
||||||
|
pRecordData)->crc32 ,
|
||||||
argv[OEM_KONTRON_CRC32_ARG_POS] ,
|
argv[OEM_KONTRON_CRC32_ARG_POS] ,
|
||||||
OEM_KONTRON_FIELD_SIZE);
|
OEM_KONTRON_FIELD_SIZE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy( ((tOemKontronInformationRecordV1 *)
|
||||||
|
pRecordData)->field1 ,
|
||||||
|
argv[OEM_KONTRON_VERSION_ARG_POS] ,
|
||||||
|
OEM_KONTRON_VERSION_FIELD_SIZE);
|
||||||
|
memcpy( ((tOemKontronInformationRecordV1 *)
|
||||||
|
pRecordData)->field2 ,
|
||||||
|
argv[OEM_KONTRON_BUILDDATE_ARG_POS],
|
||||||
|
OEM_KONTRON_FIELD_SIZE);
|
||||||
|
memcpy( ((tOemKontronInformationRecordV1 *)
|
||||||
|
pRecordData)->field3 ,
|
||||||
|
argv[OEM_KONTRON_UPDATEDATE_ARG_POS],
|
||||||
|
OEM_KONTRON_FIELD_SIZE);
|
||||||
|
memcpy( ((tOemKontronInformationRecordV1 *)
|
||||||
|
pRecordData)->crc32 ,
|
||||||
|
argv[OEM_KONTRON_CRC32_ARG_POS] ,
|
||||||
|
OEM_KONTRON_FIELD_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
matchInstance++;
|
matchInstance++;
|
||||||
hasChanged = TRUE;
|
hasChanged = TRUE;
|
||||||
}
|
}
|
||||||
else if(!strncmp((char *)argv[OEM_KONTRON_NAME_ARG_POS],
|
else if(!strncmp((char *)argv[OEM_KONTRON_NAME_ARG_POS],
|
||||||
(const char *)(fru_data+offset), nameLen)){
|
(const char *)(fru_data+offset), nameLen)){
|
||||||
printf ("Skipped : %s\n",argv[OEM_KONTRON_NAME_ARG_POS]);
|
printf ("Skipped : %s [instance %d]\n",argv[OEM_KONTRON_NAME_ARG_POS],
|
||||||
matchInstance++;
|
matchInstance);
|
||||||
offset+=nameLen;
|
matchInstance++;
|
||||||
}
|
offset+=nameLen;
|
||||||
else{
|
}
|
||||||
offset+=nameLen;
|
else {
|
||||||
}
|
offset+=nameLen;
|
||||||
|
}
|
||||||
offset+=37;
|
|
||||||
|
if( version == 0 )
|
||||||
|
{
|
||||||
|
offset+= sizeof(tOemKontronInformationRecordV0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
offset+= sizeof(tOemKontronInformationRecordV1);
|
||||||
|
}
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf (" Unsupported version %d\n",version);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
@ -1747,6 +1931,14 @@ static int ipmi_fru_picmg_ext_edit(uint8_t * fru_data,
|
|||||||
return hasChanged;
|
return hasChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ipmi_fru_picmg_ext_print - prints OEM fru record (PICMG)
|
||||||
|
*
|
||||||
|
* @fru_data: FRU data
|
||||||
|
* @offset: offset of the bytes to be modified in data
|
||||||
|
* @length: size of the record
|
||||||
|
*
|
||||||
|
* returns : n/a
|
||||||
|
*/
|
||||||
static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length)
|
static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length)
|
||||||
{
|
{
|
||||||
struct fru_multirec_oem_header *h;
|
struct fru_multirec_oem_header *h;
|
||||||
@ -3010,6 +3202,155 @@ ipmi_fru_edit_multirec(struct ipmi_intf * intf, uint8_t id ,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ipmi_fru_get_multirec - Query new values to replace original FRU content
|
||||||
|
*
|
||||||
|
* @intf: interface to use
|
||||||
|
* @id: FRU id to work on
|
||||||
|
*
|
||||||
|
* returns: nothing
|
||||||
|
*/
|
||||||
|
/* Work in progress, copy paste most of the stuff for other functions in this
|
||||||
|
file ... not elegant yet */
|
||||||
|
static int
|
||||||
|
ipmi_fru_get_multirec(struct ipmi_intf * intf, uint8_t id ,
|
||||||
|
int argc, char ** argv)
|
||||||
|
{
|
||||||
|
|
||||||
|
struct ipmi_rs * rsp;
|
||||||
|
struct ipmi_rq req;
|
||||||
|
struct fru_info fru;
|
||||||
|
struct fru_header header;
|
||||||
|
uint8_t msg_data[4];
|
||||||
|
|
||||||
|
uint16_t retStatus = 0;
|
||||||
|
uint32_t offFruMultiRec;
|
||||||
|
uint32_t fruMultiRecSize = 0;
|
||||||
|
struct fru_info fruInfo;
|
||||||
|
retStatus = ipmi_fru_get_multirec_location_from_fru(intf, id, &fruInfo,
|
||||||
|
&offFruMultiRec,
|
||||||
|
&fruMultiRecSize);
|
||||||
|
|
||||||
|
|
||||||
|
lprintf(LOG_DEBUG, "FRU Size : %lu\n", fruMultiRecSize);
|
||||||
|
lprintf(LOG_DEBUG, "Multi Rec offset: %lu\n", offFruMultiRec);
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
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.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
uint8_t * fru_data;
|
||||||
|
uint32_t fru_len, i;
|
||||||
|
uint32_t offset= offFruMultiRec;
|
||||||
|
struct fru_multirec_header * h;
|
||||||
|
uint32_t last_off, len;
|
||||||
|
uint8_t error=0;
|
||||||
|
|
||||||
|
i = last_off = offset;
|
||||||
|
fru_len = 0;
|
||||||
|
|
||||||
|
fru_data = malloc(fru.size + 1);
|
||||||
|
if (fru_data == NULL) {
|
||||||
|
lprintf(LOG_ERR, " Out of memory!");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(fru_data, 0, fru.size + 1);
|
||||||
|
|
||||||
|
do {
|
||||||
|
h = (struct fru_multirec_header *) (fru_data + i);
|
||||||
|
|
||||||
|
/* read area in (at most) FRU_MULTIREC_CHUNK_SIZE bytes at a time */
|
||||||
|
if ((last_off < (i + sizeof(*h))) || (last_off < (i + h->len)))
|
||||||
|
{
|
||||||
|
len = fru.size - last_off;
|
||||||
|
if (len > FRU_MULTIREC_CHUNK_SIZE)
|
||||||
|
len = FRU_MULTIREC_CHUNK_SIZE;
|
||||||
|
|
||||||
|
if (read_fru_area(intf, &fru, id, last_off, len, fru_data) < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
last_off += len;
|
||||||
|
}
|
||||||
|
if( h->type == FRU_RECORD_TYPE_OEM_EXTENSION ){
|
||||||
|
|
||||||
|
struct fru_multirec_oem_header *oh=(struct fru_multirec_oem_header *)
|
||||||
|
&fru_data[i + sizeof(struct fru_multirec_header)];
|
||||||
|
uint32_t iana = oh->mfg_id[0] | oh->mfg_id[1]<<8 | oh->mfg_id[2]<<16;
|
||||||
|
|
||||||
|
uint32_t suppliedIana = 0 ;
|
||||||
|
/* Now makes sure this is really PICMG record */
|
||||||
|
if( !strncmp( argv[2] , "oem" , 3 )) {
|
||||||
|
/* Expect IANA number next */
|
||||||
|
if( argc <= 3 ) {
|
||||||
|
lprintf(LOG_ERR, "oem iana <record> <format>");
|
||||||
|
error = 1;
|
||||||
|
} else {
|
||||||
|
suppliedIana = atol ( argv[3] ) ;
|
||||||
|
lprintf(LOG_DEBUG, "using iana: %d", suppliedIana);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( suppliedIana == iana ) {
|
||||||
|
lprintf(LOG_DEBUG, "Matching record found" );
|
||||||
|
|
||||||
|
if( iana == IPMI_OEM_KONTRON ) {
|
||||||
|
ipmi_fru_oemkontron_get( argc,argv,fru_data,
|
||||||
|
i + sizeof(struct fru_multirec_header),
|
||||||
|
h->len, h, oh );
|
||||||
|
}
|
||||||
|
/* FIXME: Add OEM record support here */
|
||||||
|
else{
|
||||||
|
printf(" OEM IANA (%s) Record not supported in this mode\n",
|
||||||
|
val2str( iana, ipmi_oem_info));
|
||||||
|
error = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i += h->len + sizeof (struct fru_multirec_header);
|
||||||
|
} while (!(h->format & 0x80) && (error != 1));
|
||||||
|
|
||||||
|
free(fru_data);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ipmi_fru_upg_ekeying(struct ipmi_intf * intf,
|
ipmi_fru_upg_ekeying(struct ipmi_intf * intf,
|
||||||
@ -3811,6 +4152,36 @@ ipmi_fru_main(struct ipmi_intf * intf, int argc, char ** argv)
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (!strncmp(argv[0], "get", 4)) {
|
||||||
|
|
||||||
|
if ((argc >= 2) && (strncmp(argv[1], "help", 4) == 0)) {
|
||||||
|
lprintf(LOG_ERR, "get commands:");
|
||||||
|
lprintf(LOG_ERR, " get - retrieve OEM records");
|
||||||
|
lprintf(LOG_ERR,
|
||||||
|
" get <fruid> oem iana <record> <format> <args> - limited OEM support");
|
||||||
|
} else {
|
||||||
|
|
||||||
|
uint8_t fruId = 0;
|
||||||
|
|
||||||
|
if ((argc >= 2) && (strlen(argv[1]) > 0)) {
|
||||||
|
fruId = atoi(argv[1]);
|
||||||
|
if (verbose) {
|
||||||
|
printf("Fru Id : %d\n", fruId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("Using default FRU id: %d\n", fruId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((argc >= 3) && (strlen(argv[1]) > 0)) {
|
||||||
|
if (!strncmp(argv[2], "oem", 3)){
|
||||||
|
ipmi_fru_get_multirec(intf,fruId, argc, argv);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ipmi_fru_get_multirec(intf,fruId, argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
lprintf(LOG_ERR, "Invalid FRU command: %s", argv[0]);
|
lprintf(LOG_ERR, "Invalid FRU command: %s", argv[0]);
|
||||||
lprintf(LOG_ERR, "FRU Commands: print read write upgEkey edit");
|
lprintf(LOG_ERR, "FRU Commands: print read write upgEkey edit");
|
||||||
@ -3965,6 +4336,7 @@ f_type, uint8_t f_index, char *f_string)
|
|||||||
{
|
{
|
||||||
fru_area = (uint8_t *) get_fru_area_str(fru_data, &fru_field_offset);
|
fru_area = (uint8_t *) get_fru_area_str(fru_data, &fru_field_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (fru_area == NULL ) || strlen((const char *)fru_area) == 0 ) {
|
if( (fru_area == NULL ) || strlen((const char *)fru_area) == 0 ) {
|
||||||
printf("Field not found!\n");
|
printf("Field not found!\n");
|
||||||
return -1;
|
return -1;
|
||||||
@ -3972,6 +4344,11 @@ f_type, uint8_t f_index, char *f_string)
|
|||||||
/* Get original field string */
|
/* Get original field string */
|
||||||
fru_field_offset_tmp = fru_field_offset;
|
fru_field_offset_tmp = fru_field_offset;
|
||||||
fru_area = (uint8_t *) get_fru_area_str(fru_data, &fru_field_offset);
|
fru_area = (uint8_t *) get_fru_area_str(fru_data, &fru_field_offset);
|
||||||
|
if ( (fru_area == NULL ) || strlen((const char *)fru_area) == 0 ) {
|
||||||
|
printf("Field not found!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( (fru_area == NULL ) || strlen((const char *)fru_area) == 0 ) {
|
if ( (fru_area == NULL ) || strlen((const char *)fru_area) == 0 ) {
|
||||||
printf("Field not found!\n");
|
printf("Field not found!\n");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user