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.
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.
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]
23 # Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 # Use is subject to license terms.
28 # The fan topologies can be quite complicated, but are ultimately regular. This
29 # perl file uses some simplified internal structures to generate an .xml file
30 # without the maintenance overhead.
37 # Master table of platforms.
41 # Galaxy 1/2 platforms.
43 # These systems have 2 fan-connector boards. Each fan-connector board has 3
44 # fan modules. Each fan module is an individual FRU. The fan-connector
45 # boards are also FRUs.
48 set
=> "Sun-Fire-X4100-Server|Sun-Fire-X4200-Server|" .
49 "Sun-Fire-X4100-M2|Sun-Fire-X4200-M2",
57 provider
=> "fac_prov_ipmi",
59 label
=> "FT %d FM %d",
60 entity_ref
=> "ft%d.fm%d.led",
61 entity_ref_nparams
=> 2,
62 fm_service_indctr
=> "ft%d.fm%d.led",
71 # These systems have 5 fan modules, with each fan module containing 2 fans.
72 # The FRUs for the individual fans are the containing fan module.
75 set
=> "Sun-Fire-X4500|Sun-Fire-X4540",
79 provider
=> "fac_prov_ipmi",
83 entity_ref
=> "FT%d/PRSNT,ft%d.prsnt",
84 entity_ref_nparams
=> 1,
85 fm_service_indctr
=> "FT%d/SVC,ft%d.service.led",
86 fm_ok2rm_indctr
=> "FT%d/OK,ft%d.ok2rm.led",
89 provider
=> "fac_prov_ipmi",
91 entity_ref
=> "FT%d/FAN%d/TACH,ft%d.f%d.speed",
92 entity_ref_nparams
=> 2,
99 # Fan Module/Fan topology for all G1N/G2N platforms.
101 # There are two fan boards, which are FRU's. Each fan board has
102 # 3 fan modules for a total of 6 fan modules, with each fan module
103 # containing 2 fans. The FRU's for the individual fans are the
104 # containing fan module.
106 # Unfortunately, the IPMI topology on these systems is rather broken, and
107 # all the SDRs that should be separate entities in fact refer to the same
108 # entity IDs. So we have to use the alternative 'entity_present' option
109 # using a single SDR record.
112 set
=> "Sun-Fire-X4240|Sun-Fire-X4440",
119 label
=> "FANBD%d FM%d",
122 provider
=> "fac_prov_ipmi",
123 entity_present
=> "FB%d/FM%d/PRSNT,fb%d.fm%d.prsnt",
124 fm_service_indctr
=> "FB%d/FM%d/SERVICE,fb%d.fm%d.led",
125 entity_ref_nparams
=> 2
130 provider
=> "fac_prov_ipmi",
131 entity_ref
=> "FB%d/FM%d/F%d/TACH,fb%d.fm%d.f%d.speed",
132 entity_present
=> "FB%d/FM%d/PRSNT,fb%d.fm%d.prsnt",
133 entity_ref_nparams
=> 3
140 # Fan Module/Fan topology for the Sun Fire X4600/X4600 M2 platforms.
142 # These systems have 4 fan assemblies with a single fan per assembly.
143 # Each fan assembly is a FRU. The fan assemblies have a service LED
144 # but no other indicators.
147 set
=> "Sun-Fire-X4600|Sun-Fire-X4600-M2",
151 provider
=> "fac_prov_ipmi",
155 entity_ref
=> "ft%d.fm0.prsnt",
156 entity_ref_nparams
=> 1,
157 fm_service_indctr
=> "ft%d.fm0.led"
163 # Fan Module/Fan topology for Sun Fire X4140.
165 # There are two fan boards, which are FRU's. The first fanboard has 4
166 # fanmodules (which are also FRU's). The second fan board has 3 fan
167 # modules. Each fanmodule contains two fans.
170 set
=> "Sun-Fire-X4140",
178 provider
=> "fac_prov_ipmi",
179 label
=> "FANBD%d FM%d",
182 fm_service_indctr
=> "FB%d/FM%d/SERVICE,fb%d.fm%d.led",
183 entity_ref_nparams
=> 2
186 provider
=> "fac_prov_ipmi",
189 entity_ref
=> "FB%d/FM%d/F%d/TACH,fb%d.fm%d.f%d.speed",
190 entity_ref_nparams
=> 3
196 # Fan Module/Fan topology for the Sun Fire X4150.
198 # There are two fan boards, which are FRU's. The first fanboard has 4
199 # fanmodules (which are also FRU's). The second fan board has 3 fan
200 # modules. Each fanmodule contains two fans.
203 set
=> "SUN-FIRE-X4150",
209 entity_present
=> "FB%d/PRSRNT"
211 label
=> "FANBD%d FM%d",
214 provider
=> "fac_prov_ipmi",
215 entity_ref
=> "FB%d/FM%d/PRSNT",
216 fm_service_indctr
=> "",
217 entity_ref_nparams
=> 2
222 provider
=> "fac_prov_ipmi",
223 entity_ref
=> "FB%d/FM%d/F%d/TACH",
224 entity_ref_nparams
=> 3
230 # Fan Module/Fan topology for Duradi 2U.
232 # There are two fan boards, which are FRU's. Both fanboards have 3
233 # fanmodules (which are also FRU's). Each fanmodule contains two fans.
236 set
=> "SUN-FIRE-X4250|SUN-FIRE-X4450",
242 entity_present
=> "FB%d/PRSRNT"
244 label
=> "FANBD%d FM%d",
247 provider
=> "fac_prov_ipmi",
248 entity_ref
=> "FB%d/FM%d/PRSNT",
249 fm_service_indctr
=> "",
250 entity_ref_nparams
=> 2
255 provider
=> "fac_prov_ipmi",
256 entity_ref
=> "FB%d/FM%d/F%d/TACH",
257 entity_ref_nparams
=> 3
265 # Process an entry in the topology list. We are passed the indentation level,
266 # the current topology array, the set list, and any pushed indices. This is
267 # called recursively.
271 my ($indent, $toporef, $set, @indices) = @_;
272 my @topo = @
$toporef;
273 my $level = shift @topo;
274 my $type = $#topo == -1 ?
"fan" : "fanmodule";
276 printf("%*s<range name='%s' min='%d' max='%d'>\n",
277 $indent, "", $type, 0, $level->{count
} - 1);
280 for (my $i = 0; $i < $level->{count
}; $i++) {
282 # Special case code for the 1U version of Durado and Duradi,
283 # both of which have an assymetric fan topology
285 last if ((($set eq "SUN-FIRE-X4150") || ($set eq "Sun-Fire-X4140"))
286 && ($type eq "fanmodule") && ($#indices == 0)
287 && ($indices[0] == 1) && ($i == 3));
291 printf("%*s<node instance='%d'>\n", $indent, "", $i);
295 # Facility enumerator
296 if ($level->{fac_enum
}) {
297 printf("%*s<fac-enum provider='",
299 printf($level->{provider
});
303 # Facility nodes for service and ok2rm LED's
304 if ($level->{fm_service_indctr
}) {
305 printf("%*s<facility name='service' type='indicator' ".
306 "provider='fac_prov_ipmi' >\n", $indent+2, "");
307 printf("%*s<propgroup name='facility' version='1' ".
308 "name-stability='Private' data-stability='Private' >\n",
310 printf("%*s<propval name='type' type='uint32' ".
311 "value='0' />\n", $indent+6, "");
312 printf("%*s<propmethod name='ipmi_entity' version='0' ".
313 "propname='entity_ref' proptype='string_array' >\n",
316 printf("%*s<argval name='format' type='string_array'>\n",
318 my @refs = split(/\,/, $level->{fm_service_indctr
});
319 foreach my $ref (@refs) {
320 printf("%*s<argitem value='", $indent+10, "");
321 printf($ref, @indices);
325 printf("%*s</argval>\n", $indent+8, "");
326 printf("%*s<argval name='offset' type='uint32' ".
327 "value='0' />\n", $indent+8, "");
328 printf("%*s<argval name='nparams' type='uint32' ".
329 "value='%d' />\n", $indent+8, "",
330 $level->{entity_ref_nparams
});
331 printf("%*s</propmethod>\n", $indent+6, "");
332 printf("%*s<propmethod name='ipmi_indicator_mode' ".
333 "version='0' propname='mode' proptype='uint32' ".
334 "mutable='1' >\n", $indent+6, "");
335 printf("%*s</propmethod>\n", $indent+6, "");
336 printf("%*s</propgroup>\n", $indent+4, "");
337 printf("%*s</facility>\n", $indent+2, "");
339 if ($level->{fm_ok2rm_indctr
}) {
340 printf("%*s<facility name='ok2rm' type='indicator' ".
341 "provider='fac_prov_ipmi' >\n", $indent+2, "");
342 printf("%*s<propgroup name='facility' version='1' ".
343 "name-stability='Private' data-stability='Private' >\n",
345 printf("%*s<propval name='type' type='uint32' ".
346 "value='2' />\n", $indent+6, "");
347 printf("%*s<propmethod name='ipmi_entity' version='0' ".
348 "propname='entity_ref' proptype='string_array' >\n",
351 printf("%*s<argval name='format' type='string_array'>\n",
353 my @refs = split(/\,/, $level->{fm_ok2rm_indctr
});
354 foreach my $ref (@refs) {
355 printf("%*s<argitem value='", $indent+10, "");
356 printf($ref, @indices);
359 printf("%*s</argval>\n", $indent+8, "");
360 printf("%*s<argval name='offset' type='uint32' ".
361 "value='0' />\n", $indent+8, "");
362 printf("%*s<argval name='nparams' type='uint32' ".
363 "value='%d' />\n", $indent+8, "",
364 $level->{entity_ref_nparams
});
365 printf("%*s</propmethod>\n", $indent+6, "");
366 printf("%*s<propmethod name='ipmi_indicator_mode' ".
367 "version='0' propname='mode' proptype='uint32' mutable='1' >\n",
369 printf("%*s</propmethod>\n", $indent+6, "");
370 printf("%*s</propgroup>\n", $indent+4, "");
371 printf("%*s</facility>\n", $indent+2, "");
374 # Protocol properties (label, fmri)
375 printf("%*s<propgroup name='protocol' version='1' " .
376 "name-stability='Private' data-stability='Private'>\n",
381 if ($level->{label
}) {
382 printf("%*s<propval name='label' type='string' " .
383 "value='", $indent, "");
384 printf($level->{label
}, @indices);
388 printf("%*s<propmethod name='ipmi_fru_fmri' " .
389 "version='0' propname='FRU' proptype='fmri'>\n",
391 printf("%*s<argval name='entity' type='string' " .
392 "value='%s' />\n", $indent + 2, "", $level->{fru
});
393 printf("%*s</propmethod>\n", $indent, "");
397 printf("%*s</propgroup>\n", $indent, "");
400 # Entity references (if any)
402 if ($level->{entity_ref
}) {
403 my $val = $level->{entity_ref
};
404 printf("%*s<propgroup name='ipmi' version='1' " .
405 "name-stability='Private' " .
406 "data-stability='Private' >\n", $indent, "");
408 printf("%*s<propval name='entity_ref' ".
409 "type='string_array'>\n", $indent + 2, "");
410 my @refs = split(/\,/, $val);
411 foreach my $ref (@refs) {
412 printf("%*s<propitem value='", $indent+4, "");
413 printf($ref, @indices);
416 printf("%*s</propval>\n", $indent+2, "");
417 printf("%*s</propgroup>\n", $indent, "");
419 if ($level->{entity_present
}) {
420 my $val = $level->{entity_present
};
421 printf("%*s<propgroup name='ipmi' version='1' " .
422 "name-stability='Private' " .
423 "data-stability='Private' >\n", $indent, "");
425 printf("%*s<propval name='entity_present' " .
426 "type='string_array'>\n", $indent + 2, "");
427 my @refs = split(/\,/, $val);
428 foreach my $ref (@refs) {
429 no warnings
'redundant';
430 printf("%*s<propitem value='", $indent+4, "");
431 printf($ref, @indices);
434 printf("%*s</propval>\n", $indent+4, "");
435 printf("%*s</propgroup>\n", $indent, "");
439 # Post-process IPMI enumerator method
441 printf("%*s<enum-method name='ipmi' version='1' ".
442 "/>\n", $indent, "");
448 printf("%*s<dependents grouping='children'>\n",
450 process_topology
($indent + 2, \
@topo, $set, @indices);
451 printf("%*s</dependents>\n", $indent, "");
456 printf("%*s</node>\n", $indent, "");
461 printf("%*s</range>\n", $indent, "");
465 # Process a single platform file.
472 printf("%*s<set type='product' setlist='%s'>\n", $indent, "",
475 process_topology
($indent + 2, $desc->{topology
}, $desc->{set
});
477 printf("%*s</set>\n", $indent, "");
480 print "<topology name='fan' scheme='hc'>\n";
483 foreach $desc (@platforms) {
484 process_platform
($desc);
487 print "</topology>\n";