xref: /illumos-gate/usr/src/lib/fm/topo/maps/i86pc/fan-hc-topology.xmlgen (revision 7f606acec863be28b51fb0f694ca86b41ca76e6d)
1#!/usr/bin/perl -w
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10# or http://www.opensolaris.org/os/licensing.
11# See the License for the specific language governing permissions
12# and limitations under the License.
13#
14# When distributing Covered Code, include this CDDL HEADER in each
15# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16# If applicable, add the following below this CDDL HEADER, with the
17# fields enclosed by brackets "[]" replaced with your own identifying
18# information: Portions Copyright [yyyy] [name of copyright owner]
19#
20# CDDL HEADER END
21#
22#
23# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24# Use is subject to license terms.
25#
26#ident	"%Z%%M%	%I%	%E% SMI"
27
28#
29# The fan topologies can be quite complicated, but are ultimately regular.  This
30# perl file uses some simplified internal structures to generate an .xml file
31# without the maintenance overhead.
32#
33
34use Getopt::Std;
35use strict;
36
37#
38# Master table of platforms.
39#
40my @platforms = (
41    #
42    # Galaxy 1/2 platforms.
43    #
44    # These systems have 2 fan-connector boards.  Each fan-connector board has 3
45    # fan modules.  Each fan module is an individual FRU.  The fan-connector
46    # boards are also FRUs.
47    #
48    {
49	set => "Sun-Fire-X4100-Server|Sun-Fire-X4200-Server|" .
50	    "Sun-Fire-X4100-M2|Sun-Fire-X4200-M2",
51	topology => [
52	    {
53		label => "FT %d",
54		count => 2,
55		fru => "self"
56	    }, {
57	        fac_enum => 1,
58		provider => "fac_prov_ipmi",
59		count => 3,
60		label => "FT %d FM %d",
61		entity_ref => "ft%d.fm%d.led",
62		entity_ref_nparams => 2,
63		fm_service_indctr => "ft%d.fm%d.led",
64		fru => "self"
65	    }
66	]
67    },
68
69    #
70    # Thumper platforms
71    #
72    # These systems have 5 fan modules, with each fan module containing 2 fans.
73    # The FRUs for the individual fans are the containing fan module.
74    #
75    {
76	set => "Sun-Fire-X4500|Sun-Fire-X4540",
77	topology => [
78	    {
79	        fac_enum => 0,
80		provider => "fac_prov_ipmi",
81		label => "FT %d",
82		count => 5,
83		fru => "self",
84		entity_ref => "ft%d.prsnt",
85		entity_ref_nparams => 1,
86		fm_service_indctr => "ft%d.service.led",
87		fm_ok2rm_indctr => "ft%d.ok2rm.led",
88	    }, {
89	        fac_enum => 1,
90		provider => "fac_prov_ipmi",
91		count => 2,
92		entity_ref => "ft%d.f%d.speed",
93		entity_ref_nparams => 2,
94		fru => "parent"
95	    }
96	]
97    },
98
99    #
100    # Fan Module/Fan topology for all G1N/G2N platforms.
101    #
102    # There are two fan boards, which are FRU's.  Each fan board has
103    # 3 fan modules for a total of 6 fan modules, with each fan module
104    # containing 2 fans.  The FRU's for the individual fans are the
105    # containing fan module.
106    #
107    # Unfortunately, the IPMI topology on these systems is rather broken, and
108    # all the SDRs that should be separate entities in fact refer to the same
109    # entity IDs.  So we have to use the alternative 'entity_present' option
110    # using a single SDR record.
111    #
112    {
113	set => "Sun-Fire-X4240|Sun-Fire-X4440",
114	topology => [
115	    {
116		count => 2,
117		label => "FANBD%d",
118		fru => "self"
119	    }, {
120		fac_enum => 1,
121		provider => "fac_prov_ipmi",
122		label => "FANBD%d FM%d",
123		count => 3,
124		fru => "self",
125		entity_present => "fb%d.fm%d.prsnt",
126		entity_ref => "fb%d.fm%d.prsnt",
127		entity_ref_nparams => 2,
128		fm_service_indctr=> "fb%d.fm%d.led",
129	    }, {
130		count => 2,
131		fru => "parent"
132	    }
133
134	]
135    },
136
137    #
138    # Fan Module/Fan topology for G4F platforms.
139    #
140    # These systems have 4 fan assemblies with a single fan per assembly.
141    # Each fan assembly is a FRU.  The fan assemblies have a service LED
142    # but no other indicators.
143    #
144    {
145	set => "Sun-Fire-X4600-M2",
146	topology => [
147	    {
148	        fac_enum => 1,
149		provider => "fac_prov_ipmi",
150		count => 4,
151		label => "FT %d",
152		fru => "self",
153		entity_ref => "ft%d.fm0.prsnt",
154		entity_ref_nparams => 1,
155		fm_service_indctr => "ft%d.fm0.led"
156	    }
157	]
158    }
159);
160
161#
162# Process an entry in the topology list.  We are passed the indentation level,
163# the current topology array, and any pushed indices.  This is called
164# recursively.
165#
166sub process_topology
167{
168	my ($indent, $toporef, @indices) = @_;
169	my @topo = @$toporef;
170	my $level = shift @topo;
171	my $type = $#topo == -1 ? "fan" : "fanmodule";
172
173	printf("%*s<range name='%s' min='%d' max='%d'>\n",
174	    $indent, "", $type, 0, $level->{count} - 1);
175	$indent += 2;
176
177	for (my $i = 0; $i < $level->{count}; $i++) {
178		push @indices, $i;
179
180		printf("%*s<node instance='%d'>\n", $indent, "", $i);
181
182		$indent += 2;
183
184		# Facility enumerator
185		if ($level->{fac_enum}) {
186			printf("%*s<fac-enum provider='",
187			    $indent, "");
188			printf($level->{provider}, @indices);
189			printf("' />\n");
190		}
191
192		# Facility nodes for service and ok2rm LED's
193		if ($level->{fm_service_indctr}) {
194			printf("%*s<facility name='service' type='indicator' ".
195			    "provider='fac_prov_ipmi' >\n", $indent+2, "");
196			printf("%*s<propgroup name='facility' version='1' ".
197			    "name-stability='Private' data-stability='Private' >\n",
198			    $indent+4, "");
199			printf("%*s<propval name='type' type='uint32' ".
200			    "value='1' />\n", $indent+6, "");
201			printf("%*s<propmethod name='ipmi_entity' version='0' ".
202			    "propname='entity_ref' proptype='string' >\n",
203			    $indent+6, "");
204			printf("%*s<argval name='format' type='string' ".
205			    "value='%s' />\n", $indent+8, "",
206			    $level->{fm_service_indctr});
207			printf("%*s<argval name='offset' type='uint32' ".
208			    "value='0' />\n", $indent+8, "");
209			printf("%*s<argval name='nparams' type='uint32' ".
210			    "value='%d' />\n", $indent+8, "",
211			    $level->{entity_ref_nparams});
212			printf("%*s</propmethod>\n", $indent+6, "");
213			printf("%*s<propmethod name='ipmi_indicator_mode' ".
214			    "version='0' propname='mode' proptype='uint32' ".
215			    "mutable='1' >\n", $indent+6, "");
216			printf("%*s</propmethod>\n", $indent+6, "");
217			printf("%*s</propgroup>\n", $indent+4, "");
218			printf("%*s</facility>\n", $indent+2, "");
219		}
220		if ($level->{fm_ok2rm_indctr}) {
221			printf("%*s<facility name='ok2rm' type='indicator' ".
222			    "provider='fac_prov_ipmi' >\n", $indent+2, "");
223			printf("%*s<propgroup name='facility' version='1' ".
224			    "name-stability='Private' data-stability='Private' >\n",
225			    $indent+4, "");
226			printf("%*s<propval name='type' type='uint32' ".
227			    "value='2' />\n", $indent+6, "");
228			printf("%*s<propmethod name='ipmi_entity' version='0' ".
229			    "propname='entity_ref' proptype='string' >\n",
230			    $indent+6, "");
231			printf("%*s<argval name='format' type='string' ".
232			    "value='%s' />\n", $indent+8, "",
233			    $level->{fm_ok2rm_indctr});
234			printf("%*s<argval name='offset' type='uint32' ".
235			    "value='0' />\n", $indent+8, "");
236			printf("%*s<argval name='nparams' type='uint32' ".
237			    "value='%d' />\n", $indent+8, "",
238			    $level->{entity_ref_nparams});
239			printf("%*s</propmethod>\n", $indent+6, "");
240			printf("%*s<propmethod name='ipmi_indicator_mode' ".
241			    "version='0' propname='mode' proptype='uint32' mutable='1' >\n",
242			    $indent+6, "");
243			printf("%*s</propmethod>\n", $indent+6, "");
244			printf("%*s</propgroup>\n", $indent+4, "");
245			printf("%*s</facility>\n", $indent+2, "");
246		}
247
248		# Protocol properties (label, fmri)
249		printf("%*s<propgroup name='protocol' version='1' " .
250		    "name-stability='Private' data-stability='Private'>\n",
251		    $indent, "");
252
253		$indent += 2;
254
255		if ($level->{label}) {
256			printf("%*s<propval name='label' type='string' " .
257			    "value='", $indent, "");
258			printf($level->{label}, @indices);
259			printf("' />\n");
260		}
261
262		printf("%*s<propmethod name='ipmi_fru_fmri' " .
263		    "version='0' propname='FRU' proptype='fmri'>\n",
264		    $indent, "");
265		printf("%*s<argval name='entity' type='string' " .
266		    "value='%s' />\n", $indent + 2, "", $level->{fru});
267		printf("%*s</propmethod>\n", $indent, "");
268
269		$indent -= 2;
270
271		printf("%*s</propgroup>\n", $indent, "");
272
273		#
274		# Entity references (if any)
275		#
276		if ($level->{entity_ref} || $level->{entity_present}) {
277			my $name = $level->{entity_ref} ? "entity_ref" :
278			    "entity_present";
279			my $val = $level->{$name};
280			printf("%*s<propgroup name='ipmi' version='1' " .
281			    "name-stability='Private' " .
282			    "data-stability='Private' >\n", $indent, "");
283			printf("%*s<propval name='%s' " .
284			    "type='string' value='", $indent + 2, "", $name);
285			printf($val, @indices);
286			printf("' />\n");
287			printf("%*s</propgroup>\n", $indent, "");
288		}
289
290		#
291		# Post-process IPMI enumerator method
292		#
293		if ($level->{provider}) {
294			printf("%*s<enum-method name='ipmi' version='1' ".
295			    "/>\n", $indent, "");
296		}
297
298		#
299		# Children (if any)
300		#
301		if ($#topo != -1) {
302			printf("%*s<dependents grouping='children'>\n",
303			    $indent, "");
304			process_topology($indent + 2, \@topo, @indices);
305			printf("%*s</dependents>\n", $indent, "");
306		}
307
308		$indent -= 2;
309
310		printf("%*s</node>\n", $indent, "");
311		pop @indices;
312	}
313
314	$indent -= 2;
315	printf("%*s</range>\n", $indent, "");
316}
317
318#
319# Process a single platform file.
320#
321sub process_platform
322{
323	my ($desc) = @_;
324	my $indent = 2;
325
326	printf("%*s<set type='product' setlist='%s'>\n", $indent, "",
327	    $desc->{set});
328
329	process_topology($indent + 2, $desc->{topology});
330
331	printf("%*s</set>\n", $indent, "");
332}
333
334print "<topology name='fan' scheme='hc'>\n";
335
336my $desc;
337foreach $desc (@platforms) {
338	process_platform($desc);
339}
340
341print "</topology>\n";
342