-More FRU parsing updates (not hooked into any user-standard commands yet)

git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@2200 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
jbjohnso 2008-09-18 20:54:08 +00:00
parent 337cfe9d41
commit d4cc7055bc

View File

@ -2172,7 +2172,7 @@ sub frudump {
sub parsefru {
my $bytes = shift;
my $structure;
my $fruhash;
my $curridx; #store indexes as needed for convenience
my $currsize; #store current size
my $subidx;
@ -2200,7 +2200,7 @@ sub parsefru {
return "unknown-winternal",undef;
}
#capture slice of bytes
$structure->{internal}=[@{$bytes}[($bytes->[1]*8)..($bytes->[1]*8+$internal_size)]]; #,$bytes->[1]*8,$internal_size];
$fruhash->{internal}=[@{$bytes}[($bytes->[1]*8)..($bytes->[1]*8+$internal_size)]]; #,$bytes->[1]*8,$internal_size];
}
if ($bytes->[2]) { #Chassis info area, xCAT will preserve fields, not manipulate them
$curridx=$bytes->[2]*8;
@ -2209,16 +2209,204 @@ sub parsefru {
}
$currsize=($bytes->[$curridx+1])*8;
@currarea=@{$bytes}[$curridx..($curridx+$currsize)]; #splice @$bytes,$curridx,$currsize;
parsechassis(@currarea);
$fruhash->{chassis} = parsechassis(@currarea);
}
if ($bytes->[3]) { #Board info area, to be preserved
$curridx=$bytes->[3]*8;
unless ($bytes->[$curridx]==1) {
return "unknown-COULDGUESS",undef;
}
$currsize=($bytes->[$curridx+1])*8;
@currarea=@{$bytes}[$curridx..($curridx+$currsize)];
$fruhash->{board} = parseboard(@currarea);
}
if ($bytes->[4]) { #Product info area present, will probably be thoroughly modified
$curridx=$bytes->[4]*8;
unless ($bytes->[$curridx]==1) {
return "unknown-COULDGUESS",undef;
}
$currsize=($bytes->[$curridx+1])*8;
@currarea=@{$bytes}[$curridx..($curridx+$currsize)];
$fruhash->{product} = parseprod(@currarea);
}
if ($bytes->[5]) { #Generic multirecord present..
$fruhash->{extra}=[];
my $last=0;
$curridx=$bytes->[5]*8;
my $currsize;
while (not $last) {
if ($bytes->[$curridx+1] & 128) {
$last=1;
}
$currsize=$bytes->[$curridx+2];
push @{$fruhash->{extra}},$bytes->[$curridx..$curridx+4+$currsize];
}
}
print Dumper($fruhash->{extra});
}
sub parseprod {
my @area = @_;
my %info;
my $language=$area[2];
my $idx=3;
my $currsize;
my $currdata;
my $encode;
($currsize,$currdata,$encode)=extractfield(\@area,$idx);
unless ($currsize) {
return \%info;
}
$idx+=$currsize;
if ($currsize>1) {
$info{manufacturer}->{encoding}=$encode;
$info{manufacturer}->{value}=$currdata;
}
($currsize,$currdata,$encode)=extractfield(\@area,$idx);
unless ($currsize) {
return \%info;
}
$idx+=$currsize;
if ($currsize>1) {
$info{product}->{encoding}=$encode;
$info{product}->{value}=$currdata;
}
($currsize,$currdata,$encode)=extractfield(\@area,$idx);
unless ($currsize) {
return \%info;
}
$idx+=$currsize;
if ($currsize>1) {
$info{model}->{encoding}=$encode;
$info{model}->{value}=$currdata;
}
($currsize,$currdata,$encode)=extractfield(\@area,$idx);
unless ($currsize) {
return \%info;
}
$idx+=$currsize;
if ($currsize>1) {
$info{version}->{encoding}=$encode;
$info{version}->{value}=$currdata;
}
($currsize,$currdata,$encode)=extractfield(\@area,$idx);
unless ($currsize) {
return \%info;
}
$idx+=$currsize;
if ($currsize>1) {
$info{serialnumber}->{encoding}=$encode;
$info{serialnumber}->{value}=$currdata;
}
($currsize,$currdata,$encode)=extractfield(\@area,$idx);
unless ($currsize) {
return \%info;
}
$idx+=$currsize;
if ($currsize>1) {
$info{asset}->{encoding}=$encode;
$info{asset}->{value}=$currdata;
}
($currsize,$currdata,$encode)=extractfield(\@area,$idx);
unless ($currsize) {
return \%info;
}
$idx+=$currsize;
if ($currsize>1) {
$info{fruid}->{encoding}=$encode;
$info{fruid}->{value}=$currdata;
}
($currsize,$currdata,$encode)=extractfield(\@area,$idx);
if ($currsize) {
$info{extra}=[];
}
while ($currsize>0) {
if ($currsize>1) {
push @{$info{extra}},{value=>$currdata,encodng=>$encode};
}
$idx+=$currsize;
($currsize,$currdata,$encode)=extractfield(\@area,$idx);
}
return \%info;
}
sub parseboard {
my @area = @_;
my %boardinf;
my $idx=6;
my $language=$area[2];
my $tstamp = ($area[3]+($area[4]<<8)+($area[5]<<16))*60+820472400; #820472400 is meant to be 1/1/1996
$boardinf{raw}=[@area]; #store for verbatim replacement
$boardinf{builddate}=scalar localtime($tstamp);
my $encode;
my $currsize;
my $currdata;
($currsize,$currdata,$encode)=extractfield(\@area,$idx);
unless ($currsize) {
return \%boardinf;
}
$idx+=$currsize;
if ($currsize>1) {
$boardinf{manufacturer}->{encoding}=$encode;
$boardinf{manufacturer}->{value}=$currdata;
}
($currsize,$currdata,$encode)=extractfield(\@area,$idx);
unless ($currsize) {
return \%boardinf;
}
$idx+=$currsize;
if ($currsize>1) {
$boardinf{name}->{encoding}=$encode;
$boardinf{name}->{value}=$currdata;
}
($currsize,$currdata,$encode)=extractfield(\@area,$idx);
unless ($currsize) {
return \%boardinf;
}
$idx+=$currsize;
if ($currsize>1) {
$boardinf{serialnumber}->{encoding}=$encode;
$boardinf{serialnumber}->{value}=$currdata;
}
($currsize,$currdata,$encode)=extractfield(\@area,$idx);
unless ($currsize) {
return \%boardinf;
}
$idx+=$currsize;
if ($currsize>1) {
$boardinf{partnumber}->{encoding}=$encode;
$boardinf{partnumber}->{value}=$currdata;
}
($currsize,$currdata,$encode)=extractfield(\@area,$idx);
unless ($currsize) {
return \%boardinf;
}
$idx+=$currsize;
if ($currsize>1) {
$boardinf{fruid}->{encoding}=$encode;
$boardinf{fruid}->{value}=$currdata;
}
($currsize,$currdata,$encode)=extractfield(\@area,$idx);
if ($currsize) {
$boardinf{extra}=[];
}
while ($currsize>0) {
if ($currsize>1) {
push @{$boardinf{extra}},{value=>$currdata,encodng=>$encode};
}
$idx+=$currsize;
($currsize,$currdata,$encode)=extractfield(\@area,$idx);
}
return \%boardinf;
}
sub parsechassis {
my @chassarea=@_;
my %chassisinf;
my $currsize;
my $currdata;
my $idx=3;
my $encode;
$chassisinf{raw}=[@chassarea]; #store for verbatim replacement
$chassisinf{type}="unknown";
if ($chassis_types{$chassarea[2]}) {
$chassisinf{type}=$chassis_types{$chassarea[2]};
@ -2226,36 +2414,64 @@ sub parsechassis {
if ($chassarea[$idx] == 0xc1) {
return \%chassisinf;
}
if ($chassarea[$idx++] & 0b00111111) {
$currsize=$chassarea[3] & 0b00111111;
$chassisinf{partenc}=($chassarea[3] & 0b11000000)>>6;
if ($chassisinf{partenc}==3) {
$chassisinf{partnum}=getascii(@chassarea[$idx..($idx+$currsize-1)]);
} else { #preserve the raw bytes that we don't understand
$chassisinf{partnum}=[@chassarea[$idx..($idx+$currsize-1)]];
}
$idx=$idx+$currsize; #advance index to next candidate field, chassis serial #
($currsize,$currdata,$encode)=extractfield(\@chassarea,$idx);
unless ($currsize) {
return \%chassisinf;
}
$idx+=$currsize;
if ($currsize>1) {
$chassisinf{partnumber}->{encoding}=$encode;
$chassisinf{partnumber}->{value}=$currdata;
}
if ($chassarea[$idx] == 0xc1) {
($currsize,$currdata,$encode)=extractfield(\@chassarea,$idx);
unless ($currsize) {
return \%chassisinf;
}
if ($chassarea[$idx++] & 0b00111111) {
$currsize=$chassarea[$idx-1] & 0b00111111;
$chassisinf{serialenc}=($chassarea[$idx-1] & 0b11000000)>>6;
if ($chassisinf{serialenc}==3) {
$chassisinf{serialnum}=getascii(@chassarea[$idx..($currsize+$idx-1)]);
} else {
$chassisinf{serialnum}=[@chassarea[$idx..($currsize+$idx-1)]];
$idx+=$currsize;
if ($currsize>1) {
$chassisinf{serialnumber}->{encoding}=$encode;
$chassisinf{serialnumber}->{value}=$currdata;
}
($currsize,$currdata,$encode)=extractfield(\@chassarea,$idx);
if ($currsize) {
$chassisinf{extra}=[];
}
while ($currsize>0) {
if ($currsize>1) {
push @{$chassisinf{extra}},{value=>$currdata,encodng=>$encode};
}
$idx=$idx+$currsize;
}
if ($chassarea[$idx] == 0xc1) {
return \%chassisinf;
} else {
die "Malformed FRU area";
$idx+=$currsize;
($currsize,$currdata,$encode)=extractfield(\@chassarea,$idx);
}
return \%chassisinf;
}
sub extractfield { #idx is location of the type/length byte, returns something appropriate
my $area = shift;
my $idx = shift;
my $language=shift;
my $data;
my $size = $area->[$idx] & 0b00111111;
my $encoding = ($area->[$idx] & 0b11000000)>>6;
unless ($size) {
return 1,undef,undef;
}
if ($size==1 && $encoding==3) {
return 0,'','';
}
if ($encoding==3) {
$data=getascii(@$area[$idx+1..$size+$idx]);
} else {
$data = [@$area[$idx+1..$size+$idx]];
}
return $size+1,$data,$encoding;
}
sub writefru {
my $netfun = 0x28; # Storage (0x0A << 2)
my @cmd=(0x10,0);
@ -4786,7 +5002,7 @@ sub getascii {
} else {
$alpha[$c]=" ";
}
if($alpha[$c] !~ /[\/\w\-:]/) {
if($alpha[$c] !~ /[\/\w\-:\[\]]/) {
if ($alpha[($c-1)] !~ /\s/) {
$alpha[$c] = " ";
} else {