dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / libprtdiag / common / kstat.c
blobe4150c17bd80c43485c8c124e091db96075df8ba
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * 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]
20 * CDDL HEADER END
23 * Copyright (c) 1999 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <ctype.h>
33 #include <string.h>
34 #include <kvm.h>
35 #include <varargs.h>
36 #include <errno.h>
37 #include <time.h>
38 #include <dirent.h>
39 #include <fcntl.h>
40 #include <sys/param.h>
41 #include <sys/stat.h>
42 #include <sys/types.h>
43 #include <sys/utsname.h>
44 #include <sys/openpromio.h>
45 #include <kstat.h>
46 #include <libintl.h>
47 #include <syslog.h>
48 #include <sys/dkio.h>
49 #include "pdevinfo.h"
50 #include "display.h"
51 #include "pdevinfo_sun4u.h"
52 #include "display_sun4u.h"
53 #include "libprtdiag.h"
56 * This module does the reading and interpreting of sun4u system
57 * kstats. These kstats are created by the following drivers:
58 * fhc, environ, sysctrl. Each board in the tree should have
59 * kstats created for it. There are also system wide kstats that
60 * are created.
62 void
63 read_platform_kstats(Sys_tree *tree, struct system_kstat_data *sys_kstat,
64 struct bd_kstat_data *bdp, struct envctrl_kstat_data *ep)
66 Board_node *bnode;
67 kstat_ctl_t *kc;
68 kstat_t *ksp;
69 kstat_named_t *knp;
70 int i;
71 struct hp_info *hp;
73 if ((kc = kstat_open()) == NULL) {
74 return;
77 /* For each board in the system, read the kstats for it. */
78 for (bnode = tree->bd_list; bnode != NULL; bnode = bnode->next) {
79 int board;
82 * Kstat instances numbers are set by fhc, ac, simmstat,
83 * and environ drivers based on their board# property.
85 board = bnode->board_num;
86 bdp = &sys_kstat->bd_ksp_list[board];
88 /* Try to find an FHC instance for this board number */
89 ksp = kstat_lookup(kc, UNIX, board, FHC_KSTAT_NAME);
91 /* Atempt to read the FHC kstat */
92 if ((ksp != NULL) && (kstat_read(kc, ksp, NULL) == -1)) {
93 ksp = NULL;
96 /* Now read out the data if the kstat read OK */
97 if (ksp != NULL) {
99 * We set the kstats_ok flag to good here. If we
100 * fail one of the data reads, we set it to bad.
102 bdp->fhc_kstats_ok = 1;
105 * For each data value, If the Kstat named struct
106 * is found, then get the data out.
108 knp = kstat_data_lookup(ksp, CSR_KSTAT_NAMED);
109 if (knp != NULL) {
110 bdp->fhc_csr = knp->value.ul;
111 } else {
112 bdp->fhc_kstats_ok = 0;
114 knp = kstat_data_lookup(ksp, BSR_KSTAT_NAMED);
115 if (knp != NULL) {
116 bdp->fhc_bsr = knp->value.ul;
117 } else {
118 bdp->fhc_kstats_ok = 0;
122 /* Try to find an AC instance for this board number */
123 ksp = kstat_lookup(kc, UNIX, board, AC_KSTAT_NAME);
125 /* Attempt to read the AC kstat. */
126 if ((ksp != NULL) && (kstat_read(kc, ksp, NULL) == -1)) {
127 ksp = NULL;
130 /* If the AC kstat exists, try to read the data from it. */
131 if (ksp != NULL) {
133 * We set the kstats_ok flag to good here. If we
134 * fail one of the data reads, we set it to bad.
136 bdp->ac_kstats_ok = 1;
137 bdp->ac_memstat_ok = 1;
140 * For each data value, If the Kstat named struct
141 * is found, then get the data out.
144 knp = kstat_data_lookup(ksp, MEMCTL_KSTAT_NAMED);
145 if (knp != NULL) {
146 bdp->ac_memctl = knp->value.ull;
147 } else {
148 bdp->ac_kstats_ok = 0;
151 knp = kstat_data_lookup(ksp, MEMDECODE0_KSTAT_NAMED);
152 if (knp != NULL) {
153 bdp->ac_memdecode[0] = knp->value.ull;
154 } else {
155 bdp->ac_kstats_ok = 0;
158 knp = kstat_data_lookup(ksp, MEMDECODE1_KSTAT_NAMED);
159 if (knp != NULL) {
160 bdp->ac_memdecode[1] = knp->value.ull;
161 } else {
162 bdp->ac_kstats_ok = 0;
165 knp = kstat_data_lookup(ksp, BANK_0_KSTAT_NAMED);
166 if (knp != NULL) {
167 bdp->mem_stat[0].status = knp->value.c[0];
168 bdp->mem_stat[0].condition = knp->value.c[1];
169 } else {
170 bdp->ac_memstat_ok = 0;
173 knp = kstat_data_lookup(ksp, BANK_1_KSTAT_NAMED);
174 if (knp != NULL) {
175 bdp->mem_stat[1].status = knp->value.c[0];
176 bdp->mem_stat[1].condition = knp->value.c[1];
177 } else {
178 bdp->ac_memstat_ok = 0;
183 /* Try to find an simmstat instance for this board number */
184 ksp = kstat_lookup(kc, UNIX, board, SIMMSTAT_KSTAT_NAME);
186 if (ksp != NULL) {
187 if (kstat_read(kc, ksp, NULL) == -1) {
188 bdp->simmstat_kstats_ok = 0;
189 } else {
190 bdp->simmstat_kstats_ok = 1;
191 (void) memcpy(&bdp->simm_status, ksp->ks_data,
192 sizeof (bdp->simm_status));
196 /* Try to find an overtemp kstat instance for this board */
197 ksp = kstat_lookup(kc, UNIX, board, OVERTEMP_KSTAT_NAME);
199 if (ksp != NULL) {
200 if (kstat_read(kc, ksp, NULL) == -1) {
201 bdp->temp_kstat_ok = 0;
202 } else {
203 bdp->temp_kstat_ok = 1;
204 (void) memcpy(&bdp->tempstat, ksp->ks_data,
205 sizeof (bdp->tempstat));
206 /* XXX - this is for 2.5.1 testing. remove */
207 if (sizeof (bdp->tempstat) > ksp->ks_data_size)
208 bdp->tempstat.trend = TREND_UNKNOWN;
213 /* Read the kstats for the system control board */
214 ksp = kstat_lookup(kc, UNIX, 0, SYSCTRL_KSTAT_NAME);
216 if ((ksp != NULL) && (kstat_read(kc, ksp, NULL) == -1)) {
217 sys_kstat->sys_kstats_ok = 0;
218 ksp = NULL;
221 if (ksp != NULL) {
222 sys_kstat->sys_kstats_ok = 1;
224 knp = kstat_data_lookup(ksp, CSR_KSTAT_NAMED);
225 if (knp != NULL) {
226 sys_kstat->sysctrl = knp->value.c[0];
227 } else {
228 sys_kstat->sys_kstats_ok = 0;
231 knp = kstat_data_lookup(ksp, STAT1_KSTAT_NAMED);
232 if (knp != NULL) {
233 sys_kstat->sysstat1 = knp->value.c[0];
234 } else {
235 sys_kstat->sys_kstats_ok = 0;
238 knp = kstat_data_lookup(ksp, STAT2_KSTAT_NAMED);
239 if (knp != NULL) {
240 sys_kstat->sysstat2 = knp->value.c[0];
241 } else {
242 sys_kstat->sys_kstats_ok = 0;
245 knp = kstat_data_lookup(ksp, CLK_FREQ2_KSTAT_NAMED);
246 if (knp != NULL) {
247 sys_kstat->clk_freq2 = knp->value.c[0];
248 } else {
249 sys_kstat->sys_kstats_ok = 0;
252 knp = kstat_data_lookup(ksp, FAN_KSTAT_NAMED);
253 if (knp != NULL) {
254 sys_kstat->fan_status = knp->value.c[0];
255 } else {
256 sys_kstat->sys_kstats_ok = 0;
259 knp = kstat_data_lookup(ksp, KEY_KSTAT_NAMED);
260 if (knp != NULL) {
261 sys_kstat->keysw_status = knp->value.c[0];
262 } else {
263 sys_kstat->sys_kstats_ok = 0;
266 knp = kstat_data_lookup(ksp, POWER_KSTAT_NAMED);
267 if (knp != NULL) {
268 sys_kstat->power_state =
269 (enum power_state)knp->value.l;
270 } else {
271 sys_kstat->sys_kstats_ok = 0;
274 knp = kstat_data_lookup(ksp, CLK_VER_KSTAT_NAME);
275 if (knp != NULL) {
276 sys_kstat->clk_ver = knp->value.c[0];
277 } else {
279 * the clock version register only appears
280 * on new clock boards
282 sys_kstat->clk_ver = 0;
287 /* Read the kstats for the power supply stats */
288 ksp = kstat_lookup(kc, UNIX, 0, PSSHAD_KSTAT_NAME);
290 if ((ksp != NULL) && (kstat_read(kc, ksp, NULL) != -1)) {
291 sys_kstat->psstat_kstat_ok = 1;
292 (void) memcpy(&sys_kstat->ps_shadow[0], ksp->ks_data,
293 sizeof (sys_kstat->ps_shadow));
294 } else {
295 sys_kstat->psstat_kstat_ok = 0;
298 /* read the overtemp kstat for the system control board */
299 /* Try to find an overtemp kstat instance for this board */
300 ksp = kstat_lookup(kc, UNIX, CLOCK_BOARD_INDEX, OVERTEMP_KSTAT_NAME);
302 if (ksp != NULL) {
303 if (kstat_read(kc, ksp, NULL) == -1) {
304 sys_kstat->temp_kstat_ok = 0;
305 } else {
306 sys_kstat->temp_kstat_ok = 1;
307 (void) memcpy(&sys_kstat->tempstat, ksp->ks_data,
308 sizeof (sys_kstat->tempstat));
309 /* XXX - this is for 2.5.1 testing. remove */
310 if (sizeof (sys_kstat->tempstat) > ksp->ks_data_size)
311 sys_kstat->tempstat.trend = TREND_UNKNOWN;
315 /* Read the reset-info kstat from one of the boards. */
316 ksp = kstat_lookup(kc, UNIX, 0, RESETINFO_KSTAT_NAME);
318 if (ksp == NULL) {
319 sys_kstat->reset_kstats_ok = 0;
320 } else if (kstat_read(kc, ksp, NULL) == -1) {
321 sys_kstat->reset_kstats_ok = 0;
322 } else {
323 sys_kstat->reset_kstats_ok = 1;
324 (void) memcpy(&sys_kstat->reset_info, ksp->ks_data,
325 sizeof (sys_kstat->reset_info));
328 /* read kstats for hotplugged boards */
329 for (i = 0, hp = &sys_kstat->hp_info[0]; i < MAX_BOARDS; i++, hp++) {
330 ksp = kstat_lookup(kc, UNIX, i, BDLIST_KSTAT_NAME);
332 if (ksp == NULL) {
333 continue;
336 if (kstat_read(kc, ksp, NULL) == -1) {
337 hp->kstat_ok = 0;
338 } else {
339 hp->kstat_ok = 1;
340 (void) memcpy(&hp->bd_info, ksp->ks_data,
341 sizeof (hp->bd_info));
345 /* read in the kstat for the fault list. */
346 ksp = kstat_lookup(kc, UNIX, 0, FT_LIST_KSTAT_NAME);
348 if (ksp == NULL) {
349 sys_kstat->ft_kstat_ok = 0;
350 } else {
351 if (kstat_read(kc, ksp, NULL) == -1) {
352 perror("kstat read");
353 sys_kstat->ft_kstat_ok = 0;
354 return;
357 sys_kstat->nfaults = ksp->ks_data_size /
358 sizeof (struct ft_list);
360 sys_kstat->ft_array =
361 (struct ft_list *)malloc(ksp->ks_data_size);
363 if (sys_kstat->ft_array == NULL) {
364 perror("Malloc");
365 exit(2);
367 sys_kstat->ft_kstat_ok = 1;
368 (void) memcpy(sys_kstat->ft_array, ksp->ks_data,
369 ksp->ks_data_size);
374 * This function does the reading and interpreting of sun4u system
375 * kstats. These kstats are created by the following drivers:
376 * fhc, environ, sysctrl. Each board in the tree should have
377 * kstats created for it. There are also system wide kstats that
378 * are created.
380 void
381 read_sun4u_kstats(Sys_tree *tree, struct system_kstat_data *sys_kstat)
383 #if 0
384 Board_node *bnode;
385 kstat_t *ksp;
386 kstat_named_t *knp;
387 struct hp_info *hp;
388 struct envctrltwo_kstat_data *ecp;
389 #endif
390 kstat_ctl_t *kc;
391 int i;
392 struct bd_kstat_data *bdp;
393 struct envctrl_kstat_data *ep;
395 if ((kc = kstat_open()) == NULL) {
396 return;
399 /* Initialize the kstats structure */
400 sys_kstat->sys_kstats_ok = 0;
401 sys_kstat->temp_kstat_ok = 0;
402 sys_kstat->reset_kstats_ok = 0;
403 sys_kstat->ft_kstat_ok = 0;
404 sys_kstat->envctrl_kstat_ok = 0;
405 for (i = 0; i < MAX_BOARDS; i++) {
406 bdp = &sys_kstat->bd_ksp_list[i];
407 bdp->ac_kstats_ok = 0;
408 bdp->fhc_kstats_ok = 0;
409 bdp->simmstat_kstats_ok = 0;
410 bdp->temp_kstat_ok = 0;
412 sys_kstat->hp_info[i].kstat_ok = 0;
414 for (i = 0; i < MAX_DEVS; i++) {
415 ep = &sys_kstat->env_data;
416 ep->ps_kstats[i].instance = I2C_NODEV;
417 ep->fan_kstats[i].instance = I2C_NODEV;
418 ep->encl_kstats[i].instance = I2C_NODEV;
421 read_platform_kstats(tree, sys_kstat, bdp, ep);