xref: /openbmc/phosphor-mrw-tools/Inventory.pm (revision 5dd783bfab6c73851fa31d50e6184a9511f20bcd)
1bfd10b10SMatt Spinlerpackage Inventory;
2bfd10b10SMatt Spinler
3bfd10b10SMatt Spinleruse strict;
439a033bdSMatt Spinleruse warnings;
5bfd10b10SMatt Spinler
639a033bdSMatt Spinler#Target types to always include in the inventory if present
7123437f5SMatt Spinlermy %TYPES = (SYS => 1, NODE => 1, PROC => 1,
8*5dd783bfSMarri Devender Rao             BMC => 1, GPU => 1, CORE => 1, OCC => 1, TPM => 1);
939a033bdSMatt Spinler
1039a033bdSMatt Spinler#RU_TYPES of cards to include
1139a033bdSMatt Spinler#FRU = field replaceable unit, CRU = customer replaceable unit
1239a033bdSMatt Spinlermy %RU_TYPES = (FRU => 1, CRU => 1);
1339a033bdSMatt Spinler
14fe75964bSMatt Spinler#Chips that are modeled as modules (card-chip together)
15fe75964bSMatt Spinlermy %MODULE_TYPES = (PROC => 1, GPU => 1);
16fe75964bSMatt Spinler
1739a033bdSMatt Spinler#Returns an array of hashes that represents the inventory
1839a033bdSMatt Spinler#for a system.  The hash elements are:
1939a033bdSMatt Spinler#TARGET:  The MRW target of the item
2039a033bdSMatt Spinler#OBMC_NAME: The OpenBMC name for the item.  This is usually
2139a033bdSMatt Spinler#           a simplified version of the target.
22bfd10b10SMatt Spinlersub getInventory
23bfd10b10SMatt Spinler{
24bfd10b10SMatt Spinler    my $targetObj = shift;
25bfd10b10SMatt Spinler    my @inventory;
26bfd10b10SMatt Spinler
2739a033bdSMatt Spinler    if (ref($targetObj) ne "Targets") {
2839a033bdSMatt Spinler        die "Invalid Targets object passed to getInventory\n";
2939a033bdSMatt Spinler    }
3039a033bdSMatt Spinler
3139a033bdSMatt Spinler    findItems($targetObj, \@inventory);
3239a033bdSMatt Spinler
33fe75964bSMatt Spinler    pruneModuleCards($targetObj, \@inventory);
34fe75964bSMatt Spinler
35c119a903SMatt Spinler    makeOBMCNames($targetObj, \@inventory);
36c119a903SMatt Spinler
37bfd10b10SMatt Spinler    return @inventory;
38bfd10b10SMatt Spinler}
39bfd10b10SMatt Spinler
4039a033bdSMatt Spinler
4139a033bdSMatt Spinler#Finds the inventory targets in the MRW.
4239a033bdSMatt Spinler#It selects them if the target's type is in %TYPES
4339a033bdSMatt Spinler#or the target's RU_TYPE is in %RU_TYPES.
4439a033bdSMatt Spinler#This will pick up FRUs and other chips like the BMC and processor.
4539a033bdSMatt Spinlersub findItems
4639a033bdSMatt Spinler{
4739a033bdSMatt Spinler    my ($targetObj, $inventory) = @_;
4839a033bdSMatt Spinler
4939a033bdSMatt Spinler    for my $target (sort keys %{$targetObj->getAllTargets()}) {
5039a033bdSMatt Spinler        my $type = "";
5139a033bdSMatt Spinler        my $ruType = "";
5239a033bdSMatt Spinler
5339a033bdSMatt Spinler        if (!$targetObj->isBadAttribute($target, "TYPE")) {
5439a033bdSMatt Spinler            $type = $targetObj->getAttribute($target, "TYPE");
5539a033bdSMatt Spinler        }
5639a033bdSMatt Spinler
5739a033bdSMatt Spinler        if (!$targetObj->isBadAttribute($target, "RU_TYPE")) {
5839a033bdSMatt Spinler            $ruType = $targetObj->getAttribute($target, "RU_TYPE");
5939a033bdSMatt Spinler        }
6039a033bdSMatt Spinler
6139a033bdSMatt Spinler        if ((exists $TYPES{$type}) || (exists $RU_TYPES{$ruType})) {
6239a033bdSMatt Spinler            my %item;
6339a033bdSMatt Spinler            $item{TARGET} = $target;
6439a033bdSMatt Spinler            $item{OBMC_NAME} = $target; #Will fixup later
6539a033bdSMatt Spinler            push @$inventory, { %item };
6639a033bdSMatt Spinler        }
6739a033bdSMatt Spinler    }
6839a033bdSMatt Spinler}
6939a033bdSMatt Spinler
7039a033bdSMatt Spinler
71fe75964bSMatt Spinler#Removes entries from the inventory for the card target of a module.
72fe75964bSMatt Spinler#Needed because processors and GPUs are modeled as a package which
73fe75964bSMatt Spinler#is a card-chip instance that plugs into a connector on the
74fe75964bSMatt Spinler#backplane/processor card.  Since we already include the chip target
75fe75964bSMatt Spinler#in the inventory (that's how we can identify what it is), we don't
76fe75964bSMatt Spinler#need the entry for the card target.
77fe75964bSMatt Spinler#
78fe75964bSMatt Spinler#For example, we'll already have .../module-0/proc-0 so we don't
79fe75964bSMatt Spinler#need a separate .../module-0 entry.
80fe75964bSMatt Spinlersub pruneModuleCards
81fe75964bSMatt Spinler{
82fe75964bSMatt Spinler    my ($targetObj, $inventory) = @_;
83fe75964bSMatt Spinler    my @toRemove;
84fe75964bSMatt Spinler
85fe75964bSMatt Spinler    #Find the parent (a card) of items of type %type
86fe75964bSMatt Spinler    for my $item (@$inventory) {
87fe75964bSMatt Spinler
88fe75964bSMatt Spinler        if (exists $MODULE_TYPES{$targetObj->getType($item->{TARGET})}) {
89fe75964bSMatt Spinler            my $card = $targetObj->getTargetParent($item->{TARGET});
90fe75964bSMatt Spinler            push @toRemove, $card;
91fe75964bSMatt Spinler        }
92fe75964bSMatt Spinler    }
93fe75964bSMatt Spinler
94fe75964bSMatt Spinler    #Remove these parent cards
95fe75964bSMatt Spinler    for my $c (@toRemove) {
96fe75964bSMatt Spinler        for my $i (0 .. (scalar @$inventory) - 1) {
97fe75964bSMatt Spinler            if ($c eq $inventory->[$i]{TARGET}) {
98fe75964bSMatt Spinler                splice(@$inventory, $i, 1);
99fe75964bSMatt Spinler                last;
100fe75964bSMatt Spinler            }
101fe75964bSMatt Spinler        }
102fe75964bSMatt Spinler    }
103fe75964bSMatt Spinler}
104fe75964bSMatt Spinler
105c119a903SMatt Spinler
106c119a903SMatt Spinler#Makes the OpenBMC name for the targets in the inventory.
107c119a903SMatt Spinler#Removes unnecessary segments of the path name, renames
108c119a903SMatt Spinler#some segments to match standard conventions, and numbers
109c119a903SMatt Spinler#segments based on their position attribute.
110c119a903SMatt Spinlersub makeOBMCNames
111c119a903SMatt Spinler{
112c119a903SMatt Spinler    my ($targetObj, $inventory) = @_;
113c119a903SMatt Spinler
114c119a903SMatt Spinler    #Remove connector segments from the OBMC_NAME
115c119a903SMatt Spinler    removeConnectors($targetObj, $inventory);
116c119a903SMatt Spinler
1178fd594c0SMatt Spinler    #Don't need the card instance of a PROC/GPU module
1188fd594c0SMatt Spinler    removeModuleFromPath($targetObj, $inventory);
119f0942d1aSMatt Spinler
120f0942d1aSMatt Spinler    #Don't need card segments for non-FRUs
121f0942d1aSMatt Spinler    removeNonFRUCardSegments($targetObj, $inventory);
122cf32382dSMatt Spinler
123eff6a199SMatt Spinler    #Don't need to show the middle units between proc & core
124eff6a199SMatt Spinler    removeIntermediateUnits($targetObj, $inventory);
125eff6a199SMatt Spinler
126cf32382dSMatt Spinler    #Certain parts have standard naming
127cf32382dSMatt Spinler    renameSegmentWithType("PROC", "cpu", $targetObj, $inventory);
128cf32382dSMatt Spinler    renameSegmentWithType("SYS", "system", $targetObj, $inventory);
129cf32382dSMatt Spinler    renameSegmentWithType("NODE", "chassis", $targetObj, $inventory);
130cf32382dSMatt Spinler
131cf32382dSMatt Spinler    #Make sure the motherboard is called 'motherboard' in the OBMC_NAME.
132cf32382dSMatt Spinler    #The only way to identify it is with its TARGET_TYPE,
133cf32382dSMatt Spinler    #which is different than the regular type.
134cf32382dSMatt Spinler    renameSegmentWithTargetType("card-motherboard", "motherboard",
135cf32382dSMatt Spinler                                $targetObj, $inventory);
136306e4d1dSMatt Spinler
137306e4d1dSMatt Spinler    #Don't need instance numbers unless there are more than 1 present
138306e4d1dSMatt Spinler    removeInstNumIfOneInstPresent($inventory);
139306e4d1dSMatt Spinler
140306e4d1dSMatt Spinler    #We want card1, not card-1
141306e4d1dSMatt Spinler    removeHyphensFromInstanceNum($inventory);
1423c784b66SMatt Spinler
1433c784b66SMatt Spinler    pointChassisAtMotherboard($targetObj, $inventory);
144f0942d1aSMatt Spinler}
145f0942d1aSMatt Spinler
146f0942d1aSMatt Spinler
147f0942d1aSMatt Spinler#Removes non-FRU cards in the middle of a hierarchy from OBMC_NAME.
148f0942d1aSMatt Spinler#For example, .../motherboard/fanriser-0/fan-0 ->
149f0942d1aSMatt Spinler# .../motherboard/fan-0 when fanriser-0 isn't a FRU.
150f0942d1aSMatt Spinlersub removeNonFRUCardSegments
151f0942d1aSMatt Spinler{
152f0942d1aSMatt Spinler    my ($targetObj, $inventory) = @_;
153f0942d1aSMatt Spinler
154f0942d1aSMatt Spinler    for my $item (@$inventory) {
155f0942d1aSMatt Spinler
156f0942d1aSMatt Spinler        #Split the target into segments, then start
157f0942d1aSMatt Spinler        #adding segments in to make new targets so we can
158f0942d1aSMatt Spinler        #make API calls on the segment instances.
159f0942d1aSMatt Spinler        my @segments = split('/', $item->{TARGET});
160f0942d1aSMatt Spinler        my $target = "";
161f0942d1aSMatt Spinler        for my $s (@segments) {
162f0942d1aSMatt Spinler            next if (length($s) == 0);
163f0942d1aSMatt Spinler
164f0942d1aSMatt Spinler            $target .= "/$s";
165f0942d1aSMatt Spinler
166f0942d1aSMatt Spinler            my $class = $targetObj->getAttribute($target, "CLASS");
167f0942d1aSMatt Spinler            next if ($class ne "CARD");
168f0942d1aSMatt Spinler
169f0942d1aSMatt Spinler            my $ruType = $targetObj->getAttribute($target, "RU_TYPE");
170f0942d1aSMatt Spinler
171f0942d1aSMatt Spinler            #If this segment is a card but not a FRU,
172f0942d1aSMatt Spinler            #remove it from the path.
173f0942d1aSMatt Spinler            if (not exists $RU_TYPES{$ruType}) {
174f0942d1aSMatt Spinler                my $segment = $targetObj->getInstanceName($target);
175f0942d1aSMatt Spinler                $item->{OBMC_NAME} =~ s/\b$segment-\d+\b\///;
176f0942d1aSMatt Spinler            }
177f0942d1aSMatt Spinler        }
178f0942d1aSMatt Spinler    }
179c119a903SMatt Spinler}
180c119a903SMatt Spinler
181c119a903SMatt Spinler
182c119a903SMatt Spinler#Removes connectors from the OBMC_NAME element.  Also
183c119a903SMatt Spinler#takes the POSITION value of the connector and adds it
184c119a903SMatt Spinler#to the card segment that plugs into the connector.
185c119a903SMatt Spinler#For example:
186c119a903SMatt Spinler#  /motherboard/card-conn-5/card-0 ->
187c119a903SMatt Spinler#  /motherobard/card-5
188c119a903SMatt Spinlersub removeConnectors
189c119a903SMatt Spinler{
190c119a903SMatt Spinler    my ($targetObj, $inventory) = @_;
191c119a903SMatt Spinler
192c119a903SMatt Spinler    #Find the connectors embedded in the segments
193c119a903SMatt Spinler    for my $item (@$inventory) {
194c119a903SMatt Spinler
195c119a903SMatt Spinler        #Split the target into segments, then start
196c119a903SMatt Spinler        #adding segments in to make new targets
197c119a903SMatt Spinler        my @segments = split('/', $item->{TARGET});
198c119a903SMatt Spinler        my $target = "";
199c119a903SMatt Spinler        for my $s (@segments) {
200c119a903SMatt Spinler            next if (length($s) == 0);
201c119a903SMatt Spinler
202c119a903SMatt Spinler            $target .= "/$s";
203c119a903SMatt Spinler            my $class = $targetObj->getAttribute($target, "CLASS");
204c119a903SMatt Spinler            next unless ($class eq "CONNECTOR");
205c119a903SMatt Spinler
206c119a903SMatt Spinler            my ($segment) = $target =~ /\b(\w+-\d+)$/;
207c119a903SMatt Spinler            my $pos = $targetObj->getAttribute($target, "POSITION");
208c119a903SMatt Spinler
209c119a903SMatt Spinler            #change /connector-11/card-2/ to /card-11/
210c119a903SMatt Spinler            $item->{OBMC_NAME} =~ s/\b$segment\/(\w+)-\d+/$1-$pos/;
211c119a903SMatt Spinler
212c119a903SMatt Spinler        }
213c119a903SMatt Spinler    }
214c119a903SMatt Spinler}
215c119a903SMatt Spinler
2168fd594c0SMatt Spinler
217eff6a199SMatt Spinler#Units, typically cores, can be subunits of other subunits of
218eff6a199SMatt Spinler#their parent chip.  We can remove all of these intermediate
219eff6a199SMatt Spinler#units.  For example, cpu0/someunit1/someunit2/core3 ->
220eff6a199SMatt Spinler#cpu0/core3.
221eff6a199SMatt Spinlersub removeIntermediateUnits
222eff6a199SMatt Spinler{
223eff6a199SMatt Spinler    my ($targetObj, $inventory) = @_;
224eff6a199SMatt Spinler
225eff6a199SMatt Spinler    for my $item (@$inventory) {
226eff6a199SMatt Spinler
227eff6a199SMatt Spinler        my $class = $targetObj->getAttribute($item->{TARGET}, "CLASS");
228eff6a199SMatt Spinler        next unless ($class eq "UNIT");
229eff6a199SMatt Spinler
230eff6a199SMatt Spinler        my $parent = $targetObj->getTargetParent($item->{TARGET});
231eff6a199SMatt Spinler
232eff6a199SMatt Spinler        #Remove all of these intermediate units until we find
233eff6a199SMatt Spinler        #something that isn't a unit (most likely a chip).
234eff6a199SMatt Spinler        while ($targetObj->getAttribute($parent, "CLASS") eq "UNIT") {
235eff6a199SMatt Spinler
236eff6a199SMatt Spinler            my $name = $targetObj->getInstanceName($parent);
237eff6a199SMatt Spinler            $item->{OBMC_NAME} =~ s/$name(-)*(\d+)*\///;
238eff6a199SMatt Spinler
239eff6a199SMatt Spinler            $parent = $targetObj->getTargetParent($parent);
240eff6a199SMatt Spinler        }
241eff6a199SMatt Spinler    }
242eff6a199SMatt Spinler}
243eff6a199SMatt Spinler
244eff6a199SMatt Spinler
245cf32382dSMatt Spinler#Renames segments of the paths to the name passed in
246cf32382dSMatt Spinler#based on the type of the segment.
247cf32382dSMatt Spinler#For example:
248cf32382dSMatt Spinler# renameSegmentWithType("PROC", "cpu", ...);
249cf32382dSMatt Spinler# With a target of:
250cf32382dSMatt Spinler#   motherboard-0/myp9proc-5/core-3
251cf32382dSMatt Spinler# Where target motherboard-0/myp9proc-5 has a type
252cf32382dSMatt Spinler# of PROC, gives:
253cf32382dSMatt Spinler#   motherboard-0/cpu-5/core-3
254cf32382dSMatt Spinlersub renameSegmentWithType
255cf32382dSMatt Spinler{
256cf32382dSMatt Spinler    my ($type, $newSegment, $targetObj, $inventory) = @_;
257cf32382dSMatt Spinler
258cf32382dSMatt Spinler    #Find the targets for all the segments, and
259cf32382dSMatt Spinler    #if their type matches what we're looking for, then
260cf32382dSMatt Spinler    #save it so we can rename them later.
261cf32382dSMatt Spinler    for my $item (@$inventory) {
262cf32382dSMatt Spinler
263cf32382dSMatt Spinler        my @segments = split('/', $item->{TARGET});
264cf32382dSMatt Spinler        my $target = "";
265cf32382dSMatt Spinler
266cf32382dSMatt Spinler        for my $s (@segments) {
267cf32382dSMatt Spinler            next if (length($s) == 0);
268cf32382dSMatt Spinler
269cf32382dSMatt Spinler            $target .= "/$s";
270cf32382dSMatt Spinler            my $curType = $targetObj->getType($target);
271cf32382dSMatt Spinler            next unless ($curType eq $type);
272cf32382dSMatt Spinler
273cf32382dSMatt Spinler            my $oldSegment = $targetObj->getInstanceName($target);
274cf32382dSMatt Spinler            $item->{OBMC_NAME} =~ s/$oldSegment/$newSegment/;
275cf32382dSMatt Spinler        }
276cf32382dSMatt Spinler    }
277cf32382dSMatt Spinler}
278cf32382dSMatt Spinler
279cf32382dSMatt Spinler
2808fd594c0SMatt Spinler#Removes the card portion of a module from OBMC_NAME.
2818fd594c0SMatt Spinler#For example, .../motherboard-0/module-1/proc-0 ->
2828fd594c0SMatt Spinler#.../motherboard-0/proc-1.
2838fd594c0SMatt Spinler#This needs to be revisited if multi-processor modules
2848fd594c0SMatt Spinler#ever come into plan.
2858fd594c0SMatt Spinlersub removeModuleFromPath
2868fd594c0SMatt Spinler{
2878fd594c0SMatt Spinler    my ($targetObj, $inventory) = @_;
2888fd594c0SMatt Spinler    my %chipNames;
2898fd594c0SMatt Spinler
2908fd594c0SMatt Spinler    #Find the names of the chips on the modules
2918fd594c0SMatt Spinler    for my $item (@$inventory) {
2928fd594c0SMatt Spinler        if (exists $MODULE_TYPES{$targetObj->getType($item->{TARGET})}) {
2938fd594c0SMatt Spinler            $chipNames{$targetObj->getInstanceName($item->{TARGET})} = 1;
2948fd594c0SMatt Spinler        }
2958fd594c0SMatt Spinler    }
2968fd594c0SMatt Spinler
2978fd594c0SMatt Spinler    #Now convert module-A/name-B to name-A
2988fd594c0SMatt Spinler    #Note that the -B isn't always present
2998fd594c0SMatt Spinler    for my $item (@$inventory) {
3008fd594c0SMatt Spinler
3018fd594c0SMatt Spinler        for my $name (keys %chipNames) {
3028fd594c0SMatt Spinler            $item->{OBMC_NAME} =~ s/\w+-(\d+)\/$name(-\d+)*/$name-$1/;
3038fd594c0SMatt Spinler        }
3048fd594c0SMatt Spinler    }
3058fd594c0SMatt Spinler}
3068fd594c0SMatt Spinler
307cf32382dSMatt Spinler
308cf32382dSMatt Spinler#The same as renameSegmentWithType, but finds the segment
309cf32382dSMatt Spinler#to rename by calling Targets::getTargetType() on it
310cf32382dSMatt Spinler#instead of Targets::getType().
311cf32382dSMatt Spinlersub renameSegmentWithTargetType
312cf32382dSMatt Spinler{
313cf32382dSMatt Spinler    my ($type, $newSegment, $targetObj, $inventory) = @_;
314cf32382dSMatt Spinler
315cf32382dSMatt Spinler    for my $item (@$inventory) {
316cf32382dSMatt Spinler
317cf32382dSMatt Spinler        my @segments = split('/', $item->{TARGET});
318cf32382dSMatt Spinler        my $target = "";
319cf32382dSMatt Spinler
320cf32382dSMatt Spinler        for my $s (@segments) {
321cf32382dSMatt Spinler            next if (length($s) == 0);
322cf32382dSMatt Spinler
323cf32382dSMatt Spinler            $target .= "/$s";
324cf32382dSMatt Spinler            my $curType = $targetObj->getTargetType($target);
325cf32382dSMatt Spinler            next unless ($curType eq $type);
326cf32382dSMatt Spinler
327cf32382dSMatt Spinler            my $oldSegment = $targetObj->getInstanceName($target);
328cf32382dSMatt Spinler            $item->{OBMC_NAME} =~ s/$oldSegment/$newSegment/;
329cf32382dSMatt Spinler        }
330cf32382dSMatt Spinler    }
331cf32382dSMatt Spinler}
332cf32382dSMatt Spinler
333306e4d1dSMatt Spinler
3343c784b66SMatt Spinler#FRU management code needs the node/chassis item to point
3353c784b66SMatt Spinler#to the motherboard and not /system/chassis.  Can revisit this
3363c784b66SMatt Spinler#for multi-chassis systems if they ever show up.
3373c784b66SMatt Spinlersub pointChassisAtMotherboard
3383c784b66SMatt Spinler{
3393c784b66SMatt Spinler    my ($targetObj, $inventory) = @_;
3403c784b66SMatt Spinler    my $newName = undef;
3413c784b66SMatt Spinler
3423c784b66SMatt Spinler    for my $item (@$inventory) {
3433c784b66SMatt Spinler        my $type = $targetObj->getTargetType($item->{TARGET});
3443c784b66SMatt Spinler        if ($type eq "card-motherboard") {
3453c784b66SMatt Spinler            $newName = $item->{OBMC_NAME};
3463c784b66SMatt Spinler            last;
3473c784b66SMatt Spinler        }
3483c784b66SMatt Spinler    }
3493c784b66SMatt Spinler
3503c784b66SMatt Spinler    for my $item (@$inventory) {
3513c784b66SMatt Spinler        if ($targetObj->getType($item->{TARGET}) eq "NODE") {
3523c784b66SMatt Spinler            if (defined $newName) {
3533c784b66SMatt Spinler                $item->{OBMC_NAME} = $newName;
3543c784b66SMatt Spinler            }
3553c784b66SMatt Spinler            last;
3563c784b66SMatt Spinler        }
3573c784b66SMatt Spinler    }
3583c784b66SMatt Spinler}
3593c784b66SMatt Spinler
3603c784b66SMatt Spinler
361306e4d1dSMatt Spinler#Removes the instance number from the OBMC_NAME segments
362306e4d1dSMatt Spinler#where only 1 of those segments exists because numbering isn't
363306e4d1dSMatt Spinler#necessary to distinguish them.
364306e4d1dSMatt Spinlersub removeInstNumIfOneInstPresent
365306e4d1dSMatt Spinler{
366306e4d1dSMatt Spinler    my ($inventory) = @_;
367306e4d1dSMatt Spinler    my %instanceHash;
368306e4d1dSMatt Spinler
369306e4d1dSMatt Spinler    for my $item (@$inventory) {
370306e4d1dSMatt Spinler        #Look at all the segments, keeping track if we've
371306e4d1dSMatt Spinler        #seen a particular segment with the same instance before.
372306e4d1dSMatt Spinler        my @segments = split('/', $item->{OBMC_NAME});
373306e4d1dSMatt Spinler        for my $segment (@segments) {
374306e4d1dSMatt Spinler            my ($s, $inst) = $segment =~ /(\w+)-(\d+)/;
375306e4d1dSMatt Spinler            if (defined $s) {
376306e4d1dSMatt Spinler                if (not exists $instanceHash{$s}) {
377306e4d1dSMatt Spinler                    $instanceHash{$s}{inst} = $inst;
378306e4d1dSMatt Spinler                }
379306e4d1dSMatt Spinler                else {
380306e4d1dSMatt Spinler                    if ($instanceHash{$s}{inst} ne $inst) {
381306e4d1dSMatt Spinler                        $instanceHash{$s}{keep} = 1;
382306e4d1dSMatt Spinler                    }
383306e4d1dSMatt Spinler                }
384306e4d1dSMatt Spinler            }
385306e4d1dSMatt Spinler        }
386306e4d1dSMatt Spinler    }
387306e4d1dSMatt Spinler
388306e4d1dSMatt Spinler    #Remove the instanc numbers we don't need to keep.
389306e4d1dSMatt Spinler    for my $segment (keys %instanceHash) {
390306e4d1dSMatt Spinler        if (not exists $instanceHash{$segment}{keep}) {
391306e4d1dSMatt Spinler            for my $item (@$inventory) {
392306e4d1dSMatt Spinler               $item->{OBMC_NAME} =~ s/$segment-\d+/$segment/;
393306e4d1dSMatt Spinler            }
394306e4d1dSMatt Spinler        }
395306e4d1dSMatt Spinler    }
396306e4d1dSMatt Spinler}
397306e4d1dSMatt Spinler
398306e4d1dSMatt Spinler
399306e4d1dSMatt Spinler#Removes the '-' from between the segment name and instance.
400306e4d1dSMatt Spinlersub removeHyphensFromInstanceNum
401306e4d1dSMatt Spinler{
402306e4d1dSMatt Spinler    my ($inventory) = @_;
403306e4d1dSMatt Spinler
404306e4d1dSMatt Spinler    for my $item (@$inventory) {
405306e4d1dSMatt Spinler        $item->{OBMC_NAME} =~ s/-(\d+)\b/$1/g;
406306e4d1dSMatt Spinler    }
407306e4d1dSMatt Spinler}
408306e4d1dSMatt Spinler
409bfd10b10SMatt Spinler1;
410bfd10b10SMatt Spinler
411bfd10b10SMatt Spinler=head1 NAME
412bfd10b10SMatt Spinler
413bfd10b10SMatt SpinlerInventory
414bfd10b10SMatt Spinler
415bfd10b10SMatt Spinler=head1 DESCRIPTION
416bfd10b10SMatt Spinler
417bfd10b10SMatt SpinlerRetrieves the OpenBMC inventory from the MRW.
418bfd10b10SMatt Spinler
419bfd10b10SMatt SpinlerThe inventory contains:
420bfd10b10SMatt Spinler
421bfd10b10SMatt Spinler=over 4
422bfd10b10SMatt Spinler
423bfd10b10SMatt Spinler=item * The system target
424bfd10b10SMatt Spinler
425bfd10b10SMatt Spinler=item * The chassis target(s)  (Called a 'node' in the MRW.)
426bfd10b10SMatt Spinler
427bfd10b10SMatt Spinler=item * All targets of class CARD or CHIP that are FRUs.
428bfd10b10SMatt Spinler
429bfd10b10SMatt Spinler=item * All targets of type PROC
430bfd10b10SMatt Spinler
431eff6a199SMatt Spinler=item * All targets of type CORE
432eff6a199SMatt Spinler
433bfd10b10SMatt Spinler=item * All targets of type BMC
434bfd10b10SMatt Spinler
435bfd10b10SMatt Spinler=item * All targets of type GPU
436bfd10b10SMatt Spinler
437bfd10b10SMatt Spinler=back
438bfd10b10SMatt Spinler
439bfd10b10SMatt Spinler=head2 Notes:
440bfd10b10SMatt Spinler
441bfd10b10SMatt SpinlerThe processor and GPU chips are usually modeled in the MRW as a
442bfd10b10SMatt Spinlercard->chip package that would plug into a connector on the motherboard
443bfd10b10SMatt Spinleror other parent card.  So, even if both card and chip are marked as a FRU,
444bfd10b10SMatt Spinlerthere will only be 1 entry in the inventory for both, and the MRW
445bfd10b10SMatt Spinlertarget associated with it will be for the chip and not the card.
446bfd10b10SMatt Spinler
447bfd10b10SMatt SpinlerIn addition, this intermediate card will be removed from the path name:
448bfd10b10SMatt Spinler  /system/chassis/motheboard/cpu and not
449bfd10b10SMatt Spinler  /system/chassis/motherboard/cpucard/cpu
450bfd10b10SMatt Spinler
451bfd10b10SMatt Spinler=head2 Inventory naming conventions
452bfd10b10SMatt Spinler
453bfd10b10SMatt SpinlerThe inventory names returned in the OBMC_NAME hash element will follow
454bfd10b10SMatt Spinlerthe conventions listed below.  An example of an inventory name is:
455bfd10b10SMatt Spinler/system/chassis/motherboard/cpu5
456bfd10b10SMatt Spinler
457bfd10b10SMatt Spinler=over 4
458bfd10b10SMatt Spinler
459bfd10b10SMatt Spinler=item * If there is only 1 instance of any segment in the system, then
460bfd10b10SMatt Spinler        it won't have an instance number, otherwise there will be one.
461bfd10b10SMatt Spinler
462bfd10b10SMatt Spinler=item * The root of the name is '/system'.
463bfd10b10SMatt Spinler
464bfd10b10SMatt Spinler=item * After system is 'chassis', of which there can be 1 or more.
465bfd10b10SMatt Spinler
466bfd10b10SMatt Spinler=item * The name is based on the MRW card plugging order, and not what
467bfd10b10SMatt Spinler        the system looks like from the outside.  For example, a power
468bfd10b10SMatt Spinler        supply that plugs into a motherboard (maybe via a non-fru riser
469bfd10b10SMatt Spinler        or cable, see the item below), would be:
470bfd10b10SMatt Spinler        /system/chassis/motherboard/psu2 and not
471bfd10b10SMatt Spinler        /system/chassis/psu2.
472bfd10b10SMatt Spinler
473bfd10b10SMatt Spinler=item * If a card is not a FRU so isn't in the inventory itself, then it
474bfd10b10SMatt Spinler        won't show up in the name of any child cards that are FRUs.
475bfd10b10SMatt Spinler        For example, if fan-riser isn't a FRU, it would be
476bfd10b10SMatt Spinler        /system/chassis/motherboard/fan3 and not
477bfd10b10SMatt Spinler        /system/chassis/motherboard/fan-riser/fan3.
478bfd10b10SMatt Spinler
479bfd10b10SMatt Spinler=item * The MRW models connectors between cards, but these never show up
480bfd10b10SMatt Spinler        in the inventory name.
481bfd10b10SMatt Spinler
482bfd10b10SMatt Spinler=item * If there is a motherboard, it is always called 'motherboard'.
483bfd10b10SMatt Spinler
484bfd10b10SMatt Spinler=item * Processors, GPUs, and BMCs are always called: 'cpu', 'gpu' and
485bfd10b10SMatt Spinler        'bmc' respectively.
486bfd10b10SMatt Spinler
487bfd10b10SMatt Spinler=back
488bfd10b10SMatt Spinler
489bfd10b10SMatt Spinler=head1 METHODS
490bfd10b10SMatt Spinler
491bfd10b10SMatt Spinler=over 4
492bfd10b10SMatt Spinler
493bfd10b10SMatt Spinler=item getInventory (C<TargetsObj>)
494bfd10b10SMatt Spinler
495bfd10b10SMatt SpinlerReturns an array of hashes representing inventory items.
496bfd10b10SMatt Spinler
497bfd10b10SMatt SpinlerThe Hash contains:
498bfd10b10SMatt Spinler
499bfd10b10SMatt Spinler* TARGET: The MRW target of the item, for example:
500bfd10b10SMatt Spinler
501bfd10b10SMatt Spinler    /sys-0/node-0/motherboard-0/proc_socket-0/module-0/p9_proc_m
502bfd10b10SMatt Spinler
503bfd10b10SMatt Spinler* OBMC_NAME: The OpenBMC name of the item, for example:
504bfd10b10SMatt Spinler
505bfd10b10SMatt Spinler   /system/chassis/motherboard/cpu2
506bfd10b10SMatt Spinler
507bfd10b10SMatt Spinler=back
508bfd10b10SMatt Spinler
509bfd10b10SMatt Spinler=cut
510