xref: /openbmc/ipmitool/lib/ipmi_sdr.c (revision 2d79e69f)
1c18ec02fSPetter Reinholdtsen /*
2c18ec02fSPetter Reinholdtsen  * Copyright (c) 2012 Hewlett-Packard Development Company, L.P.
3c18ec02fSPetter Reinholdtsen  *
4c18ec02fSPetter Reinholdtsen  * Based on code from
5c18ec02fSPetter Reinholdtsen  * Copyright (c) 2003 Sun Microsystems, Inc.  All Rights Reserved.
6c18ec02fSPetter Reinholdtsen  *
7c18ec02fSPetter Reinholdtsen  * Redistribution and use in source and binary forms, with or without
8c18ec02fSPetter Reinholdtsen  * modification, are permitted provided that the following conditions
9c18ec02fSPetter Reinholdtsen  * are met:
10c18ec02fSPetter Reinholdtsen  *
11c18ec02fSPetter Reinholdtsen  * Redistribution of source code must retain the above copyright
12c18ec02fSPetter Reinholdtsen  * notice, this list of conditions and the following disclaimer.
13c18ec02fSPetter Reinholdtsen  *
14c18ec02fSPetter Reinholdtsen  * Redistribution in binary form must reproduce the above copyright
15c18ec02fSPetter Reinholdtsen  * notice, this list of conditions and the following disclaimer in the
16c18ec02fSPetter Reinholdtsen  * documentation and/or other materials provided with the distribution.
17c18ec02fSPetter Reinholdtsen  *
18c18ec02fSPetter Reinholdtsen  * Neither the name of Sun Microsystems, Inc. or the names of
19c18ec02fSPetter Reinholdtsen  * contributors may be used to endorse or promote products derived
20c18ec02fSPetter Reinholdtsen  * from this software without specific prior written permission.
21c18ec02fSPetter Reinholdtsen  *
22c18ec02fSPetter Reinholdtsen  * This software is provided "AS IS," without a warranty of any kind.
23c18ec02fSPetter Reinholdtsen  * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
24c18ec02fSPetter Reinholdtsen  * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
25c18ec02fSPetter Reinholdtsen  * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
26c18ec02fSPetter Reinholdtsen  * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
27c18ec02fSPetter Reinholdtsen  * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
28c18ec02fSPetter Reinholdtsen  * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL
29c18ec02fSPetter Reinholdtsen  * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
30c18ec02fSPetter Reinholdtsen  * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
31c18ec02fSPetter Reinholdtsen  * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
32c18ec02fSPetter Reinholdtsen  * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
33c18ec02fSPetter Reinholdtsen  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
34c18ec02fSPetter Reinholdtsen  */
35c18ec02fSPetter Reinholdtsen 
36c18ec02fSPetter Reinholdtsen #include <string.h>
37c18ec02fSPetter Reinholdtsen 
38c18ec02fSPetter Reinholdtsen #include <math.h>
39c18ec02fSPetter Reinholdtsen #include <stdio.h>
40c18ec02fSPetter Reinholdtsen #include <unistd.h>
41c18ec02fSPetter Reinholdtsen #include <sys/types.h>
42c18ec02fSPetter Reinholdtsen #include <time.h>
43c18ec02fSPetter Reinholdtsen 
44c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi.h>
45c18ec02fSPetter Reinholdtsen #include <ipmitool/log.h>
46c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_mc.h>
47c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sdr.h>
48c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sdradd.h>
49c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sensor.h>
50c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_intf.h>
51c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sel.h>
52c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_entity.h>
53c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_constants.h>
54c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_strings.h>
55c18ec02fSPetter Reinholdtsen 
56c18ec02fSPetter Reinholdtsen #if HAVE_CONFIG_H
57c18ec02fSPetter Reinholdtsen # include <config.h>
58c18ec02fSPetter Reinholdtsen #endif
59c18ec02fSPetter Reinholdtsen 
60c18ec02fSPetter Reinholdtsen extern int verbose;
61c18ec02fSPetter Reinholdtsen static int use_built_in;	/* Uses DeviceSDRs instead of SDRR */
6223e9340bSZdenek Styblik static int sdr_max_read_len = 0;
63c18ec02fSPetter Reinholdtsen static int sdr_extended = 0;
64c18ec02fSPetter Reinholdtsen static long sdriana = 0;
65c18ec02fSPetter Reinholdtsen 
66c18ec02fSPetter Reinholdtsen static struct sdr_record_list *sdr_list_head = NULL;
67c18ec02fSPetter Reinholdtsen static struct sdr_record_list *sdr_list_tail = NULL;
68c18ec02fSPetter Reinholdtsen static struct ipmi_sdr_iterator *sdr_list_itr = NULL;
69c18ec02fSPetter Reinholdtsen 
70c18ec02fSPetter Reinholdtsen void printf_sdr_usage();
71c18ec02fSPetter Reinholdtsen 
72c18ec02fSPetter Reinholdtsen /* ipmi_sdr_get_unit_string  -  return units for base/modifier
73c18ec02fSPetter Reinholdtsen  *
74c18ec02fSPetter Reinholdtsen  * @pct:	units are a percentage
75c18ec02fSPetter Reinholdtsen  * @type:	unit type
76c18ec02fSPetter Reinholdtsen  * @base:	base
77c18ec02fSPetter Reinholdtsen  * @modifier:	modifier
78c18ec02fSPetter Reinholdtsen  *
79c18ec02fSPetter Reinholdtsen  * returns pointer to static string
80c18ec02fSPetter Reinholdtsen  */
81c18ec02fSPetter Reinholdtsen const char *
ipmi_sdr_get_unit_string(uint8_t pct,uint8_t type,uint8_t base,uint8_t modifier)82c18ec02fSPetter Reinholdtsen ipmi_sdr_get_unit_string(uint8_t pct, uint8_t type, uint8_t base, uint8_t modifier)
83c18ec02fSPetter Reinholdtsen {
84c18ec02fSPetter Reinholdtsen 	static char unitstr[16];
85c18ec02fSPetter Reinholdtsen 	/*
86c18ec02fSPetter Reinholdtsen 	 * By default, if units are supposed to be percent, we will pre-pend
87c18ec02fSPetter Reinholdtsen 	 * the percent string  to the textual representation of the units.
88c18ec02fSPetter Reinholdtsen 	 */
89c18ec02fSPetter Reinholdtsen 	char *pctstr = pct ? "% " : "";
90c18ec02fSPetter Reinholdtsen 	memset(unitstr, 0, sizeof (unitstr));
91c18ec02fSPetter Reinholdtsen 	switch (type) {
92c18ec02fSPetter Reinholdtsen 	case 2:
93c18ec02fSPetter Reinholdtsen 		snprintf(unitstr, sizeof (unitstr), "%s%s * %s",
94c18ec02fSPetter Reinholdtsen 			 pctstr, unit_desc[base], unit_desc[modifier]);
95c18ec02fSPetter Reinholdtsen 		break;
96c18ec02fSPetter Reinholdtsen 	case 1:
97c18ec02fSPetter Reinholdtsen 		snprintf(unitstr, sizeof (unitstr), "%s%s/%s",
98c18ec02fSPetter Reinholdtsen 			 pctstr, unit_desc[base], unit_desc[modifier]);
99c18ec02fSPetter Reinholdtsen 		break;
100c18ec02fSPetter Reinholdtsen 	case 0:
101c18ec02fSPetter Reinholdtsen 	default:
102c18ec02fSPetter Reinholdtsen 		/*
103c18ec02fSPetter Reinholdtsen 		 * Display the text "percent" only when the Base unit is
104c18ec02fSPetter Reinholdtsen 		 * "unspecified" and the caller specified to print percent.
105c18ec02fSPetter Reinholdtsen 		 */
106c18ec02fSPetter Reinholdtsen 		if (base == 0 && pct) {
107c18ec02fSPetter Reinholdtsen 			snprintf(unitstr, sizeof(unitstr), "percent");
108c18ec02fSPetter Reinholdtsen 		} else {
109c18ec02fSPetter Reinholdtsen 			snprintf(unitstr, sizeof (unitstr), "%s%s",
110c18ec02fSPetter Reinholdtsen 				pctstr, unit_desc[base]);
111c18ec02fSPetter Reinholdtsen 		}
112c18ec02fSPetter Reinholdtsen 		break;
113c18ec02fSPetter Reinholdtsen 	}
114c18ec02fSPetter Reinholdtsen 	return unitstr;
115c18ec02fSPetter Reinholdtsen }
116c18ec02fSPetter Reinholdtsen 
117c18ec02fSPetter Reinholdtsen /* sdr_sensor_has_analog_reading  -  Determine if sensor has an analog reading
118c18ec02fSPetter Reinholdtsen  *
119c18ec02fSPetter Reinholdtsen  */
120c18ec02fSPetter Reinholdtsen static int
sdr_sensor_has_analog_reading(struct ipmi_intf * intf,struct sensor_reading * sr)121c18ec02fSPetter Reinholdtsen sdr_sensor_has_analog_reading(struct ipmi_intf *intf,
122c18ec02fSPetter Reinholdtsen 			    struct sensor_reading *sr)
123c18ec02fSPetter Reinholdtsen {
124c18ec02fSPetter Reinholdtsen 	/* Compact sensors can't return analog values so we false */
125c18ec02fSPetter Reinholdtsen 	if (!sr->full) {
126c18ec02fSPetter Reinholdtsen 		return 0;
127c18ec02fSPetter Reinholdtsen 	}
128c18ec02fSPetter Reinholdtsen 	/*
129c18ec02fSPetter Reinholdtsen 	 * Per the IPMI Specification:
130c18ec02fSPetter Reinholdtsen 	 *	Only Full Threshold sensors are identified as providing
131c18ec02fSPetter Reinholdtsen 	 *	analog readings.
132c18ec02fSPetter Reinholdtsen 	 *
133c18ec02fSPetter Reinholdtsen 	 * But... HP didn't interpret this as meaning that "Only Threshold
134c18ec02fSPetter Reinholdtsen 	 *        Sensors" can provide analog readings.  So, HP packed analog
135c18ec02fSPetter Reinholdtsen 	 *        readings into some of their non-Threshold Sensor.   There is
136c18ec02fSPetter Reinholdtsen 	 *	  nothing that explictly prohibits this in the spec, so if
137c18ec02fSPetter Reinholdtsen 	 *	  an Analog reading is available in a Non-Threshod sensor and
138c18ec02fSPetter Reinholdtsen 	 *	  there are units specified for identifying the reading then
139c18ec02fSPetter Reinholdtsen 	 *	  we do an analog conversion even though the sensor is
140c18ec02fSPetter Reinholdtsen 	 *	  non-Threshold.   To be safe, we provide this extension for
141c18ec02fSPetter Reinholdtsen 	 *	  HP.
142c18ec02fSPetter Reinholdtsen 	 *
143c18ec02fSPetter Reinholdtsen 	 */
144c18ec02fSPetter Reinholdtsen 	if ( UNITS_ARE_DISCRETE(&sr->full->cmn) ) {
145c18ec02fSPetter Reinholdtsen 		return 0;/* Sensor specified as not having Analog Units */
146c18ec02fSPetter Reinholdtsen 	}
147c18ec02fSPetter Reinholdtsen 	if ( !IS_THRESHOLD_SENSOR(&sr->full->cmn) ) {
148c18ec02fSPetter Reinholdtsen 		/* Non-Threshold Sensors are not defined as having analog */
149c18ec02fSPetter Reinholdtsen 		/* But.. We have one with defined with Analog Units */
150c18ec02fSPetter Reinholdtsen 		if ( (sr->full->cmn.unit.pct | sr->full->cmn.unit.modifier |
151c18ec02fSPetter Reinholdtsen 			 sr->full->cmn.unit.type.base |
152c18ec02fSPetter Reinholdtsen 			 sr->full->cmn.unit.type.modifier)) {
153c18ec02fSPetter Reinholdtsen 			 /* And it does have the necessary units specs */
154c18ec02fSPetter Reinholdtsen 			 if ( !(intf->manufacturer_id == IPMI_OEM_HP) ) {
155c18ec02fSPetter Reinholdtsen 				/* But to be safe we only do this for HP */
156c18ec02fSPetter Reinholdtsen 				return 0;
157c18ec02fSPetter Reinholdtsen 			 }
158c18ec02fSPetter Reinholdtsen 		} else {
159c18ec02fSPetter Reinholdtsen 			return 0;
160c18ec02fSPetter Reinholdtsen 		}
161c18ec02fSPetter Reinholdtsen 	}
162c18ec02fSPetter Reinholdtsen 	/*
163c18ec02fSPetter Reinholdtsen 	 * If sensor has linearization, then we should be able to update the
164c18ec02fSPetter Reinholdtsen 	 * reading factors and if we cannot fail the conversion.
165c18ec02fSPetter Reinholdtsen 	 */
166c18ec02fSPetter Reinholdtsen 	if (sr->full->linearization >= SDR_SENSOR_L_NONLINEAR &&
167c18ec02fSPetter Reinholdtsen 	    sr->full->linearization <= 0x7F) {
168c18ec02fSPetter Reinholdtsen 		if (ipmi_sensor_get_sensor_reading_factors(intf, sr->full, sr->s_reading) < 0){
169c18ec02fSPetter Reinholdtsen 			sr->s_reading_valid = 0;
170c18ec02fSPetter Reinholdtsen 			return 0;
171c18ec02fSPetter Reinholdtsen 		}
172c18ec02fSPetter Reinholdtsen 	}
173c18ec02fSPetter Reinholdtsen 
174c18ec02fSPetter Reinholdtsen 	return 1;
175c18ec02fSPetter Reinholdtsen }
176c18ec02fSPetter Reinholdtsen 
177c18ec02fSPetter Reinholdtsen /* sdr_convert_sensor_reading  -  convert raw sensor reading
178c18ec02fSPetter Reinholdtsen  *
179c18ec02fSPetter Reinholdtsen  * @sensor:	sensor record
180c18ec02fSPetter Reinholdtsen  * @val:	raw sensor reading
181c18ec02fSPetter Reinholdtsen  *
182c18ec02fSPetter Reinholdtsen  * returns floating-point sensor reading
183c18ec02fSPetter Reinholdtsen  */
184c18ec02fSPetter Reinholdtsen double
sdr_convert_sensor_reading(struct sdr_record_full_sensor * sensor,uint8_t val)185c18ec02fSPetter Reinholdtsen sdr_convert_sensor_reading(struct sdr_record_full_sensor *sensor, uint8_t val)
186c18ec02fSPetter Reinholdtsen {
187c18ec02fSPetter Reinholdtsen 	int m, b, k1, k2;
188c18ec02fSPetter Reinholdtsen 	double result;
189c18ec02fSPetter Reinholdtsen 
190c18ec02fSPetter Reinholdtsen 	m = __TO_M(sensor->mtol);
191c18ec02fSPetter Reinholdtsen 	b = __TO_B(sensor->bacc);
192c18ec02fSPetter Reinholdtsen 	k1 = __TO_B_EXP(sensor->bacc);
193c18ec02fSPetter Reinholdtsen 	k2 = __TO_R_EXP(sensor->bacc);
194c18ec02fSPetter Reinholdtsen 
195c18ec02fSPetter Reinholdtsen 	switch (sensor->cmn.unit.analog) {
196c18ec02fSPetter Reinholdtsen 	case 0:
197c18ec02fSPetter Reinholdtsen 		result = (double) (((m * val) +
198c18ec02fSPetter Reinholdtsen 				    (b * pow(10, k1))) * pow(10, k2));
199c18ec02fSPetter Reinholdtsen 		break;
200c18ec02fSPetter Reinholdtsen 	case 1:
201c18ec02fSPetter Reinholdtsen 		if (val & 0x80)
202c18ec02fSPetter Reinholdtsen 			val++;
203c18ec02fSPetter Reinholdtsen 		/* Deliberately fall through to case 2. */
204c18ec02fSPetter Reinholdtsen 	case 2:
205c18ec02fSPetter Reinholdtsen 		result = (double) (((m * (int8_t) val) +
206c18ec02fSPetter Reinholdtsen 				    (b * pow(10, k1))) * pow(10, k2));
207c18ec02fSPetter Reinholdtsen 		break;
208c18ec02fSPetter Reinholdtsen 	default:
209c18ec02fSPetter Reinholdtsen 		/* Oops! This isn't an analog sensor. */
210c18ec02fSPetter Reinholdtsen 		return 0.0;
211c18ec02fSPetter Reinholdtsen 	}
212c18ec02fSPetter Reinholdtsen 
213c18ec02fSPetter Reinholdtsen 	switch (sensor->linearization & 0x7f) {
214c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_LN:
215c18ec02fSPetter Reinholdtsen 		result = log(result);
216c18ec02fSPetter Reinholdtsen 		break;
217c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_LOG10:
218c18ec02fSPetter Reinholdtsen 		result = log10(result);
219c18ec02fSPetter Reinholdtsen 		break;
220c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_LOG2:
221c18ec02fSPetter Reinholdtsen 		result = (double) (log(result) / log(2.0));
222c18ec02fSPetter Reinholdtsen 		break;
223c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_E:
224c18ec02fSPetter Reinholdtsen 		result = exp(result);
225c18ec02fSPetter Reinholdtsen 		break;
226c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_EXP10:
227c18ec02fSPetter Reinholdtsen 		result = pow(10.0, result);
228c18ec02fSPetter Reinholdtsen 		break;
229c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_EXP2:
230c18ec02fSPetter Reinholdtsen 		result = pow(2.0, result);
231c18ec02fSPetter Reinholdtsen 		break;
232c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_1_X:
233c18ec02fSPetter Reinholdtsen 		result = pow(result, -1.0);	/*1/x w/o exception */
234c18ec02fSPetter Reinholdtsen 		break;
235c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_SQR:
236c18ec02fSPetter Reinholdtsen 		result = pow(result, 2.0);
237c18ec02fSPetter Reinholdtsen 		break;
238c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_CUBE:
239c18ec02fSPetter Reinholdtsen 		result = pow(result, 3.0);
240c18ec02fSPetter Reinholdtsen 		break;
241c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_SQRT:
242c18ec02fSPetter Reinholdtsen 		result = sqrt(result);
243c18ec02fSPetter Reinholdtsen 		break;
244c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_CUBERT:
245c18ec02fSPetter Reinholdtsen 		result = cbrt(result);
246c18ec02fSPetter Reinholdtsen 		break;
247c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_LINEAR:
248c18ec02fSPetter Reinholdtsen 	default:
249c18ec02fSPetter Reinholdtsen 		break;
250c18ec02fSPetter Reinholdtsen 	}
251c18ec02fSPetter Reinholdtsen 	return result;
252c18ec02fSPetter Reinholdtsen }
253c18ec02fSPetter Reinholdtsen /* sdr_convert_sensor_hysterisis  -  convert raw sensor hysterisis
254c18ec02fSPetter Reinholdtsen  *
255c18ec02fSPetter Reinholdtsen  * Even though spec says histerisis should be computed using Mx+B
256c18ec02fSPetter Reinholdtsen  * formula, B is irrelevant when doing raw comparison
257c18ec02fSPetter Reinholdtsen  *
258c18ec02fSPetter Reinholdtsen  * threshold rearm point is computed using threshold +/- hysterisis
259c18ec02fSPetter Reinholdtsen  * with the full formula however B can't be applied in raw comparisons
260c18ec02fSPetter Reinholdtsen  *
261c18ec02fSPetter Reinholdtsen  * @sensor:	sensor record
262c18ec02fSPetter Reinholdtsen  * @val:	raw sensor reading
263c18ec02fSPetter Reinholdtsen  *
264c18ec02fSPetter Reinholdtsen  * returns floating-point sensor reading
265c18ec02fSPetter Reinholdtsen  */
266c18ec02fSPetter Reinholdtsen double
sdr_convert_sensor_hysterisis(struct sdr_record_full_sensor * sensor,uint8_t val)267c18ec02fSPetter Reinholdtsen sdr_convert_sensor_hysterisis(struct sdr_record_full_sensor *sensor, uint8_t val)
268c18ec02fSPetter Reinholdtsen {
269c18ec02fSPetter Reinholdtsen 	int m, k2;
270c18ec02fSPetter Reinholdtsen 	double result;
271c18ec02fSPetter Reinholdtsen 
272c18ec02fSPetter Reinholdtsen 	m = __TO_M(sensor->mtol);
273c18ec02fSPetter Reinholdtsen 
274c18ec02fSPetter Reinholdtsen 	k2 = __TO_R_EXP(sensor->bacc);
275c18ec02fSPetter Reinholdtsen 
276c18ec02fSPetter Reinholdtsen 	switch (sensor->cmn.unit.analog) {
277c18ec02fSPetter Reinholdtsen 	case 0:
278c18ec02fSPetter Reinholdtsen 		result = (double) (((m * val)) * pow(10, k2));
279c18ec02fSPetter Reinholdtsen 		break;
280c18ec02fSPetter Reinholdtsen 	case 1:
281c18ec02fSPetter Reinholdtsen 		if (val & 0x80)
282c18ec02fSPetter Reinholdtsen 			val++;
283c18ec02fSPetter Reinholdtsen 		/* Deliberately fall through to case 2. */
284c18ec02fSPetter Reinholdtsen 	case 2:
285c18ec02fSPetter Reinholdtsen 		result = (double) (((m * (int8_t) val) ) * pow(10, k2));
286c18ec02fSPetter Reinholdtsen 		break;
287c18ec02fSPetter Reinholdtsen 	default:
288c18ec02fSPetter Reinholdtsen 		/* Oops! This isn't an analog sensor. */
289c18ec02fSPetter Reinholdtsen 		return 0.0;
290c18ec02fSPetter Reinholdtsen 	}
291c18ec02fSPetter Reinholdtsen 
292c18ec02fSPetter Reinholdtsen 	switch (sensor->linearization & 0x7f) {
293c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_LN:
294c18ec02fSPetter Reinholdtsen 		result = log(result);
295c18ec02fSPetter Reinholdtsen 		break;
296c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_LOG10:
297c18ec02fSPetter Reinholdtsen 		result = log10(result);
298c18ec02fSPetter Reinholdtsen 		break;
299c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_LOG2:
300c18ec02fSPetter Reinholdtsen 		result = (double) (log(result) / log(2.0));
301c18ec02fSPetter Reinholdtsen 		break;
302c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_E:
303c18ec02fSPetter Reinholdtsen 		result = exp(result);
304c18ec02fSPetter Reinholdtsen 		break;
305c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_EXP10:
306c18ec02fSPetter Reinholdtsen 		result = pow(10.0, result);
307c18ec02fSPetter Reinholdtsen 		break;
308c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_EXP2:
309c18ec02fSPetter Reinholdtsen 		result = pow(2.0, result);
310c18ec02fSPetter Reinholdtsen 		break;
311c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_1_X:
312c18ec02fSPetter Reinholdtsen 		result = pow(result, -1.0);	/*1/x w/o exception */
313c18ec02fSPetter Reinholdtsen 		break;
314c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_SQR:
315c18ec02fSPetter Reinholdtsen 		result = pow(result, 2.0);
316c18ec02fSPetter Reinholdtsen 		break;
317c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_CUBE:
318c18ec02fSPetter Reinholdtsen 		result = pow(result, 3.0);
319c18ec02fSPetter Reinholdtsen 		break;
320c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_SQRT:
321c18ec02fSPetter Reinholdtsen 		result = sqrt(result);
322c18ec02fSPetter Reinholdtsen 		break;
323c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_CUBERT:
324c18ec02fSPetter Reinholdtsen 		result = cbrt(result);
325c18ec02fSPetter Reinholdtsen 		break;
326c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_LINEAR:
327c18ec02fSPetter Reinholdtsen 	default:
328c18ec02fSPetter Reinholdtsen 		break;
329c18ec02fSPetter Reinholdtsen 	}
330c18ec02fSPetter Reinholdtsen 	return result;
331c18ec02fSPetter Reinholdtsen }
332c18ec02fSPetter Reinholdtsen 
333c18ec02fSPetter Reinholdtsen 
334c18ec02fSPetter Reinholdtsen /* sdr_convert_sensor_tolerance  -  convert raw sensor reading
335c18ec02fSPetter Reinholdtsen  *
336c18ec02fSPetter Reinholdtsen  * @sensor:	sensor record
337c18ec02fSPetter Reinholdtsen  * @val:	raw sensor reading
338c18ec02fSPetter Reinholdtsen  *
339c18ec02fSPetter Reinholdtsen  * returns floating-point sensor tolerance(interpreted)
340c18ec02fSPetter Reinholdtsen  */
341c18ec02fSPetter Reinholdtsen double
sdr_convert_sensor_tolerance(struct sdr_record_full_sensor * sensor,uint8_t val)342c18ec02fSPetter Reinholdtsen sdr_convert_sensor_tolerance(struct sdr_record_full_sensor *sensor, uint8_t val)
343c18ec02fSPetter Reinholdtsen {
344c18ec02fSPetter Reinholdtsen 	int m,   k2;
345c18ec02fSPetter Reinholdtsen 	double result;
346c18ec02fSPetter Reinholdtsen 
347c18ec02fSPetter Reinholdtsen 	m = __TO_M(sensor->mtol);
348c18ec02fSPetter Reinholdtsen 	k2 = __TO_R_EXP(sensor->bacc);
349c18ec02fSPetter Reinholdtsen 
350c18ec02fSPetter Reinholdtsen 	switch (sensor->cmn.unit.analog) {
351c18ec02fSPetter Reinholdtsen 	case 0:
352c18ec02fSPetter Reinholdtsen                 /* as suggested in section 30.4.1 of IPMI 1.5 spec */
353c18ec02fSPetter Reinholdtsen 		result = (double) ((((m * (double)val/2)) ) * pow(10, k2));
354c18ec02fSPetter Reinholdtsen 		break;
355c18ec02fSPetter Reinholdtsen 	case 1:
356c18ec02fSPetter Reinholdtsen 		if (val & 0x80)
357c18ec02fSPetter Reinholdtsen 			val++;
358c18ec02fSPetter Reinholdtsen 		/* Deliberately fall through to case 2. */
359c18ec02fSPetter Reinholdtsen 	case 2:
360c18ec02fSPetter Reinholdtsen 		result = (double) (((m * ((double)((int8_t) val)/2))) * pow(10, k2));
361c18ec02fSPetter Reinholdtsen 		break;
362c18ec02fSPetter Reinholdtsen 	default:
363c18ec02fSPetter Reinholdtsen 		/* Oops! This isn't an analog sensor. */
364c18ec02fSPetter Reinholdtsen 		return 0.0;
365c18ec02fSPetter Reinholdtsen 	}
366c18ec02fSPetter Reinholdtsen 
367c18ec02fSPetter Reinholdtsen 	switch (sensor->linearization & 0x7f) {
368c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_LN:
369c18ec02fSPetter Reinholdtsen 		result = log(result);
370c18ec02fSPetter Reinholdtsen 		break;
371c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_LOG10:
372c18ec02fSPetter Reinholdtsen 		result = log10(result);
373c18ec02fSPetter Reinholdtsen 		break;
374c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_LOG2:
375c18ec02fSPetter Reinholdtsen 		result = (double) (log(result) / log(2.0));
376c18ec02fSPetter Reinholdtsen 		break;
377c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_E:
378c18ec02fSPetter Reinholdtsen 		result = exp(result);
379c18ec02fSPetter Reinholdtsen 		break;
380c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_EXP10:
381c18ec02fSPetter Reinholdtsen 		result = pow(10.0, result);
382c18ec02fSPetter Reinholdtsen 		break;
383c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_EXP2:
384c18ec02fSPetter Reinholdtsen 		result = pow(2.0, result);
385c18ec02fSPetter Reinholdtsen 		break;
386c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_1_X:
387c18ec02fSPetter Reinholdtsen 		result = pow(result, -1.0);	/*1/x w/o exception */
388c18ec02fSPetter Reinholdtsen 		break;
389c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_SQR:
390c18ec02fSPetter Reinholdtsen 		result = pow(result, 2.0);
391c18ec02fSPetter Reinholdtsen 		break;
392c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_CUBE:
393c18ec02fSPetter Reinholdtsen 		result = pow(result, 3.0);
394c18ec02fSPetter Reinholdtsen 		break;
395c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_SQRT:
396c18ec02fSPetter Reinholdtsen 		result = sqrt(result);
397c18ec02fSPetter Reinholdtsen 		break;
398c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_CUBERT:
399c18ec02fSPetter Reinholdtsen 		result = cbrt(result);
400c18ec02fSPetter Reinholdtsen 		break;
401c18ec02fSPetter Reinholdtsen 	case SDR_SENSOR_L_LINEAR:
402c18ec02fSPetter Reinholdtsen 	default:
403c18ec02fSPetter Reinholdtsen 		break;
404c18ec02fSPetter Reinholdtsen 	}
405c18ec02fSPetter Reinholdtsen 	return result;
406c18ec02fSPetter Reinholdtsen }
407c18ec02fSPetter Reinholdtsen 
408c18ec02fSPetter Reinholdtsen /* sdr_convert_sensor_value_to_raw  -  convert sensor reading back to raw
409c18ec02fSPetter Reinholdtsen  *
410c18ec02fSPetter Reinholdtsen  * @sensor:	sensor record
411c18ec02fSPetter Reinholdtsen  * @val:	converted sensor reading
412c18ec02fSPetter Reinholdtsen  *
413c18ec02fSPetter Reinholdtsen  * returns raw sensor reading
414c18ec02fSPetter Reinholdtsen  */
415c18ec02fSPetter Reinholdtsen uint8_t
sdr_convert_sensor_value_to_raw(struct sdr_record_full_sensor * sensor,double val)416c18ec02fSPetter Reinholdtsen sdr_convert_sensor_value_to_raw(struct sdr_record_full_sensor * sensor,
417c18ec02fSPetter Reinholdtsen 				double val)
418c18ec02fSPetter Reinholdtsen {
419c18ec02fSPetter Reinholdtsen 	int m, b, k1, k2;
420c18ec02fSPetter Reinholdtsen 	double result;
421c18ec02fSPetter Reinholdtsen 
422c18ec02fSPetter Reinholdtsen 	/* only works for analog sensors */
423c18ec02fSPetter Reinholdtsen 	if (UNITS_ARE_DISCRETE((&sensor->cmn)))
424c18ec02fSPetter Reinholdtsen 		return 0;
425c18ec02fSPetter Reinholdtsen 
426c18ec02fSPetter Reinholdtsen 	m = __TO_M(sensor->mtol);
427c18ec02fSPetter Reinholdtsen 	b = __TO_B(sensor->bacc);
428c18ec02fSPetter Reinholdtsen 	k1 = __TO_B_EXP(sensor->bacc);
429c18ec02fSPetter Reinholdtsen 	k2 = __TO_R_EXP(sensor->bacc);
430c18ec02fSPetter Reinholdtsen 
431c18ec02fSPetter Reinholdtsen 	/* don't divide by zero */
432c18ec02fSPetter Reinholdtsen 	if (m == 0)
433c18ec02fSPetter Reinholdtsen 		return 0;
434c18ec02fSPetter Reinholdtsen 
435c18ec02fSPetter Reinholdtsen 	result = (((val / pow(10, k2)) - (b * pow(10, k1))) / m);
436c18ec02fSPetter Reinholdtsen 
437c18ec02fSPetter Reinholdtsen 	if ((result - (int) result) >= .5)
438c18ec02fSPetter Reinholdtsen 		return (uint8_t) ceil(result);
439c18ec02fSPetter Reinholdtsen 	else
440c18ec02fSPetter Reinholdtsen 		return (uint8_t) result;
441c18ec02fSPetter Reinholdtsen }
442c18ec02fSPetter Reinholdtsen 
443c18ec02fSPetter Reinholdtsen /* ipmi_sdr_get_sensor_thresholds  -  return thresholds for sensor
444c18ec02fSPetter Reinholdtsen  *
445c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
446c18ec02fSPetter Reinholdtsen  * @sensor:	sensor number
447c18ec02fSPetter Reinholdtsen  * @target:	sensor owner ID
448c18ec02fSPetter Reinholdtsen  * @lun:	sensor lun
449c18ec02fSPetter Reinholdtsen  * @channel:	channel number
450c18ec02fSPetter Reinholdtsen  *
451c18ec02fSPetter Reinholdtsen  * returns pointer to ipmi response
452c18ec02fSPetter Reinholdtsen  */
453c18ec02fSPetter Reinholdtsen struct ipmi_rs *
ipmi_sdr_get_sensor_thresholds(struct ipmi_intf * intf,uint8_t sensor,uint8_t target,uint8_t lun,uint8_t channel)454c18ec02fSPetter Reinholdtsen ipmi_sdr_get_sensor_thresholds(struct ipmi_intf *intf, uint8_t sensor,
455c18ec02fSPetter Reinholdtsen 					uint8_t target, uint8_t lun, uint8_t channel)
456c18ec02fSPetter Reinholdtsen {
457c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
458c18ec02fSPetter Reinholdtsen 	struct ipmi_rs *rsp;
459c18ec02fSPetter Reinholdtsen 	uint8_t  bridged_request = 0;
460c18ec02fSPetter Reinholdtsen 	uint32_t save_addr;
461c18ec02fSPetter Reinholdtsen 	uint32_t save_channel;
462c18ec02fSPetter Reinholdtsen 
463c18ec02fSPetter Reinholdtsen 	if ( BRIDGE_TO_SENSOR(intf, target, channel) ) {
464c18ec02fSPetter Reinholdtsen 		bridged_request = 1;
465c18ec02fSPetter Reinholdtsen 		save_addr = intf->target_addr;
466c18ec02fSPetter Reinholdtsen 		intf->target_addr = target;
467c18ec02fSPetter Reinholdtsen 		save_channel = intf->target_channel;
468c18ec02fSPetter Reinholdtsen 		intf->target_channel = channel;
469c18ec02fSPetter Reinholdtsen 	}
470c18ec02fSPetter Reinholdtsen 
471c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof (req));
472c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_SE;
473c18ec02fSPetter Reinholdtsen 	req.msg.lun = lun;
474c18ec02fSPetter Reinholdtsen 	req.msg.cmd = GET_SENSOR_THRESHOLDS;
475c18ec02fSPetter Reinholdtsen 	req.msg.data = &sensor;
476c18ec02fSPetter Reinholdtsen 	req.msg.data_len = sizeof (sensor);
477c18ec02fSPetter Reinholdtsen 
478c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
479c18ec02fSPetter Reinholdtsen 	if (bridged_request) {
480c18ec02fSPetter Reinholdtsen 		intf->target_addr = save_addr;
481c18ec02fSPetter Reinholdtsen 		intf->target_channel = save_channel;
482c18ec02fSPetter Reinholdtsen 	}
483c18ec02fSPetter Reinholdtsen 	return rsp;
484c18ec02fSPetter Reinholdtsen }
485c18ec02fSPetter Reinholdtsen 
486c18ec02fSPetter Reinholdtsen /* ipmi_sdr_get_sensor_hysteresis  -  return hysteresis for sensor
487c18ec02fSPetter Reinholdtsen  *
488c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
489c18ec02fSPetter Reinholdtsen  * @sensor:	sensor number
490c18ec02fSPetter Reinholdtsen  * @target:	sensor owner ID
491c18ec02fSPetter Reinholdtsen  * @lun:	sensor lun
492c18ec02fSPetter Reinholdtsen  * @channel:	channel number
493c18ec02fSPetter Reinholdtsen  *
494c18ec02fSPetter Reinholdtsen  * returns pointer to ipmi response
495c18ec02fSPetter Reinholdtsen  */
496c18ec02fSPetter Reinholdtsen struct ipmi_rs *
ipmi_sdr_get_sensor_hysteresis(struct ipmi_intf * intf,uint8_t sensor,uint8_t target,uint8_t lun,uint8_t channel)497c18ec02fSPetter Reinholdtsen ipmi_sdr_get_sensor_hysteresis(struct ipmi_intf *intf, uint8_t sensor,
498c18ec02fSPetter Reinholdtsen 					uint8_t target, uint8_t lun, uint8_t channel)
499c18ec02fSPetter Reinholdtsen {
500c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
501c18ec02fSPetter Reinholdtsen 	uint8_t rqdata[2];
502c18ec02fSPetter Reinholdtsen 	struct ipmi_rs *rsp;
503c18ec02fSPetter Reinholdtsen 	uint8_t  bridged_request = 0;
504c18ec02fSPetter Reinholdtsen 	uint32_t save_addr;
505c18ec02fSPetter Reinholdtsen 	uint32_t save_channel;
506c18ec02fSPetter Reinholdtsen 
507c18ec02fSPetter Reinholdtsen 	if ( BRIDGE_TO_SENSOR(intf, target, channel) ) {
508c18ec02fSPetter Reinholdtsen 		bridged_request = 1;
509c18ec02fSPetter Reinholdtsen 		save_addr = intf->target_addr;
510c18ec02fSPetter Reinholdtsen 		intf->target_addr = target;
511c18ec02fSPetter Reinholdtsen 		save_channel = intf->target_channel;
512c18ec02fSPetter Reinholdtsen 		intf->target_channel = channel;
513c18ec02fSPetter Reinholdtsen 	}
514c18ec02fSPetter Reinholdtsen 
515c18ec02fSPetter Reinholdtsen 	rqdata[0] = sensor;
516c18ec02fSPetter Reinholdtsen 	rqdata[1] = 0xff;	/* reserved */
517c18ec02fSPetter Reinholdtsen 
518c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof (req));
519c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_SE;
520c18ec02fSPetter Reinholdtsen 	req.msg.lun = lun;
521c18ec02fSPetter Reinholdtsen 	req.msg.cmd = GET_SENSOR_HYSTERESIS;
522c18ec02fSPetter Reinholdtsen 	req.msg.data = rqdata;
523c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 2;
524c18ec02fSPetter Reinholdtsen 
525c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
526c18ec02fSPetter Reinholdtsen 	if (bridged_request) {
527c18ec02fSPetter Reinholdtsen 		intf->target_addr = save_addr;
528c18ec02fSPetter Reinholdtsen 		intf->target_channel = save_channel;
529c18ec02fSPetter Reinholdtsen 	}
530c18ec02fSPetter Reinholdtsen 	return rsp;
531c18ec02fSPetter Reinholdtsen }
532c18ec02fSPetter Reinholdtsen 
533c18ec02fSPetter Reinholdtsen /* ipmi_sdr_get_sensor_reading  -  retrieve a raw sensor reading
534c18ec02fSPetter Reinholdtsen  *
535c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
536c18ec02fSPetter Reinholdtsen  * @sensor:	sensor id
537c18ec02fSPetter Reinholdtsen  *
538c18ec02fSPetter Reinholdtsen  * returns ipmi response structure
539c18ec02fSPetter Reinholdtsen  */
540c18ec02fSPetter Reinholdtsen struct ipmi_rs *
ipmi_sdr_get_sensor_reading(struct ipmi_intf * intf,uint8_t sensor)541c18ec02fSPetter Reinholdtsen ipmi_sdr_get_sensor_reading(struct ipmi_intf *intf, uint8_t sensor)
542c18ec02fSPetter Reinholdtsen {
543c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
544c18ec02fSPetter Reinholdtsen 
545c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof (req));
546c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_SE;
547c18ec02fSPetter Reinholdtsen 	req.msg.cmd = GET_SENSOR_READING;
548c18ec02fSPetter Reinholdtsen 	req.msg.data = &sensor;
549c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 1;
550c18ec02fSPetter Reinholdtsen 
551c18ec02fSPetter Reinholdtsen 	return intf->sendrecv(intf, &req);
552c18ec02fSPetter Reinholdtsen }
553c18ec02fSPetter Reinholdtsen 
554c18ec02fSPetter Reinholdtsen 
555c18ec02fSPetter Reinholdtsen /* ipmi_sdr_get_sensor_reading_ipmb  -  retrieve a raw sensor reading from ipmb
556c18ec02fSPetter Reinholdtsen  *
557c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
558c18ec02fSPetter Reinholdtsen  * @sensor:	sensor id
559c18ec02fSPetter Reinholdtsen  * @target:	IPMB target address
560c18ec02fSPetter Reinholdtsen  * @lun:	sensor lun
561c18ec02fSPetter Reinholdtsen  * @channel:	channel number
562c18ec02fSPetter Reinholdtsen  *
563c18ec02fSPetter Reinholdtsen  * returns ipmi response structure
564c18ec02fSPetter Reinholdtsen  */
565c18ec02fSPetter Reinholdtsen struct ipmi_rs *
ipmi_sdr_get_sensor_reading_ipmb(struct ipmi_intf * intf,uint8_t sensor,uint8_t target,uint8_t lun,uint8_t channel)566c18ec02fSPetter Reinholdtsen ipmi_sdr_get_sensor_reading_ipmb(struct ipmi_intf *intf, uint8_t sensor,
567c18ec02fSPetter Reinholdtsen 				 uint8_t target, uint8_t lun, uint8_t channel)
568c18ec02fSPetter Reinholdtsen {
569c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
570c18ec02fSPetter Reinholdtsen 	struct ipmi_rs *rsp;
571c18ec02fSPetter Reinholdtsen 	uint8_t  bridged_request = 0;
572c18ec02fSPetter Reinholdtsen 	uint32_t save_addr;
573c18ec02fSPetter Reinholdtsen 	uint32_t save_channel;
574c18ec02fSPetter Reinholdtsen 
575c18ec02fSPetter Reinholdtsen 	if ( BRIDGE_TO_SENSOR(intf, target, channel) ) {
576c18ec02fSPetter Reinholdtsen 		lprintf(LOG_DEBUG,
577c18ec02fSPetter Reinholdtsen 			"Bridge to Sensor "
578c18ec02fSPetter Reinholdtsen 			"Intf my/%#x tgt/%#x:%#x Sdr tgt/%#x:%#x\n",
579c18ec02fSPetter Reinholdtsen 			intf->my_addr, intf->target_addr, intf->target_channel,
580c18ec02fSPetter Reinholdtsen 			target, channel);
581c18ec02fSPetter Reinholdtsen 		bridged_request = 1;
582c18ec02fSPetter Reinholdtsen 		save_addr = intf->target_addr;
583c18ec02fSPetter Reinholdtsen 		intf->target_addr = target;
584c18ec02fSPetter Reinholdtsen 		save_channel = intf->target_channel;
585c18ec02fSPetter Reinholdtsen 		intf->target_channel = channel;
586c18ec02fSPetter Reinholdtsen 	}
587c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof (req));
588c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_SE;
589c18ec02fSPetter Reinholdtsen 	req.msg.lun = lun;
590c18ec02fSPetter Reinholdtsen 	req.msg.cmd = GET_SENSOR_READING;
591c18ec02fSPetter Reinholdtsen 	req.msg.data = &sensor;
592c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 1;
593c18ec02fSPetter Reinholdtsen 
594c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
595c18ec02fSPetter Reinholdtsen 	if (bridged_request) {
596c18ec02fSPetter Reinholdtsen 		intf->target_addr    = save_addr;
597c18ec02fSPetter Reinholdtsen 		intf->target_channel = save_channel;
598c18ec02fSPetter Reinholdtsen 	}
599c18ec02fSPetter Reinholdtsen 	return rsp;
600c18ec02fSPetter Reinholdtsen }
601c18ec02fSPetter Reinholdtsen 
602c18ec02fSPetter Reinholdtsen /* ipmi_sdr_get_sensor_event_status  -  retrieve sensor event status
603c18ec02fSPetter Reinholdtsen  *
604c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
605c18ec02fSPetter Reinholdtsen  * @sensor:	sensor id
606c18ec02fSPetter Reinholdtsen  * @target:	sensor owner ID
607c18ec02fSPetter Reinholdtsen  * @lun:	sensor lun
608c18ec02fSPetter Reinholdtsen  * @channel:	channel number
609c18ec02fSPetter Reinholdtsen  *
610c18ec02fSPetter Reinholdtsen  * returns ipmi response structure
611c18ec02fSPetter Reinholdtsen  */
612c18ec02fSPetter Reinholdtsen struct ipmi_rs *
ipmi_sdr_get_sensor_event_status(struct ipmi_intf * intf,uint8_t sensor,uint8_t target,uint8_t lun,uint8_t channel)613c18ec02fSPetter Reinholdtsen ipmi_sdr_get_sensor_event_status(struct ipmi_intf *intf, uint8_t sensor,
614c18ec02fSPetter Reinholdtsen 				 uint8_t target, uint8_t lun, uint8_t channel)
615c18ec02fSPetter Reinholdtsen {
616c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
617c18ec02fSPetter Reinholdtsen 	struct ipmi_rs *rsp;
618c18ec02fSPetter Reinholdtsen 	uint8_t  bridged_request = 0;
619c18ec02fSPetter Reinholdtsen 	uint32_t save_addr;
620c18ec02fSPetter Reinholdtsen 	uint32_t save_channel;
621c18ec02fSPetter Reinholdtsen 
622c18ec02fSPetter Reinholdtsen 	if ( BRIDGE_TO_SENSOR(intf, target, channel) ) {
623c18ec02fSPetter Reinholdtsen 		bridged_request = 1;
624c18ec02fSPetter Reinholdtsen 		save_addr = intf->target_addr;
625c18ec02fSPetter Reinholdtsen 		intf->target_addr = target;
626c18ec02fSPetter Reinholdtsen 		save_channel = intf->target_channel;
627c18ec02fSPetter Reinholdtsen 		intf->target_channel = channel;
628c18ec02fSPetter Reinholdtsen 	}
629c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof (req));
630c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_SE;
631c18ec02fSPetter Reinholdtsen 	req.msg.lun = lun;
632c18ec02fSPetter Reinholdtsen 	req.msg.cmd = GET_SENSOR_EVENT_STATUS;
633c18ec02fSPetter Reinholdtsen 	req.msg.data = &sensor;
634c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 1;
635c18ec02fSPetter Reinholdtsen 
636c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
637c18ec02fSPetter Reinholdtsen 	if (bridged_request) {
638c18ec02fSPetter Reinholdtsen 		intf->target_addr = save_addr;
639c18ec02fSPetter Reinholdtsen 		intf->target_channel = save_channel;
640c18ec02fSPetter Reinholdtsen 	}
641c18ec02fSPetter Reinholdtsen 	return rsp;
642c18ec02fSPetter Reinholdtsen }
643c18ec02fSPetter Reinholdtsen 
644c18ec02fSPetter Reinholdtsen /* ipmi_sdr_get_sensor_event_enable  -  retrieve sensor event enables
645c18ec02fSPetter Reinholdtsen  *
646c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
647c18ec02fSPetter Reinholdtsen  * @sensor:	sensor id
648c18ec02fSPetter Reinholdtsen  * @target:	sensor owner ID
649c18ec02fSPetter Reinholdtsen  * @lun:	sensor lun
650c18ec02fSPetter Reinholdtsen  * @channel:	channel number
651c18ec02fSPetter Reinholdtsen  *
652c18ec02fSPetter Reinholdtsen  * returns ipmi response structure
653c18ec02fSPetter Reinholdtsen  */
654c18ec02fSPetter Reinholdtsen struct ipmi_rs *
ipmi_sdr_get_sensor_event_enable(struct ipmi_intf * intf,uint8_t sensor,uint8_t target,uint8_t lun,uint8_t channel)655c18ec02fSPetter Reinholdtsen ipmi_sdr_get_sensor_event_enable(struct ipmi_intf *intf, uint8_t sensor,
656c18ec02fSPetter Reinholdtsen 				 uint8_t target, uint8_t lun, uint8_t channel)
657c18ec02fSPetter Reinholdtsen {
658c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
659c18ec02fSPetter Reinholdtsen 	struct ipmi_rs *rsp;
660c18ec02fSPetter Reinholdtsen 	uint8_t  bridged_request = 0;
661c18ec02fSPetter Reinholdtsen 	uint32_t save_addr;
662c18ec02fSPetter Reinholdtsen 	uint32_t save_channel;
663c18ec02fSPetter Reinholdtsen 
664c18ec02fSPetter Reinholdtsen 	if ( BRIDGE_TO_SENSOR(intf, target, channel) ) {
665c18ec02fSPetter Reinholdtsen 		bridged_request = 1;
666c18ec02fSPetter Reinholdtsen 		save_addr = intf->target_addr;
667c18ec02fSPetter Reinholdtsen 		intf->target_addr = target;
668c18ec02fSPetter Reinholdtsen 		save_channel = intf->target_channel;
669c18ec02fSPetter Reinholdtsen 		intf->target_channel = channel;
670c18ec02fSPetter Reinholdtsen 	}
671c18ec02fSPetter Reinholdtsen 
672c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof (req));
673c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_SE;
674c18ec02fSPetter Reinholdtsen 	req.msg.lun = lun;
675c18ec02fSPetter Reinholdtsen 	req.msg.cmd = GET_SENSOR_EVENT_ENABLE;
676c18ec02fSPetter Reinholdtsen 	req.msg.data = &sensor;
677c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 1;
678c18ec02fSPetter Reinholdtsen 
679c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
680c18ec02fSPetter Reinholdtsen 	if (bridged_request) {
681c18ec02fSPetter Reinholdtsen 		intf->target_addr = save_addr;
682c18ec02fSPetter Reinholdtsen 		intf->target_channel = save_channel;
683c18ec02fSPetter Reinholdtsen 	}
684c18ec02fSPetter Reinholdtsen 	return rsp;
685c18ec02fSPetter Reinholdtsen }
686c18ec02fSPetter Reinholdtsen 
687c18ec02fSPetter Reinholdtsen /* ipmi_sdr_get_sensor_type_desc  -  Get sensor type descriptor
688c18ec02fSPetter Reinholdtsen  *
689c18ec02fSPetter Reinholdtsen  * @type:	ipmi sensor type
690c18ec02fSPetter Reinholdtsen  *
691c18ec02fSPetter Reinholdtsen  * returns
692c18ec02fSPetter Reinholdtsen  *   string from sensor_type_desc
693c18ec02fSPetter Reinholdtsen  *   or "reserved"
694c18ec02fSPetter Reinholdtsen  *   or "OEM reserved"
695c18ec02fSPetter Reinholdtsen  */
696c18ec02fSPetter Reinholdtsen const char *
ipmi_sdr_get_sensor_type_desc(const uint8_t type)697c18ec02fSPetter Reinholdtsen ipmi_sdr_get_sensor_type_desc(const uint8_t type)
698c18ec02fSPetter Reinholdtsen {
699c18ec02fSPetter Reinholdtsen 	static char desc[32];
700c18ec02fSPetter Reinholdtsen 	memset(desc, 0, 32);
701c18ec02fSPetter Reinholdtsen 	if (type <= SENSOR_TYPE_MAX)
702c18ec02fSPetter Reinholdtsen 		return sensor_type_desc[type];
703c18ec02fSPetter Reinholdtsen 	if (type < 0xc0)
704c18ec02fSPetter Reinholdtsen 		snprintf(desc, 32, "reserved #%02x", type);
705c18ec02fSPetter Reinholdtsen 	else
706c18ec02fSPetter Reinholdtsen    {
707c18ec02fSPetter Reinholdtsen       snprintf(desc, 32, oemval2str(sdriana,type,ipmi_oem_sdr_type_vals),
708c18ec02fSPetter Reinholdtsen                                                                    type);
709c18ec02fSPetter Reinholdtsen    }
710c18ec02fSPetter Reinholdtsen 	return desc;
711c18ec02fSPetter Reinholdtsen }
712c18ec02fSPetter Reinholdtsen 
713c18ec02fSPetter Reinholdtsen /* ipmi_sdr_get_thresh_status  -  threshold status indicator
714c18ec02fSPetter Reinholdtsen  *
715c18ec02fSPetter Reinholdtsen  * @rsp:		response from Get Sensor Reading comand
716c18ec02fSPetter Reinholdtsen  * @validread:	validity of the status field argument
717c18ec02fSPetter Reinholdtsen  * @invalidstr:	string to return if status field is not valid
718c18ec02fSPetter Reinholdtsen  *
719c18ec02fSPetter Reinholdtsen  * returns
720c18ec02fSPetter Reinholdtsen  *   cr = critical
721c18ec02fSPetter Reinholdtsen  *   nc = non-critical
722c18ec02fSPetter Reinholdtsen  *   nr = non-recoverable
723c18ec02fSPetter Reinholdtsen  *   ok = ok
724c18ec02fSPetter Reinholdtsen  *   ns = not specified
725c18ec02fSPetter Reinholdtsen  */
726c18ec02fSPetter Reinholdtsen const char *
ipmi_sdr_get_thresh_status(struct sensor_reading * sr,const char * invalidstr)727c18ec02fSPetter Reinholdtsen ipmi_sdr_get_thresh_status(struct sensor_reading *sr, const char *invalidstr)
728c18ec02fSPetter Reinholdtsen {
729c18ec02fSPetter Reinholdtsen 	uint8_t stat;
730c18ec02fSPetter Reinholdtsen 	if (!sr->s_reading_valid) {
731c18ec02fSPetter Reinholdtsen 	    return invalidstr;
732c18ec02fSPetter Reinholdtsen 	}
733c18ec02fSPetter Reinholdtsen 	stat = sr->s_data2;
734c18ec02fSPetter Reinholdtsen 	if (stat & SDR_SENSOR_STAT_LO_NR) {
735c18ec02fSPetter Reinholdtsen 		if (verbose)
736c18ec02fSPetter Reinholdtsen 			return "Lower Non-Recoverable";
737c18ec02fSPetter Reinholdtsen 		else if (sdr_extended)
738c18ec02fSPetter Reinholdtsen 			return "lnr";
739c18ec02fSPetter Reinholdtsen 		else
740c18ec02fSPetter Reinholdtsen 			return "nr";
741c18ec02fSPetter Reinholdtsen 	} else if (stat & SDR_SENSOR_STAT_HI_NR) {
742c18ec02fSPetter Reinholdtsen 		if (verbose)
743c18ec02fSPetter Reinholdtsen 			return "Upper Non-Recoverable";
744c18ec02fSPetter Reinholdtsen 		else if (sdr_extended)
745c18ec02fSPetter Reinholdtsen 			return "unr";
746c18ec02fSPetter Reinholdtsen 		else
747c18ec02fSPetter Reinholdtsen 			return "nr";
748c18ec02fSPetter Reinholdtsen 	} else if (stat & SDR_SENSOR_STAT_LO_CR) {
749c18ec02fSPetter Reinholdtsen 		if (verbose)
750c18ec02fSPetter Reinholdtsen 			return "Lower Critical";
751c18ec02fSPetter Reinholdtsen 		else if (sdr_extended)
752c18ec02fSPetter Reinholdtsen 			return "lcr";
753c18ec02fSPetter Reinholdtsen 		else
754c18ec02fSPetter Reinholdtsen 			return "cr";
755c18ec02fSPetter Reinholdtsen 	} else if (stat & SDR_SENSOR_STAT_HI_CR) {
756c18ec02fSPetter Reinholdtsen 		if (verbose)
757c18ec02fSPetter Reinholdtsen 			return "Upper Critical";
758c18ec02fSPetter Reinholdtsen 		else if (sdr_extended)
759c18ec02fSPetter Reinholdtsen 			return "ucr";
760c18ec02fSPetter Reinholdtsen 		else
761c18ec02fSPetter Reinholdtsen 			return "cr";
762c18ec02fSPetter Reinholdtsen 	} else if (stat & SDR_SENSOR_STAT_LO_NC) {
763c18ec02fSPetter Reinholdtsen 		if (verbose)
764c18ec02fSPetter Reinholdtsen 			return "Lower Non-Critical";
765c18ec02fSPetter Reinholdtsen 		else if (sdr_extended)
766c18ec02fSPetter Reinholdtsen 			return "lnc";
767c18ec02fSPetter Reinholdtsen 		else
768c18ec02fSPetter Reinholdtsen 			return "nc";
769c18ec02fSPetter Reinholdtsen 	} else if (stat & SDR_SENSOR_STAT_HI_NC) {
770c18ec02fSPetter Reinholdtsen 		if (verbose)
771c18ec02fSPetter Reinholdtsen 			return "Upper Non-Critical";
772c18ec02fSPetter Reinholdtsen 		else if (sdr_extended)
773c18ec02fSPetter Reinholdtsen 			return "unc";
774c18ec02fSPetter Reinholdtsen 		else
775c18ec02fSPetter Reinholdtsen 			return "nc";
776c18ec02fSPetter Reinholdtsen 	}
777c18ec02fSPetter Reinholdtsen 	return "ok";
778c18ec02fSPetter Reinholdtsen }
779c18ec02fSPetter Reinholdtsen 
780c18ec02fSPetter Reinholdtsen /* ipmi_sdr_get_header  -  retreive SDR record header
781c18ec02fSPetter Reinholdtsen  *
782c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
783c18ec02fSPetter Reinholdtsen  * @itr:	sdr iterator
784c18ec02fSPetter Reinholdtsen  *
785c18ec02fSPetter Reinholdtsen  * returns pointer to static sensor retrieval struct
786c18ec02fSPetter Reinholdtsen  * returns NULL on error
787c18ec02fSPetter Reinholdtsen  */
788c18ec02fSPetter Reinholdtsen static struct sdr_get_rs *
ipmi_sdr_get_header(struct ipmi_intf * intf,struct ipmi_sdr_iterator * itr)789c18ec02fSPetter Reinholdtsen ipmi_sdr_get_header(struct ipmi_intf *intf, struct ipmi_sdr_iterator *itr)
790c18ec02fSPetter Reinholdtsen {
791c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
792c18ec02fSPetter Reinholdtsen 	struct ipmi_rs *rsp;
793c18ec02fSPetter Reinholdtsen 	struct sdr_get_rq sdr_rq;
794c18ec02fSPetter Reinholdtsen 	static struct sdr_get_rs sdr_rs;
795c18ec02fSPetter Reinholdtsen 	int try = 0;
796c18ec02fSPetter Reinholdtsen 
797c18ec02fSPetter Reinholdtsen 	memset(&sdr_rq, 0, sizeof (sdr_rq));
798c18ec02fSPetter Reinholdtsen 	sdr_rq.reserve_id = itr->reservation;
799c18ec02fSPetter Reinholdtsen 	sdr_rq.id = itr->next;
800c18ec02fSPetter Reinholdtsen 	sdr_rq.offset = 0;
801c18ec02fSPetter Reinholdtsen 	sdr_rq.length = 5;	/* only get the header */
802c18ec02fSPetter Reinholdtsen 
803c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof (req));
804c18ec02fSPetter Reinholdtsen 	if (itr->use_built_in == 0) {
805c18ec02fSPetter Reinholdtsen 		req.msg.netfn = IPMI_NETFN_STORAGE;
806c18ec02fSPetter Reinholdtsen 		req.msg.cmd = GET_SDR;
807c18ec02fSPetter Reinholdtsen 	} else {
808c18ec02fSPetter Reinholdtsen 		req.msg.netfn = IPMI_NETFN_SE;
809c18ec02fSPetter Reinholdtsen 		req.msg.cmd = GET_DEVICE_SDR;
810c18ec02fSPetter Reinholdtsen 	}
811c18ec02fSPetter Reinholdtsen 	req.msg.data = (uint8_t *) & sdr_rq;
812c18ec02fSPetter Reinholdtsen 	req.msg.data_len = sizeof (sdr_rq);
813c18ec02fSPetter Reinholdtsen 
814c18ec02fSPetter Reinholdtsen 	for (try = 0; try < 5; try++) {
815c18ec02fSPetter Reinholdtsen 		sdr_rq.reserve_id = itr->reservation;
816c18ec02fSPetter Reinholdtsen 		rsp = intf->sendrecv(intf, &req);
817c18ec02fSPetter Reinholdtsen 		if (rsp == NULL) {
818c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Get SDR %04x command failed",
819c18ec02fSPetter Reinholdtsen 				itr->next);
820c18ec02fSPetter Reinholdtsen 			continue;
821c18ec02fSPetter Reinholdtsen 		} else if (rsp->ccode == 0xc5) {
822c18ec02fSPetter Reinholdtsen 			/* lost reservation */
823c18ec02fSPetter Reinholdtsen 			lprintf(LOG_DEBUG, "SDR reservation %04x cancelled. "
824c18ec02fSPetter Reinholdtsen 				"Sleeping a bit and retrying...",
825c18ec02fSPetter Reinholdtsen 				itr->reservation);
826c18ec02fSPetter Reinholdtsen 
827c18ec02fSPetter Reinholdtsen 			sleep(rand() & 3);
828c18ec02fSPetter Reinholdtsen 
829c18ec02fSPetter Reinholdtsen 			if (ipmi_sdr_get_reservation(intf, itr->use_built_in,
830c18ec02fSPetter Reinholdtsen                                       &(itr->reservation)) < 0) {
831c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR,
832c18ec02fSPetter Reinholdtsen 					"Unable to renew SDR reservation");
833c18ec02fSPetter Reinholdtsen 				return NULL;
834c18ec02fSPetter Reinholdtsen 			}
835c18ec02fSPetter Reinholdtsen 		} else if (rsp->ccode > 0) {
836c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Get SDR %04x command failed: %s",
837c18ec02fSPetter Reinholdtsen 				itr->next, val2str(rsp->ccode,
838c18ec02fSPetter Reinholdtsen 						   completion_code_vals));
839c18ec02fSPetter Reinholdtsen 			continue;
840c18ec02fSPetter Reinholdtsen 		} else {
841c18ec02fSPetter Reinholdtsen 			break;
842c18ec02fSPetter Reinholdtsen 		}
843c18ec02fSPetter Reinholdtsen 	}
844c18ec02fSPetter Reinholdtsen 
845c18ec02fSPetter Reinholdtsen    if (try == 5)
846c18ec02fSPetter Reinholdtsen       return NULL;
847c18ec02fSPetter Reinholdtsen 
848c18ec02fSPetter Reinholdtsen 	if (!rsp)
849c18ec02fSPetter Reinholdtsen 		return NULL;
850c18ec02fSPetter Reinholdtsen 
851c18ec02fSPetter Reinholdtsen 	lprintf(LOG_DEBUG, "SDR record ID   : 0x%04x", itr->next);
852c18ec02fSPetter Reinholdtsen 
853c18ec02fSPetter Reinholdtsen 	memcpy(&sdr_rs, rsp->data, sizeof (sdr_rs));
854c18ec02fSPetter Reinholdtsen 
855c18ec02fSPetter Reinholdtsen 	if (sdr_rs.length == 0) {
856c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "SDR record id 0x%04x: invalid length %d",
857c18ec02fSPetter Reinholdtsen 			itr->next, sdr_rs.length);
858c18ec02fSPetter Reinholdtsen 		return NULL;
859c18ec02fSPetter Reinholdtsen 	}
860c18ec02fSPetter Reinholdtsen 
861c18ec02fSPetter Reinholdtsen 	/* achu (chu11 at llnl dot gov): - Some boards are stupid and
862c18ec02fSPetter Reinholdtsen 	 * return a record id from the Get SDR Record command
863c18ec02fSPetter Reinholdtsen 	 * different than the record id passed in.  If we find this
864c18ec02fSPetter Reinholdtsen 	 * situation, we cheat and put the original record id back in.
865c18ec02fSPetter Reinholdtsen 	 * Otherwise, a later Get SDR Record command will fail with
866c18ec02fSPetter Reinholdtsen 	 * completion code CBh = "Requested Sensor, data, or record
867c18ec02fSPetter Reinholdtsen 	 * not present"
868c18ec02fSPetter Reinholdtsen 	 */
869c18ec02fSPetter Reinholdtsen 	if (sdr_rs.id != itr->next) {
870c18ec02fSPetter Reinholdtsen 		lprintf(LOG_DEBUG, "SDR record id mismatch: 0x%04x", sdr_rs.id);
871c18ec02fSPetter Reinholdtsen 		sdr_rs.id = itr->next;
872c18ec02fSPetter Reinholdtsen 	}
873c18ec02fSPetter Reinholdtsen 
874c18ec02fSPetter Reinholdtsen 	lprintf(LOG_DEBUG, "SDR record type : 0x%02x", sdr_rs.type);
875c18ec02fSPetter Reinholdtsen 	lprintf(LOG_DEBUG, "SDR record next : 0x%04x", sdr_rs.next);
876c18ec02fSPetter Reinholdtsen 	lprintf(LOG_DEBUG, "SDR record bytes: %d", sdr_rs.length);
877c18ec02fSPetter Reinholdtsen 
878c18ec02fSPetter Reinholdtsen 	return &sdr_rs;
879c18ec02fSPetter Reinholdtsen }
880c18ec02fSPetter Reinholdtsen 
881c18ec02fSPetter Reinholdtsen /* ipmi_sdr_get_next_header  -  retreive next SDR header
882c18ec02fSPetter Reinholdtsen  *
883c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
884c18ec02fSPetter Reinholdtsen  * @itr:	sdr iterator
885c18ec02fSPetter Reinholdtsen  *
886c18ec02fSPetter Reinholdtsen  * returns pointer to sensor retrieval struct
887c18ec02fSPetter Reinholdtsen  * returns NULL on error
888c18ec02fSPetter Reinholdtsen  */
889c18ec02fSPetter Reinholdtsen struct sdr_get_rs *
ipmi_sdr_get_next_header(struct ipmi_intf * intf,struct ipmi_sdr_iterator * itr)890c18ec02fSPetter Reinholdtsen ipmi_sdr_get_next_header(struct ipmi_intf *intf, struct ipmi_sdr_iterator *itr)
891c18ec02fSPetter Reinholdtsen {
892c18ec02fSPetter Reinholdtsen 	struct sdr_get_rs *header;
893c18ec02fSPetter Reinholdtsen 
894c18ec02fSPetter Reinholdtsen 	if (itr->next == 0xffff)
895c18ec02fSPetter Reinholdtsen 		return NULL;
896c18ec02fSPetter Reinholdtsen 
897c18ec02fSPetter Reinholdtsen 	header = ipmi_sdr_get_header(intf, itr);
898c18ec02fSPetter Reinholdtsen 	if (header == NULL)
899c18ec02fSPetter Reinholdtsen 		return NULL;
900c18ec02fSPetter Reinholdtsen 
901c18ec02fSPetter Reinholdtsen 	itr->next = header->next;
902c18ec02fSPetter Reinholdtsen 
903c18ec02fSPetter Reinholdtsen 	return header;
904c18ec02fSPetter Reinholdtsen }
905c18ec02fSPetter Reinholdtsen 
906c18ec02fSPetter Reinholdtsen /*
907c18ec02fSPetter Reinholdtsen  * This macro is used to print nominal, normal and threshold settings,
908c18ec02fSPetter Reinholdtsen  * but it is not compatible with PRINT_NORMAL/PRINT_THRESH since it does
909c18ec02fSPetter Reinholdtsen  * not have the sensor.init.thresholds setting qualifier as is done in
910c18ec02fSPetter Reinholdtsen  * PRINT_THRESH.   This means CSV output can be different than non CSV
911c18ec02fSPetter Reinholdtsen  * output if sensor.init.thresholds is ever zero
912c18ec02fSPetter Reinholdtsen  */
913c18ec02fSPetter Reinholdtsen /* helper macro for printing CSV output for Full SDR Threshold reading */
914c18ec02fSPetter Reinholdtsen #define SENSOR_PRINT_CSV(FULLSENS, FLAG, READ)				\
915c18ec02fSPetter Reinholdtsen 	if ((FLAG)) {							\
916c18ec02fSPetter Reinholdtsen 		if (UNITS_ARE_DISCRETE((&FULLSENS->cmn)))		\
917c18ec02fSPetter Reinholdtsen 			printf("0x%02X,", READ); 			\
918c18ec02fSPetter Reinholdtsen 		else							\
919c18ec02fSPetter Reinholdtsen 			printf("%.3f,",	sdr_convert_sensor_reading(	\
920c18ec02fSPetter Reinholdtsen 			       (FULLSENS), READ));			\
921c18ec02fSPetter Reinholdtsen 	} else {							\
922c18ec02fSPetter Reinholdtsen 		printf(",");						\
923c18ec02fSPetter Reinholdtsen 	}
924c18ec02fSPetter Reinholdtsen 
925c18ec02fSPetter Reinholdtsen /* helper macro for printing analog values for Full SDR Threshold readings */
926c18ec02fSPetter Reinholdtsen #define SENSOR_PRINT_NORMAL(FULLSENS, NAME, READ)			\
927c18ec02fSPetter Reinholdtsen 	if ((FULLSENS)->analog_flag.READ != 0) {			\
928c18ec02fSPetter Reinholdtsen 		printf(" %-21s : ", NAME);				\
929c18ec02fSPetter Reinholdtsen 		if (UNITS_ARE_DISCRETE((&FULLSENS->cmn)))		\
930c18ec02fSPetter Reinholdtsen 			printf("0x%02X\n",				\
931c18ec02fSPetter Reinholdtsen 			       (FULLSENS)->READ);			\
932c18ec02fSPetter Reinholdtsen 		else							\
933c18ec02fSPetter Reinholdtsen 			printf("%.3f\n", sdr_convert_sensor_reading(	\
934c18ec02fSPetter Reinholdtsen 				         (FULLSENS), (FULLSENS)->READ));\
935c18ec02fSPetter Reinholdtsen 	}
936c18ec02fSPetter Reinholdtsen 
937c18ec02fSPetter Reinholdtsen /* helper macro for printing Full SDR sensor Thresholds */
938c18ec02fSPetter Reinholdtsen #define SENSOR_PRINT_THRESH(FULLSENS, NAME, READ, FLAG)			\
939c18ec02fSPetter Reinholdtsen 	if ((FULLSENS)->cmn.sensor.init.thresholds &&			\
940c18ec02fSPetter Reinholdtsen 	    (FULLSENS)->cmn.mask.type.threshold.read.FLAG != 0) {	\
941c18ec02fSPetter Reinholdtsen 		printf(" %-21s : ", NAME);				\
942c18ec02fSPetter Reinholdtsen 		if (UNITS_ARE_DISCRETE((&FULLSENS->cmn)))		\
943c18ec02fSPetter Reinholdtsen 			printf("0x%02X\n",				\
944c18ec02fSPetter Reinholdtsen 			       (FULLSENS)->threshold.READ);		\
945c18ec02fSPetter Reinholdtsen 		else                                        		\
946c18ec02fSPetter Reinholdtsen 			printf("%.3f\n", sdr_convert_sensor_reading(	\
947c18ec02fSPetter Reinholdtsen 			     (FULLSENS), (FULLSENS)->threshold.READ));	\
948c18ec02fSPetter Reinholdtsen 	}
949c18ec02fSPetter Reinholdtsen 
950c18ec02fSPetter Reinholdtsen int
ipmi_sdr_print_sensor_event_status(struct ipmi_intf * intf,uint8_t sensor_num,uint8_t sensor_type,uint8_t event_type,int numeric_fmt,uint8_t target,uint8_t lun,uint8_t channel)951c18ec02fSPetter Reinholdtsen ipmi_sdr_print_sensor_event_status(struct ipmi_intf *intf,
952c18ec02fSPetter Reinholdtsen 				   uint8_t sensor_num,
953c18ec02fSPetter Reinholdtsen 				   uint8_t sensor_type,
954c18ec02fSPetter Reinholdtsen 				   uint8_t event_type, int numeric_fmt,
955c18ec02fSPetter Reinholdtsen 				   uint8_t target, uint8_t lun, uint8_t channel)
956c18ec02fSPetter Reinholdtsen {
957c18ec02fSPetter Reinholdtsen 	struct ipmi_rs *rsp;
958c18ec02fSPetter Reinholdtsen 	int i;
959c18ec02fSPetter Reinholdtsen 	const struct valstr assert_cond_1[] = {
960c18ec02fSPetter Reinholdtsen 		{0x80, "unc+"},
961c18ec02fSPetter Reinholdtsen 		{0x40, "unc-"},
962c18ec02fSPetter Reinholdtsen 		{0x20, "lnr+"},
963c18ec02fSPetter Reinholdtsen 		{0x10, "lnr-"},
964c18ec02fSPetter Reinholdtsen 		{0x08, "lcr+"},
965c18ec02fSPetter Reinholdtsen 		{0x04, "lcr-"},
966c18ec02fSPetter Reinholdtsen 		{0x02, "lnc+"},
967c18ec02fSPetter Reinholdtsen 		{0x01, "lnc-"},
968c18ec02fSPetter Reinholdtsen 		{0x00, NULL},
969c18ec02fSPetter Reinholdtsen 	};
970c18ec02fSPetter Reinholdtsen 	const struct valstr assert_cond_2[] = {
971c18ec02fSPetter Reinholdtsen 		{0x08, "unr+"},
972c18ec02fSPetter Reinholdtsen 		{0x04, "unr-"},
973c18ec02fSPetter Reinholdtsen 		{0x02, "ucr+"},
974c18ec02fSPetter Reinholdtsen 		{0x01, "ucr-"},
975c18ec02fSPetter Reinholdtsen 		{0x00, NULL},
976c18ec02fSPetter Reinholdtsen 	};
977c18ec02fSPetter Reinholdtsen 
978c18ec02fSPetter Reinholdtsen 	rsp = ipmi_sdr_get_sensor_event_status(intf, sensor_num,
979c18ec02fSPetter Reinholdtsen 						target, lun, channel);
980c18ec02fSPetter Reinholdtsen 
981c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
982c18ec02fSPetter Reinholdtsen 		lprintf(LOG_DEBUG,
983c18ec02fSPetter Reinholdtsen 			"Error reading event status for sensor #%02x",
984c18ec02fSPetter Reinholdtsen 			sensor_num);
985c18ec02fSPetter Reinholdtsen 		return -1;
986c18ec02fSPetter Reinholdtsen 	}
987c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
988c18ec02fSPetter Reinholdtsen 		lprintf(LOG_DEBUG,
989c18ec02fSPetter Reinholdtsen 			"Error reading event status for sensor #%02x: %s",
990c18ec02fSPetter Reinholdtsen 			sensor_num, val2str(rsp->ccode, completion_code_vals));
991c18ec02fSPetter Reinholdtsen 		return -1;
992c18ec02fSPetter Reinholdtsen 	}
993c18ec02fSPetter Reinholdtsen 	/* There is an assumption here that data_len >= 1 */
994c18ec02fSPetter Reinholdtsen 	if (IS_READING_UNAVAILABLE(rsp->data[0])) {
995c18ec02fSPetter Reinholdtsen 		printf(" Event Status          : Unavailable\n");
996c18ec02fSPetter Reinholdtsen 		return 0;
997c18ec02fSPetter Reinholdtsen 	}
998c18ec02fSPetter Reinholdtsen 	if (IS_SCANNING_DISABLED(rsp->data[0])) {
999c18ec02fSPetter Reinholdtsen 		//printf(" Event Status          : Scanning Disabled\n");
1000c18ec02fSPetter Reinholdtsen 		//return 0;
1001c18ec02fSPetter Reinholdtsen 	}
1002c18ec02fSPetter Reinholdtsen 	if (IS_EVENT_MSG_DISABLED(rsp->data[0])) {
1003c18ec02fSPetter Reinholdtsen 		printf(" Event Status          : Event Messages Disabled\n");
1004c18ec02fSPetter Reinholdtsen 		//return 0;
1005c18ec02fSPetter Reinholdtsen 	}
1006c18ec02fSPetter Reinholdtsen 
1007c18ec02fSPetter Reinholdtsen 	switch (numeric_fmt) {
1008c18ec02fSPetter Reinholdtsen 	case DISCRETE_SENSOR:
1009c18ec02fSPetter Reinholdtsen 		if (rsp->data_len == 2) {
1010c18ec02fSPetter Reinholdtsen 			ipmi_sdr_print_discrete_state("Assertion Events",
1011c18ec02fSPetter Reinholdtsen 						      sensor_type, event_type,
1012c18ec02fSPetter Reinholdtsen 						      rsp->data[1], 0);
1013c18ec02fSPetter Reinholdtsen 		} else if (rsp->data_len > 2) {
1014c18ec02fSPetter Reinholdtsen 			ipmi_sdr_print_discrete_state("Assertion Events",
1015c18ec02fSPetter Reinholdtsen 						      sensor_type, event_type,
1016c18ec02fSPetter Reinholdtsen 						      rsp->data[1],
1017c18ec02fSPetter Reinholdtsen 						      rsp->data[2]);
1018c18ec02fSPetter Reinholdtsen 		}
1019c18ec02fSPetter Reinholdtsen 		if (rsp->data_len == 4) {
1020c18ec02fSPetter Reinholdtsen 			ipmi_sdr_print_discrete_state("Deassertion Events",
1021c18ec02fSPetter Reinholdtsen 						      sensor_type, event_type,
1022c18ec02fSPetter Reinholdtsen 						      rsp->data[3], 0);
1023c18ec02fSPetter Reinholdtsen 		} else if (rsp->data_len > 4) {
1024c18ec02fSPetter Reinholdtsen 			ipmi_sdr_print_discrete_state("Deassertion Events",
1025c18ec02fSPetter Reinholdtsen 						      sensor_type, event_type,
1026c18ec02fSPetter Reinholdtsen 						      rsp->data[3],
1027c18ec02fSPetter Reinholdtsen 						      rsp->data[4]);
1028c18ec02fSPetter Reinholdtsen 		}
1029c18ec02fSPetter Reinholdtsen 		break;
1030c18ec02fSPetter Reinholdtsen 
1031c18ec02fSPetter Reinholdtsen 	case ANALOG_SENSOR:
1032c18ec02fSPetter Reinholdtsen 		printf(" Assertion Events      : ");
1033c18ec02fSPetter Reinholdtsen 		for (i = 0; i < 8; i++) {
1034c18ec02fSPetter Reinholdtsen 			if (rsp->data[1] & (1 << i))
1035c18ec02fSPetter Reinholdtsen 				printf("%s ", val2str(1 << i, assert_cond_1));
1036c18ec02fSPetter Reinholdtsen 		}
1037c18ec02fSPetter Reinholdtsen 		if (rsp->data_len > 2) {
1038c18ec02fSPetter Reinholdtsen 			for (i = 0; i < 4; i++) {
1039c18ec02fSPetter Reinholdtsen 				if (rsp->data[2] & (1 << i))
1040c18ec02fSPetter Reinholdtsen 					printf("%s ",
1041c18ec02fSPetter Reinholdtsen 					       val2str(1 << i, assert_cond_2));
1042c18ec02fSPetter Reinholdtsen 			}
1043c18ec02fSPetter Reinholdtsen 			printf("\n");
1044c18ec02fSPetter Reinholdtsen 			if ((rsp->data_len == 4 && rsp->data[3] != 0) ||
1045c18ec02fSPetter Reinholdtsen 			    (rsp->data_len > 4
1046c18ec02fSPetter Reinholdtsen 			     && (rsp->data[3] != 0 && rsp->data[4] != 0))) {
1047c18ec02fSPetter Reinholdtsen 				printf(" Deassertion Events    : ");
1048c18ec02fSPetter Reinholdtsen 				for (i = 0; i < 8; i++) {
1049c18ec02fSPetter Reinholdtsen 					if (rsp->data[3] & (1 << i))
1050c18ec02fSPetter Reinholdtsen 						printf("%s ",
1051c18ec02fSPetter Reinholdtsen 						       val2str(1 << i,
1052c18ec02fSPetter Reinholdtsen 							       assert_cond_1));
1053c18ec02fSPetter Reinholdtsen 				}
1054c18ec02fSPetter Reinholdtsen 				if (rsp->data_len > 4) {
1055c18ec02fSPetter Reinholdtsen 					for (i = 0; i < 4; i++) {
1056c18ec02fSPetter Reinholdtsen 						if (rsp->data[4] & (1 << i))
1057c18ec02fSPetter Reinholdtsen 							printf("%s ",
1058c18ec02fSPetter Reinholdtsen 							       val2str(1 << i,
1059c18ec02fSPetter Reinholdtsen 								       assert_cond_2));
1060c18ec02fSPetter Reinholdtsen 					}
1061c18ec02fSPetter Reinholdtsen 				}
1062c18ec02fSPetter Reinholdtsen 				printf("\n");
1063c18ec02fSPetter Reinholdtsen 			}
1064c18ec02fSPetter Reinholdtsen 		} else {
1065c18ec02fSPetter Reinholdtsen 			printf("\n");
1066c18ec02fSPetter Reinholdtsen 		}
1067c18ec02fSPetter Reinholdtsen 		break;
1068c18ec02fSPetter Reinholdtsen 
1069c18ec02fSPetter Reinholdtsen 	default:
1070c18ec02fSPetter Reinholdtsen 		break;
1071c18ec02fSPetter Reinholdtsen 	}
1072c18ec02fSPetter Reinholdtsen 
1073c18ec02fSPetter Reinholdtsen 	return 0;
1074c18ec02fSPetter Reinholdtsen }
1075c18ec02fSPetter Reinholdtsen 
1076c18ec02fSPetter Reinholdtsen static int
ipmi_sdr_print_sensor_mask(struct sdr_record_mask * mask,uint8_t sensor_type,uint8_t event_type,int numeric_fmt)1077c18ec02fSPetter Reinholdtsen ipmi_sdr_print_sensor_mask(struct sdr_record_mask *mask,
1078c18ec02fSPetter Reinholdtsen 			   uint8_t sensor_type,
1079c18ec02fSPetter Reinholdtsen 			   uint8_t event_type, int numeric_fmt)
1080c18ec02fSPetter Reinholdtsen {
1081c18ec02fSPetter Reinholdtsen 	/* iceblink - don't print some event status fields - CVS rev1.53 */
1082c18ec02fSPetter Reinholdtsen 	return 0;
1083c18ec02fSPetter Reinholdtsen 
1084c18ec02fSPetter Reinholdtsen 	switch (numeric_fmt) {
1085c18ec02fSPetter Reinholdtsen 	case DISCRETE_SENSOR:
1086c18ec02fSPetter Reinholdtsen 		ipmi_sdr_print_discrete_state("Assert Event Mask", sensor_type,
1087c18ec02fSPetter Reinholdtsen 					      event_type,
1088c18ec02fSPetter Reinholdtsen 					      mask->type.discrete.
1089c18ec02fSPetter Reinholdtsen 					      assert_event & 0xff,
1090c18ec02fSPetter Reinholdtsen 					      (mask->type.discrete.
1091c18ec02fSPetter Reinholdtsen 					       assert_event & 0xff00) >> 8);
1092c18ec02fSPetter Reinholdtsen 		ipmi_sdr_print_discrete_state("Deassert Event Mask",
1093c18ec02fSPetter Reinholdtsen 					      sensor_type, event_type,
1094c18ec02fSPetter Reinholdtsen 					      mask->type.discrete.
1095c18ec02fSPetter Reinholdtsen 					      deassert_event & 0xff,
1096c18ec02fSPetter Reinholdtsen 					      (mask->type.discrete.
1097c18ec02fSPetter Reinholdtsen 					       deassert_event & 0xff00) >> 8);
1098c18ec02fSPetter Reinholdtsen 		break;
1099c18ec02fSPetter Reinholdtsen 
1100c18ec02fSPetter Reinholdtsen 	case ANALOG_SENSOR:
1101c18ec02fSPetter Reinholdtsen 		printf(" Assert Event Mask     : ");
1102c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.assert_lnr_high)
1103c18ec02fSPetter Reinholdtsen 			printf("lnr+ ");
1104c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.assert_lnr_low)
1105c18ec02fSPetter Reinholdtsen 			printf("lnr- ");
1106c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.assert_lcr_high)
1107c18ec02fSPetter Reinholdtsen 			printf("lcr+ ");
1108c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.assert_lcr_low)
1109c18ec02fSPetter Reinholdtsen 			printf("lcr- ");
1110c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.assert_lnc_high)
1111c18ec02fSPetter Reinholdtsen 			printf("lnc+ ");
1112c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.assert_lnc_low)
1113c18ec02fSPetter Reinholdtsen 			printf("lnc- ");
1114c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.assert_unc_high)
1115c18ec02fSPetter Reinholdtsen 			printf("unc+ ");
1116c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.assert_unc_low)
1117c18ec02fSPetter Reinholdtsen 			printf("unc- ");
1118c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.assert_ucr_high)
1119c18ec02fSPetter Reinholdtsen 			printf("ucr+ ");
1120c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.assert_ucr_low)
1121c18ec02fSPetter Reinholdtsen 			printf("ucr- ");
1122c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.assert_unr_high)
1123c18ec02fSPetter Reinholdtsen 			printf("unr+ ");
1124c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.assert_unr_low)
1125c18ec02fSPetter Reinholdtsen 			printf("unr- ");
1126c18ec02fSPetter Reinholdtsen 		printf("\n");
1127c18ec02fSPetter Reinholdtsen 
1128c18ec02fSPetter Reinholdtsen 		printf(" Deassert Event Mask   : ");
1129c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.deassert_lnr_high)
1130c18ec02fSPetter Reinholdtsen 			printf("lnr+ ");
1131c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.deassert_lnr_low)
1132c18ec02fSPetter Reinholdtsen 			printf("lnr- ");
1133c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.deassert_lcr_high)
1134c18ec02fSPetter Reinholdtsen 			printf("lcr+ ");
1135c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.deassert_lcr_low)
1136c18ec02fSPetter Reinholdtsen 			printf("lcr- ");
1137c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.deassert_lnc_high)
1138c18ec02fSPetter Reinholdtsen 			printf("lnc+ ");
1139c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.deassert_lnc_low)
1140c18ec02fSPetter Reinholdtsen 			printf("lnc- ");
1141c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.deassert_unc_high)
1142c18ec02fSPetter Reinholdtsen 			printf("unc+ ");
1143c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.deassert_unc_low)
1144c18ec02fSPetter Reinholdtsen 			printf("unc- ");
1145c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.deassert_ucr_high)
1146c18ec02fSPetter Reinholdtsen 			printf("ucr+ ");
1147c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.deassert_ucr_low)
1148c18ec02fSPetter Reinholdtsen 			printf("ucr- ");
1149c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.deassert_unr_high)
1150c18ec02fSPetter Reinholdtsen 			printf("unr+ ");
1151c18ec02fSPetter Reinholdtsen 		if (mask->type.threshold.deassert_unr_low)
1152c18ec02fSPetter Reinholdtsen 			printf("unr- ");
1153c18ec02fSPetter Reinholdtsen 		printf("\n");
1154c18ec02fSPetter Reinholdtsen 		break;
1155c18ec02fSPetter Reinholdtsen 
1156c18ec02fSPetter Reinholdtsen 	default:
1157c18ec02fSPetter Reinholdtsen 		break;
1158c18ec02fSPetter Reinholdtsen 	}
1159c18ec02fSPetter Reinholdtsen 
1160c18ec02fSPetter Reinholdtsen 	return 0;
1161c18ec02fSPetter Reinholdtsen }
1162c18ec02fSPetter Reinholdtsen 
1163c18ec02fSPetter Reinholdtsen int
ipmi_sdr_print_sensor_event_enable(struct ipmi_intf * intf,uint8_t sensor_num,uint8_t sensor_type,uint8_t event_type,int numeric_fmt,uint8_t target,uint8_t lun,uint8_t channel)1164c18ec02fSPetter Reinholdtsen ipmi_sdr_print_sensor_event_enable(struct ipmi_intf *intf,
1165c18ec02fSPetter Reinholdtsen 				   uint8_t sensor_num,
1166c18ec02fSPetter Reinholdtsen 				   uint8_t sensor_type,
1167c18ec02fSPetter Reinholdtsen 				   uint8_t event_type, int numeric_fmt,
1168c18ec02fSPetter Reinholdtsen 				   uint8_t target, uint8_t lun, uint8_t channel)
1169c18ec02fSPetter Reinholdtsen {
1170c18ec02fSPetter Reinholdtsen 	struct ipmi_rs *rsp;
1171c18ec02fSPetter Reinholdtsen 	int i;
1172c18ec02fSPetter Reinholdtsen 	const struct valstr assert_cond_1[] = {
1173c18ec02fSPetter Reinholdtsen 		{0x80, "unc+"},
1174c18ec02fSPetter Reinholdtsen 		{0x40, "unc-"},
1175c18ec02fSPetter Reinholdtsen 		{0x20, "lnr+"},
1176c18ec02fSPetter Reinholdtsen 		{0x10, "lnr-"},
1177c18ec02fSPetter Reinholdtsen 		{0x08, "lcr+"},
1178c18ec02fSPetter Reinholdtsen 		{0x04, "lcr-"},
1179c18ec02fSPetter Reinholdtsen 		{0x02, "lnc+"},
1180c18ec02fSPetter Reinholdtsen 		{0x01, "lnc-"},
1181c18ec02fSPetter Reinholdtsen 		{0x00, NULL},
1182c18ec02fSPetter Reinholdtsen 	};
1183c18ec02fSPetter Reinholdtsen 	const struct valstr assert_cond_2[] = {
1184c18ec02fSPetter Reinholdtsen 		{0x08, "unr+"},
1185c18ec02fSPetter Reinholdtsen 		{0x04, "unr-"},
1186c18ec02fSPetter Reinholdtsen 		{0x02, "ucr+"},
1187c18ec02fSPetter Reinholdtsen 		{0x01, "ucr-"},
1188c18ec02fSPetter Reinholdtsen 		{0x00, NULL},
1189c18ec02fSPetter Reinholdtsen 	};
1190c18ec02fSPetter Reinholdtsen 
1191c18ec02fSPetter Reinholdtsen 	rsp = ipmi_sdr_get_sensor_event_enable(intf, sensor_num,
1192c18ec02fSPetter Reinholdtsen 						target, lun, channel);
1193c18ec02fSPetter Reinholdtsen 
1194c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
1195c18ec02fSPetter Reinholdtsen 		lprintf(LOG_DEBUG,
1196c18ec02fSPetter Reinholdtsen 			"Error reading event enable for sensor #%02x",
1197c18ec02fSPetter Reinholdtsen 			sensor_num);
1198c18ec02fSPetter Reinholdtsen 		return -1;
1199c18ec02fSPetter Reinholdtsen 	}
1200c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
1201c18ec02fSPetter Reinholdtsen 		lprintf(LOG_DEBUG,
1202c18ec02fSPetter Reinholdtsen 			"Error reading event enable for sensor #%02x: %s",
1203c18ec02fSPetter Reinholdtsen 			sensor_num, val2str(rsp->ccode, completion_code_vals));
1204c18ec02fSPetter Reinholdtsen 		return -1;
1205c18ec02fSPetter Reinholdtsen 	}
1206c18ec02fSPetter Reinholdtsen 
1207c18ec02fSPetter Reinholdtsen 	if (IS_SCANNING_DISABLED(rsp->data[0])) {
1208c18ec02fSPetter Reinholdtsen 		//printf(" Event Enable          : Scanning Disabled\n");
1209c18ec02fSPetter Reinholdtsen 		//return 0;
1210c18ec02fSPetter Reinholdtsen 	}
1211c18ec02fSPetter Reinholdtsen 	if (IS_EVENT_MSG_DISABLED(rsp->data[0])) {
1212c18ec02fSPetter Reinholdtsen 		printf(" Event Enable          : Event Messages Disabled\n");
1213c18ec02fSPetter Reinholdtsen 		//return 0;
1214c18ec02fSPetter Reinholdtsen 	}
1215c18ec02fSPetter Reinholdtsen 
1216c18ec02fSPetter Reinholdtsen 	switch (numeric_fmt) {
1217c18ec02fSPetter Reinholdtsen 	case DISCRETE_SENSOR:
1218c18ec02fSPetter Reinholdtsen 		/* discrete */
1219c18ec02fSPetter Reinholdtsen 		if (rsp->data_len == 2) {
1220c18ec02fSPetter Reinholdtsen 			ipmi_sdr_print_discrete_state("Assertions Enabled",
1221c18ec02fSPetter Reinholdtsen 						      sensor_type, event_type,
1222c18ec02fSPetter Reinholdtsen 						      rsp->data[1], 0);
1223c18ec02fSPetter Reinholdtsen 		} else if (rsp->data_len > 2) {
1224c18ec02fSPetter Reinholdtsen 			ipmi_sdr_print_discrete_state("Assertions Enabled",
1225c18ec02fSPetter Reinholdtsen 						      sensor_type, event_type,
1226c18ec02fSPetter Reinholdtsen 						      rsp->data[1],
1227c18ec02fSPetter Reinholdtsen 						      rsp->data[2]);
1228c18ec02fSPetter Reinholdtsen 		}
1229c18ec02fSPetter Reinholdtsen 		if (rsp->data_len == 4) {
1230c18ec02fSPetter Reinholdtsen 			ipmi_sdr_print_discrete_state("Deassertions Enabled",
1231c18ec02fSPetter Reinholdtsen 						      sensor_type, event_type,
1232c18ec02fSPetter Reinholdtsen 						      rsp->data[3], 0);
1233c18ec02fSPetter Reinholdtsen 		} else if (rsp->data_len > 4) {
1234c18ec02fSPetter Reinholdtsen 			ipmi_sdr_print_discrete_state("Deassertions Enabled",
1235c18ec02fSPetter Reinholdtsen 						      sensor_type, event_type,
1236c18ec02fSPetter Reinholdtsen 						      rsp->data[3],
1237c18ec02fSPetter Reinholdtsen 						      rsp->data[4]);
1238c18ec02fSPetter Reinholdtsen 		}
1239c18ec02fSPetter Reinholdtsen 		break;
1240c18ec02fSPetter Reinholdtsen 
1241c18ec02fSPetter Reinholdtsen 	case ANALOG_SENSOR:
1242c18ec02fSPetter Reinholdtsen 		/* analog */
1243c18ec02fSPetter Reinholdtsen 		printf(" Assertions Enabled    : ");
1244c18ec02fSPetter Reinholdtsen 		for (i = 0; i < 8; i++) {
1245c18ec02fSPetter Reinholdtsen 			if (rsp->data[1] & (1 << i))
1246c18ec02fSPetter Reinholdtsen 				printf("%s ", val2str(1 << i, assert_cond_1));
1247c18ec02fSPetter Reinholdtsen 		}
1248c18ec02fSPetter Reinholdtsen 		if (rsp->data_len > 2) {
1249c18ec02fSPetter Reinholdtsen 			for (i = 0; i < 4; i++) {
1250c18ec02fSPetter Reinholdtsen 				if (rsp->data[2] & (1 << i))
1251c18ec02fSPetter Reinholdtsen 					printf("%s ",
1252c18ec02fSPetter Reinholdtsen 					       val2str(1 << i, assert_cond_2));
1253c18ec02fSPetter Reinholdtsen 			}
1254c18ec02fSPetter Reinholdtsen 			printf("\n");
1255c18ec02fSPetter Reinholdtsen 			if ((rsp->data_len == 4 && rsp->data[3] != 0) ||
1256c18ec02fSPetter Reinholdtsen 			    (rsp->data_len > 4
1257c18ec02fSPetter Reinholdtsen 			     && (rsp->data[3] != 0 || rsp->data[4] != 0))) {
1258c18ec02fSPetter Reinholdtsen 				printf(" Deassertions Enabled  : ");
1259c18ec02fSPetter Reinholdtsen 				for (i = 0; i < 8; i++) {
1260c18ec02fSPetter Reinholdtsen 					if (rsp->data[3] & (1 << i))
1261c18ec02fSPetter Reinholdtsen 						printf("%s ",
1262c18ec02fSPetter Reinholdtsen 						       val2str(1 << i,
1263c18ec02fSPetter Reinholdtsen 							       assert_cond_1));
1264c18ec02fSPetter Reinholdtsen 				}
1265c18ec02fSPetter Reinholdtsen 				if (rsp->data_len > 4) {
1266c18ec02fSPetter Reinholdtsen 					for (i = 0; i < 4; i++) {
1267c18ec02fSPetter Reinholdtsen 						if (rsp->data[4] & (1 << i))
1268c18ec02fSPetter Reinholdtsen 							printf("%s ",
1269c18ec02fSPetter Reinholdtsen 							       val2str(1 << i,
1270c18ec02fSPetter Reinholdtsen 								       assert_cond_2));
1271c18ec02fSPetter Reinholdtsen 					}
1272c18ec02fSPetter Reinholdtsen 				}
1273c18ec02fSPetter Reinholdtsen 				printf("\n");
1274c18ec02fSPetter Reinholdtsen 			}
1275c18ec02fSPetter Reinholdtsen 		} else {
1276c18ec02fSPetter Reinholdtsen 			printf("\n");
1277c18ec02fSPetter Reinholdtsen 		}
1278c18ec02fSPetter Reinholdtsen 		break;
1279c18ec02fSPetter Reinholdtsen 
1280c18ec02fSPetter Reinholdtsen 	default:
1281c18ec02fSPetter Reinholdtsen 		break;
1282c18ec02fSPetter Reinholdtsen 	}
1283c18ec02fSPetter Reinholdtsen 
1284c18ec02fSPetter Reinholdtsen 	return 0;
1285c18ec02fSPetter Reinholdtsen }
1286c18ec02fSPetter Reinholdtsen 
1287c18ec02fSPetter Reinholdtsen /* ipmi_sdr_print_sensor_hysteresis  -  print hysteresis for Discrete & Analog
1288c18ec02fSPetter Reinholdtsen  *
1289c18ec02fSPetter Reinholdtsen  * @sensor:		Common Sensor Record SDR pointer
1290c18ec02fSPetter Reinholdtsen  * @full:		Full Sensor Record SDR pointer (if applicable)
1291c18ec02fSPetter Reinholdtsen  * @hysteresis_value:	Actual hysteresis value
1292c18ec02fSPetter Reinholdtsen  * @hvstr:		hysteresis value Identifier String
1293c18ec02fSPetter Reinholdtsen  *
1294c18ec02fSPetter Reinholdtsen  * returns void
1295c18ec02fSPetter Reinholdtsen  */
1296c18ec02fSPetter Reinholdtsen void
ipmi_sdr_print_sensor_hysteresis(struct sdr_record_common_sensor * sensor,struct sdr_record_full_sensor * full,uint8_t hysteresis_value,const char * hvstr)1297c18ec02fSPetter Reinholdtsen ipmi_sdr_print_sensor_hysteresis(struct sdr_record_common_sensor *sensor,
1298c18ec02fSPetter Reinholdtsen 		 struct sdr_record_full_sensor   *full,
1299c18ec02fSPetter Reinholdtsen 		 uint8_t hysteresis_value,
1300c18ec02fSPetter Reinholdtsen 		 const char *hvstr)
1301c18ec02fSPetter Reinholdtsen {
1302c18ec02fSPetter Reinholdtsen 	/*
1303c18ec02fSPetter Reinholdtsen 	 * compact can have pos/neg hysteresis, but they cannot be analog!
1304c18ec02fSPetter Reinholdtsen 	 * We use not full in addition to our discrete units check just in
1305c18ec02fSPetter Reinholdtsen 	 * case a compact sensor is incorrectly identified as analog.
1306c18ec02fSPetter Reinholdtsen 	 */
1307c18ec02fSPetter Reinholdtsen 	if (!full || UNITS_ARE_DISCRETE(sensor)) {
1308c18ec02fSPetter Reinholdtsen 		if ( hysteresis_value == 0x00 || hysteresis_value == 0xff ) {
1309c18ec02fSPetter Reinholdtsen 			printf(" %s   : Unspecified\n", hvstr);
1310c18ec02fSPetter Reinholdtsen 		} else {
1311c18ec02fSPetter Reinholdtsen 			printf(" %s   : 0x%02X\n", hvstr, hysteresis_value);
1312c18ec02fSPetter Reinholdtsen 		}
1313c18ec02fSPetter Reinholdtsen 		return;
1314c18ec02fSPetter Reinholdtsen 	}
1315c18ec02fSPetter Reinholdtsen 	/* A Full analog sensor */
1316c18ec02fSPetter Reinholdtsen 	double creading = sdr_convert_sensor_hysterisis(full, hysteresis_value);
1317c18ec02fSPetter Reinholdtsen 	if ( hysteresis_value == 0x00 || hysteresis_value == 0xff ||
1318c18ec02fSPetter Reinholdtsen 	     creading == 0.0 ) {
1319c18ec02fSPetter Reinholdtsen 		printf(" %s   : Unspecified\n", hvstr);
1320c18ec02fSPetter Reinholdtsen 	} else {
1321c18ec02fSPetter Reinholdtsen 		printf(" %s   : %.3f\n", hvstr, creading);
1322c18ec02fSPetter Reinholdtsen 	}
1323c18ec02fSPetter Reinholdtsen }
1324c18ec02fSPetter Reinholdtsen 
1325c18ec02fSPetter Reinholdtsen /* print_sensor_min_max  -  print Discrete & Analog Minimum/Maximum Sensor Range
1326c18ec02fSPetter Reinholdtsen  *
1327c18ec02fSPetter Reinholdtsen  * @full:		Full Sensor Record SDR pointer
1328c18ec02fSPetter Reinholdtsen  *
1329c18ec02fSPetter Reinholdtsen  * returns void
1330c18ec02fSPetter Reinholdtsen  */
1331c18ec02fSPetter Reinholdtsen static void
print_sensor_min_max(struct sdr_record_full_sensor * full)1332c18ec02fSPetter Reinholdtsen print_sensor_min_max(struct sdr_record_full_sensor *full)
1333c18ec02fSPetter Reinholdtsen {
1334c18ec02fSPetter Reinholdtsen 	if (!full) { /* No min/max for compact SDR record */
1335c18ec02fSPetter Reinholdtsen 	    return;
1336c18ec02fSPetter Reinholdtsen 	}
1337c18ec02fSPetter Reinholdtsen 
1338c18ec02fSPetter Reinholdtsen 	double creading = 0.0;
1339c18ec02fSPetter Reinholdtsen 	uint8_t is_analog = !UNITS_ARE_DISCRETE(&full->cmn);
1340c18ec02fSPetter Reinholdtsen 	if (is_analog)
1341c18ec02fSPetter Reinholdtsen 		creading = sdr_convert_sensor_reading(full, full->sensor_min);
1342c18ec02fSPetter Reinholdtsen 	if ((full->cmn.unit.analog == 0 && full->sensor_min == 0x00) ||
1343c18ec02fSPetter Reinholdtsen 	    (full->cmn.unit.analog == 1 && full->sensor_min == 0xff) ||
1344c18ec02fSPetter Reinholdtsen 	    (full->cmn.unit.analog == 2 && full->sensor_min == 0x80) ||
1345c18ec02fSPetter Reinholdtsen 	    (is_analog && (creading == 0.0)))
1346c18ec02fSPetter Reinholdtsen 		printf(" Minimum sensor range  : Unspecified\n");
1347c18ec02fSPetter Reinholdtsen 	else {
1348c18ec02fSPetter Reinholdtsen 		if (is_analog)
1349c18ec02fSPetter Reinholdtsen 			printf(" Minimum sensor range  : %.3f\n", creading);
1350c18ec02fSPetter Reinholdtsen 		else
1351c18ec02fSPetter Reinholdtsen 			printf(" Minimum sensor range  : 0x%02X\n", full->sensor_min);
1352c18ec02fSPetter Reinholdtsen 
1353c18ec02fSPetter Reinholdtsen 	}
1354c18ec02fSPetter Reinholdtsen 	if (is_analog)
1355c18ec02fSPetter Reinholdtsen 		creading = sdr_convert_sensor_reading(full, full->sensor_max);
1356c18ec02fSPetter Reinholdtsen 	if ((full->cmn.unit.analog == 0 && full->sensor_max == 0xff) ||
1357c18ec02fSPetter Reinholdtsen 	    (full->cmn.unit.analog == 1 && full->sensor_max == 0x00) ||
1358c18ec02fSPetter Reinholdtsen 	    (full->cmn.unit.analog == 2 && full->sensor_max == 0x7f) ||
1359c18ec02fSPetter Reinholdtsen 	    (is_analog && (creading == 0.0)))
1360c18ec02fSPetter Reinholdtsen 		printf(" Maximum sensor range  : Unspecified\n");
1361c18ec02fSPetter Reinholdtsen 	else {
1362c18ec02fSPetter Reinholdtsen 		if (is_analog)
1363c18ec02fSPetter Reinholdtsen 			printf(" Maximum sensor range  : %.3f\n", creading);
1364c18ec02fSPetter Reinholdtsen 		else
1365c18ec02fSPetter Reinholdtsen 			printf(" Maximum sensor range  : 0x%02X\n", full->sensor_max);
1366c18ec02fSPetter Reinholdtsen 	}
1367c18ec02fSPetter Reinholdtsen }
1368c18ec02fSPetter Reinholdtsen 
1369c18ec02fSPetter Reinholdtsen /* print_csv_discrete  -  print csv formatted discrete sensor
1370c18ec02fSPetter Reinholdtsen  *
1371c18ec02fSPetter Reinholdtsen  * @sensor:		common sensor structure
1372c18ec02fSPetter Reinholdtsen  * @sr:			sensor reading
1373c18ec02fSPetter Reinholdtsen  *
1374c18ec02fSPetter Reinholdtsen  * returns void
1375c18ec02fSPetter Reinholdtsen  */
1376c18ec02fSPetter Reinholdtsen static void
print_csv_discrete(struct sdr_record_common_sensor * sensor,const struct sensor_reading * sr)1377c18ec02fSPetter Reinholdtsen print_csv_discrete(struct sdr_record_common_sensor    *sensor,
1378c18ec02fSPetter Reinholdtsen 		   const struct sensor_reading *sr)
1379c18ec02fSPetter Reinholdtsen {
1380c18ec02fSPetter Reinholdtsen 	if (!sr->s_reading_valid  || sr->s_reading_unavailable) {
1381c18ec02fSPetter Reinholdtsen 		printf("%02Xh,ns,%d.%d,No Reading",
1382c18ec02fSPetter Reinholdtsen 		       sensor->keys.sensor_num,
1383c18ec02fSPetter Reinholdtsen 		       sensor->entity.id,
1384c18ec02fSPetter Reinholdtsen 		       sensor->entity.instance);
1385c18ec02fSPetter Reinholdtsen 		return;
1386c18ec02fSPetter Reinholdtsen 	}
1387c18ec02fSPetter Reinholdtsen 
1388c18ec02fSPetter Reinholdtsen 	if (sr->s_has_analog_value) {	/* Sensor has an analog value */
1389c18ec02fSPetter Reinholdtsen 		printf("%s,%s,", sr->s_a_str, sr->s_a_units);
1390c18ec02fSPetter Reinholdtsen 	} else {	/* Sensor has a discrete value */
1391c18ec02fSPetter Reinholdtsen 		printf("%02Xh,", sensor->keys.sensor_num);
1392c18ec02fSPetter Reinholdtsen 	}
1393c18ec02fSPetter Reinholdtsen 	printf("ok,%d.%d,",
1394c18ec02fSPetter Reinholdtsen 	       sensor->entity.id,
1395c18ec02fSPetter Reinholdtsen 	       sensor->entity.instance);
1396c18ec02fSPetter Reinholdtsen 	ipmi_sdr_print_discrete_state_mini(NULL, ", ",
1397c18ec02fSPetter Reinholdtsen 		sensor->sensor.type,
1398c18ec02fSPetter Reinholdtsen 		sensor->event_type,
1399c18ec02fSPetter Reinholdtsen 		sr->s_data2,
1400c18ec02fSPetter Reinholdtsen 		sr->s_data3);
1401c18ec02fSPetter Reinholdtsen }
1402c18ec02fSPetter Reinholdtsen 
1403c18ec02fSPetter Reinholdtsen /* ipmi_sdr_read_sensor_value  -  read sensor value
1404c18ec02fSPetter Reinholdtsen  *
1405c18ec02fSPetter Reinholdtsen  * @intf		Interface pointer
1406c18ec02fSPetter Reinholdtsen  * @sensor		Common sensor component pointer
1407c18ec02fSPetter Reinholdtsen  * @sdr_record_type	Type of sdr sensor record
1408c18ec02fSPetter Reinholdtsen  * @precision		decimal precision for analog format conversion
1409c18ec02fSPetter Reinholdtsen  *
1410c18ec02fSPetter Reinholdtsen  * returns a pointer to sensor value reading data structure
1411c18ec02fSPetter Reinholdtsen  */
1412c18ec02fSPetter Reinholdtsen struct sensor_reading *
ipmi_sdr_read_sensor_value(struct ipmi_intf * intf,struct sdr_record_common_sensor * sensor,uint8_t sdr_record_type,int precision)1413c18ec02fSPetter Reinholdtsen ipmi_sdr_read_sensor_value(struct ipmi_intf *intf,
1414c18ec02fSPetter Reinholdtsen 		 struct sdr_record_common_sensor *sensor,
1415c18ec02fSPetter Reinholdtsen 		 uint8_t sdr_record_type, int precision)
1416c18ec02fSPetter Reinholdtsen {
1417c18ec02fSPetter Reinholdtsen 	static struct sensor_reading sr;
1418c18ec02fSPetter Reinholdtsen 
1419c18ec02fSPetter Reinholdtsen 	if (sensor == NULL)
1420c18ec02fSPetter Reinholdtsen 		return NULL;
1421c18ec02fSPetter Reinholdtsen 
1422c18ec02fSPetter Reinholdtsen 	/* Initialize to reading valid value of zero */
1423c18ec02fSPetter Reinholdtsen 	memset(&sr, 0, sizeof(sr));
1424c18ec02fSPetter Reinholdtsen 
1425c18ec02fSPetter Reinholdtsen 	switch (sdr_record_type) {
1426c18ec02fSPetter Reinholdtsen 		int idlen;
1427c18ec02fSPetter Reinholdtsen 		case (SDR_RECORD_TYPE_FULL_SENSOR):
1428c18ec02fSPetter Reinholdtsen 			sr.full = (struct sdr_record_full_sensor *)sensor;
1429c18ec02fSPetter Reinholdtsen 			idlen = sr.full->id_code & 0x1f;
1430c18ec02fSPetter Reinholdtsen 			idlen = idlen < sizeof(sr.s_id) ?
1431c18ec02fSPetter Reinholdtsen 						idlen : sizeof(sr.s_id) - 1;
1432c18ec02fSPetter Reinholdtsen 			memcpy(sr.s_id, sr.full->id_string, idlen);
1433c18ec02fSPetter Reinholdtsen 			break;
1434c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_COMPACT_SENSOR:
1435c18ec02fSPetter Reinholdtsen 			sr.compact = (struct sdr_record_compact_sensor *)sensor;
1436c18ec02fSPetter Reinholdtsen 			idlen = sr.compact->id_code & 0x1f;
1437c18ec02fSPetter Reinholdtsen 			idlen = idlen < sizeof(sr.s_id) ?
1438c18ec02fSPetter Reinholdtsen 						idlen : sizeof(sr.s_id) - 1;
1439c18ec02fSPetter Reinholdtsen 			memcpy(sr.s_id, sr.compact->id_string, idlen);
1440c18ec02fSPetter Reinholdtsen 			break;
1441c18ec02fSPetter Reinholdtsen 		default:
1442c18ec02fSPetter Reinholdtsen 			return NULL;
1443c18ec02fSPetter Reinholdtsen 	}
1444c18ec02fSPetter Reinholdtsen 
1445c18ec02fSPetter Reinholdtsen 	/*
1446c18ec02fSPetter Reinholdtsen 	 * Get current reading via IPMI interface
1447c18ec02fSPetter Reinholdtsen 	 */
1448c18ec02fSPetter Reinholdtsen 	struct ipmi_rs *rsp;
1449c18ec02fSPetter Reinholdtsen 	rsp = ipmi_sdr_get_sensor_reading_ipmb(intf,
1450c18ec02fSPetter Reinholdtsen 					       sensor->keys.sensor_num,
1451c18ec02fSPetter Reinholdtsen 					       sensor->keys.owner_id,
1452c18ec02fSPetter Reinholdtsen 					       sensor->keys.lun,
1453c18ec02fSPetter Reinholdtsen 					       sensor->keys.channel);
1454c18ec02fSPetter Reinholdtsen 	sr.s_a_val   = 0.0;	/* init analog value to a floating point 0 */
1455c18ec02fSPetter Reinholdtsen 	sr.s_a_str[0] = '\0';	/* no converted analog value string */
1456c18ec02fSPetter Reinholdtsen 	sr.s_a_units = "";	/* no converted analog units units */
1457c18ec02fSPetter Reinholdtsen 
1458c18ec02fSPetter Reinholdtsen 
1459c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
1460c18ec02fSPetter Reinholdtsen 		lprintf(LOG_DEBUG, "Error reading sensor %s (#%02x)",
1461c18ec02fSPetter Reinholdtsen 			sr.s_id, sensor->keys.sensor_num);
1462c18ec02fSPetter Reinholdtsen 		return &sr;
1463c18ec02fSPetter Reinholdtsen 	}
1464c18ec02fSPetter Reinholdtsen 
1465c18ec02fSPetter Reinholdtsen 	if (rsp->ccode) {
1466c18ec02fSPetter Reinholdtsen 		if ( !((sr.full    && rsp->ccode == 0xcb) ||
1467c18ec02fSPetter Reinholdtsen 		       (sr.compact && rsp->ccode == 0xcd)) ) {
1468c18ec02fSPetter Reinholdtsen 			lprintf(LOG_DEBUG,
1469c18ec02fSPetter Reinholdtsen 				"Error reading sensor %s (#%02x): %s", sr.s_id,
1470c18ec02fSPetter Reinholdtsen 				sensor->keys.sensor_num,
1471c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
1472c18ec02fSPetter Reinholdtsen 		}
1473c18ec02fSPetter Reinholdtsen 		return &sr;
1474c18ec02fSPetter Reinholdtsen 	}
1475c18ec02fSPetter Reinholdtsen 
1476c18ec02fSPetter Reinholdtsen 	if (rsp->data_len < 2) {
1477c18ec02fSPetter Reinholdtsen 		/*
1478c18ec02fSPetter Reinholdtsen 		 * We must be returned both a value (data[0]), and the validity
1479c18ec02fSPetter Reinholdtsen 		 * of the value (data[1]), in order to correctly interpret
1480c18ec02fSPetter Reinholdtsen 		 * the reading.    If we don't have both of these we can't have
1481c18ec02fSPetter Reinholdtsen 		 * a valid sensor reading.
1482c18ec02fSPetter Reinholdtsen 		 */
1483c18ec02fSPetter Reinholdtsen 		lprintf(LOG_DEBUG, "Error reading sensor %s invalid len %d",
1484c18ec02fSPetter Reinholdtsen 			sr.s_id, rsp->data_len);
1485c18ec02fSPetter Reinholdtsen 		return &sr;
1486c18ec02fSPetter Reinholdtsen 	}
1487c18ec02fSPetter Reinholdtsen 
1488c18ec02fSPetter Reinholdtsen 
1489c18ec02fSPetter Reinholdtsen 	if (IS_READING_UNAVAILABLE(rsp->data[1]))
1490c18ec02fSPetter Reinholdtsen 		sr.s_reading_unavailable = 1;
1491c18ec02fSPetter Reinholdtsen 
1492c18ec02fSPetter Reinholdtsen 	if (IS_SCANNING_DISABLED(rsp->data[1])) {
1493c18ec02fSPetter Reinholdtsen 		sr.s_scanning_disabled = 1;
1494c18ec02fSPetter Reinholdtsen 		lprintf(LOG_DEBUG, "Sensor %s (#%02x) scanning disabled",
1495c18ec02fSPetter Reinholdtsen 			sr.s_id, sensor->keys.sensor_num);
1496c18ec02fSPetter Reinholdtsen 		return &sr;
1497c18ec02fSPetter Reinholdtsen 	}
1498c18ec02fSPetter Reinholdtsen 	if ( !sr.s_reading_unavailable ) {
1499c18ec02fSPetter Reinholdtsen 		sr.s_reading_valid = 1;
1500c18ec02fSPetter Reinholdtsen 		sr.s_reading = rsp->data[0];
1501c18ec02fSPetter Reinholdtsen 	}
1502c18ec02fSPetter Reinholdtsen 	if (rsp->data_len > 2)
1503c18ec02fSPetter Reinholdtsen 		sr.s_data2   = rsp->data[2];
1504c18ec02fSPetter Reinholdtsen 	if (rsp->data_len > 3)
1505c18ec02fSPetter Reinholdtsen 		sr.s_data3   = rsp->data[3];
1506c18ec02fSPetter Reinholdtsen 	if (sdr_sensor_has_analog_reading(intf, &sr)) {
1507c18ec02fSPetter Reinholdtsen 		sr.s_has_analog_value = 1;
1508c18ec02fSPetter Reinholdtsen 		if (sr.s_reading_valid) {
1509c18ec02fSPetter Reinholdtsen 			sr.s_a_val = sdr_convert_sensor_reading(sr.full, sr.s_reading);
1510c18ec02fSPetter Reinholdtsen 		}
1511c18ec02fSPetter Reinholdtsen 		/* determine units string with possible modifiers */
1512c18ec02fSPetter Reinholdtsen 		sr.s_a_units = ipmi_sdr_get_unit_string(sr.full->cmn.unit.pct,
1513c18ec02fSPetter Reinholdtsen 					   sr.full->cmn.unit.modifier,
1514c18ec02fSPetter Reinholdtsen 					   sr.full->cmn.unit.type.base,
1515c18ec02fSPetter Reinholdtsen 					   sr.full->cmn.unit.type.modifier);
1516c18ec02fSPetter Reinholdtsen 		snprintf(sr.s_a_str, sizeof(sr.s_a_str), "%.*f",
1517c18ec02fSPetter Reinholdtsen 			(sr.s_a_val == (int) sr.s_a_val) ? 0 :
1518c18ec02fSPetter Reinholdtsen 			precision, sr.s_a_val);
1519c18ec02fSPetter Reinholdtsen 	}
1520c18ec02fSPetter Reinholdtsen 	return &sr;
1521c18ec02fSPetter Reinholdtsen }
1522c18ec02fSPetter Reinholdtsen 
1523c18ec02fSPetter Reinholdtsen /* ipmi_sdr_print_sensor_fc  -  print full & compact SDR records
1524c18ec02fSPetter Reinholdtsen  *
1525c18ec02fSPetter Reinholdtsen  * @intf:		ipmi interface
1526c18ec02fSPetter Reinholdtsen  * @sensor:		common sensor structure
1527c18ec02fSPetter Reinholdtsen  * @sdr_record_type:	type of sdr record, either full or compact
1528c18ec02fSPetter Reinholdtsen  *
1529c18ec02fSPetter Reinholdtsen  * returns 0 on success
1530c18ec02fSPetter Reinholdtsen  * returns -1 on error
1531c18ec02fSPetter Reinholdtsen  */
1532c18ec02fSPetter Reinholdtsen int
ipmi_sdr_print_sensor_fc(struct ipmi_intf * intf,struct sdr_record_common_sensor * sensor,uint8_t sdr_record_type)1533c18ec02fSPetter Reinholdtsen ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
1534c18ec02fSPetter Reinholdtsen 			   struct sdr_record_common_sensor    *sensor,
1535c18ec02fSPetter Reinholdtsen 			   uint8_t sdr_record_type)
1536c18ec02fSPetter Reinholdtsen {
1537c18ec02fSPetter Reinholdtsen 	char sval[16];
1538c18ec02fSPetter Reinholdtsen 	int i = 0;
1539c18ec02fSPetter Reinholdtsen 	uint8_t target, lun, channel;
1540c18ec02fSPetter Reinholdtsen 	struct sensor_reading *sr;
1541c18ec02fSPetter Reinholdtsen 
1542c18ec02fSPetter Reinholdtsen 
1543c18ec02fSPetter Reinholdtsen 	sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 2);
1544c18ec02fSPetter Reinholdtsen 
1545c18ec02fSPetter Reinholdtsen 	if (sr == NULL)
1546c18ec02fSPetter Reinholdtsen 		return -1;
1547c18ec02fSPetter Reinholdtsen 
1548c18ec02fSPetter Reinholdtsen 	target = sensor->keys.owner_id;
1549c18ec02fSPetter Reinholdtsen 	lun = sensor->keys.lun;
1550c18ec02fSPetter Reinholdtsen 	channel = sensor->keys.channel;
1551c18ec02fSPetter Reinholdtsen 
1552c18ec02fSPetter Reinholdtsen 	/*
1553c18ec02fSPetter Reinholdtsen 	 * CSV OUTPUT
1554c18ec02fSPetter Reinholdtsen 	 */
1555c18ec02fSPetter Reinholdtsen 
1556c18ec02fSPetter Reinholdtsen 	if (csv_output) {
1557c18ec02fSPetter Reinholdtsen 		/*
1558c18ec02fSPetter Reinholdtsen 		 * print sensor name, reading, unit, state
1559c18ec02fSPetter Reinholdtsen 		 */
1560c18ec02fSPetter Reinholdtsen 		printf("%s,", sr->s_id);
1561c18ec02fSPetter Reinholdtsen 		if (!IS_THRESHOLD_SENSOR(sensor)) {
1562c18ec02fSPetter Reinholdtsen 			/* Discrete/Non-Threshold */
1563c18ec02fSPetter Reinholdtsen 			print_csv_discrete(sensor, sr);
1564c18ec02fSPetter Reinholdtsen 			printf("\n");
1565c18ec02fSPetter Reinholdtsen 		}
1566c18ec02fSPetter Reinholdtsen 		else {
1567c18ec02fSPetter Reinholdtsen 			/* Threshold Analog & Discrete*/
1568c18ec02fSPetter Reinholdtsen 			if (sr->s_reading_valid) {
1569c18ec02fSPetter Reinholdtsen 				if (sr->s_has_analog_value) {
1570c18ec02fSPetter Reinholdtsen 					/* Analog/Threshold */
1571c18ec02fSPetter Reinholdtsen 					printf("%.*f,", (sr->s_a_val ==
1572c18ec02fSPetter Reinholdtsen 					(int) sr->s_a_val) ? 0 : 3,
1573c18ec02fSPetter Reinholdtsen 					sr->s_a_val);
1574c18ec02fSPetter Reinholdtsen 					printf("%s,%s", sr->s_a_units,
1575c18ec02fSPetter Reinholdtsen 					       ipmi_sdr_get_thresh_status(sr, "ns"));
1576c18ec02fSPetter Reinholdtsen 				} else { /* Discrete/Threshold */
1577c18ec02fSPetter Reinholdtsen 					print_csv_discrete(sensor, sr);
1578c18ec02fSPetter Reinholdtsen 				}
1579c18ec02fSPetter Reinholdtsen 			} else {
1580c18ec02fSPetter Reinholdtsen 				printf(",,ns");
1581c18ec02fSPetter Reinholdtsen 			}
1582c18ec02fSPetter Reinholdtsen 
1583c18ec02fSPetter Reinholdtsen 			if (verbose) {
1584c18ec02fSPetter Reinholdtsen 				printf(",%d.%d,%s,%s,",
1585c18ec02fSPetter Reinholdtsen 				       sensor->entity.id, sensor->entity.instance,
1586c18ec02fSPetter Reinholdtsen 				       val2str(sensor->entity.id, entity_id_vals),
1587c18ec02fSPetter Reinholdtsen 				       ipmi_sdr_get_sensor_type_desc(sensor->sensor.
1588c18ec02fSPetter Reinholdtsen 								     type));
1589c18ec02fSPetter Reinholdtsen 
1590c18ec02fSPetter Reinholdtsen 				if (sr->full) {
1591c18ec02fSPetter Reinholdtsen 					SENSOR_PRINT_CSV(sr->full, sr->full->analog_flag.nominal_read,
1592c18ec02fSPetter Reinholdtsen 						sr->full->nominal_read);
1593c18ec02fSPetter Reinholdtsen 					SENSOR_PRINT_CSV(sr->full, sr->full->analog_flag.normal_min,
1594c18ec02fSPetter Reinholdtsen 						sr->full->normal_min);
1595c18ec02fSPetter Reinholdtsen 					SENSOR_PRINT_CSV(sr->full, sr->full->analog_flag.normal_max,
1596c18ec02fSPetter Reinholdtsen 						     sr->full->normal_max);
1597c18ec02fSPetter Reinholdtsen 					SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.unr,
1598c18ec02fSPetter Reinholdtsen 						sr->full->threshold.upper.non_recover);
1599c18ec02fSPetter Reinholdtsen 					SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.ucr,
1600c18ec02fSPetter Reinholdtsen 						sr->full->threshold.upper.critical);
1601c18ec02fSPetter Reinholdtsen 					SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.unc,
1602c18ec02fSPetter Reinholdtsen 						sr->full->threshold.upper.non_critical);
1603c18ec02fSPetter Reinholdtsen 					SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.lnr,
1604c18ec02fSPetter Reinholdtsen 						sr->full->threshold.lower.non_recover);
1605c18ec02fSPetter Reinholdtsen 					SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.lcr,
1606c18ec02fSPetter Reinholdtsen 						sr->full->threshold.lower.critical);
1607c18ec02fSPetter Reinholdtsen 					SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.lnc,
1608c18ec02fSPetter Reinholdtsen 						sr->full->threshold.lower.non_critical);
1609c18ec02fSPetter Reinholdtsen 
1610c18ec02fSPetter Reinholdtsen 					if (UNITS_ARE_DISCRETE(sensor)) {
1611c18ec02fSPetter Reinholdtsen 						printf("0x%02X,0x%02X", sr->full->sensor_min, sr->full->sensor_max);
1612c18ec02fSPetter Reinholdtsen 					}
1613c18ec02fSPetter Reinholdtsen 					else {
1614c18ec02fSPetter Reinholdtsen 						printf("%.3f,%.3f",
1615c18ec02fSPetter Reinholdtsen 						       sdr_convert_sensor_reading(sr->full,
1616c18ec02fSPetter Reinholdtsen 									      sr->full->sensor_min),
1617c18ec02fSPetter Reinholdtsen 						       sdr_convert_sensor_reading(sr->full,
1618c18ec02fSPetter Reinholdtsen 									      sr->full->sensor_max));
1619c18ec02fSPetter Reinholdtsen 					}
1620c18ec02fSPetter Reinholdtsen 				} else {
1621c18ec02fSPetter Reinholdtsen 					printf(",,,,,,,,,,");
1622c18ec02fSPetter Reinholdtsen 				}
1623c18ec02fSPetter Reinholdtsen 			}
1624c18ec02fSPetter Reinholdtsen 			printf("\n");
1625c18ec02fSPetter Reinholdtsen 		}
1626c18ec02fSPetter Reinholdtsen 
1627c18ec02fSPetter Reinholdtsen 		return 0;	/* done */
1628c18ec02fSPetter Reinholdtsen 	}
1629c18ec02fSPetter Reinholdtsen 
1630c18ec02fSPetter Reinholdtsen 	/*
1631c18ec02fSPetter Reinholdtsen 	 * NORMAL OUTPUT
1632c18ec02fSPetter Reinholdtsen 	 */
1633c18ec02fSPetter Reinholdtsen 
1634c18ec02fSPetter Reinholdtsen 	if (verbose == 0 && sdr_extended == 0) {
1635c18ec02fSPetter Reinholdtsen 		/*
1636c18ec02fSPetter Reinholdtsen 		 * print sensor name, reading, state
1637c18ec02fSPetter Reinholdtsen 		 */
1638c18ec02fSPetter Reinholdtsen 		printf("%-16s | ", sr->s_id);
1639c18ec02fSPetter Reinholdtsen 
1640c18ec02fSPetter Reinholdtsen 		memset(sval, 0, sizeof (sval));
1641c18ec02fSPetter Reinholdtsen 
1642c18ec02fSPetter Reinholdtsen 		if (sr->s_reading_valid) {
1643c18ec02fSPetter Reinholdtsen 			if( sr->s_has_analog_value ) {
1644c18ec02fSPetter Reinholdtsen 				snprintf(sval, sizeof (sval), "%s %s",
1645c18ec02fSPetter Reinholdtsen 						      sr->s_a_str,
1646c18ec02fSPetter Reinholdtsen 						      sr->s_a_units);
1647c18ec02fSPetter Reinholdtsen 			} else /* Discrete */
1648c18ec02fSPetter Reinholdtsen 				snprintf(sval, sizeof(sval),
1649c18ec02fSPetter Reinholdtsen 					"0x%02x", sr->s_reading);
1650c18ec02fSPetter Reinholdtsen 		}
1651c18ec02fSPetter Reinholdtsen 		else if (sr->s_scanning_disabled)
1652c18ec02fSPetter Reinholdtsen 			snprintf(sval, sizeof (sval), sr->full ? "disabled"   : "Not Readable");
1653c18ec02fSPetter Reinholdtsen 		else
1654c18ec02fSPetter Reinholdtsen 			snprintf(sval, sizeof (sval), sr->full ? "no reading" : "Not Readable");
1655c18ec02fSPetter Reinholdtsen 
1656c18ec02fSPetter Reinholdtsen 		printf("%s", sval);
1657c18ec02fSPetter Reinholdtsen 
1658c18ec02fSPetter Reinholdtsen 		for (i = strlen(sval); i <= sizeof (sval); i++)
1659c18ec02fSPetter Reinholdtsen 			printf(" ");
1660c18ec02fSPetter Reinholdtsen 		printf(" | ");
1661c18ec02fSPetter Reinholdtsen 
1662c18ec02fSPetter Reinholdtsen 		if (IS_THRESHOLD_SENSOR(sensor)) {
1663c18ec02fSPetter Reinholdtsen 			printf("%s", ipmi_sdr_get_thresh_status(sr, "ns"));
1664c18ec02fSPetter Reinholdtsen 		}
1665c18ec02fSPetter Reinholdtsen 		else {
1666c18ec02fSPetter Reinholdtsen 			printf("%s", sr->s_reading_valid ? "ok" : "ns");
1667c18ec02fSPetter Reinholdtsen 		}
1668c18ec02fSPetter Reinholdtsen 
1669c18ec02fSPetter Reinholdtsen 		printf("\n");
1670c18ec02fSPetter Reinholdtsen 
1671c18ec02fSPetter Reinholdtsen 		return 0;	/* done */
1672c18ec02fSPetter Reinholdtsen 	} else if (verbose == 0 && sdr_extended == 1) {
1673c18ec02fSPetter Reinholdtsen 		/*
1674c18ec02fSPetter Reinholdtsen 		 * print sensor name, number, state, entity, reading
1675c18ec02fSPetter Reinholdtsen 		 */
1676c18ec02fSPetter Reinholdtsen 		printf("%-16s | %02Xh | ",
1677c18ec02fSPetter Reinholdtsen 		       sr->s_id, sensor->keys.sensor_num);
1678c18ec02fSPetter Reinholdtsen 
1679c18ec02fSPetter Reinholdtsen 		if (IS_THRESHOLD_SENSOR(sensor)) {
1680c18ec02fSPetter Reinholdtsen 			/* Threshold Analog & Discrete */
1681c18ec02fSPetter Reinholdtsen 			printf("%-3s | %2d.%1d | ",
1682c18ec02fSPetter Reinholdtsen 			   ipmi_sdr_get_thresh_status(sr, "ns"),
1683c18ec02fSPetter Reinholdtsen 		           sensor->entity.id, sensor->entity.instance);
1684c18ec02fSPetter Reinholdtsen 		}
1685c18ec02fSPetter Reinholdtsen 		else {
1686c18ec02fSPetter Reinholdtsen 			/* Non Threshold Analog & Discrete */
1687c18ec02fSPetter Reinholdtsen 			printf("%-3s | %2d.%1d | ",
1688c18ec02fSPetter Reinholdtsen 			       (sr->s_reading_valid ? "ok" : "ns"),
1689c18ec02fSPetter Reinholdtsen 			       sensor->entity.id, sensor->entity.instance);
1690c18ec02fSPetter Reinholdtsen 		}
1691c18ec02fSPetter Reinholdtsen 
1692c18ec02fSPetter Reinholdtsen 		memset(sval, 0, sizeof (sval));
1693c18ec02fSPetter Reinholdtsen 
1694c18ec02fSPetter Reinholdtsen 		if (sr->s_reading_valid) {
1695c18ec02fSPetter Reinholdtsen 			if (IS_THRESHOLD_SENSOR(sensor) &&
1696c18ec02fSPetter Reinholdtsen 				sr->s_has_analog_value ) {
1697c18ec02fSPetter Reinholdtsen 				/* Threshold Analog */
1698c18ec02fSPetter Reinholdtsen 					snprintf(sval, sizeof (sval), "%s %s",
1699c18ec02fSPetter Reinholdtsen 						      sr->s_a_str,
1700c18ec02fSPetter Reinholdtsen 						      sr->s_a_units);
1701c18ec02fSPetter Reinholdtsen 			} else {
1702c18ec02fSPetter Reinholdtsen 				/* Analog & Discrete & Threshold/Discrete */
1703c18ec02fSPetter Reinholdtsen 				char *header = NULL;
1704c18ec02fSPetter Reinholdtsen 				if (sr->s_has_analog_value) { /* Sensor has an analog value */
1705c18ec02fSPetter Reinholdtsen 					printf("%s %s", sr->s_a_str, sr->s_a_units);
1706c18ec02fSPetter Reinholdtsen 					header = ", ";
1707c18ec02fSPetter Reinholdtsen 				}
1708c18ec02fSPetter Reinholdtsen 				ipmi_sdr_print_discrete_state_mini(header, ", ",
1709c18ec02fSPetter Reinholdtsen 								   sensor->sensor.type,
1710c18ec02fSPetter Reinholdtsen 								   sensor->event_type,
1711c18ec02fSPetter Reinholdtsen 								   sr->s_data2,
1712c18ec02fSPetter Reinholdtsen 								   sr->s_data3);
1713c18ec02fSPetter Reinholdtsen 			}
1714c18ec02fSPetter Reinholdtsen 		}
1715c18ec02fSPetter Reinholdtsen 		else if (sr->s_scanning_disabled)
1716c18ec02fSPetter Reinholdtsen 			snprintf(sval, sizeof (sval), "Disabled");
1717c18ec02fSPetter Reinholdtsen 		else
1718c18ec02fSPetter Reinholdtsen 			snprintf(sval, sizeof (sval), "No Reading");
1719c18ec02fSPetter Reinholdtsen 
1720c18ec02fSPetter Reinholdtsen 		printf("%s\n", sval);
1721c18ec02fSPetter Reinholdtsen 		return 0;	/* done */
1722c18ec02fSPetter Reinholdtsen 	}
1723c18ec02fSPetter Reinholdtsen 	/*
1724c18ec02fSPetter Reinholdtsen 	 * VERBOSE OUTPUT
1725c18ec02fSPetter Reinholdtsen 	 */
1726c18ec02fSPetter Reinholdtsen 
1727c18ec02fSPetter Reinholdtsen 	printf("Sensor ID              : %s (0x%x)\n",
1728c18ec02fSPetter Reinholdtsen 	       sr->s_id, sensor->keys.sensor_num);
1729c18ec02fSPetter Reinholdtsen 	printf(" Entity ID             : %d.%d (%s)\n",
1730c18ec02fSPetter Reinholdtsen 	       sensor->entity.id, sensor->entity.instance,
1731c18ec02fSPetter Reinholdtsen 	       val2str(sensor->entity.id, entity_id_vals));
1732c18ec02fSPetter Reinholdtsen 
1733c18ec02fSPetter Reinholdtsen 	if (!IS_THRESHOLD_SENSOR(sensor)) {
1734c18ec02fSPetter Reinholdtsen 		/* Discrete */
1735c18ec02fSPetter Reinholdtsen 		printf(" Sensor Type (Discrete): %s (0x%02x)\n",
1736c18ec02fSPetter Reinholdtsen 				ipmi_sdr_get_sensor_type_desc(sensor->sensor.type),
1737c18ec02fSPetter Reinholdtsen 				sensor->sensor.type);
1738c18ec02fSPetter Reinholdtsen 		lprintf(LOG_DEBUG, " Event Type Code       : 0x%02x",
1739c18ec02fSPetter Reinholdtsen 			sensor->event_type);
1740c18ec02fSPetter Reinholdtsen 
1741c18ec02fSPetter Reinholdtsen 		printf(" Sensor Reading        : ");
1742c18ec02fSPetter Reinholdtsen 		if (sr->s_reading_valid) {
1743c18ec02fSPetter Reinholdtsen 			if (sr->s_has_analog_value) { /* Sensor has an analog value */
1744c18ec02fSPetter Reinholdtsen 				printf("%s %s\n", sr->s_a_str, sr->s_a_units);
1745c18ec02fSPetter Reinholdtsen 			} else {
1746c18ec02fSPetter Reinholdtsen 				printf("%xh\n", sr->s_reading);
1747c18ec02fSPetter Reinholdtsen 			}
1748c18ec02fSPetter Reinholdtsen 		}
1749c18ec02fSPetter Reinholdtsen 		else if (sr->s_scanning_disabled)
1750c18ec02fSPetter Reinholdtsen 			printf("Disabled\n");
1751c18ec02fSPetter Reinholdtsen 		else {
1752c18ec02fSPetter Reinholdtsen 			/* Used to be 'Not Reading' */
1753c18ec02fSPetter Reinholdtsen 			printf("No Reading\n");
1754c18ec02fSPetter Reinholdtsen 		}
1755c18ec02fSPetter Reinholdtsen 
1756c18ec02fSPetter Reinholdtsen 		printf(" Event Message Control : ");
1757c18ec02fSPetter Reinholdtsen 		switch (sensor->sensor.capabilities.event_msg) {
1758c18ec02fSPetter Reinholdtsen 		case 0:
1759c18ec02fSPetter Reinholdtsen 			printf("Per-threshold\n");
1760c18ec02fSPetter Reinholdtsen 			break;
1761c18ec02fSPetter Reinholdtsen 		case 1:
1762c18ec02fSPetter Reinholdtsen 			printf("Entire Sensor Only\n");
1763c18ec02fSPetter Reinholdtsen 			break;
1764c18ec02fSPetter Reinholdtsen 		case 2:
1765c18ec02fSPetter Reinholdtsen 			printf("Global Disable Only\n");
1766c18ec02fSPetter Reinholdtsen 			break;
1767c18ec02fSPetter Reinholdtsen 		case 3:
1768c18ec02fSPetter Reinholdtsen 			printf("No Events From Sensor\n");
1769c18ec02fSPetter Reinholdtsen 			break;
1770c18ec02fSPetter Reinholdtsen 		}
1771c18ec02fSPetter Reinholdtsen 
1772c18ec02fSPetter Reinholdtsen 		ipmi_sdr_print_discrete_state("States Asserted",
1773c18ec02fSPetter Reinholdtsen 					      sensor->sensor.type,
1774c18ec02fSPetter Reinholdtsen 					      sensor->event_type,
1775c18ec02fSPetter Reinholdtsen 					      sr->s_data2,
1776c18ec02fSPetter Reinholdtsen 					      sr->s_data3);
1777c18ec02fSPetter Reinholdtsen 		ipmi_sdr_print_sensor_mask(&sensor->mask, sensor->sensor.type,
1778c18ec02fSPetter Reinholdtsen 					   sensor->event_type, DISCRETE_SENSOR);
1779c18ec02fSPetter Reinholdtsen 		ipmi_sdr_print_sensor_event_status(intf,
1780c18ec02fSPetter Reinholdtsen 						   sensor->keys.sensor_num,
1781c18ec02fSPetter Reinholdtsen 						   sensor->sensor.type,
1782c18ec02fSPetter Reinholdtsen 						   sensor->event_type,
1783c18ec02fSPetter Reinholdtsen 						   DISCRETE_SENSOR,
1784c18ec02fSPetter Reinholdtsen 						   target,
1785c18ec02fSPetter Reinholdtsen 						   lun, channel);
1786c18ec02fSPetter Reinholdtsen 		ipmi_sdr_print_sensor_event_enable(intf,
1787c18ec02fSPetter Reinholdtsen 						   sensor->keys.sensor_num,
1788c18ec02fSPetter Reinholdtsen 						   sensor->sensor.type,
1789c18ec02fSPetter Reinholdtsen 						   sensor->event_type,
1790c18ec02fSPetter Reinholdtsen 						   DISCRETE_SENSOR,
1791c18ec02fSPetter Reinholdtsen 						   target,
1792c18ec02fSPetter Reinholdtsen 						   lun, channel);
1793c18ec02fSPetter Reinholdtsen 		printf(" OEM                   : %X\n",
1794c18ec02fSPetter Reinholdtsen 					sr->full ? sr->full->oem : sr->compact->oem);
1795c18ec02fSPetter Reinholdtsen 		printf("\n");
1796c18ec02fSPetter Reinholdtsen 
1797c18ec02fSPetter Reinholdtsen 		return 0;	/* done */
1798c18ec02fSPetter Reinholdtsen 	}
1799c18ec02fSPetter Reinholdtsen 	printf(" Sensor Type (Threshold)  : %s (0x%02x)\n",
1800c18ec02fSPetter Reinholdtsen 		ipmi_sdr_get_sensor_type_desc(sensor->sensor.type),
1801c18ec02fSPetter Reinholdtsen 		sensor->sensor.type);
1802c18ec02fSPetter Reinholdtsen 
1803c18ec02fSPetter Reinholdtsen 	printf(" Sensor Reading        : ");
1804c18ec02fSPetter Reinholdtsen 	if (sr->s_reading_valid) {
1805c18ec02fSPetter Reinholdtsen 		if (sr->full) {
1806c18ec02fSPetter Reinholdtsen 			uint16_t raw_tol = __TO_TOL(sr->full->mtol);
1807c18ec02fSPetter Reinholdtsen 			if (UNITS_ARE_DISCRETE(sensor)) {
1808c18ec02fSPetter Reinholdtsen 				printf("0x%02X (+/- 0x%02X) %s\n",
1809c18ec02fSPetter Reinholdtsen 				sr->s_reading, raw_tol, sr->s_a_units);
1810c18ec02fSPetter Reinholdtsen 			}
1811c18ec02fSPetter Reinholdtsen 			else {
1812c18ec02fSPetter Reinholdtsen 				double tol = sdr_convert_sensor_tolerance(sr->full, raw_tol);
1813c18ec02fSPetter Reinholdtsen 				printf("%.*f (+/- %.*f) %s\n",
1814c18ec02fSPetter Reinholdtsen 				       (sr->s_a_val == (int) sr->s_a_val) ? 0 : 3,
1815c18ec02fSPetter Reinholdtsen 				       sr->s_a_val, (tol == (int) tol) ? 0 :
1816c18ec02fSPetter Reinholdtsen 				       3, tol, sr->s_a_units);
1817c18ec02fSPetter Reinholdtsen 			}
1818c18ec02fSPetter Reinholdtsen 		} else {
1819c18ec02fSPetter Reinholdtsen 			printf("0x%02X %s\n", sr->s_reading, sr->s_a_units);
1820c18ec02fSPetter Reinholdtsen 		}
1821c18ec02fSPetter Reinholdtsen 	} else if (sr->s_scanning_disabled)
1822c18ec02fSPetter Reinholdtsen 		printf("Disabled\n");
1823c18ec02fSPetter Reinholdtsen 	else
1824c18ec02fSPetter Reinholdtsen 		printf("No Reading\n");
1825c18ec02fSPetter Reinholdtsen 
1826c18ec02fSPetter Reinholdtsen 	printf(" Status                : %s\n",
1827c18ec02fSPetter Reinholdtsen 	       ipmi_sdr_get_thresh_status(sr, "Not Available"));
1828c18ec02fSPetter Reinholdtsen 
1829c18ec02fSPetter Reinholdtsen 	if(sr->full) {
1830c18ec02fSPetter Reinholdtsen 		SENSOR_PRINT_NORMAL(sr->full, "Nominal Reading", nominal_read);
1831c18ec02fSPetter Reinholdtsen 		SENSOR_PRINT_NORMAL(sr->full, "Normal Minimum", normal_min);
1832c18ec02fSPetter Reinholdtsen 		SENSOR_PRINT_NORMAL(sr->full, "Normal Maximum", normal_max);
1833c18ec02fSPetter Reinholdtsen 
1834c18ec02fSPetter Reinholdtsen 		SENSOR_PRINT_THRESH(sr->full, "Upper non-recoverable", upper.non_recover, unr);
1835c18ec02fSPetter Reinholdtsen 		SENSOR_PRINT_THRESH(sr->full, "Upper critical", upper.critical, ucr);
1836c18ec02fSPetter Reinholdtsen 		SENSOR_PRINT_THRESH(sr->full, "Upper non-critical", upper.non_critical, unc);
1837c18ec02fSPetter Reinholdtsen 		SENSOR_PRINT_THRESH(sr->full, "Lower non-recoverable", lower.non_recover, lnr);
1838c18ec02fSPetter Reinholdtsen 		SENSOR_PRINT_THRESH(sr->full, "Lower critical", lower.critical, lcr);
1839c18ec02fSPetter Reinholdtsen 		SENSOR_PRINT_THRESH(sr->full, "Lower non-critical", lower.non_critical, lnc);
1840c18ec02fSPetter Reinholdtsen 	}
1841c18ec02fSPetter Reinholdtsen 	ipmi_sdr_print_sensor_hysteresis(sensor, sr->full,
1842c18ec02fSPetter Reinholdtsen 		sr->full ? sr->full->threshold.hysteresis.positive :
1843c18ec02fSPetter Reinholdtsen 		sr->compact->threshold.hysteresis.positive, "Positive Hysteresis");
1844c18ec02fSPetter Reinholdtsen 
1845c18ec02fSPetter Reinholdtsen 	ipmi_sdr_print_sensor_hysteresis(sensor, sr->full,
1846c18ec02fSPetter Reinholdtsen 		sr->full ? sr->full->threshold.hysteresis.negative :
1847c18ec02fSPetter Reinholdtsen 		sr->compact->threshold.hysteresis.negative, "Negative Hysteresis");
1848c18ec02fSPetter Reinholdtsen 
1849c18ec02fSPetter Reinholdtsen 	print_sensor_min_max(sr->full);
1850c18ec02fSPetter Reinholdtsen 
1851c18ec02fSPetter Reinholdtsen 	printf(" Event Message Control : ");
1852c18ec02fSPetter Reinholdtsen 	switch (sensor->sensor.capabilities.event_msg) {
1853c18ec02fSPetter Reinholdtsen 	case 0:
1854c18ec02fSPetter Reinholdtsen 		printf("Per-threshold\n");
1855c18ec02fSPetter Reinholdtsen 		break;
1856c18ec02fSPetter Reinholdtsen 	case 1:
1857c18ec02fSPetter Reinholdtsen 		printf("Entire Sensor Only\n");
1858c18ec02fSPetter Reinholdtsen 		break;
1859c18ec02fSPetter Reinholdtsen 	case 2:
1860c18ec02fSPetter Reinholdtsen 		printf("Global Disable Only\n");
1861c18ec02fSPetter Reinholdtsen 		break;
1862c18ec02fSPetter Reinholdtsen 	case 3:
1863c18ec02fSPetter Reinholdtsen 		printf("No Events From Sensor\n");
1864c18ec02fSPetter Reinholdtsen 		break;
1865c18ec02fSPetter Reinholdtsen 	}
1866c18ec02fSPetter Reinholdtsen 
1867c18ec02fSPetter Reinholdtsen 	printf(" Readable Thresholds   : ");
1868c18ec02fSPetter Reinholdtsen 	switch (sensor->sensor.capabilities.threshold) {
1869c18ec02fSPetter Reinholdtsen 	case 0:
1870c18ec02fSPetter Reinholdtsen 		printf("No Thresholds\n");
1871c18ec02fSPetter Reinholdtsen 		break;
1872c18ec02fSPetter Reinholdtsen 	case 1:		/* readable according to mask */
1873c18ec02fSPetter Reinholdtsen 	case 2:		/* readable and settable according to mask */
1874c18ec02fSPetter Reinholdtsen 		if (sensor->mask.type.threshold.read.lnr)
1875c18ec02fSPetter Reinholdtsen 			printf("lnr ");
1876c18ec02fSPetter Reinholdtsen 		if (sensor->mask.type.threshold.read.lcr)
1877c18ec02fSPetter Reinholdtsen 			printf("lcr ");
1878c18ec02fSPetter Reinholdtsen 		if (sensor->mask.type.threshold.read.lnc)
1879c18ec02fSPetter Reinholdtsen 			printf("lnc ");
1880c18ec02fSPetter Reinholdtsen 		if (sensor->mask.type.threshold.read.unc)
1881c18ec02fSPetter Reinholdtsen 			printf("unc ");
1882c18ec02fSPetter Reinholdtsen 		if (sensor->mask.type.threshold.read.ucr)
1883c18ec02fSPetter Reinholdtsen 			printf("ucr ");
1884c18ec02fSPetter Reinholdtsen 		if (sensor->mask.type.threshold.read.unr)
1885c18ec02fSPetter Reinholdtsen 			printf("unr ");
1886c18ec02fSPetter Reinholdtsen 		printf("\n");
1887c18ec02fSPetter Reinholdtsen 		break;
1888c18ec02fSPetter Reinholdtsen 	case 3:
1889c18ec02fSPetter Reinholdtsen 		printf("Thresholds Fixed\n");
1890c18ec02fSPetter Reinholdtsen 		break;
1891c18ec02fSPetter Reinholdtsen 	}
1892c18ec02fSPetter Reinholdtsen 
1893c18ec02fSPetter Reinholdtsen 	printf(" Settable Thresholds   : ");
1894c18ec02fSPetter Reinholdtsen 	switch (sensor->sensor.capabilities.threshold) {
1895c18ec02fSPetter Reinholdtsen 	case 0:
1896c18ec02fSPetter Reinholdtsen 		printf("No Thresholds\n");
1897c18ec02fSPetter Reinholdtsen 		break;
1898c18ec02fSPetter Reinholdtsen 	case 1:		/* readable according to mask */
1899c18ec02fSPetter Reinholdtsen 	case 2:		/* readable and settable according to mask */
1900c18ec02fSPetter Reinholdtsen 		if (sensor->mask.type.threshold.set.lnr)
1901c18ec02fSPetter Reinholdtsen 			printf("lnr ");
1902c18ec02fSPetter Reinholdtsen 		if (sensor->mask.type.threshold.set.lcr)
1903c18ec02fSPetter Reinholdtsen 			printf("lcr ");
1904c18ec02fSPetter Reinholdtsen 		if (sensor->mask.type.threshold.set.lnc)
1905c18ec02fSPetter Reinholdtsen 			printf("lnc ");
1906c18ec02fSPetter Reinholdtsen 		if (sensor->mask.type.threshold.set.unc)
1907c18ec02fSPetter Reinholdtsen 			printf("unc ");
1908c18ec02fSPetter Reinholdtsen 		if (sensor->mask.type.threshold.set.ucr)
1909c18ec02fSPetter Reinholdtsen 			printf("ucr ");
1910c18ec02fSPetter Reinholdtsen 		if (sensor->mask.type.threshold.set.unr)
1911c18ec02fSPetter Reinholdtsen 			printf("unr ");
1912c18ec02fSPetter Reinholdtsen 		printf("\n");
1913c18ec02fSPetter Reinholdtsen 		break;
1914c18ec02fSPetter Reinholdtsen 	case 3:
1915c18ec02fSPetter Reinholdtsen 		printf("Thresholds Fixed\n");
1916c18ec02fSPetter Reinholdtsen 		break;
1917c18ec02fSPetter Reinholdtsen 	}
1918c18ec02fSPetter Reinholdtsen 
1919c18ec02fSPetter Reinholdtsen 	if (sensor->mask.type.threshold.status_lnr ||
1920c18ec02fSPetter Reinholdtsen 	    sensor->mask.type.threshold.status_lcr ||
1921c18ec02fSPetter Reinholdtsen 	    sensor->mask.type.threshold.status_lnc ||
1922c18ec02fSPetter Reinholdtsen 	    sensor->mask.type.threshold.status_unc ||
1923c18ec02fSPetter Reinholdtsen 	    sensor->mask.type.threshold.status_ucr ||
1924c18ec02fSPetter Reinholdtsen 	    sensor->mask.type.threshold.status_unr) {
1925c18ec02fSPetter Reinholdtsen 		printf(" Threshold Read Mask   : ");
1926c18ec02fSPetter Reinholdtsen 		if (sensor->mask.type.threshold.status_lnr)
1927c18ec02fSPetter Reinholdtsen 			printf("lnr ");
1928c18ec02fSPetter Reinholdtsen 		if (sensor->mask.type.threshold.status_lcr)
1929c18ec02fSPetter Reinholdtsen 			printf("lcr ");
1930c18ec02fSPetter Reinholdtsen 		if (sensor->mask.type.threshold.status_lnc)
1931c18ec02fSPetter Reinholdtsen 			printf("lnc ");
1932c18ec02fSPetter Reinholdtsen 		if (sensor->mask.type.threshold.status_unc)
1933c18ec02fSPetter Reinholdtsen 			printf("unc ");
1934c18ec02fSPetter Reinholdtsen 		if (sensor->mask.type.threshold.status_ucr)
1935c18ec02fSPetter Reinholdtsen 			printf("ucr ");
1936c18ec02fSPetter Reinholdtsen 		if (sensor->mask.type.threshold.status_unr)
1937c18ec02fSPetter Reinholdtsen 			printf("unr ");
1938c18ec02fSPetter Reinholdtsen 		printf("\n");
1939c18ec02fSPetter Reinholdtsen 	}
1940c18ec02fSPetter Reinholdtsen 
1941c18ec02fSPetter Reinholdtsen 	ipmi_sdr_print_sensor_mask(&sensor->mask,
1942c18ec02fSPetter Reinholdtsen 				   sensor->sensor.type,
1943c18ec02fSPetter Reinholdtsen 				   sensor->event_type, ANALOG_SENSOR);
1944c18ec02fSPetter Reinholdtsen 	ipmi_sdr_print_sensor_event_status(intf,
1945c18ec02fSPetter Reinholdtsen 					   sensor->keys.sensor_num,
1946c18ec02fSPetter Reinholdtsen 					   sensor->sensor.type,
1947c18ec02fSPetter Reinholdtsen 					   sensor->event_type, ANALOG_SENSOR,
1948c18ec02fSPetter Reinholdtsen 					   target,
1949c18ec02fSPetter Reinholdtsen 					   lun, channel);
1950c18ec02fSPetter Reinholdtsen 
1951c18ec02fSPetter Reinholdtsen 	ipmi_sdr_print_sensor_event_enable(intf,
1952c18ec02fSPetter Reinholdtsen 					   sensor->keys.sensor_num,
1953c18ec02fSPetter Reinholdtsen 					   sensor->sensor.type,
1954c18ec02fSPetter Reinholdtsen 					   sensor->event_type, ANALOG_SENSOR,
1955c18ec02fSPetter Reinholdtsen 					   target,
1956c18ec02fSPetter Reinholdtsen 					   lun, channel);
1957c18ec02fSPetter Reinholdtsen 
1958c18ec02fSPetter Reinholdtsen 	printf("\n");
1959c18ec02fSPetter Reinholdtsen 	return 0;
1960c18ec02fSPetter Reinholdtsen }
1961c18ec02fSPetter Reinholdtsen 
1962c18ec02fSPetter Reinholdtsen static inline int
get_offset(uint8_t x)1963c18ec02fSPetter Reinholdtsen get_offset(uint8_t x)
1964c18ec02fSPetter Reinholdtsen {
1965c18ec02fSPetter Reinholdtsen 	int i;
1966c18ec02fSPetter Reinholdtsen 	for (i = 0; i < 8; i++)
1967c18ec02fSPetter Reinholdtsen 		if (x >> i == 1)
1968c18ec02fSPetter Reinholdtsen 			return i;
1969c18ec02fSPetter Reinholdtsen 	return 0;
1970c18ec02fSPetter Reinholdtsen }
1971c18ec02fSPetter Reinholdtsen 
1972c18ec02fSPetter Reinholdtsen /* ipmi_sdr_print_discrete_state_mini  -  print list of asserted states
1973c18ec02fSPetter Reinholdtsen  *                                        for a discrete sensor
1974c18ec02fSPetter Reinholdtsen  *
1975c18ec02fSPetter Reinholdtsen  * @header	: header string if necessary
1976c18ec02fSPetter Reinholdtsen  * @separator	: field separator string
1977c18ec02fSPetter Reinholdtsen  * @sensor_type	: sensor type code
1978c18ec02fSPetter Reinholdtsen  * @event_type	: event type code
1979c18ec02fSPetter Reinholdtsen  * @state	: mask of asserted states
1980c18ec02fSPetter Reinholdtsen  *
1981c18ec02fSPetter Reinholdtsen  * no meaningful return value
1982c18ec02fSPetter Reinholdtsen  */
1983c18ec02fSPetter Reinholdtsen void
ipmi_sdr_print_discrete_state_mini(const char * header,const char * separator,uint8_t sensor_type,uint8_t event_type,uint8_t state1,uint8_t state2)1984c18ec02fSPetter Reinholdtsen ipmi_sdr_print_discrete_state_mini(const char *header, const char *separator,
1985c18ec02fSPetter Reinholdtsen 				   uint8_t sensor_type, uint8_t event_type,
1986c18ec02fSPetter Reinholdtsen 				   uint8_t state1, uint8_t state2)
1987c18ec02fSPetter Reinholdtsen {
1988c18ec02fSPetter Reinholdtsen 	uint8_t typ;
1989c18ec02fSPetter Reinholdtsen 	struct ipmi_event_sensor_types *evt;
1990c18ec02fSPetter Reinholdtsen 	int pre = 0, c = 0;
1991c18ec02fSPetter Reinholdtsen 
1992c18ec02fSPetter Reinholdtsen 	if (state1 == 0 && (state2 & 0x7f) == 0)
1993c18ec02fSPetter Reinholdtsen 		return;
1994c18ec02fSPetter Reinholdtsen 
1995c18ec02fSPetter Reinholdtsen 	if (event_type == 0x6f) {
1996c18ec02fSPetter Reinholdtsen 		evt = sensor_specific_types;
1997c18ec02fSPetter Reinholdtsen 		typ = sensor_type;
1998c18ec02fSPetter Reinholdtsen 	} else {
1999c18ec02fSPetter Reinholdtsen 		evt = generic_event_types;
2000c18ec02fSPetter Reinholdtsen 		typ = event_type;
2001c18ec02fSPetter Reinholdtsen 	}
2002c18ec02fSPetter Reinholdtsen 
2003c18ec02fSPetter Reinholdtsen 	if (header)
2004c18ec02fSPetter Reinholdtsen 		printf("%s", header);
2005c18ec02fSPetter Reinholdtsen 
2006c18ec02fSPetter Reinholdtsen 	for (; evt->type != NULL; evt++) {
2007c18ec02fSPetter Reinholdtsen 		if ((evt->code != typ) ||
2008c18ec02fSPetter Reinholdtsen 			(evt->data != 0xFF))
2009c18ec02fSPetter Reinholdtsen 			continue;
2010c18ec02fSPetter Reinholdtsen 
2011c18ec02fSPetter Reinholdtsen 		if (evt->offset > 7) {
2012c18ec02fSPetter Reinholdtsen 			if ((1 << (evt->offset - 8)) & (state2 & 0x7f)) {
2013c18ec02fSPetter Reinholdtsen 				if (pre++ != 0)
2014c18ec02fSPetter Reinholdtsen 					printf("%s", separator);
2015c18ec02fSPetter Reinholdtsen 				if (evt->desc)
2016c18ec02fSPetter Reinholdtsen 					printf("%s", evt->desc);
2017c18ec02fSPetter Reinholdtsen 			}
2018c18ec02fSPetter Reinholdtsen 		} else {
2019c18ec02fSPetter Reinholdtsen 			if ((1 << evt->offset) & state1) {
2020c18ec02fSPetter Reinholdtsen 				if (pre++ != 0)
2021c18ec02fSPetter Reinholdtsen 					printf("%s", separator);
2022c18ec02fSPetter Reinholdtsen 				if (evt->desc)
2023c18ec02fSPetter Reinholdtsen 					printf("%s", evt->desc);
2024c18ec02fSPetter Reinholdtsen 			}
2025c18ec02fSPetter Reinholdtsen 		}
2026c18ec02fSPetter Reinholdtsen 		c++;
2027c18ec02fSPetter Reinholdtsen 	}
2028c18ec02fSPetter Reinholdtsen }
2029c18ec02fSPetter Reinholdtsen 
2030c18ec02fSPetter Reinholdtsen /* ipmi_sdr_print_discrete_state  -  print list of asserted states
2031c18ec02fSPetter Reinholdtsen  *                                   for a discrete sensor
2032c18ec02fSPetter Reinholdtsen  *
2033c18ec02fSPetter Reinholdtsen  * @desc        : description for this line
2034c18ec02fSPetter Reinholdtsen  * @sensor_type	: sensor type code
2035c18ec02fSPetter Reinholdtsen  * @event_type	: event type code
2036c18ec02fSPetter Reinholdtsen  * @state	: mask of asserted states
2037c18ec02fSPetter Reinholdtsen  *
2038c18ec02fSPetter Reinholdtsen  * no meaningful return value
2039c18ec02fSPetter Reinholdtsen  */
2040c18ec02fSPetter Reinholdtsen void
ipmi_sdr_print_discrete_state(const char * desc,uint8_t sensor_type,uint8_t event_type,uint8_t state1,uint8_t state2)2041c18ec02fSPetter Reinholdtsen ipmi_sdr_print_discrete_state(const char *desc,
2042c18ec02fSPetter Reinholdtsen 			      uint8_t sensor_type, uint8_t event_type,
2043c18ec02fSPetter Reinholdtsen 			      uint8_t state1, uint8_t state2)
2044c18ec02fSPetter Reinholdtsen {
2045c18ec02fSPetter Reinholdtsen 	uint8_t typ;
2046c18ec02fSPetter Reinholdtsen 	struct ipmi_event_sensor_types *evt;
2047c18ec02fSPetter Reinholdtsen 	int pre = 0, c = 0;
2048c18ec02fSPetter Reinholdtsen 
2049c18ec02fSPetter Reinholdtsen 	if (state1 == 0 && (state2 & 0x7f) == 0)
2050c18ec02fSPetter Reinholdtsen 		return;
2051c18ec02fSPetter Reinholdtsen 
2052c18ec02fSPetter Reinholdtsen 	if (event_type == 0x6f) {
2053c18ec02fSPetter Reinholdtsen 		evt = sensor_specific_types;
2054c18ec02fSPetter Reinholdtsen 		typ = sensor_type;
2055c18ec02fSPetter Reinholdtsen 	} else {
2056c18ec02fSPetter Reinholdtsen 		evt = generic_event_types;
2057c18ec02fSPetter Reinholdtsen 		typ = event_type;
2058c18ec02fSPetter Reinholdtsen 	}
2059c18ec02fSPetter Reinholdtsen 
2060c18ec02fSPetter Reinholdtsen 	for (; evt->type != NULL; evt++) {
2061c18ec02fSPetter Reinholdtsen 		if ((evt->code != typ) ||
2062c18ec02fSPetter Reinholdtsen 			(evt->data != 0xFF))
2063c18ec02fSPetter Reinholdtsen 			continue;
2064c18ec02fSPetter Reinholdtsen 
2065c18ec02fSPetter Reinholdtsen 		if (pre == 0) {
2066c18ec02fSPetter Reinholdtsen 			printf(" %-21s : %s\n", desc, evt->type);
2067c18ec02fSPetter Reinholdtsen 			pre = 1;
2068c18ec02fSPetter Reinholdtsen 		}
2069c18ec02fSPetter Reinholdtsen 
2070c18ec02fSPetter Reinholdtsen 		if (evt->offset > 7) {
2071c18ec02fSPetter Reinholdtsen 			if ((1 << (evt->offset - 8)) & (state2 & 0x7f)) {
2072c18ec02fSPetter Reinholdtsen 				if (evt->desc) {
2073c18ec02fSPetter Reinholdtsen 					printf("                         "
2074c18ec02fSPetter Reinholdtsen 					       "[%s]\n",
2075c18ec02fSPetter Reinholdtsen 					       evt->desc);
2076c18ec02fSPetter Reinholdtsen 				} else {
2077c18ec02fSPetter Reinholdtsen 					printf("                         "
2078c18ec02fSPetter Reinholdtsen 					       "[no description]\n");
2079c18ec02fSPetter Reinholdtsen 				}
2080c18ec02fSPetter Reinholdtsen 			}
2081c18ec02fSPetter Reinholdtsen 		} else {
2082c18ec02fSPetter Reinholdtsen 			if ((1 << evt->offset) & state1) {
2083c18ec02fSPetter Reinholdtsen 				if (evt->desc) {
2084c18ec02fSPetter Reinholdtsen 					printf("                         "
2085c18ec02fSPetter Reinholdtsen 					       "[%s]\n",
2086c18ec02fSPetter Reinholdtsen 					       evt->desc);
2087c18ec02fSPetter Reinholdtsen 				} else {
2088c18ec02fSPetter Reinholdtsen 					printf("                         "
2089c18ec02fSPetter Reinholdtsen 					       "[no description]\n");
2090c18ec02fSPetter Reinholdtsen 				}
2091c18ec02fSPetter Reinholdtsen 			}
2092c18ec02fSPetter Reinholdtsen 		}
2093c18ec02fSPetter Reinholdtsen 		c++;
2094c18ec02fSPetter Reinholdtsen 	}
2095c18ec02fSPetter Reinholdtsen }
2096c18ec02fSPetter Reinholdtsen 
2097c18ec02fSPetter Reinholdtsen 
2098c18ec02fSPetter Reinholdtsen /* ipmi_sdr_print_sensor_eventonly  -  print SDR event only record
2099c18ec02fSPetter Reinholdtsen  *
2100c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
2101c18ec02fSPetter Reinholdtsen  * @sensor:	event only sdr record
2102c18ec02fSPetter Reinholdtsen  *
2103c18ec02fSPetter Reinholdtsen  * returns 0 on success
2104c18ec02fSPetter Reinholdtsen  * returns -1 on error
2105c18ec02fSPetter Reinholdtsen  */
2106c18ec02fSPetter Reinholdtsen int
ipmi_sdr_print_sensor_eventonly(struct ipmi_intf * intf,struct sdr_record_eventonly_sensor * sensor)2107c18ec02fSPetter Reinholdtsen ipmi_sdr_print_sensor_eventonly(struct ipmi_intf *intf,
2108c18ec02fSPetter Reinholdtsen 				struct sdr_record_eventonly_sensor *sensor)
2109c18ec02fSPetter Reinholdtsen {
2110c18ec02fSPetter Reinholdtsen 	char desc[17];
2111c18ec02fSPetter Reinholdtsen 
2112c18ec02fSPetter Reinholdtsen 	if (sensor == NULL)
2113c18ec02fSPetter Reinholdtsen 		return -1;
2114c18ec02fSPetter Reinholdtsen 
2115c18ec02fSPetter Reinholdtsen 	memset(desc, 0, sizeof (desc));
2116c18ec02fSPetter Reinholdtsen 	snprintf(desc, (sensor->id_code & 0x1f) + 1, "%s", sensor->id_string);
2117c18ec02fSPetter Reinholdtsen 
2118c18ec02fSPetter Reinholdtsen 	if (verbose) {
2119c18ec02fSPetter Reinholdtsen 		printf("Sensor ID              : %s (0x%x)\n",
2120c18ec02fSPetter Reinholdtsen 		       sensor->id_code ? desc : "", sensor->keys.sensor_num);
2121c18ec02fSPetter Reinholdtsen 		printf("Entity ID              : %d.%d (%s)\n",
2122c18ec02fSPetter Reinholdtsen 		       sensor->entity.id, sensor->entity.instance,
2123c18ec02fSPetter Reinholdtsen 		       val2str(sensor->entity.id, entity_id_vals));
2124c18ec02fSPetter Reinholdtsen 		printf("Sensor Type            : %s (0x%02x)\n",
2125c18ec02fSPetter Reinholdtsen 			ipmi_sdr_get_sensor_type_desc(sensor->sensor_type),
2126c18ec02fSPetter Reinholdtsen 			sensor->sensor_type);
2127c18ec02fSPetter Reinholdtsen 		lprintf(LOG_DEBUG, "Event Type Code        : 0x%02x",
2128c18ec02fSPetter Reinholdtsen 			sensor->event_type);
2129c18ec02fSPetter Reinholdtsen 		printf("\n");
2130c18ec02fSPetter Reinholdtsen 	} else {
2131c18ec02fSPetter Reinholdtsen 		if (csv_output)
2132c18ec02fSPetter Reinholdtsen 			printf("%s,%02Xh,ns,%d.%d,Event-Only\n",
2133c18ec02fSPetter Reinholdtsen 			       sensor->id_code ? desc : "",
2134c18ec02fSPetter Reinholdtsen 			       sensor->keys.sensor_num,
2135c18ec02fSPetter Reinholdtsen 			       sensor->entity.id, sensor->entity.instance);
2136c18ec02fSPetter Reinholdtsen 		else if (sdr_extended)
2137c18ec02fSPetter Reinholdtsen 			printf("%-16s | %02Xh | ns  | %2d.%1d | Event-Only\n",
2138c18ec02fSPetter Reinholdtsen 			       sensor->id_code ? desc : "",
2139c18ec02fSPetter Reinholdtsen 			       sensor->keys.sensor_num,
2140c18ec02fSPetter Reinholdtsen 			       sensor->entity.id, sensor->entity.instance);
2141c18ec02fSPetter Reinholdtsen 		else
2142c18ec02fSPetter Reinholdtsen 			printf("%-16s | Event-Only        | ns\n",
2143c18ec02fSPetter Reinholdtsen 			       sensor->id_code ? desc : "");
2144c18ec02fSPetter Reinholdtsen 	}
2145c18ec02fSPetter Reinholdtsen 
2146c18ec02fSPetter Reinholdtsen 	return 0;
2147c18ec02fSPetter Reinholdtsen }
2148c18ec02fSPetter Reinholdtsen 
2149c18ec02fSPetter Reinholdtsen /* ipmi_sdr_print_sensor_mc_locator  -  print SDR MC locator record
2150c18ec02fSPetter Reinholdtsen  *
2151c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
2152c18ec02fSPetter Reinholdtsen  * @mc:		mc locator sdr record
2153c18ec02fSPetter Reinholdtsen  *
2154c18ec02fSPetter Reinholdtsen  * returns 0 on success
2155c18ec02fSPetter Reinholdtsen  * returns -1 on error
2156c18ec02fSPetter Reinholdtsen  */
2157c18ec02fSPetter Reinholdtsen int
ipmi_sdr_print_sensor_mc_locator(struct ipmi_intf * intf,struct sdr_record_mc_locator * mc)2158c18ec02fSPetter Reinholdtsen ipmi_sdr_print_sensor_mc_locator(struct ipmi_intf *intf,
2159c18ec02fSPetter Reinholdtsen 				 struct sdr_record_mc_locator *mc)
2160c18ec02fSPetter Reinholdtsen {
2161c18ec02fSPetter Reinholdtsen 	char desc[17];
2162c18ec02fSPetter Reinholdtsen 
2163c18ec02fSPetter Reinholdtsen 	if (mc == NULL)
2164c18ec02fSPetter Reinholdtsen 		return -1;
2165c18ec02fSPetter Reinholdtsen 
2166c18ec02fSPetter Reinholdtsen 	memset(desc, 0, sizeof (desc));
2167c18ec02fSPetter Reinholdtsen 	snprintf(desc, (mc->id_code & 0x1f) + 1, "%s", mc->id_string);
2168c18ec02fSPetter Reinholdtsen 
2169c18ec02fSPetter Reinholdtsen 	if (verbose == 0) {
2170c18ec02fSPetter Reinholdtsen 		if (csv_output)
2171c18ec02fSPetter Reinholdtsen 			printf("%s,00h,ok,%d.%d\n",
2172c18ec02fSPetter Reinholdtsen 			       mc->id_code ? desc : "",
2173c18ec02fSPetter Reinholdtsen 			       mc->entity.id, mc->entity.instance);
2174c18ec02fSPetter Reinholdtsen 		else if (sdr_extended) {
2175c18ec02fSPetter Reinholdtsen 			printf("%-16s | 00h | ok  | %2d.%1d | ",
2176c18ec02fSPetter Reinholdtsen 			       mc->id_code ? desc : "",
2177c18ec02fSPetter Reinholdtsen 			       mc->entity.id, mc->entity.instance);
2178c18ec02fSPetter Reinholdtsen 
2179c18ec02fSPetter Reinholdtsen 			printf("%s MC @ %02Xh\n",
2180c18ec02fSPetter Reinholdtsen 			       (mc->
2181c18ec02fSPetter Reinholdtsen 				pwr_state_notif & 0x1) ? "Static" : "Dynamic",
2182c18ec02fSPetter Reinholdtsen 			       mc->dev_slave_addr);
2183c18ec02fSPetter Reinholdtsen 		} else {
2184c18ec02fSPetter Reinholdtsen 			printf("%-16s | %s MC @ %02Xh %s | ok\n",
2185c18ec02fSPetter Reinholdtsen 			       mc->id_code ? desc : "",
2186c18ec02fSPetter Reinholdtsen 			       (mc->
2187c18ec02fSPetter Reinholdtsen 				pwr_state_notif & 0x1) ? "Static" : "Dynamic",
2188c18ec02fSPetter Reinholdtsen 			       mc->dev_slave_addr,
2189c18ec02fSPetter Reinholdtsen 			       (mc->pwr_state_notif & 0x1) ? " " : "");
2190c18ec02fSPetter Reinholdtsen 		}
2191c18ec02fSPetter Reinholdtsen 
2192c18ec02fSPetter Reinholdtsen 		return 0;	/* done */
2193c18ec02fSPetter Reinholdtsen 	}
2194c18ec02fSPetter Reinholdtsen 
2195c18ec02fSPetter Reinholdtsen 	printf("Device ID              : %s\n", mc->id_string);
2196c18ec02fSPetter Reinholdtsen 	printf("Entity ID              : %d.%d (%s)\n",
2197c18ec02fSPetter Reinholdtsen 	       mc->entity.id, mc->entity.instance,
2198c18ec02fSPetter Reinholdtsen 	       val2str(mc->entity.id, entity_id_vals));
2199c18ec02fSPetter Reinholdtsen 
2200c18ec02fSPetter Reinholdtsen 	printf("Device Slave Address   : %02Xh\n", mc->dev_slave_addr);
2201c18ec02fSPetter Reinholdtsen 	printf("Channel Number         : %01Xh\n", mc->channel_num);
2202c18ec02fSPetter Reinholdtsen 
2203c18ec02fSPetter Reinholdtsen 	printf("ACPI System P/S Notif  : %sRequired\n",
2204c18ec02fSPetter Reinholdtsen 	       (mc->pwr_state_notif & 0x4) ? "" : "Not ");
2205c18ec02fSPetter Reinholdtsen 	printf("ACPI Device P/S Notif  : %sRequired\n",
2206c18ec02fSPetter Reinholdtsen 	       (mc->pwr_state_notif & 0x2) ? "" : "Not ");
2207c18ec02fSPetter Reinholdtsen 	printf("Controller Presence    : %s\n",
2208c18ec02fSPetter Reinholdtsen 	       (mc->pwr_state_notif & 0x1) ? "Static" : "Dynamic");
2209c18ec02fSPetter Reinholdtsen 	printf("Logs Init Agent Errors : %s\n",
2210c18ec02fSPetter Reinholdtsen 	       (mc->global_init & 0x8) ? "Yes" : "No");
2211c18ec02fSPetter Reinholdtsen 
2212c18ec02fSPetter Reinholdtsen 	printf("Event Message Gen      : ");
2213c18ec02fSPetter Reinholdtsen 	if (!(mc->global_init & 0x3))
2214c18ec02fSPetter Reinholdtsen 		printf("Enable\n");
2215c18ec02fSPetter Reinholdtsen 	else if ((mc->global_init & 0x3) == 0x1)
2216c18ec02fSPetter Reinholdtsen 		printf("Disable\n");
2217c18ec02fSPetter Reinholdtsen 	else if ((mc->global_init & 0x3) == 0x2)
2218c18ec02fSPetter Reinholdtsen 		printf("Do Not Init Controller\n");
2219c18ec02fSPetter Reinholdtsen 	else
2220c18ec02fSPetter Reinholdtsen 		printf("Reserved\n");
2221c18ec02fSPetter Reinholdtsen 
2222c18ec02fSPetter Reinholdtsen 	printf("Device Capabilities\n");
2223c18ec02fSPetter Reinholdtsen 	printf(" Chassis Device        : %s\n",
2224c18ec02fSPetter Reinholdtsen 	       (mc->dev_support & 0x80) ? "Yes" : "No");
2225c18ec02fSPetter Reinholdtsen 	printf(" Bridge                : %s\n",
2226c18ec02fSPetter Reinholdtsen 	       (mc->dev_support & 0x40) ? "Yes" : "No");
2227c18ec02fSPetter Reinholdtsen 	printf(" IPMB Event Generator  : %s\n",
2228c18ec02fSPetter Reinholdtsen 	       (mc->dev_support & 0x20) ? "Yes" : "No");
2229c18ec02fSPetter Reinholdtsen 	printf(" IPMB Event Receiver   : %s\n",
2230c18ec02fSPetter Reinholdtsen 	       (mc->dev_support & 0x10) ? "Yes" : "No");
2231c18ec02fSPetter Reinholdtsen 	printf(" FRU Inventory Device  : %s\n",
2232c18ec02fSPetter Reinholdtsen 	       (mc->dev_support & 0x08) ? "Yes" : "No");
2233c18ec02fSPetter Reinholdtsen 	printf(" SEL Device            : %s\n",
2234c18ec02fSPetter Reinholdtsen 	       (mc->dev_support & 0x04) ? "Yes" : "No");
2235c18ec02fSPetter Reinholdtsen 	printf(" SDR Repository        : %s\n",
2236c18ec02fSPetter Reinholdtsen 	       (mc->dev_support & 0x02) ? "Yes" : "No");
2237c18ec02fSPetter Reinholdtsen 	printf(" Sensor Device         : %s\n",
2238c18ec02fSPetter Reinholdtsen 	       (mc->dev_support & 0x01) ? "Yes" : "No");
2239c18ec02fSPetter Reinholdtsen 
2240c18ec02fSPetter Reinholdtsen 	printf("\n");
2241c18ec02fSPetter Reinholdtsen 
2242c18ec02fSPetter Reinholdtsen 	return 0;
2243c18ec02fSPetter Reinholdtsen }
2244c18ec02fSPetter Reinholdtsen 
2245c18ec02fSPetter Reinholdtsen /* ipmi_sdr_print_sensor_generic_locator  -  print generic device locator record
2246c18ec02fSPetter Reinholdtsen  *
2247c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
2248c18ec02fSPetter Reinholdtsen  * @gen:	generic device locator sdr record
2249c18ec02fSPetter Reinholdtsen  *
2250c18ec02fSPetter Reinholdtsen  * returns 0 on success
2251c18ec02fSPetter Reinholdtsen  * returns -1 on error
2252c18ec02fSPetter Reinholdtsen  */
2253c18ec02fSPetter Reinholdtsen int
ipmi_sdr_print_sensor_generic_locator(struct ipmi_intf * intf,struct sdr_record_generic_locator * dev)2254c18ec02fSPetter Reinholdtsen ipmi_sdr_print_sensor_generic_locator(struct ipmi_intf *intf,
2255c18ec02fSPetter Reinholdtsen 				      struct sdr_record_generic_locator *dev)
2256c18ec02fSPetter Reinholdtsen {
2257c18ec02fSPetter Reinholdtsen 	char desc[17];
2258c18ec02fSPetter Reinholdtsen 
2259c18ec02fSPetter Reinholdtsen 	memset(desc, 0, sizeof (desc));
2260c18ec02fSPetter Reinholdtsen 	snprintf(desc, (dev->id_code & 0x1f) + 1, "%s", dev->id_string);
2261c18ec02fSPetter Reinholdtsen 
2262c18ec02fSPetter Reinholdtsen 	if (!verbose) {
2263c18ec02fSPetter Reinholdtsen 		if (csv_output)
2264c18ec02fSPetter Reinholdtsen 			printf("%s,00h,ns,%d.%d\n",
2265c18ec02fSPetter Reinholdtsen 			       dev->id_code ? desc : "",
2266c18ec02fSPetter Reinholdtsen 			       dev->entity.id, dev->entity.instance);
2267c18ec02fSPetter Reinholdtsen 		else if (sdr_extended)
2268c18ec02fSPetter Reinholdtsen 			printf
2269c18ec02fSPetter Reinholdtsen 			    ("%-16s | 00h | ns  | %2d.%1d | Generic Device @%02Xh:%02Xh.%1d\n",
2270c18ec02fSPetter Reinholdtsen 			     dev->id_code ? desc : "", dev->entity.id,
2271c18ec02fSPetter Reinholdtsen 			     dev->entity.instance, dev->dev_access_addr,
2272c18ec02fSPetter Reinholdtsen 			     dev->dev_slave_addr, dev->oem);
2273c18ec02fSPetter Reinholdtsen 		else
2274c18ec02fSPetter Reinholdtsen 			printf("%-16s | Generic @%02X:%02X.%-2d | ok\n",
2275c18ec02fSPetter Reinholdtsen 			       dev->id_code ? desc : "",
2276c18ec02fSPetter Reinholdtsen 			       dev->dev_access_addr,
2277c18ec02fSPetter Reinholdtsen 			       dev->dev_slave_addr, dev->oem);
2278c18ec02fSPetter Reinholdtsen 
2279c18ec02fSPetter Reinholdtsen 		return 0;
2280c18ec02fSPetter Reinholdtsen 	}
2281c18ec02fSPetter Reinholdtsen 
2282c18ec02fSPetter Reinholdtsen 	printf("Device ID              : %s\n", dev->id_string);
2283c18ec02fSPetter Reinholdtsen 	printf("Entity ID              : %d.%d (%s)\n",
2284c18ec02fSPetter Reinholdtsen 	       dev->entity.id, dev->entity.instance,
2285c18ec02fSPetter Reinholdtsen 	       val2str(dev->entity.id, entity_id_vals));
2286c18ec02fSPetter Reinholdtsen 
2287c18ec02fSPetter Reinholdtsen 	printf("Device Access Address  : %02Xh\n", dev->dev_access_addr);
2288c18ec02fSPetter Reinholdtsen 	printf("Device Slave Address   : %02Xh\n", dev->dev_slave_addr);
2289c18ec02fSPetter Reinholdtsen 	printf("Address Span           : %02Xh\n", dev->addr_span);
2290c18ec02fSPetter Reinholdtsen 	printf("Channel Number         : %01Xh\n", dev->channel_num);
2291c18ec02fSPetter Reinholdtsen 	printf("LUN.Bus                : %01Xh.%01Xh\n", dev->lun, dev->bus);
2292c18ec02fSPetter Reinholdtsen 	printf("Device Type.Modifier   : %01Xh.%01Xh (%s)\n",
2293c18ec02fSPetter Reinholdtsen 	       dev->dev_type, dev->dev_type_modifier,
2294c18ec02fSPetter Reinholdtsen 	       val2str(dev->dev_type << 8 | dev->dev_type_modifier,
2295c18ec02fSPetter Reinholdtsen 		       entity_device_type_vals));
2296c18ec02fSPetter Reinholdtsen 	printf("OEM                    : %02Xh\n", dev->oem);
2297c18ec02fSPetter Reinholdtsen 	printf("\n");
2298c18ec02fSPetter Reinholdtsen 
2299c18ec02fSPetter Reinholdtsen 	return 0;
2300c18ec02fSPetter Reinholdtsen }
2301c18ec02fSPetter Reinholdtsen 
2302c18ec02fSPetter Reinholdtsen /* ipmi_sdr_print_sensor_fru_locator  -  print FRU locator record
2303c18ec02fSPetter Reinholdtsen  *
2304c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
2305c18ec02fSPetter Reinholdtsen  * @fru:	fru locator sdr record
2306c18ec02fSPetter Reinholdtsen  *
2307c18ec02fSPetter Reinholdtsen  * returns 0 on success
2308c18ec02fSPetter Reinholdtsen  * returns -1 on error
2309c18ec02fSPetter Reinholdtsen  */
2310c18ec02fSPetter Reinholdtsen int
ipmi_sdr_print_sensor_fru_locator(struct ipmi_intf * intf,struct sdr_record_fru_locator * fru)2311c18ec02fSPetter Reinholdtsen ipmi_sdr_print_sensor_fru_locator(struct ipmi_intf *intf,
2312c18ec02fSPetter Reinholdtsen 				  struct sdr_record_fru_locator *fru)
2313c18ec02fSPetter Reinholdtsen {
2314c18ec02fSPetter Reinholdtsen 	char desc[17];
2315c18ec02fSPetter Reinholdtsen 
2316c18ec02fSPetter Reinholdtsen 	memset(desc, 0, sizeof (desc));
2317c18ec02fSPetter Reinholdtsen 	snprintf(desc, (fru->id_code & 0x1f) + 1, "%s", fru->id_string);
2318c18ec02fSPetter Reinholdtsen 
2319c18ec02fSPetter Reinholdtsen 	if (!verbose) {
2320c18ec02fSPetter Reinholdtsen 		if (csv_output)
2321c18ec02fSPetter Reinholdtsen 			printf("%s,00h,ns,%d.%d\n",
2322c18ec02fSPetter Reinholdtsen 			       fru->id_code ? desc : "",
2323c18ec02fSPetter Reinholdtsen 			       fru->entity.id, fru->entity.instance);
2324c18ec02fSPetter Reinholdtsen 		else if (sdr_extended)
2325c18ec02fSPetter Reinholdtsen 			printf("%-16s | 00h | ns  | %2d.%1d | %s FRU @%02Xh\n",
2326c18ec02fSPetter Reinholdtsen 			       fru->id_code ? desc : "",
2327c18ec02fSPetter Reinholdtsen 			       fru->entity.id, fru->entity.instance,
2328c18ec02fSPetter Reinholdtsen 			       (fru->logical) ? "Logical" : "Physical",
2329c18ec02fSPetter Reinholdtsen 			       fru->device_id);
2330c18ec02fSPetter Reinholdtsen 		else
2331c18ec02fSPetter Reinholdtsen 			printf("%-16s | %s FRU @%02Xh %02x.%x | ok\n",
2332c18ec02fSPetter Reinholdtsen 			       fru->id_code ? desc : "",
2333c18ec02fSPetter Reinholdtsen 			       (fru->logical) ? "Log" : "Phy",
2334c18ec02fSPetter Reinholdtsen 			       fru->device_id,
2335c18ec02fSPetter Reinholdtsen 			       fru->entity.id, fru->entity.instance);
2336c18ec02fSPetter Reinholdtsen 
2337c18ec02fSPetter Reinholdtsen 		return 0;
2338c18ec02fSPetter Reinholdtsen 	}
2339c18ec02fSPetter Reinholdtsen 
2340c18ec02fSPetter Reinholdtsen 	printf("Device ID              : %s\n", fru->id_string);
2341c18ec02fSPetter Reinholdtsen 	printf("Entity ID              : %d.%d (%s)\n",
2342c18ec02fSPetter Reinholdtsen 	       fru->entity.id, fru->entity.instance,
2343c18ec02fSPetter Reinholdtsen 	       val2str(fru->entity.id, entity_id_vals));
2344c18ec02fSPetter Reinholdtsen 
2345c18ec02fSPetter Reinholdtsen 	printf("Device Access Address  : %02Xh\n", fru->dev_slave_addr);
2346c18ec02fSPetter Reinholdtsen 	printf("%s: %02Xh\n",
2347c18ec02fSPetter Reinholdtsen 	       fru->logical ? "Logical FRU Device     " :
2348c18ec02fSPetter Reinholdtsen 	       "Slave Address          ", fru->device_id);
2349c18ec02fSPetter Reinholdtsen 	printf("Channel Number         : %01Xh\n", fru->channel_num);
2350c18ec02fSPetter Reinholdtsen 	printf("LUN.Bus                : %01Xh.%01Xh\n", fru->lun, fru->bus);
2351c18ec02fSPetter Reinholdtsen 	printf("Device Type.Modifier   : %01Xh.%01Xh (%s)\n",
2352c18ec02fSPetter Reinholdtsen 	       fru->dev_type, fru->dev_type_modifier,
2353c18ec02fSPetter Reinholdtsen 	       val2str(fru->dev_type << 8 | fru->dev_type_modifier,
2354c18ec02fSPetter Reinholdtsen 		       entity_device_type_vals));
2355c18ec02fSPetter Reinholdtsen 	printf("OEM                    : %02Xh\n", fru->oem);
2356c18ec02fSPetter Reinholdtsen 	printf("\n");
2357c18ec02fSPetter Reinholdtsen 
2358c18ec02fSPetter Reinholdtsen 	return 0;
2359c18ec02fSPetter Reinholdtsen }
2360c18ec02fSPetter Reinholdtsen 
2361c18ec02fSPetter Reinholdtsen /* ipmi_sdr_print_sensor_entity_assoc  -  print SDR entity association record
2362c18ec02fSPetter Reinholdtsen  *
2363c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
2364c18ec02fSPetter Reinholdtsen  * @mc:		entity association sdr record
2365c18ec02fSPetter Reinholdtsen  *
2366c18ec02fSPetter Reinholdtsen  * returns 0 on success
2367c18ec02fSPetter Reinholdtsen  * returns -1 on error
2368c18ec02fSPetter Reinholdtsen  */
2369c18ec02fSPetter Reinholdtsen int
ipmi_sdr_print_sensor_entity_assoc(struct ipmi_intf * intf,struct sdr_record_entity_assoc * assoc)2370c18ec02fSPetter Reinholdtsen ipmi_sdr_print_sensor_entity_assoc(struct ipmi_intf *intf,
2371c18ec02fSPetter Reinholdtsen 				   struct sdr_record_entity_assoc *assoc)
2372c18ec02fSPetter Reinholdtsen {
2373c18ec02fSPetter Reinholdtsen 	return 0;
2374c18ec02fSPetter Reinholdtsen }
2375c18ec02fSPetter Reinholdtsen 
2376c18ec02fSPetter Reinholdtsen /* ipmi_sdr_print_sensor_oem_intel  -  print Intel OEM sensors
2377c18ec02fSPetter Reinholdtsen  *
2378c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
2379c18ec02fSPetter Reinholdtsen  * @oem:	oem sdr record
2380c18ec02fSPetter Reinholdtsen  *
2381c18ec02fSPetter Reinholdtsen  * returns 0 on success
2382c18ec02fSPetter Reinholdtsen  * returns -1 on error
2383c18ec02fSPetter Reinholdtsen  */
2384c18ec02fSPetter Reinholdtsen static int
ipmi_sdr_print_sensor_oem_intel(struct ipmi_intf * intf,struct sdr_record_oem * oem)2385c18ec02fSPetter Reinholdtsen ipmi_sdr_print_sensor_oem_intel(struct ipmi_intf *intf,
2386c18ec02fSPetter Reinholdtsen 				struct sdr_record_oem *oem)
2387c18ec02fSPetter Reinholdtsen {
2388c18ec02fSPetter Reinholdtsen 	switch (oem->data[3]) {	/* record sub-type */
2389c18ec02fSPetter Reinholdtsen 	case 0x02:		/* Power Unit Map */
2390c18ec02fSPetter Reinholdtsen 		if (verbose) {
2391c18ec02fSPetter Reinholdtsen 			printf
2392c18ec02fSPetter Reinholdtsen 			    ("Sensor ID              : Power Unit Redundancy (0x%x)\n",
2393c18ec02fSPetter Reinholdtsen 			     oem->data[4]);
2394c18ec02fSPetter Reinholdtsen 			printf
2395c18ec02fSPetter Reinholdtsen 			    ("Sensor Type            : Intel OEM - Power Unit Map\n");
2396c18ec02fSPetter Reinholdtsen 			printf("Redundant Supplies     : %d", oem->data[6]);
2397c18ec02fSPetter Reinholdtsen 			if (oem->data[5])
2398c18ec02fSPetter Reinholdtsen 				printf(" (flags %xh)", oem->data[5]);
2399c18ec02fSPetter Reinholdtsen 			printf("\n");
2400c18ec02fSPetter Reinholdtsen 		}
2401c18ec02fSPetter Reinholdtsen 
2402c18ec02fSPetter Reinholdtsen 		switch (oem->data_len) {
2403c18ec02fSPetter Reinholdtsen 		case 7:	/* SR1300, non-redundant */
2404c18ec02fSPetter Reinholdtsen 			if (verbose)
2405c18ec02fSPetter Reinholdtsen 				printf("Power Redundancy       : No\n");
2406c18ec02fSPetter Reinholdtsen 			else if (csv_output)
2407c18ec02fSPetter Reinholdtsen 				printf("Power Redundancy,Not Available,nr\n");
2408c18ec02fSPetter Reinholdtsen 			else
2409c18ec02fSPetter Reinholdtsen 				printf
2410c18ec02fSPetter Reinholdtsen 				    ("Power Redundancy | Not Available     | nr\n");
2411c18ec02fSPetter Reinholdtsen 			break;
2412c18ec02fSPetter Reinholdtsen 		case 8:	/* SR2300, redundant, PS1 & PS2 present */
2413c18ec02fSPetter Reinholdtsen 			if (verbose) {
2414c18ec02fSPetter Reinholdtsen 				printf("Power Redundancy       : No\n");
2415c18ec02fSPetter Reinholdtsen 				printf("Power Supply 2 Sensor  : %x\n",
2416c18ec02fSPetter Reinholdtsen 				       oem->data[8]);
2417c18ec02fSPetter Reinholdtsen 			} else if (csv_output) {
2418c18ec02fSPetter Reinholdtsen 				printf("Power Redundancy,PS@%02xh,nr\n",
2419c18ec02fSPetter Reinholdtsen 				       oem->data[8]);
2420c18ec02fSPetter Reinholdtsen 			} else {
2421c18ec02fSPetter Reinholdtsen 				printf
2422c18ec02fSPetter Reinholdtsen 				    ("Power Redundancy | PS@%02xh            | nr\n",
2423c18ec02fSPetter Reinholdtsen 				     oem->data[8]);
2424c18ec02fSPetter Reinholdtsen 			}
2425c18ec02fSPetter Reinholdtsen 			break;
2426c18ec02fSPetter Reinholdtsen 		case 9:	/* SR2300, non-redundant, PSx present */
2427c18ec02fSPetter Reinholdtsen 			if (verbose) {
2428c18ec02fSPetter Reinholdtsen 				printf("Power Redundancy       : Yes\n");
2429c18ec02fSPetter Reinholdtsen 				printf("Power Supply Sensor    : %x\n",
2430c18ec02fSPetter Reinholdtsen 				       oem->data[7]);
2431c18ec02fSPetter Reinholdtsen 				printf("Power Supply Sensor    : %x\n",
2432c18ec02fSPetter Reinholdtsen 				       oem->data[8]);
2433c18ec02fSPetter Reinholdtsen 			} else if (csv_output) {
2434c18ec02fSPetter Reinholdtsen 				printf
2435c18ec02fSPetter Reinholdtsen 				    ("Power Redundancy,PS@%02xh + PS@%02xh,ok\n",
2436c18ec02fSPetter Reinholdtsen 				     oem->data[7], oem->data[8]);
2437c18ec02fSPetter Reinholdtsen 			} else {
2438c18ec02fSPetter Reinholdtsen 				printf
2439c18ec02fSPetter Reinholdtsen 				    ("Power Redundancy | PS@%02xh + PS@%02xh   | ok\n",
2440c18ec02fSPetter Reinholdtsen 				     oem->data[7], oem->data[8]);
2441c18ec02fSPetter Reinholdtsen 			}
2442c18ec02fSPetter Reinholdtsen 			break;
2443c18ec02fSPetter Reinholdtsen 		}
2444c18ec02fSPetter Reinholdtsen 		if (verbose)
2445c18ec02fSPetter Reinholdtsen 			printf("\n");
2446c18ec02fSPetter Reinholdtsen 		break;
2447c18ec02fSPetter Reinholdtsen 	case 0x03:		/* Fan Speed Control */
2448c18ec02fSPetter Reinholdtsen 		break;
2449c18ec02fSPetter Reinholdtsen 	case 0x06:		/* System Information */
2450c18ec02fSPetter Reinholdtsen 		break;
2451c18ec02fSPetter Reinholdtsen 	case 0x07:		/* Ambient Temperature Fan Speed Control */
2452c18ec02fSPetter Reinholdtsen 		break;
2453c18ec02fSPetter Reinholdtsen 	default:
2454c18ec02fSPetter Reinholdtsen 		lprintf(LOG_DEBUG, "Unknown Intel OEM SDR Record type %02x",
2455c18ec02fSPetter Reinholdtsen 			oem->data[3]);
2456c18ec02fSPetter Reinholdtsen 	}
2457c18ec02fSPetter Reinholdtsen 
2458c18ec02fSPetter Reinholdtsen 	return 0;
2459c18ec02fSPetter Reinholdtsen }
2460c18ec02fSPetter Reinholdtsen 
2461c18ec02fSPetter Reinholdtsen /* ipmi_sdr_print_sensor_oem  -  print OEM sensors
2462c18ec02fSPetter Reinholdtsen  *
2463c18ec02fSPetter Reinholdtsen  * This function is generally only filled out by decoding what
2464c18ec02fSPetter Reinholdtsen  * a particular BMC might stuff into its OEM records.  The
2465c18ec02fSPetter Reinholdtsen  * records are keyed off manufacturer ID and record subtypes.
2466c18ec02fSPetter Reinholdtsen  *
2467c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
2468c18ec02fSPetter Reinholdtsen  * @oem:	oem sdr record
2469c18ec02fSPetter Reinholdtsen  *
2470c18ec02fSPetter Reinholdtsen  * returns 0 on success
2471c18ec02fSPetter Reinholdtsen  * returns -1 on error
2472c18ec02fSPetter Reinholdtsen  */
2473c18ec02fSPetter Reinholdtsen static int
ipmi_sdr_print_sensor_oem(struct ipmi_intf * intf,struct sdr_record_oem * oem)2474c18ec02fSPetter Reinholdtsen ipmi_sdr_print_sensor_oem(struct ipmi_intf *intf, struct sdr_record_oem *oem)
2475c18ec02fSPetter Reinholdtsen {
2476c18ec02fSPetter Reinholdtsen 	int rc = 0;
2477c18ec02fSPetter Reinholdtsen 
2478c18ec02fSPetter Reinholdtsen 	if (oem == NULL)
2479c18ec02fSPetter Reinholdtsen 		return -1;
2480c18ec02fSPetter Reinholdtsen 	if (oem->data_len == 0 || oem->data == NULL)
2481c18ec02fSPetter Reinholdtsen 		return -1;
2482c18ec02fSPetter Reinholdtsen 
2483c18ec02fSPetter Reinholdtsen 	if (verbose > 2)
2484c18ec02fSPetter Reinholdtsen 		printbuf(oem->data, oem->data_len, "OEM Record");
2485c18ec02fSPetter Reinholdtsen 
2486c18ec02fSPetter Reinholdtsen 	/* intel manufacturer id */
2487c18ec02fSPetter Reinholdtsen 	if (oem->data[0] == 0x57 &&
2488c18ec02fSPetter Reinholdtsen 	    oem->data[1] == 0x01 && oem->data[2] == 0x00) {
2489c18ec02fSPetter Reinholdtsen 		rc = ipmi_sdr_print_sensor_oem_intel(intf, oem);
2490c18ec02fSPetter Reinholdtsen 	}
2491c18ec02fSPetter Reinholdtsen 
2492c18ec02fSPetter Reinholdtsen 	return rc;
2493c18ec02fSPetter Reinholdtsen }
2494c18ec02fSPetter Reinholdtsen 
2495c18ec02fSPetter Reinholdtsen /* ipmi_sdr_print_name_from_rawentry  -  Print SDR name  from raw data
2496c18ec02fSPetter Reinholdtsen  *
2497c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
2498c18ec02fSPetter Reinholdtsen  * @type:	sensor type
2499c18ec02fSPetter Reinholdtsen  * @raw:	raw sensor data
2500c18ec02fSPetter Reinholdtsen  *
2501c18ec02fSPetter Reinholdtsen  * returns 0 on success
2502c18ec02fSPetter Reinholdtsen  * returns -1 on error
2503c18ec02fSPetter Reinholdtsen  */
2504c18ec02fSPetter Reinholdtsen int
ipmi_sdr_print_name_from_rawentry(struct ipmi_intf * intf,uint16_t id,uint8_t type,uint8_t * raw)2505c18ec02fSPetter Reinholdtsen ipmi_sdr_print_name_from_rawentry(struct ipmi_intf *intf,uint16_t id,
2506c18ec02fSPetter Reinholdtsen                                   uint8_t type,uint8_t * raw)
2507c18ec02fSPetter Reinholdtsen {
2508c18ec02fSPetter Reinholdtsen    union {
2509c18ec02fSPetter Reinholdtsen       struct sdr_record_full_sensor *full;
2510c18ec02fSPetter Reinholdtsen       struct sdr_record_compact_sensor *compact;
2511c18ec02fSPetter Reinholdtsen       struct sdr_record_eventonly_sensor *eventonly;
2512c18ec02fSPetter Reinholdtsen       struct sdr_record_generic_locator *genloc;
2513c18ec02fSPetter Reinholdtsen       struct sdr_record_fru_locator *fruloc;
2514c18ec02fSPetter Reinholdtsen       struct sdr_record_mc_locator *mcloc;
2515c18ec02fSPetter Reinholdtsen       struct sdr_record_entity_assoc *entassoc;
2516c18ec02fSPetter Reinholdtsen       struct sdr_record_oem *oem;
2517c18ec02fSPetter Reinholdtsen    } record;
2518c18ec02fSPetter Reinholdtsen 
2519c18ec02fSPetter Reinholdtsen    int rc =0;
2520c18ec02fSPetter Reinholdtsen    char desc[17];
2521c18ec02fSPetter Reinholdtsen    memset(desc, ' ', sizeof (desc));
2522c18ec02fSPetter Reinholdtsen 
2523c18ec02fSPetter Reinholdtsen    switch ( type) {
2524c18ec02fSPetter Reinholdtsen       case SDR_RECORD_TYPE_FULL_SENSOR:
2525c18ec02fSPetter Reinholdtsen       record.full = (struct sdr_record_full_sensor *) raw;
2526c18ec02fSPetter Reinholdtsen       snprintf(desc, (record.full->id_code & 0x1f) +1, "%s",
2527c18ec02fSPetter Reinholdtsen                (const char *)record.full->id_string);
2528c18ec02fSPetter Reinholdtsen       break;
2529c18ec02fSPetter Reinholdtsen       case SDR_RECORD_TYPE_COMPACT_SENSOR:
2530c18ec02fSPetter Reinholdtsen       record.compact = (struct sdr_record_compact_sensor *) raw	;
2531c18ec02fSPetter Reinholdtsen       snprintf(desc, (record.compact->id_code & 0x1f)  +1, "%s",
2532c18ec02fSPetter Reinholdtsen                (const char *)record.compact->id_string);
2533c18ec02fSPetter Reinholdtsen       break;
2534c18ec02fSPetter Reinholdtsen       case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
2535c18ec02fSPetter Reinholdtsen       record.eventonly  = (struct sdr_record_eventonly_sensor *) raw ;
2536c18ec02fSPetter Reinholdtsen       snprintf(desc, (record.eventonly->id_code & 0x1f)  +1, "%s",
2537c18ec02fSPetter Reinholdtsen                (const char *)record.eventonly->id_string);
2538c18ec02fSPetter Reinholdtsen       break;
2539c18ec02fSPetter Reinholdtsen       case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
2540c18ec02fSPetter Reinholdtsen       record.mcloc  = (struct sdr_record_mc_locator *) raw ;
2541c18ec02fSPetter Reinholdtsen       snprintf(desc, (record.mcloc->id_code & 0x1f)  +1, "%s",
2542c18ec02fSPetter Reinholdtsen                (const char *)record.mcloc->id_string);
2543c18ec02fSPetter Reinholdtsen       break;
2544c18ec02fSPetter Reinholdtsen       default:
2545c18ec02fSPetter Reinholdtsen       rc = -1;
2546c18ec02fSPetter Reinholdtsen       break;
2547c18ec02fSPetter Reinholdtsen    }
2548c18ec02fSPetter Reinholdtsen 
2549c18ec02fSPetter Reinholdtsen       lprintf(LOG_INFO, "ID: 0x%04x , NAME: %-16s", id, desc);
2550c18ec02fSPetter Reinholdtsen    return rc;
2551c18ec02fSPetter Reinholdtsen }
2552c18ec02fSPetter Reinholdtsen 
2553c18ec02fSPetter Reinholdtsen /* ipmi_sdr_print_rawentry  -  Print SDR entry from raw data
2554c18ec02fSPetter Reinholdtsen  *
2555c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
2556c18ec02fSPetter Reinholdtsen  * @type:	sensor type
2557c18ec02fSPetter Reinholdtsen  * @raw:	raw sensor data
2558c18ec02fSPetter Reinholdtsen  * @len:	length of raw sensor data
2559c18ec02fSPetter Reinholdtsen  *
2560c18ec02fSPetter Reinholdtsen  * returns 0 on success
2561c18ec02fSPetter Reinholdtsen  * returns -1 on error
2562c18ec02fSPetter Reinholdtsen  */
2563c18ec02fSPetter Reinholdtsen int
ipmi_sdr_print_rawentry(struct ipmi_intf * intf,uint8_t type,uint8_t * raw,int len)2564c18ec02fSPetter Reinholdtsen ipmi_sdr_print_rawentry(struct ipmi_intf *intf, uint8_t type,
2565c18ec02fSPetter Reinholdtsen 			uint8_t * raw, int len)
2566c18ec02fSPetter Reinholdtsen {
2567c18ec02fSPetter Reinholdtsen 	int rc = 0;
2568c18ec02fSPetter Reinholdtsen 
2569c18ec02fSPetter Reinholdtsen 	switch (type) {
2570c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_FULL_SENSOR:
2571c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_COMPACT_SENSOR:
2572c18ec02fSPetter Reinholdtsen 		rc = ipmi_sdr_print_sensor_fc(intf,
2573c18ec02fSPetter Reinholdtsen 					(struct sdr_record_common_sensor *) raw,
2574c18ec02fSPetter Reinholdtsen 					type);
2575c18ec02fSPetter Reinholdtsen 		break;
2576c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
2577c18ec02fSPetter Reinholdtsen 		rc = ipmi_sdr_print_sensor_eventonly(intf,
2578c18ec02fSPetter Reinholdtsen 						     (struct
2579c18ec02fSPetter Reinholdtsen 						      sdr_record_eventonly_sensor
2580c18ec02fSPetter Reinholdtsen 						      *) raw);
2581c18ec02fSPetter Reinholdtsen 		break;
2582c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR:
2583c18ec02fSPetter Reinholdtsen 		rc = ipmi_sdr_print_sensor_generic_locator(intf,
2584c18ec02fSPetter Reinholdtsen 							   (struct
2585c18ec02fSPetter Reinholdtsen 							    sdr_record_generic_locator
2586c18ec02fSPetter Reinholdtsen 							    *) raw);
2587c18ec02fSPetter Reinholdtsen 		break;
2588c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
2589c18ec02fSPetter Reinholdtsen 		rc = ipmi_sdr_print_sensor_fru_locator(intf,
2590c18ec02fSPetter Reinholdtsen 						       (struct
2591c18ec02fSPetter Reinholdtsen 							sdr_record_fru_locator
2592c18ec02fSPetter Reinholdtsen 							*) raw);
2593c18ec02fSPetter Reinholdtsen 		break;
2594c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
2595c18ec02fSPetter Reinholdtsen 		rc = ipmi_sdr_print_sensor_mc_locator(intf,
2596c18ec02fSPetter Reinholdtsen 						      (struct
2597c18ec02fSPetter Reinholdtsen 						       sdr_record_mc_locator *)
2598c18ec02fSPetter Reinholdtsen 						      raw);
2599c18ec02fSPetter Reinholdtsen 		break;
2600c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_ENTITY_ASSOC:
2601c18ec02fSPetter Reinholdtsen 		rc = ipmi_sdr_print_sensor_entity_assoc(intf,
2602c18ec02fSPetter Reinholdtsen 							(struct
2603c18ec02fSPetter Reinholdtsen 							 sdr_record_entity_assoc
2604c18ec02fSPetter Reinholdtsen 							 *) raw);
2605c18ec02fSPetter Reinholdtsen 		break;
2606c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_OEM:{
2607c18ec02fSPetter Reinholdtsen 			struct sdr_record_oem oem;
2608c18ec02fSPetter Reinholdtsen 			oem.data = raw;
2609c18ec02fSPetter Reinholdtsen 			oem.data_len = len;
2610c18ec02fSPetter Reinholdtsen 			rc = ipmi_sdr_print_sensor_oem(intf,
2611c18ec02fSPetter Reinholdtsen 						       (struct sdr_record_oem *)
2612c18ec02fSPetter Reinholdtsen 						       &oem);
2613c18ec02fSPetter Reinholdtsen 			break;
2614c18ec02fSPetter Reinholdtsen 		}
2615c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_DEVICE_ENTITY_ASSOC:
2616c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_MC_CONFIRMATION:
2617c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_BMC_MSG_CHANNEL_INFO:
2618c18ec02fSPetter Reinholdtsen 		/* not implemented */
2619c18ec02fSPetter Reinholdtsen 		break;
2620c18ec02fSPetter Reinholdtsen 	}
2621c18ec02fSPetter Reinholdtsen 
2622c18ec02fSPetter Reinholdtsen 	return rc;
2623c18ec02fSPetter Reinholdtsen }
2624c18ec02fSPetter Reinholdtsen 
2625c18ec02fSPetter Reinholdtsen /* ipmi_sdr_print_listentry  -  Print SDR entry from list
2626c18ec02fSPetter Reinholdtsen  *
2627c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
2628c18ec02fSPetter Reinholdtsen  * @entry:	sdr record list entry
2629c18ec02fSPetter Reinholdtsen  *
2630c18ec02fSPetter Reinholdtsen  * returns 0 on success
2631c18ec02fSPetter Reinholdtsen  * returns -1 on error
2632c18ec02fSPetter Reinholdtsen  */
2633c18ec02fSPetter Reinholdtsen int
ipmi_sdr_print_listentry(struct ipmi_intf * intf,struct sdr_record_list * entry)2634c18ec02fSPetter Reinholdtsen ipmi_sdr_print_listentry(struct ipmi_intf *intf, struct sdr_record_list *entry)
2635c18ec02fSPetter Reinholdtsen {
2636c18ec02fSPetter Reinholdtsen 	int rc = 0;
2637c18ec02fSPetter Reinholdtsen 
2638c18ec02fSPetter Reinholdtsen 	switch (entry->type) {
2639c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_FULL_SENSOR:
2640c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_COMPACT_SENSOR:
2641c18ec02fSPetter Reinholdtsen 		rc = ipmi_sdr_print_sensor_fc(intf, entry->record.common, entry->type);
2642c18ec02fSPetter Reinholdtsen 		break;
2643c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
2644c18ec02fSPetter Reinholdtsen 		rc = ipmi_sdr_print_sensor_eventonly(intf,
2645c18ec02fSPetter Reinholdtsen 						     entry->record.eventonly);
2646c18ec02fSPetter Reinholdtsen 		break;
2647c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR:
2648c18ec02fSPetter Reinholdtsen 		rc = ipmi_sdr_print_sensor_generic_locator(intf,
2649c18ec02fSPetter Reinholdtsen 							   entry->record.
2650c18ec02fSPetter Reinholdtsen 							   genloc);
2651c18ec02fSPetter Reinholdtsen 		break;
2652c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
2653c18ec02fSPetter Reinholdtsen 		rc = ipmi_sdr_print_sensor_fru_locator(intf,
2654c18ec02fSPetter Reinholdtsen 						       entry->record.fruloc);
2655c18ec02fSPetter Reinholdtsen 		break;
2656c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
2657c18ec02fSPetter Reinholdtsen 		rc = ipmi_sdr_print_sensor_mc_locator(intf,
2658c18ec02fSPetter Reinholdtsen 						      entry->record.mcloc);
2659c18ec02fSPetter Reinholdtsen 		break;
2660c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_ENTITY_ASSOC:
2661c18ec02fSPetter Reinholdtsen 		rc = ipmi_sdr_print_sensor_entity_assoc(intf,
2662c18ec02fSPetter Reinholdtsen 							entry->record.entassoc);
2663c18ec02fSPetter Reinholdtsen 		break;
2664c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_OEM:
2665c18ec02fSPetter Reinholdtsen 		rc = ipmi_sdr_print_sensor_oem(intf, entry->record.oem);
2666c18ec02fSPetter Reinholdtsen 		break;
2667c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_DEVICE_ENTITY_ASSOC:
2668c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_MC_CONFIRMATION:
2669c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_BMC_MSG_CHANNEL_INFO:
2670c18ec02fSPetter Reinholdtsen 		/* not implemented yet */
2671c18ec02fSPetter Reinholdtsen 		break;
2672c18ec02fSPetter Reinholdtsen 	}
2673c18ec02fSPetter Reinholdtsen 
2674c18ec02fSPetter Reinholdtsen 	return rc;
2675c18ec02fSPetter Reinholdtsen }
2676c18ec02fSPetter Reinholdtsen 
2677c18ec02fSPetter Reinholdtsen /* ipmi_sdr_print_sdr  -  iterate through SDR printing records
2678c18ec02fSPetter Reinholdtsen  *
2679c18ec02fSPetter Reinholdtsen  * intf:	ipmi interface
2680c18ec02fSPetter Reinholdtsen  * type:	record type to print
2681c18ec02fSPetter Reinholdtsen  *
2682c18ec02fSPetter Reinholdtsen  * returns 0 on success
2683c18ec02fSPetter Reinholdtsen  * returns -1 on error
2684c18ec02fSPetter Reinholdtsen  */
2685c18ec02fSPetter Reinholdtsen int
ipmi_sdr_print_sdr(struct ipmi_intf * intf,uint8_t type)2686c18ec02fSPetter Reinholdtsen ipmi_sdr_print_sdr(struct ipmi_intf *intf, uint8_t type)
2687c18ec02fSPetter Reinholdtsen {
2688c18ec02fSPetter Reinholdtsen 	struct sdr_get_rs *header;
2689c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *e;
2690c18ec02fSPetter Reinholdtsen 	int rc = 0;
2691c18ec02fSPetter Reinholdtsen 
2692c18ec02fSPetter Reinholdtsen 	lprintf(LOG_DEBUG, "Querying SDR for sensor list");
2693c18ec02fSPetter Reinholdtsen 
2694c18ec02fSPetter Reinholdtsen 	if (sdr_list_itr == NULL) {
2695c18ec02fSPetter Reinholdtsen 		sdr_list_itr = ipmi_sdr_start(intf, 0);
2696c18ec02fSPetter Reinholdtsen 		if (sdr_list_itr == NULL) {
2697c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Unable to open SDR for reading");
2698c18ec02fSPetter Reinholdtsen 			return -1;
2699c18ec02fSPetter Reinholdtsen 		}
2700c18ec02fSPetter Reinholdtsen 	}
2701c18ec02fSPetter Reinholdtsen 
2702c18ec02fSPetter Reinholdtsen 	for (e = sdr_list_head; e != NULL; e = e->next) {
2703c18ec02fSPetter Reinholdtsen 		if (type != e->type && type != 0xff && type != 0xfe)
2704c18ec02fSPetter Reinholdtsen 			continue;
2705c18ec02fSPetter Reinholdtsen 		if (type == 0xfe &&
2706c18ec02fSPetter Reinholdtsen 		    e->type != SDR_RECORD_TYPE_FULL_SENSOR &&
2707c18ec02fSPetter Reinholdtsen 		    e->type != SDR_RECORD_TYPE_COMPACT_SENSOR)
2708c18ec02fSPetter Reinholdtsen 			continue;
2709c18ec02fSPetter Reinholdtsen 		if (ipmi_sdr_print_listentry(intf, e) < 0)
2710c18ec02fSPetter Reinholdtsen 			rc = -1;
2711c18ec02fSPetter Reinholdtsen 	}
2712c18ec02fSPetter Reinholdtsen 
2713c18ec02fSPetter Reinholdtsen 	while ((header = ipmi_sdr_get_next_header(intf, sdr_list_itr)) != NULL) {
2714c18ec02fSPetter Reinholdtsen 		uint8_t *rec;
2715c18ec02fSPetter Reinholdtsen 		struct sdr_record_list *sdrr;
2716c18ec02fSPetter Reinholdtsen 
2717c18ec02fSPetter Reinholdtsen 		rec = ipmi_sdr_get_record(intf, header, sdr_list_itr);
2718c18ec02fSPetter Reinholdtsen 		if (rec == NULL) {
2719c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "ipmitool: ipmi_sdr_get_record() failed");
2720c18ec02fSPetter Reinholdtsen 			rc = -1;
2721c18ec02fSPetter Reinholdtsen 			continue;
2722c18ec02fSPetter Reinholdtsen 		}
2723c18ec02fSPetter Reinholdtsen 
2724c18ec02fSPetter Reinholdtsen 		sdrr = malloc(sizeof (struct sdr_record_list));
2725c18ec02fSPetter Reinholdtsen 		if (sdrr == NULL) {
2726c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "ipmitool: malloc failure");
2727c18ec02fSPetter Reinholdtsen 			if (rec != NULL) {
2728c18ec02fSPetter Reinholdtsen 				free(rec);
2729c18ec02fSPetter Reinholdtsen 				rec = NULL;
2730c18ec02fSPetter Reinholdtsen 			}
2731c18ec02fSPetter Reinholdtsen 			break;
2732c18ec02fSPetter Reinholdtsen 		}
2733c18ec02fSPetter Reinholdtsen 		memset(sdrr, 0, sizeof (struct sdr_record_list));
2734c18ec02fSPetter Reinholdtsen 		sdrr->id = header->id;
2735c18ec02fSPetter Reinholdtsen 		sdrr->type = header->type;
2736c18ec02fSPetter Reinholdtsen 
2737c18ec02fSPetter Reinholdtsen 		switch (header->type) {
2738c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FULL_SENSOR:
2739c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_COMPACT_SENSOR:
2740c18ec02fSPetter Reinholdtsen 			sdrr->record.common =
2741c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_common_sensor *) rec;
2742c18ec02fSPetter Reinholdtsen 			break;
2743c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
2744c18ec02fSPetter Reinholdtsen 			sdrr->record.eventonly =
2745c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_eventonly_sensor *) rec;
2746c18ec02fSPetter Reinholdtsen 			break;
2747c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR:
2748c18ec02fSPetter Reinholdtsen 			sdrr->record.genloc =
2749c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_generic_locator *) rec;
2750c18ec02fSPetter Reinholdtsen 			break;
2751c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
2752c18ec02fSPetter Reinholdtsen 			sdrr->record.fruloc =
2753c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_fru_locator *) rec;
2754c18ec02fSPetter Reinholdtsen 			break;
2755c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
2756c18ec02fSPetter Reinholdtsen 			sdrr->record.mcloc =
2757c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_mc_locator *) rec;
2758c18ec02fSPetter Reinholdtsen 			break;
2759c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_ENTITY_ASSOC:
2760c18ec02fSPetter Reinholdtsen 			sdrr->record.entassoc =
2761c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_entity_assoc *) rec;
2762c18ec02fSPetter Reinholdtsen 			break;
2763c18ec02fSPetter Reinholdtsen 		default:
2764c18ec02fSPetter Reinholdtsen 			free(rec);
2765c18ec02fSPetter Reinholdtsen 			rec = NULL;
2766c18ec02fSPetter Reinholdtsen 			if (sdrr != NULL) {
2767c18ec02fSPetter Reinholdtsen 				free(sdrr);
2768c18ec02fSPetter Reinholdtsen 				sdrr = NULL;
2769c18ec02fSPetter Reinholdtsen 			}
2770c18ec02fSPetter Reinholdtsen 			continue;
2771c18ec02fSPetter Reinholdtsen 		}
2772c18ec02fSPetter Reinholdtsen 
2773c18ec02fSPetter Reinholdtsen                 lprintf(LOG_DEBUG, "SDR record ID   : 0x%04x", sdrr->id);
2774c18ec02fSPetter Reinholdtsen 
2775c18ec02fSPetter Reinholdtsen 		if (type == header->type || type == 0xff ||
2776c18ec02fSPetter Reinholdtsen 		    (type == 0xfe &&
2777c18ec02fSPetter Reinholdtsen 		     (header->type == SDR_RECORD_TYPE_FULL_SENSOR ||
2778c18ec02fSPetter Reinholdtsen 		      header->type == SDR_RECORD_TYPE_COMPACT_SENSOR))) {
2779c18ec02fSPetter Reinholdtsen 			if (ipmi_sdr_print_rawentry(intf, header->type,
2780c18ec02fSPetter Reinholdtsen 						    rec, header->length) < 0)
2781c18ec02fSPetter Reinholdtsen 				rc = -1;
2782c18ec02fSPetter Reinholdtsen 		}
2783c18ec02fSPetter Reinholdtsen 
2784c18ec02fSPetter Reinholdtsen 		/* add to global record liset */
2785c18ec02fSPetter Reinholdtsen 		if (sdr_list_head == NULL)
2786c18ec02fSPetter Reinholdtsen 			sdr_list_head = sdrr;
2787c18ec02fSPetter Reinholdtsen 		else
2788c18ec02fSPetter Reinholdtsen 			sdr_list_tail->next = sdrr;
2789c18ec02fSPetter Reinholdtsen 
2790c18ec02fSPetter Reinholdtsen 		sdr_list_tail = sdrr;
2791c18ec02fSPetter Reinholdtsen 	}
2792c18ec02fSPetter Reinholdtsen 
2793c18ec02fSPetter Reinholdtsen 	return rc;
2794c18ec02fSPetter Reinholdtsen }
2795c18ec02fSPetter Reinholdtsen 
2796c18ec02fSPetter Reinholdtsen /* ipmi_sdr_get_reservation  -  Obtain SDR reservation ID
2797c18ec02fSPetter Reinholdtsen  *
2798c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
2799c18ec02fSPetter Reinholdtsen  * @reserve_id:	pointer to short int for storing the id
2800c18ec02fSPetter Reinholdtsen  *
2801c18ec02fSPetter Reinholdtsen  * returns 0 on success
2802c18ec02fSPetter Reinholdtsen  * returns -1 on error
2803c18ec02fSPetter Reinholdtsen  */
2804c18ec02fSPetter Reinholdtsen int
ipmi_sdr_get_reservation(struct ipmi_intf * intf,int use_builtin,uint16_t * reserve_id)2805c18ec02fSPetter Reinholdtsen ipmi_sdr_get_reservation(struct ipmi_intf *intf, int use_builtin,
2806c18ec02fSPetter Reinholdtsen                          uint16_t * reserve_id)
2807c18ec02fSPetter Reinholdtsen {
2808c18ec02fSPetter Reinholdtsen 	struct ipmi_rs *rsp;
2809c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
2810c18ec02fSPetter Reinholdtsen 
2811c18ec02fSPetter Reinholdtsen 	/* obtain reservation ID */
2812c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof (req));
2813c18ec02fSPetter Reinholdtsen 
2814c18ec02fSPetter Reinholdtsen 	if (use_builtin == 0) {
2815c18ec02fSPetter Reinholdtsen 		req.msg.netfn = IPMI_NETFN_STORAGE;
2816c18ec02fSPetter Reinholdtsen 	} else {
2817c18ec02fSPetter Reinholdtsen 		req.msg.netfn = IPMI_NETFN_SE;
2818c18ec02fSPetter Reinholdtsen 	}
2819c18ec02fSPetter Reinholdtsen 
2820c18ec02fSPetter Reinholdtsen 	req.msg.cmd = GET_SDR_RESERVE_REPO;
2821c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
2822c18ec02fSPetter Reinholdtsen 
2823c18ec02fSPetter Reinholdtsen 	/* be slient for errors, they are handled by calling function */
2824c18ec02fSPetter Reinholdtsen 	if (rsp == NULL)
2825c18ec02fSPetter Reinholdtsen 		return -1;
2826c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0)
2827c18ec02fSPetter Reinholdtsen 		return -1;
2828c18ec02fSPetter Reinholdtsen 
2829c18ec02fSPetter Reinholdtsen 	*reserve_id = ((struct sdr_reserve_repo_rs *) &(rsp->data))->reserve_id;
2830c18ec02fSPetter Reinholdtsen 	lprintf(LOG_DEBUG, "SDR reservation ID %04x", *reserve_id);
2831c18ec02fSPetter Reinholdtsen 
2832c18ec02fSPetter Reinholdtsen 	return 0;
2833c18ec02fSPetter Reinholdtsen }
2834c18ec02fSPetter Reinholdtsen 
2835c18ec02fSPetter Reinholdtsen /* ipmi_sdr_start  -  setup sdr iterator
2836c18ec02fSPetter Reinholdtsen  *
2837c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
2838c18ec02fSPetter Reinholdtsen  *
2839c18ec02fSPetter Reinholdtsen  * returns sdr iterator structure pointer
2840c18ec02fSPetter Reinholdtsen  * returns NULL on error
2841c18ec02fSPetter Reinholdtsen  */
2842c18ec02fSPetter Reinholdtsen struct ipmi_sdr_iterator *
ipmi_sdr_start(struct ipmi_intf * intf,int use_builtin)2843c18ec02fSPetter Reinholdtsen ipmi_sdr_start(struct ipmi_intf *intf, int use_builtin)
2844c18ec02fSPetter Reinholdtsen {
2845c18ec02fSPetter Reinholdtsen 	struct ipmi_sdr_iterator *itr;
2846c18ec02fSPetter Reinholdtsen 	struct ipmi_rs *rsp;
2847c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
2848c18ec02fSPetter Reinholdtsen 
2849c18ec02fSPetter Reinholdtsen 	struct ipm_devid_rsp *devid;
2850c18ec02fSPetter Reinholdtsen 
2851c18ec02fSPetter Reinholdtsen 	itr = malloc(sizeof (struct ipmi_sdr_iterator));
2852c18ec02fSPetter Reinholdtsen 	if (itr == NULL) {
2853c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "ipmitool: malloc failure");
2854c18ec02fSPetter Reinholdtsen 		return NULL;
2855c18ec02fSPetter Reinholdtsen 	}
2856c18ec02fSPetter Reinholdtsen 
2857c18ec02fSPetter Reinholdtsen 	/* check SDRR capability */
2858c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof (req));
2859c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
2860c18ec02fSPetter Reinholdtsen 	req.msg.cmd = BMC_GET_DEVICE_ID;
2861c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 0;
2862c18ec02fSPetter Reinholdtsen 
2863c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
2864c18ec02fSPetter Reinholdtsen 
2865c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
2866c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Device ID command failed");
2867c18ec02fSPetter Reinholdtsen 		free(itr);
2868c18ec02fSPetter Reinholdtsen 		itr = NULL;
2869c18ec02fSPetter Reinholdtsen 		return NULL;
2870c18ec02fSPetter Reinholdtsen 	}
2871c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
2872c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Device ID command failed: %#x %s",
2873c18ec02fSPetter Reinholdtsen 			rsp->ccode, val2str(rsp->ccode, completion_code_vals));
2874c18ec02fSPetter Reinholdtsen 		free(itr);
2875c18ec02fSPetter Reinholdtsen 		itr = NULL;
2876c18ec02fSPetter Reinholdtsen 		return NULL;
2877c18ec02fSPetter Reinholdtsen 	}
2878c18ec02fSPetter Reinholdtsen 	devid = (struct ipm_devid_rsp *) rsp->data;
2879c18ec02fSPetter Reinholdtsen 
2880c18ec02fSPetter Reinholdtsen    sdriana =  (long)IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id);
2881c18ec02fSPetter Reinholdtsen 
2882c18ec02fSPetter Reinholdtsen 	if (!use_builtin && (devid->device_revision & IPM_DEV_DEVICE_ID_SDR_MASK)) {
2883c18ec02fSPetter Reinholdtsen 		if ((devid->adtl_device_support & 0x02) == 0) {
2884c18ec02fSPetter Reinholdtsen 			if ((devid->adtl_device_support & 0x01)) {
2885c18ec02fSPetter Reinholdtsen 				lprintf(LOG_DEBUG, "Using Device SDRs\n");
2886c18ec02fSPetter Reinholdtsen 				use_built_in = 1;
2887c18ec02fSPetter Reinholdtsen 			} else {
2888c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, "Error obtaining SDR info");
2889c18ec02fSPetter Reinholdtsen 				free(itr);
2890c18ec02fSPetter Reinholdtsen 				itr = NULL;
2891c18ec02fSPetter Reinholdtsen 				return NULL;
2892c18ec02fSPetter Reinholdtsen 			}
2893c18ec02fSPetter Reinholdtsen 		} else {
2894c18ec02fSPetter Reinholdtsen 			lprintf(LOG_DEBUG, "Using SDR from Repository \n");
2895c18ec02fSPetter Reinholdtsen 		}
2896c18ec02fSPetter Reinholdtsen 	}
2897c18ec02fSPetter Reinholdtsen 	itr->use_built_in = use_builtin ? 1 : use_built_in;
2898c18ec02fSPetter Reinholdtsen    /***********************/
2899c18ec02fSPetter Reinholdtsen 	if (itr->use_built_in == 0) {
2900c18ec02fSPetter Reinholdtsen 		struct sdr_repo_info_rs sdr_info;
2901c18ec02fSPetter Reinholdtsen 		/* get sdr repository info */
2902c18ec02fSPetter Reinholdtsen 		memset(&req, 0, sizeof (req));
2903c18ec02fSPetter Reinholdtsen 		req.msg.netfn = IPMI_NETFN_STORAGE;
2904c18ec02fSPetter Reinholdtsen 		req.msg.cmd = GET_SDR_REPO_INFO;
2905c18ec02fSPetter Reinholdtsen 
2906c18ec02fSPetter Reinholdtsen 		rsp = intf->sendrecv(intf, &req);
2907c18ec02fSPetter Reinholdtsen 		if (rsp == NULL) {
2908c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Error obtaining SDR info");
2909c18ec02fSPetter Reinholdtsen 			free(itr);
2910c18ec02fSPetter Reinholdtsen 			itr = NULL;
2911c18ec02fSPetter Reinholdtsen 			return NULL;
2912c18ec02fSPetter Reinholdtsen 		}
2913c18ec02fSPetter Reinholdtsen 		if (rsp->ccode > 0) {
2914c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Error obtaining SDR info: %s",
2915c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
2916c18ec02fSPetter Reinholdtsen 			free(itr);
2917c18ec02fSPetter Reinholdtsen 			itr = NULL;
2918c18ec02fSPetter Reinholdtsen 			return NULL;
2919c18ec02fSPetter Reinholdtsen 		}
2920c18ec02fSPetter Reinholdtsen 
2921c18ec02fSPetter Reinholdtsen 		memcpy(&sdr_info, rsp->data, sizeof (sdr_info));
2922c18ec02fSPetter Reinholdtsen 		/* IPMIv1.0 == 0x01
2923c18ec02fSPetter Reinholdtsen 		   * IPMIv1.5 == 0x51
2924c18ec02fSPetter Reinholdtsen 		   * IPMIv2.0 == 0x02
2925c18ec02fSPetter Reinholdtsen 		 */
2926c18ec02fSPetter Reinholdtsen 		if ((sdr_info.version != 0x51) &&
2927c18ec02fSPetter Reinholdtsen 		    (sdr_info.version != 0x01) &&
2928c18ec02fSPetter Reinholdtsen 		    (sdr_info.version != 0x02)) {
2929c18ec02fSPetter Reinholdtsen 			lprintf(LOG_WARN, "WARNING: Unknown SDR repository "
2930c18ec02fSPetter Reinholdtsen 				"version 0x%02x", sdr_info.version);
2931c18ec02fSPetter Reinholdtsen 		}
2932c18ec02fSPetter Reinholdtsen 
2933c18ec02fSPetter Reinholdtsen 		itr->total = sdr_info.count;
2934c18ec02fSPetter Reinholdtsen 		itr->next = 0;
2935c18ec02fSPetter Reinholdtsen 
2936c18ec02fSPetter Reinholdtsen 		lprintf(LOG_DEBUG, "SDR free space: %d", sdr_info.free);
2937c18ec02fSPetter Reinholdtsen 		lprintf(LOG_DEBUG, "SDR records   : %d", sdr_info.count);
2938c18ec02fSPetter Reinholdtsen 
2939c18ec02fSPetter Reinholdtsen 		/* Build SDRR if there is no record in repository */
2940c18ec02fSPetter Reinholdtsen 		if( sdr_info.count == 0 ) {
2941c18ec02fSPetter Reinholdtsen 		   lprintf(LOG_DEBUG, "Rebuilding SDRR...");
2942c18ec02fSPetter Reinholdtsen 
2943c18ec02fSPetter Reinholdtsen 		   if( ipmi_sdr_add_from_sensors( intf, 0 ) != 0 ) {
2944c18ec02fSPetter Reinholdtsen 		      lprintf(LOG_ERR, "Could not build SDRR!");
2945c18ec02fSPetter Reinholdtsen 		      free(itr);
2946c18ec02fSPetter Reinholdtsen 					itr = NULL;
2947c18ec02fSPetter Reinholdtsen 		      return NULL;
2948c18ec02fSPetter Reinholdtsen 		   }
2949c18ec02fSPetter Reinholdtsen 		}
2950c18ec02fSPetter Reinholdtsen 	} else {
2951c18ec02fSPetter Reinholdtsen 		struct sdr_device_info_rs sdr_info;
2952c18ec02fSPetter Reinholdtsen 		/* get device sdr info */
2953c18ec02fSPetter Reinholdtsen 		memset(&req, 0, sizeof (req));
2954c18ec02fSPetter Reinholdtsen 		req.msg.netfn = IPMI_NETFN_SE;
2955c18ec02fSPetter Reinholdtsen 		req.msg.cmd = GET_DEVICE_SDR_INFO;
2956c18ec02fSPetter Reinholdtsen 
2957c18ec02fSPetter Reinholdtsen 		rsp = intf->sendrecv(intf, &req);
2958c18ec02fSPetter Reinholdtsen 		if (!rsp || !rsp->data_len || rsp->ccode) {
2959c18ec02fSPetter Reinholdtsen 			printf("Err in cmd get sensor sdr info\n");
2960c18ec02fSPetter Reinholdtsen 			free(itr);
2961c18ec02fSPetter Reinholdtsen 			itr = NULL;
2962c18ec02fSPetter Reinholdtsen 			return NULL;
2963c18ec02fSPetter Reinholdtsen 		}
2964c18ec02fSPetter Reinholdtsen 		memcpy(&sdr_info, rsp->data, sizeof (sdr_info));
2965c18ec02fSPetter Reinholdtsen 
2966c18ec02fSPetter Reinholdtsen 		itr->total = sdr_info.count;
2967c18ec02fSPetter Reinholdtsen 		itr->next = 0;
2968c18ec02fSPetter Reinholdtsen 		lprintf(LOG_DEBUG, "SDR records   : %d", sdr_info.count);
2969c18ec02fSPetter Reinholdtsen 	}
2970c18ec02fSPetter Reinholdtsen 
2971c18ec02fSPetter Reinholdtsen 	if (ipmi_sdr_get_reservation(intf, itr->use_built_in,
2972c18ec02fSPetter Reinholdtsen                                 &(itr->reservation)) < 0) {
2973c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Unable to obtain SDR reservation");
2974c18ec02fSPetter Reinholdtsen 		free(itr);
2975c18ec02fSPetter Reinholdtsen 		itr = NULL;
2976c18ec02fSPetter Reinholdtsen 		return NULL;
2977c18ec02fSPetter Reinholdtsen 	}
2978c18ec02fSPetter Reinholdtsen 
2979c18ec02fSPetter Reinholdtsen 	return itr;
2980c18ec02fSPetter Reinholdtsen }
2981c18ec02fSPetter Reinholdtsen 
2982c18ec02fSPetter Reinholdtsen /* ipmi_sdr_get_record  -  return RAW SDR record
2983c18ec02fSPetter Reinholdtsen  *
2984c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
2985c18ec02fSPetter Reinholdtsen  * @header:	SDR header
2986c18ec02fSPetter Reinholdtsen  * @itr:	SDR iterator
2987c18ec02fSPetter Reinholdtsen  *
2988c18ec02fSPetter Reinholdtsen  * returns raw SDR data
2989c18ec02fSPetter Reinholdtsen  * returns NULL on error
2990c18ec02fSPetter Reinholdtsen  */
2991c18ec02fSPetter Reinholdtsen uint8_t *
ipmi_sdr_get_record(struct ipmi_intf * intf,struct sdr_get_rs * header,struct ipmi_sdr_iterator * itr)2992c18ec02fSPetter Reinholdtsen ipmi_sdr_get_record(struct ipmi_intf * intf, struct sdr_get_rs * header,
2993c18ec02fSPetter Reinholdtsen 		    struct ipmi_sdr_iterator * itr)
2994c18ec02fSPetter Reinholdtsen {
2995c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
2996c18ec02fSPetter Reinholdtsen 	struct ipmi_rs *rsp;
2997c18ec02fSPetter Reinholdtsen 	struct sdr_get_rq sdr_rq;
2998c18ec02fSPetter Reinholdtsen 	uint8_t *data;
2999c18ec02fSPetter Reinholdtsen 	int i = 0, len = header->length;
3000c18ec02fSPetter Reinholdtsen 
3001c18ec02fSPetter Reinholdtsen 	if (len < 1)
3002c18ec02fSPetter Reinholdtsen 		return NULL;
3003c18ec02fSPetter Reinholdtsen 
3004c18ec02fSPetter Reinholdtsen 	data = malloc(len + 1);
3005c18ec02fSPetter Reinholdtsen 	if (data == NULL) {
3006c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "ipmitool: malloc failure");
3007c18ec02fSPetter Reinholdtsen 		return NULL;
3008c18ec02fSPetter Reinholdtsen 	}
3009c18ec02fSPetter Reinholdtsen 	memset(data, 0, len + 1);
3010c18ec02fSPetter Reinholdtsen 
3011c18ec02fSPetter Reinholdtsen 	memset(&sdr_rq, 0, sizeof (sdr_rq));
3012c18ec02fSPetter Reinholdtsen 	sdr_rq.reserve_id = itr->reservation;
3013c18ec02fSPetter Reinholdtsen 	sdr_rq.id = header->id;
3014c18ec02fSPetter Reinholdtsen 	sdr_rq.offset = 0;
3015c18ec02fSPetter Reinholdtsen 
3016c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof (req));
3017c18ec02fSPetter Reinholdtsen 	if (itr->use_built_in == 0) {
3018c18ec02fSPetter Reinholdtsen 		req.msg.netfn = IPMI_NETFN_STORAGE;
3019c18ec02fSPetter Reinholdtsen 		req.msg.cmd = GET_SDR;
3020c18ec02fSPetter Reinholdtsen 	} else {
3021c18ec02fSPetter Reinholdtsen 		req.msg.netfn = IPMI_NETFN_SE;
3022c18ec02fSPetter Reinholdtsen 		req.msg.cmd = GET_DEVICE_SDR;
3023c18ec02fSPetter Reinholdtsen 	}
3024c18ec02fSPetter Reinholdtsen 	req.msg.data = (uint8_t *) & sdr_rq;
3025c18ec02fSPetter Reinholdtsen 	req.msg.data_len = sizeof (sdr_rq);
3026c18ec02fSPetter Reinholdtsen 
302723e9340bSZdenek Styblik 	/* check if max length is null */
302823e9340bSZdenek Styblik 	if ( sdr_max_read_len == 0 ) {
302923e9340bSZdenek Styblik 		/* get maximum response size */
303023e9340bSZdenek Styblik 		sdr_max_read_len = ipmi_intf_get_max_response_data_size(intf) - 2;
303123e9340bSZdenek Styblik 
303223e9340bSZdenek Styblik 		/* cap the number of bytes to read */
303323e9340bSZdenek Styblik 		if (sdr_max_read_len > 0xFE) {
303423e9340bSZdenek Styblik 			sdr_max_read_len = 0xFE;
303523e9340bSZdenek Styblik 		}
303623e9340bSZdenek Styblik 	}
303723e9340bSZdenek Styblik 
3038c18ec02fSPetter Reinholdtsen 	/* read SDR record with partial reads
3039c18ec02fSPetter Reinholdtsen 	 * because a full read usually exceeds the maximum
3040c18ec02fSPetter Reinholdtsen 	 * transport buffer size.  (completion code 0xca)
3041c18ec02fSPetter Reinholdtsen 	 */
3042c18ec02fSPetter Reinholdtsen 	while (i < len) {
3043c18ec02fSPetter Reinholdtsen 		sdr_rq.length = (len - i < sdr_max_read_len) ?
3044c18ec02fSPetter Reinholdtsen 		    len - i : sdr_max_read_len;
3045c18ec02fSPetter Reinholdtsen 		sdr_rq.offset = i + 5;	/* 5 header bytes */
3046c18ec02fSPetter Reinholdtsen 
3047c18ec02fSPetter Reinholdtsen 		lprintf(LOG_DEBUG, "Getting %d bytes from SDR at offset %d",
3048c18ec02fSPetter Reinholdtsen 			sdr_rq.length, sdr_rq.offset);
3049c18ec02fSPetter Reinholdtsen 
3050c18ec02fSPetter Reinholdtsen 		rsp = intf->sendrecv(intf, &req);
3051c18ec02fSPetter Reinholdtsen 		if (rsp == NULL) {
3052c18ec02fSPetter Reinholdtsen 		    sdr_max_read_len = sdr_rq.length - 1;
3053c18ec02fSPetter Reinholdtsen 		    if (sdr_max_read_len > 0) {
3054c18ec02fSPetter Reinholdtsen 			/* no response may happen if requests are bridged
3055c18ec02fSPetter Reinholdtsen 			   and too many bytes are requested */
3056c18ec02fSPetter Reinholdtsen 			continue;
3057c18ec02fSPetter Reinholdtsen 		    } else {
3058c18ec02fSPetter Reinholdtsen 			free(data);
3059c18ec02fSPetter Reinholdtsen 			data = NULL;
3060c18ec02fSPetter Reinholdtsen 			return NULL;
3061c18ec02fSPetter Reinholdtsen 		    }
3062c18ec02fSPetter Reinholdtsen 		}
3063c18ec02fSPetter Reinholdtsen 
3064c18ec02fSPetter Reinholdtsen 		switch (rsp->ccode) {
3065c18ec02fSPetter Reinholdtsen 		case 0xca:
3066c18ec02fSPetter Reinholdtsen 			/* read too many bytes at once */
3067c18ec02fSPetter Reinholdtsen 			sdr_max_read_len = sdr_rq.length - 1;
3068c18ec02fSPetter Reinholdtsen 			continue;
3069c18ec02fSPetter Reinholdtsen 		case 0xc5:
3070c18ec02fSPetter Reinholdtsen 			/* lost reservation */
3071c18ec02fSPetter Reinholdtsen 			lprintf(LOG_DEBUG, "SDR reservation cancelled. "
3072c18ec02fSPetter Reinholdtsen 				"Sleeping a bit and retrying...");
3073c18ec02fSPetter Reinholdtsen 
3074c18ec02fSPetter Reinholdtsen 			sleep(rand() & 3);
3075c18ec02fSPetter Reinholdtsen 
3076c18ec02fSPetter Reinholdtsen 			if (ipmi_sdr_get_reservation(intf, itr->use_built_in,
3077c18ec02fSPetter Reinholdtsen                                       &(itr->reservation)) < 0) {
3078c18ec02fSPetter Reinholdtsen 				free(data);
3079c18ec02fSPetter Reinholdtsen 				data = NULL;
3080c18ec02fSPetter Reinholdtsen 				return NULL;
3081c18ec02fSPetter Reinholdtsen 			}
3082c18ec02fSPetter Reinholdtsen 			sdr_rq.reserve_id = itr->reservation;
3083c18ec02fSPetter Reinholdtsen 			continue;
3084c18ec02fSPetter Reinholdtsen 		}
3085c18ec02fSPetter Reinholdtsen 
3086c18ec02fSPetter Reinholdtsen 		/* special completion codes handled above */
3087c18ec02fSPetter Reinholdtsen 		if (rsp->ccode > 0 || rsp->data_len == 0) {
3088c18ec02fSPetter Reinholdtsen 			free(data);
3089c18ec02fSPetter Reinholdtsen 			data = NULL;
3090c18ec02fSPetter Reinholdtsen 			return NULL;
3091c18ec02fSPetter Reinholdtsen 		}
3092c18ec02fSPetter Reinholdtsen 
3093c18ec02fSPetter Reinholdtsen 		memcpy(data + i, rsp->data + 2, sdr_rq.length);
3094c18ec02fSPetter Reinholdtsen 		i += sdr_max_read_len;
3095c18ec02fSPetter Reinholdtsen 	}
3096c18ec02fSPetter Reinholdtsen 
3097c18ec02fSPetter Reinholdtsen 	return data;
3098c18ec02fSPetter Reinholdtsen }
3099c18ec02fSPetter Reinholdtsen 
3100c18ec02fSPetter Reinholdtsen /* ipmi_sdr_end  -  cleanup SDR iterator
3101c18ec02fSPetter Reinholdtsen  *
3102c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
3103c18ec02fSPetter Reinholdtsen  * @itr:	SDR iterator
3104c18ec02fSPetter Reinholdtsen  *
3105c18ec02fSPetter Reinholdtsen  * no meaningful return code
3106c18ec02fSPetter Reinholdtsen  */
3107c18ec02fSPetter Reinholdtsen void
ipmi_sdr_end(struct ipmi_intf * intf,struct ipmi_sdr_iterator * itr)3108c18ec02fSPetter Reinholdtsen ipmi_sdr_end(struct ipmi_intf *intf, struct ipmi_sdr_iterator *itr)
3109c18ec02fSPetter Reinholdtsen {
3110c18ec02fSPetter Reinholdtsen 	if (itr) {
3111c18ec02fSPetter Reinholdtsen 		free(itr);
3112c18ec02fSPetter Reinholdtsen 		itr = NULL;
3113c18ec02fSPetter Reinholdtsen 	}
3114c18ec02fSPetter Reinholdtsen }
3115c18ec02fSPetter Reinholdtsen 
3116c18ec02fSPetter Reinholdtsen /* __sdr_list_add  -  helper function to add SDR record to list
3117c18ec02fSPetter Reinholdtsen  *
3118c18ec02fSPetter Reinholdtsen  * @head:	list head
3119c18ec02fSPetter Reinholdtsen  * @entry:	new entry to add to end of list
3120c18ec02fSPetter Reinholdtsen  *
3121c18ec02fSPetter Reinholdtsen  * returns 0 on success
3122c18ec02fSPetter Reinholdtsen  * returns -1 on error
3123c18ec02fSPetter Reinholdtsen  */
3124c18ec02fSPetter Reinholdtsen static int
__sdr_list_add(struct sdr_record_list * head,struct sdr_record_list * entry)3125c18ec02fSPetter Reinholdtsen __sdr_list_add(struct sdr_record_list *head, struct sdr_record_list *entry)
3126c18ec02fSPetter Reinholdtsen {
3127c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *e;
3128c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *new;
3129c18ec02fSPetter Reinholdtsen 
3130c18ec02fSPetter Reinholdtsen 	if (head == NULL)
3131c18ec02fSPetter Reinholdtsen 		return -1;
3132c18ec02fSPetter Reinholdtsen 
3133c18ec02fSPetter Reinholdtsen 	new = malloc(sizeof (struct sdr_record_list));
3134c18ec02fSPetter Reinholdtsen 	if (new == NULL) {
3135c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "ipmitool: malloc failure");
3136c18ec02fSPetter Reinholdtsen 		return -1;
3137c18ec02fSPetter Reinholdtsen 	}
3138c18ec02fSPetter Reinholdtsen 	memcpy(new, entry, sizeof (struct sdr_record_list));
3139c18ec02fSPetter Reinholdtsen 
3140c18ec02fSPetter Reinholdtsen 	e = head;
3141c18ec02fSPetter Reinholdtsen 	while (e->next)
3142c18ec02fSPetter Reinholdtsen 		e = e->next;
3143c18ec02fSPetter Reinholdtsen 	e->next = new;
3144c18ec02fSPetter Reinholdtsen 	new->next = NULL;
3145c18ec02fSPetter Reinholdtsen 
3146c18ec02fSPetter Reinholdtsen 	return 0;
3147c18ec02fSPetter Reinholdtsen }
3148c18ec02fSPetter Reinholdtsen 
3149c18ec02fSPetter Reinholdtsen /* __sdr_list_empty  -  low-level handler to clean up record list
3150c18ec02fSPetter Reinholdtsen  *
3151c18ec02fSPetter Reinholdtsen  * @head:	list head to clean
3152c18ec02fSPetter Reinholdtsen  *
3153c18ec02fSPetter Reinholdtsen  * no meaningful return code
3154c18ec02fSPetter Reinholdtsen  */
3155c18ec02fSPetter Reinholdtsen static void
__sdr_list_empty(struct sdr_record_list * head)3156c18ec02fSPetter Reinholdtsen __sdr_list_empty(struct sdr_record_list *head)
3157c18ec02fSPetter Reinholdtsen {
3158c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *e, *f;
3159c18ec02fSPetter Reinholdtsen 	for (e = head; e != NULL; e = f) {
3160c18ec02fSPetter Reinholdtsen 		f = e->next;
3161c18ec02fSPetter Reinholdtsen 		free(e);
3162c18ec02fSPetter Reinholdtsen 		e = NULL;
3163c18ec02fSPetter Reinholdtsen 	}
3164c18ec02fSPetter Reinholdtsen 	head = NULL;
3165c18ec02fSPetter Reinholdtsen }
3166c18ec02fSPetter Reinholdtsen 
3167c18ec02fSPetter Reinholdtsen /* ipmi_sdr_list_empty  -  clean global SDR list
3168c18ec02fSPetter Reinholdtsen  *
3169c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
3170c18ec02fSPetter Reinholdtsen  *
3171c18ec02fSPetter Reinholdtsen  * no meaningful return code
3172c18ec02fSPetter Reinholdtsen  */
3173c18ec02fSPetter Reinholdtsen void
ipmi_sdr_list_empty(struct ipmi_intf * intf)3174c18ec02fSPetter Reinholdtsen ipmi_sdr_list_empty(struct ipmi_intf *intf)
3175c18ec02fSPetter Reinholdtsen {
3176c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *list, *next;
3177c18ec02fSPetter Reinholdtsen 
3178c18ec02fSPetter Reinholdtsen 	ipmi_sdr_end(intf, sdr_list_itr);
3179c18ec02fSPetter Reinholdtsen 
3180c18ec02fSPetter Reinholdtsen 	for (list = sdr_list_head; list != NULL; list = next) {
3181c18ec02fSPetter Reinholdtsen 		switch (list->type) {
3182c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FULL_SENSOR:
3183c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_COMPACT_SENSOR:
3184c18ec02fSPetter Reinholdtsen 			if (list->record.common) {
3185c18ec02fSPetter Reinholdtsen 				free(list->record.common);
3186c18ec02fSPetter Reinholdtsen 				list->record.common = NULL;
3187c18ec02fSPetter Reinholdtsen 			}
3188c18ec02fSPetter Reinholdtsen 			break;
3189c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
3190c18ec02fSPetter Reinholdtsen 			if (list->record.eventonly) {
3191c18ec02fSPetter Reinholdtsen 				free(list->record.eventonly);
3192c18ec02fSPetter Reinholdtsen 				list->record.eventonly = NULL;
3193c18ec02fSPetter Reinholdtsen 			}
3194c18ec02fSPetter Reinholdtsen 			break;
3195c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR:
3196c18ec02fSPetter Reinholdtsen 			if (list->record.genloc) {
3197c18ec02fSPetter Reinholdtsen 				free(list->record.genloc);
3198c18ec02fSPetter Reinholdtsen 				list->record.genloc = NULL;
3199c18ec02fSPetter Reinholdtsen 			}
3200c18ec02fSPetter Reinholdtsen 			break;
3201c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
3202c18ec02fSPetter Reinholdtsen 			if (list->record.fruloc) {
3203c18ec02fSPetter Reinholdtsen 				free(list->record.fruloc);
3204c18ec02fSPetter Reinholdtsen 				list->record.fruloc = NULL;
3205c18ec02fSPetter Reinholdtsen 			}
3206c18ec02fSPetter Reinholdtsen 			break;
3207c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
3208c18ec02fSPetter Reinholdtsen 			if (list->record.mcloc) {
3209c18ec02fSPetter Reinholdtsen 				free(list->record.mcloc);
3210c18ec02fSPetter Reinholdtsen 				list->record.mcloc = NULL;
3211c18ec02fSPetter Reinholdtsen 			}
3212c18ec02fSPetter Reinholdtsen 			break;
3213c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_ENTITY_ASSOC:
3214c18ec02fSPetter Reinholdtsen 			if (list->record.entassoc) {
3215c18ec02fSPetter Reinholdtsen 				free(list->record.entassoc);
3216c18ec02fSPetter Reinholdtsen 				list->record.entassoc = NULL;
3217c18ec02fSPetter Reinholdtsen 			}
3218c18ec02fSPetter Reinholdtsen 			break;
3219c18ec02fSPetter Reinholdtsen 		}
3220c18ec02fSPetter Reinholdtsen 		next = list->next;
3221c18ec02fSPetter Reinholdtsen 		free(list);
3222c18ec02fSPetter Reinholdtsen 		list = NULL;
3223c18ec02fSPetter Reinholdtsen 	}
3224c18ec02fSPetter Reinholdtsen 
3225c18ec02fSPetter Reinholdtsen 	sdr_list_head = NULL;
3226c18ec02fSPetter Reinholdtsen 	sdr_list_tail = NULL;
3227c18ec02fSPetter Reinholdtsen 	sdr_list_itr = NULL;
3228c18ec02fSPetter Reinholdtsen }
3229c18ec02fSPetter Reinholdtsen 
3230c18ec02fSPetter Reinholdtsen /* ipmi_sdr_find_sdr_bynumtype  -  lookup SDR entry by number/type
3231c18ec02fSPetter Reinholdtsen  *
3232c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
3233c18ec02fSPetter Reinholdtsen  * @gen_id:	sensor owner ID/LUN - SEL generator ID
3234c18ec02fSPetter Reinholdtsen  * @num:	sensor number to search for
3235c18ec02fSPetter Reinholdtsen  * @type:	sensor type to search for
3236c18ec02fSPetter Reinholdtsen  *
3237c18ec02fSPetter Reinholdtsen  * returns pointer to SDR list
3238c18ec02fSPetter Reinholdtsen  * returns NULL on error
3239c18ec02fSPetter Reinholdtsen  */
3240c18ec02fSPetter Reinholdtsen struct sdr_record_list *
ipmi_sdr_find_sdr_bynumtype(struct ipmi_intf * intf,uint16_t gen_id,uint8_t num,uint8_t type)3241c18ec02fSPetter Reinholdtsen ipmi_sdr_find_sdr_bynumtype(struct ipmi_intf *intf, uint16_t gen_id, uint8_t num, uint8_t type)
3242c18ec02fSPetter Reinholdtsen {
3243c18ec02fSPetter Reinholdtsen 	struct sdr_get_rs *header;
3244c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *e;
3245c18ec02fSPetter Reinholdtsen 	int found = 0;
3246c18ec02fSPetter Reinholdtsen 
3247c18ec02fSPetter Reinholdtsen 	if (sdr_list_itr == NULL) {
3248c18ec02fSPetter Reinholdtsen 		sdr_list_itr = ipmi_sdr_start(intf, 0);
3249c18ec02fSPetter Reinholdtsen 		if (sdr_list_itr == NULL) {
3250c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Unable to open SDR for reading");
3251c18ec02fSPetter Reinholdtsen 			return NULL;
3252c18ec02fSPetter Reinholdtsen 		}
3253c18ec02fSPetter Reinholdtsen 	}
3254c18ec02fSPetter Reinholdtsen 
3255c18ec02fSPetter Reinholdtsen 	/* check what we've already read */
3256c18ec02fSPetter Reinholdtsen 	for (e = sdr_list_head; e != NULL; e = e->next) {
3257c18ec02fSPetter Reinholdtsen 		switch (e->type) {
3258c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FULL_SENSOR:
3259c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_COMPACT_SENSOR:
3260c18ec02fSPetter Reinholdtsen 			if (e->record.common->keys.sensor_num == num &&
3261c18ec02fSPetter Reinholdtsen 			    e->record.common->keys.owner_id == (gen_id & 0x00ff) &&
3262c18ec02fSPetter Reinholdtsen 			    e->record.common->sensor.type == type)
3263c18ec02fSPetter Reinholdtsen 				return e;
3264c18ec02fSPetter Reinholdtsen 			break;
3265c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
3266c18ec02fSPetter Reinholdtsen 			if (e->record.eventonly->keys.sensor_num == num &&
3267c18ec02fSPetter Reinholdtsen 			    e->record.eventonly->keys.owner_id == (gen_id & 0x00ff) &&
3268c18ec02fSPetter Reinholdtsen 			    e->record.eventonly->sensor_type == type)
3269c18ec02fSPetter Reinholdtsen 				return e;
3270c18ec02fSPetter Reinholdtsen 			break;
3271c18ec02fSPetter Reinholdtsen 		}
3272c18ec02fSPetter Reinholdtsen 	}
3273c18ec02fSPetter Reinholdtsen 
3274c18ec02fSPetter Reinholdtsen 	/* now keep looking */
3275c18ec02fSPetter Reinholdtsen 	while ((header = ipmi_sdr_get_next_header(intf, sdr_list_itr)) != NULL) {
3276c18ec02fSPetter Reinholdtsen 		uint8_t *rec;
3277c18ec02fSPetter Reinholdtsen 		struct sdr_record_list *sdrr;
3278c18ec02fSPetter Reinholdtsen 
3279c18ec02fSPetter Reinholdtsen 		sdrr = malloc(sizeof (struct sdr_record_list));
3280c18ec02fSPetter Reinholdtsen 		if (sdrr == NULL) {
3281c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "ipmitool: malloc failure");
3282c18ec02fSPetter Reinholdtsen 			break;
3283c18ec02fSPetter Reinholdtsen 		}
3284c18ec02fSPetter Reinholdtsen 		memset(sdrr, 0, sizeof (struct sdr_record_list));
3285c18ec02fSPetter Reinholdtsen 		sdrr->id = header->id;
3286c18ec02fSPetter Reinholdtsen 		sdrr->type = header->type;
3287c18ec02fSPetter Reinholdtsen 
3288c18ec02fSPetter Reinholdtsen 		rec = ipmi_sdr_get_record(intf, header, sdr_list_itr);
3289c18ec02fSPetter Reinholdtsen 		if (rec == NULL) {
3290c18ec02fSPetter Reinholdtsen 			if (sdrr != NULL) {
3291c18ec02fSPetter Reinholdtsen 				free(sdrr);
3292c18ec02fSPetter Reinholdtsen 				sdrr = NULL;
3293c18ec02fSPetter Reinholdtsen 			}
3294c18ec02fSPetter Reinholdtsen 			continue;
3295c18ec02fSPetter Reinholdtsen 		}
3296c18ec02fSPetter Reinholdtsen 
3297c18ec02fSPetter Reinholdtsen 		switch (header->type) {
3298c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FULL_SENSOR:
3299c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_COMPACT_SENSOR:
3300c18ec02fSPetter Reinholdtsen 			sdrr->record.common =
3301c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_common_sensor *) rec;
3302c18ec02fSPetter Reinholdtsen 			if (sdrr->record.common->keys.sensor_num == num
3303c18ec02fSPetter Reinholdtsen 			    && sdrr->record.common->keys.owner_id == (gen_id & 0x00ff)
3304c18ec02fSPetter Reinholdtsen 			    && sdrr->record.common->sensor.type == type)
3305c18ec02fSPetter Reinholdtsen 				found = 1;
3306c18ec02fSPetter Reinholdtsen 			break;
3307c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
3308c18ec02fSPetter Reinholdtsen 			sdrr->record.eventonly =
3309c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_eventonly_sensor *) rec;
3310c18ec02fSPetter Reinholdtsen 			if (sdrr->record.eventonly->keys.sensor_num == num
3311c18ec02fSPetter Reinholdtsen 			    && sdrr->record.eventonly->keys.owner_id == (gen_id & 0x00ff)
3312c18ec02fSPetter Reinholdtsen 			    && sdrr->record.eventonly->sensor_type == type)
3313c18ec02fSPetter Reinholdtsen 				found = 1;
3314c18ec02fSPetter Reinholdtsen 			break;
3315c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR:
3316c18ec02fSPetter Reinholdtsen 			sdrr->record.genloc =
3317c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_generic_locator *) rec;
3318c18ec02fSPetter Reinholdtsen 			break;
3319c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
3320c18ec02fSPetter Reinholdtsen 			sdrr->record.fruloc =
3321c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_fru_locator *) rec;
3322c18ec02fSPetter Reinholdtsen 			break;
3323c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
3324c18ec02fSPetter Reinholdtsen 			sdrr->record.mcloc =
3325c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_mc_locator *) rec;
3326c18ec02fSPetter Reinholdtsen 			break;
3327c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_ENTITY_ASSOC:
3328c18ec02fSPetter Reinholdtsen 			sdrr->record.entassoc =
3329c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_entity_assoc *) rec;
3330c18ec02fSPetter Reinholdtsen 			break;
3331c18ec02fSPetter Reinholdtsen 		default:
3332c18ec02fSPetter Reinholdtsen 			free(rec);
3333c18ec02fSPetter Reinholdtsen 			rec = NULL;
3334c18ec02fSPetter Reinholdtsen 			if (sdrr != NULL) {
3335c18ec02fSPetter Reinholdtsen 				free(sdrr);
3336c18ec02fSPetter Reinholdtsen 				sdrr = NULL;
3337c18ec02fSPetter Reinholdtsen 			}
3338c18ec02fSPetter Reinholdtsen 			continue;
3339c18ec02fSPetter Reinholdtsen 		}
3340c18ec02fSPetter Reinholdtsen 
3341c18ec02fSPetter Reinholdtsen 		/* put in the global record list */
3342c18ec02fSPetter Reinholdtsen 		if (sdr_list_head == NULL)
3343c18ec02fSPetter Reinholdtsen 			sdr_list_head = sdrr;
3344c18ec02fSPetter Reinholdtsen 		else
3345c18ec02fSPetter Reinholdtsen 			sdr_list_tail->next = sdrr;
3346c18ec02fSPetter Reinholdtsen 
3347c18ec02fSPetter Reinholdtsen 		sdr_list_tail = sdrr;
3348c18ec02fSPetter Reinholdtsen 
3349c18ec02fSPetter Reinholdtsen 		if (found)
3350c18ec02fSPetter Reinholdtsen 			return sdrr;
3351c18ec02fSPetter Reinholdtsen 	}
3352c18ec02fSPetter Reinholdtsen 
3353c18ec02fSPetter Reinholdtsen 	return NULL;
3354c18ec02fSPetter Reinholdtsen }
3355c18ec02fSPetter Reinholdtsen 
3356c18ec02fSPetter Reinholdtsen /* ipmi_sdr_find_sdr_bysensortype  -  lookup SDR entry by sensor type
3357c18ec02fSPetter Reinholdtsen  *
3358c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
3359c18ec02fSPetter Reinholdtsen  * @type:	sensor type to search for
3360c18ec02fSPetter Reinholdtsen  *
3361c18ec02fSPetter Reinholdtsen  * returns pointer to SDR list
3362c18ec02fSPetter Reinholdtsen  * returns NULL on error
3363c18ec02fSPetter Reinholdtsen  */
3364c18ec02fSPetter Reinholdtsen struct sdr_record_list *
ipmi_sdr_find_sdr_bysensortype(struct ipmi_intf * intf,uint8_t type)3365c18ec02fSPetter Reinholdtsen ipmi_sdr_find_sdr_bysensortype(struct ipmi_intf *intf, uint8_t type)
3366c18ec02fSPetter Reinholdtsen {
3367c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *head;
3368c18ec02fSPetter Reinholdtsen 	struct sdr_get_rs *header;
3369c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *e;
3370c18ec02fSPetter Reinholdtsen 
3371c18ec02fSPetter Reinholdtsen 	if (sdr_list_itr == NULL) {
3372c18ec02fSPetter Reinholdtsen 		sdr_list_itr = ipmi_sdr_start(intf, 0);
3373c18ec02fSPetter Reinholdtsen 		if (sdr_list_itr == NULL) {
3374c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Unable to open SDR for reading");
3375c18ec02fSPetter Reinholdtsen 			return NULL;
3376c18ec02fSPetter Reinholdtsen 		}
3377c18ec02fSPetter Reinholdtsen 	}
3378c18ec02fSPetter Reinholdtsen 
3379c18ec02fSPetter Reinholdtsen 	/* check what we've already read */
3380c18ec02fSPetter Reinholdtsen 	head = malloc(sizeof (struct sdr_record_list));
3381c18ec02fSPetter Reinholdtsen 	if (head == NULL) {
3382c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "ipmitool: malloc failure");
3383c18ec02fSPetter Reinholdtsen 		return NULL;
3384c18ec02fSPetter Reinholdtsen 	}
3385c18ec02fSPetter Reinholdtsen 	memset(head, 0, sizeof (struct sdr_record_list));
3386c18ec02fSPetter Reinholdtsen 
3387c18ec02fSPetter Reinholdtsen 	for (e = sdr_list_head; e != NULL; e = e->next) {
3388c18ec02fSPetter Reinholdtsen 		switch (e->type) {
3389c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FULL_SENSOR:
3390c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_COMPACT_SENSOR:
3391c18ec02fSPetter Reinholdtsen 			if (e->record.common->sensor.type == type)
3392c18ec02fSPetter Reinholdtsen 				__sdr_list_add(head, e);
3393c18ec02fSPetter Reinholdtsen 			break;
3394c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
3395c18ec02fSPetter Reinholdtsen 			if (e->record.eventonly->sensor_type == type)
3396c18ec02fSPetter Reinholdtsen 				__sdr_list_add(head, e);
3397c18ec02fSPetter Reinholdtsen 			break;
3398c18ec02fSPetter Reinholdtsen 		}
3399c18ec02fSPetter Reinholdtsen 	}
3400c18ec02fSPetter Reinholdtsen 
3401c18ec02fSPetter Reinholdtsen 	/* now keep looking */
3402c18ec02fSPetter Reinholdtsen 	while ((header = ipmi_sdr_get_next_header(intf, sdr_list_itr)) != NULL) {
3403c18ec02fSPetter Reinholdtsen 		uint8_t *rec;
3404c18ec02fSPetter Reinholdtsen 		struct sdr_record_list *sdrr;
3405c18ec02fSPetter Reinholdtsen 
3406c18ec02fSPetter Reinholdtsen 		sdrr = malloc(sizeof (struct sdr_record_list));
3407c18ec02fSPetter Reinholdtsen 		if (sdrr == NULL) {
3408c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "ipmitool: malloc failure");
3409c18ec02fSPetter Reinholdtsen 			break;
3410c18ec02fSPetter Reinholdtsen 		}
3411c18ec02fSPetter Reinholdtsen 		memset(sdrr, 0, sizeof (struct sdr_record_list));
3412c18ec02fSPetter Reinholdtsen 		sdrr->id = header->id;
3413c18ec02fSPetter Reinholdtsen 		sdrr->type = header->type;
3414c18ec02fSPetter Reinholdtsen 
3415c18ec02fSPetter Reinholdtsen 		rec = ipmi_sdr_get_record(intf, header, sdr_list_itr);
3416c18ec02fSPetter Reinholdtsen 		if (rec == NULL) {
3417c18ec02fSPetter Reinholdtsen 			if (sdrr != NULL) {
3418c18ec02fSPetter Reinholdtsen 				free(sdrr);
3419c18ec02fSPetter Reinholdtsen 				sdrr = NULL;
3420c18ec02fSPetter Reinholdtsen 			}
3421c18ec02fSPetter Reinholdtsen 			continue;
3422c18ec02fSPetter Reinholdtsen 		}
3423c18ec02fSPetter Reinholdtsen 
3424c18ec02fSPetter Reinholdtsen 		switch (header->type) {
3425c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FULL_SENSOR:
3426c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_COMPACT_SENSOR:
3427c18ec02fSPetter Reinholdtsen 			sdrr->record.common =
3428c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_common_sensor *) rec;
3429c18ec02fSPetter Reinholdtsen 			if (sdrr->record.common->sensor.type == type)
3430c18ec02fSPetter Reinholdtsen 				__sdr_list_add(head, sdrr);
3431c18ec02fSPetter Reinholdtsen 			break;
3432c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
3433c18ec02fSPetter Reinholdtsen 			sdrr->record.eventonly =
3434c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_eventonly_sensor *) rec;
3435c18ec02fSPetter Reinholdtsen 			if (sdrr->record.eventonly->sensor_type == type)
3436c18ec02fSPetter Reinholdtsen 				__sdr_list_add(head, sdrr);
3437c18ec02fSPetter Reinholdtsen 			break;
3438c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR:
3439c18ec02fSPetter Reinholdtsen 			sdrr->record.genloc =
3440c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_generic_locator *) rec;
3441c18ec02fSPetter Reinholdtsen 			break;
3442c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
3443c18ec02fSPetter Reinholdtsen 			sdrr->record.fruloc =
3444c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_fru_locator *) rec;
3445c18ec02fSPetter Reinholdtsen 			break;
3446c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
3447c18ec02fSPetter Reinholdtsen 			sdrr->record.mcloc =
3448c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_mc_locator *) rec;
3449c18ec02fSPetter Reinholdtsen 			break;
3450c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_ENTITY_ASSOC:
3451c18ec02fSPetter Reinholdtsen 			sdrr->record.entassoc =
3452c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_entity_assoc *) rec;
3453c18ec02fSPetter Reinholdtsen 			break;
3454c18ec02fSPetter Reinholdtsen 		default:
3455c18ec02fSPetter Reinholdtsen 			free(rec);
3456c18ec02fSPetter Reinholdtsen 			rec = NULL;
3457c18ec02fSPetter Reinholdtsen 			if (sdrr != NULL) {
3458c18ec02fSPetter Reinholdtsen 				free(sdrr);
3459c18ec02fSPetter Reinholdtsen 				sdrr = NULL;
3460c18ec02fSPetter Reinholdtsen 			}
3461c18ec02fSPetter Reinholdtsen 			continue;
3462c18ec02fSPetter Reinholdtsen 		}
3463c18ec02fSPetter Reinholdtsen 
3464c18ec02fSPetter Reinholdtsen 		/* put in the global record list */
3465c18ec02fSPetter Reinholdtsen 		if (sdr_list_head == NULL)
3466c18ec02fSPetter Reinholdtsen 			sdr_list_head = sdrr;
3467c18ec02fSPetter Reinholdtsen 		else
3468c18ec02fSPetter Reinholdtsen 			sdr_list_tail->next = sdrr;
3469c18ec02fSPetter Reinholdtsen 
3470c18ec02fSPetter Reinholdtsen 		sdr_list_tail = sdrr;
3471c18ec02fSPetter Reinholdtsen 	}
3472c18ec02fSPetter Reinholdtsen 
3473c18ec02fSPetter Reinholdtsen 	return head;
3474c18ec02fSPetter Reinholdtsen }
3475c18ec02fSPetter Reinholdtsen 
3476c18ec02fSPetter Reinholdtsen /* ipmi_sdr_find_sdr_byentity  -  lookup SDR entry by entity association
3477c18ec02fSPetter Reinholdtsen  *
3478c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
3479c18ec02fSPetter Reinholdtsen  * @entity:	entity id/instance to search for
3480c18ec02fSPetter Reinholdtsen  *
3481c18ec02fSPetter Reinholdtsen  * returns pointer to SDR list
3482c18ec02fSPetter Reinholdtsen  * returns NULL on error
3483c18ec02fSPetter Reinholdtsen  */
3484c18ec02fSPetter Reinholdtsen struct sdr_record_list *
ipmi_sdr_find_sdr_byentity(struct ipmi_intf * intf,struct entity_id * entity)3485c18ec02fSPetter Reinholdtsen ipmi_sdr_find_sdr_byentity(struct ipmi_intf *intf, struct entity_id *entity)
3486c18ec02fSPetter Reinholdtsen {
3487c18ec02fSPetter Reinholdtsen 	struct sdr_get_rs *header;
3488c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *e;
3489c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *head;
3490c18ec02fSPetter Reinholdtsen 
3491c18ec02fSPetter Reinholdtsen 	if (sdr_list_itr == NULL) {
3492c18ec02fSPetter Reinholdtsen 		sdr_list_itr = ipmi_sdr_start(intf, 0);
3493c18ec02fSPetter Reinholdtsen 		if (sdr_list_itr == NULL) {
3494c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Unable to open SDR for reading");
3495c18ec02fSPetter Reinholdtsen 			return NULL;
3496c18ec02fSPetter Reinholdtsen 		}
3497c18ec02fSPetter Reinholdtsen 	}
3498c18ec02fSPetter Reinholdtsen 
3499c18ec02fSPetter Reinholdtsen 	head = malloc(sizeof (struct sdr_record_list));
3500c18ec02fSPetter Reinholdtsen 	if (head == NULL) {
3501c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "ipmitool: malloc failure");
3502c18ec02fSPetter Reinholdtsen 		return NULL;
3503c18ec02fSPetter Reinholdtsen 	}
3504c18ec02fSPetter Reinholdtsen 	memset(head, 0, sizeof (struct sdr_record_list));
3505c18ec02fSPetter Reinholdtsen 
3506c18ec02fSPetter Reinholdtsen 	/* check what we've already read */
3507c18ec02fSPetter Reinholdtsen 	for (e = sdr_list_head; e != NULL; e = e->next) {
3508c18ec02fSPetter Reinholdtsen 		switch (e->type) {
3509c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FULL_SENSOR:
3510c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_COMPACT_SENSOR:
3511c18ec02fSPetter Reinholdtsen 			if (e->record.common->entity.id == entity->id &&
3512c18ec02fSPetter Reinholdtsen 			    (entity->instance == 0x7f ||
3513c18ec02fSPetter Reinholdtsen 			     e->record.common->entity.instance ==
3514c18ec02fSPetter Reinholdtsen 			     entity->instance))
3515c18ec02fSPetter Reinholdtsen 				__sdr_list_add(head, e);
3516c18ec02fSPetter Reinholdtsen 			break;
3517c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
3518c18ec02fSPetter Reinholdtsen 			if (e->record.eventonly->entity.id == entity->id &&
3519c18ec02fSPetter Reinholdtsen 			    (entity->instance == 0x7f ||
3520c18ec02fSPetter Reinholdtsen 			     e->record.eventonly->entity.instance ==
3521c18ec02fSPetter Reinholdtsen 			     entity->instance))
3522c18ec02fSPetter Reinholdtsen 				__sdr_list_add(head, e);
3523c18ec02fSPetter Reinholdtsen 			break;
3524c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR:
3525c18ec02fSPetter Reinholdtsen 			if (e->record.genloc->entity.id == entity->id &&
3526c18ec02fSPetter Reinholdtsen 			    (entity->instance == 0x7f ||
3527c18ec02fSPetter Reinholdtsen 			     e->record.genloc->entity.instance ==
3528c18ec02fSPetter Reinholdtsen 			     entity->instance))
3529c18ec02fSPetter Reinholdtsen 				__sdr_list_add(head, e);
3530c18ec02fSPetter Reinholdtsen 			break;
3531c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
3532c18ec02fSPetter Reinholdtsen 			if (e->record.fruloc->entity.id == entity->id &&
3533c18ec02fSPetter Reinholdtsen 			    (entity->instance == 0x7f ||
3534c18ec02fSPetter Reinholdtsen 			     e->record.fruloc->entity.instance ==
3535c18ec02fSPetter Reinholdtsen 			     entity->instance))
3536c18ec02fSPetter Reinholdtsen 				__sdr_list_add(head, e);
3537c18ec02fSPetter Reinholdtsen 			break;
3538c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
3539c18ec02fSPetter Reinholdtsen 			if (e->record.mcloc->entity.id == entity->id &&
3540c18ec02fSPetter Reinholdtsen 			    (entity->instance == 0x7f ||
3541c18ec02fSPetter Reinholdtsen 			     e->record.mcloc->entity.instance ==
3542c18ec02fSPetter Reinholdtsen 			     entity->instance))
3543c18ec02fSPetter Reinholdtsen 				__sdr_list_add(head, e);
3544c18ec02fSPetter Reinholdtsen 			break;
3545c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_ENTITY_ASSOC:
3546c18ec02fSPetter Reinholdtsen 			if (e->record.entassoc->entity.id == entity->id &&
3547c18ec02fSPetter Reinholdtsen 			    (entity->instance == 0x7f ||
3548c18ec02fSPetter Reinholdtsen 			     e->record.entassoc->entity.instance ==
3549c18ec02fSPetter Reinholdtsen 			     entity->instance))
3550c18ec02fSPetter Reinholdtsen 				__sdr_list_add(head, e);
3551c18ec02fSPetter Reinholdtsen 			break;
3552c18ec02fSPetter Reinholdtsen 		}
3553c18ec02fSPetter Reinholdtsen 	}
3554c18ec02fSPetter Reinholdtsen 
3555c18ec02fSPetter Reinholdtsen 	/* now keep looking */
3556c18ec02fSPetter Reinholdtsen 	while ((header = ipmi_sdr_get_next_header(intf, sdr_list_itr)) != NULL) {
3557c18ec02fSPetter Reinholdtsen 		uint8_t *rec;
3558c18ec02fSPetter Reinholdtsen 		struct sdr_record_list *sdrr;
3559c18ec02fSPetter Reinholdtsen 
3560c18ec02fSPetter Reinholdtsen 		sdrr = malloc(sizeof (struct sdr_record_list));
3561c18ec02fSPetter Reinholdtsen 		if (sdrr == NULL) {
3562c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "ipmitool: malloc failure");
3563c18ec02fSPetter Reinholdtsen 			break;
3564c18ec02fSPetter Reinholdtsen 		}
3565c18ec02fSPetter Reinholdtsen 		memset(sdrr, 0, sizeof (struct sdr_record_list));
3566c18ec02fSPetter Reinholdtsen 		sdrr->id = header->id;
3567c18ec02fSPetter Reinholdtsen 		sdrr->type = header->type;
3568c18ec02fSPetter Reinholdtsen 
3569c18ec02fSPetter Reinholdtsen 		rec = ipmi_sdr_get_record(intf, header, sdr_list_itr);
3570c18ec02fSPetter Reinholdtsen 		if (rec == NULL) {
3571c18ec02fSPetter Reinholdtsen 			if (sdrr != NULL) {
3572c18ec02fSPetter Reinholdtsen 				free(sdrr);
3573c18ec02fSPetter Reinholdtsen 				sdrr = NULL;
3574c18ec02fSPetter Reinholdtsen 			}
3575c18ec02fSPetter Reinholdtsen 			continue;
3576c18ec02fSPetter Reinholdtsen 		}
3577c18ec02fSPetter Reinholdtsen 
3578c18ec02fSPetter Reinholdtsen 		switch (header->type) {
3579c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FULL_SENSOR:
3580c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_COMPACT_SENSOR:
3581c18ec02fSPetter Reinholdtsen 			sdrr->record.common =
3582c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_common_sensor *) rec;
3583c18ec02fSPetter Reinholdtsen 			if (sdrr->record.common->entity.id == entity->id
3584c18ec02fSPetter Reinholdtsen 			    && (entity->instance == 0x7f
3585c18ec02fSPetter Reinholdtsen 				|| sdrr->record.common->entity.instance ==
3586c18ec02fSPetter Reinholdtsen 				entity->instance))
3587c18ec02fSPetter Reinholdtsen 				__sdr_list_add(head, sdrr);
3588c18ec02fSPetter Reinholdtsen 			break;
3589c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
3590c18ec02fSPetter Reinholdtsen 			sdrr->record.eventonly =
3591c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_eventonly_sensor *) rec;
3592c18ec02fSPetter Reinholdtsen 			if (sdrr->record.eventonly->entity.id == entity->id
3593c18ec02fSPetter Reinholdtsen 			    && (entity->instance == 0x7f
3594c18ec02fSPetter Reinholdtsen 				|| sdrr->record.eventonly->entity.instance ==
3595c18ec02fSPetter Reinholdtsen 				entity->instance))
3596c18ec02fSPetter Reinholdtsen 				__sdr_list_add(head, sdrr);
3597c18ec02fSPetter Reinholdtsen 			break;
3598c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR:
3599c18ec02fSPetter Reinholdtsen 			sdrr->record.genloc =
3600c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_generic_locator *) rec;
3601c18ec02fSPetter Reinholdtsen 			if (sdrr->record.genloc->entity.id == entity->id
3602c18ec02fSPetter Reinholdtsen 			    && (entity->instance == 0x7f
3603c18ec02fSPetter Reinholdtsen 				|| sdrr->record.genloc->entity.instance ==
3604c18ec02fSPetter Reinholdtsen 				entity->instance))
3605c18ec02fSPetter Reinholdtsen 				__sdr_list_add(head, sdrr);
3606c18ec02fSPetter Reinholdtsen 			break;
3607c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
3608c18ec02fSPetter Reinholdtsen 			sdrr->record.fruloc =
3609c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_fru_locator *) rec;
3610c18ec02fSPetter Reinholdtsen 			if (sdrr->record.fruloc->entity.id == entity->id
3611c18ec02fSPetter Reinholdtsen 			    && (entity->instance == 0x7f
3612c18ec02fSPetter Reinholdtsen 				|| sdrr->record.fruloc->entity.instance ==
3613c18ec02fSPetter Reinholdtsen 				entity->instance))
3614c18ec02fSPetter Reinholdtsen 				__sdr_list_add(head, sdrr);
3615c18ec02fSPetter Reinholdtsen 			break;
3616c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
3617c18ec02fSPetter Reinholdtsen 			sdrr->record.mcloc =
3618c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_mc_locator *) rec;
3619c18ec02fSPetter Reinholdtsen 			if (sdrr->record.mcloc->entity.id == entity->id
3620c18ec02fSPetter Reinholdtsen 			    && (entity->instance == 0x7f
3621c18ec02fSPetter Reinholdtsen 				|| sdrr->record.mcloc->entity.instance ==
3622c18ec02fSPetter Reinholdtsen 				entity->instance))
3623c18ec02fSPetter Reinholdtsen 				__sdr_list_add(head, sdrr);
3624c18ec02fSPetter Reinholdtsen 			break;
3625c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_ENTITY_ASSOC:
3626c18ec02fSPetter Reinholdtsen 			sdrr->record.entassoc =
3627c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_entity_assoc *) rec;
3628c18ec02fSPetter Reinholdtsen 			if (sdrr->record.entassoc->entity.id == entity->id
3629c18ec02fSPetter Reinholdtsen 			    && (entity->instance == 0x7f
3630c18ec02fSPetter Reinholdtsen 				|| sdrr->record.entassoc->entity.instance ==
3631c18ec02fSPetter Reinholdtsen 				entity->instance))
3632c18ec02fSPetter Reinholdtsen 				__sdr_list_add(head, sdrr);
3633c18ec02fSPetter Reinholdtsen 			break;
3634c18ec02fSPetter Reinholdtsen 		default:
3635c18ec02fSPetter Reinholdtsen 			free(rec);
3636c18ec02fSPetter Reinholdtsen 			rec = NULL;
3637c18ec02fSPetter Reinholdtsen 			if (sdrr != NULL) {
3638c18ec02fSPetter Reinholdtsen 				free(sdrr);
3639c18ec02fSPetter Reinholdtsen 				sdrr = NULL;
3640c18ec02fSPetter Reinholdtsen 			}
3641c18ec02fSPetter Reinholdtsen 			continue;
3642c18ec02fSPetter Reinholdtsen 		}
3643c18ec02fSPetter Reinholdtsen 
3644c18ec02fSPetter Reinholdtsen 		/* add to global record list */
3645c18ec02fSPetter Reinholdtsen 		if (sdr_list_head == NULL)
3646c18ec02fSPetter Reinholdtsen 			sdr_list_head = sdrr;
3647c18ec02fSPetter Reinholdtsen 		else
3648c18ec02fSPetter Reinholdtsen 			sdr_list_tail->next = sdrr;
3649c18ec02fSPetter Reinholdtsen 
3650c18ec02fSPetter Reinholdtsen 		sdr_list_tail = sdrr;
3651c18ec02fSPetter Reinholdtsen 	}
3652c18ec02fSPetter Reinholdtsen 
3653c18ec02fSPetter Reinholdtsen 	return head;
3654c18ec02fSPetter Reinholdtsen }
3655c18ec02fSPetter Reinholdtsen 
3656c18ec02fSPetter Reinholdtsen /* ipmi_sdr_find_sdr_bytype  -  lookup SDR entries by type
3657c18ec02fSPetter Reinholdtsen  *
3658c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
3659c18ec02fSPetter Reinholdtsen  * @type:	type of sensor record to search for
3660c18ec02fSPetter Reinholdtsen  *
3661c18ec02fSPetter Reinholdtsen  * returns pointer to SDR list with all matching entities
3662c18ec02fSPetter Reinholdtsen  * returns NULL on error
3663c18ec02fSPetter Reinholdtsen  */
3664c18ec02fSPetter Reinholdtsen struct sdr_record_list *
ipmi_sdr_find_sdr_bytype(struct ipmi_intf * intf,uint8_t type)3665c18ec02fSPetter Reinholdtsen ipmi_sdr_find_sdr_bytype(struct ipmi_intf *intf, uint8_t type)
3666c18ec02fSPetter Reinholdtsen {
3667c18ec02fSPetter Reinholdtsen 	struct sdr_get_rs *header;
3668c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *e;
3669c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *head;
3670c18ec02fSPetter Reinholdtsen 
3671c18ec02fSPetter Reinholdtsen 	if (sdr_list_itr == NULL) {
3672c18ec02fSPetter Reinholdtsen 		sdr_list_itr = ipmi_sdr_start(intf, 0);
3673c18ec02fSPetter Reinholdtsen 		if (sdr_list_itr == NULL) {
3674c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Unable to open SDR for reading");
3675c18ec02fSPetter Reinholdtsen 			return NULL;
3676c18ec02fSPetter Reinholdtsen 		}
3677c18ec02fSPetter Reinholdtsen 	}
3678c18ec02fSPetter Reinholdtsen 
3679c18ec02fSPetter Reinholdtsen 	head = malloc(sizeof (struct sdr_record_list));
3680c18ec02fSPetter Reinholdtsen 	if (head == NULL) {
3681c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "ipmitool: malloc failure");
3682c18ec02fSPetter Reinholdtsen 		return NULL;
3683c18ec02fSPetter Reinholdtsen 	}
3684c18ec02fSPetter Reinholdtsen 	memset(head, 0, sizeof (struct sdr_record_list));
3685c18ec02fSPetter Reinholdtsen 
3686c18ec02fSPetter Reinholdtsen 	/* check what we've already read */
3687c18ec02fSPetter Reinholdtsen 	for (e = sdr_list_head; e != NULL; e = e->next)
3688c18ec02fSPetter Reinholdtsen 		if (e->type == type)
3689c18ec02fSPetter Reinholdtsen 			__sdr_list_add(head, e);
3690c18ec02fSPetter Reinholdtsen 
3691c18ec02fSPetter Reinholdtsen 	/* now keep looking */
3692c18ec02fSPetter Reinholdtsen 	while ((header = ipmi_sdr_get_next_header(intf, sdr_list_itr)) != NULL) {
3693c18ec02fSPetter Reinholdtsen 		uint8_t *rec;
3694c18ec02fSPetter Reinholdtsen 		struct sdr_record_list *sdrr;
3695c18ec02fSPetter Reinholdtsen 
3696c18ec02fSPetter Reinholdtsen 		sdrr = malloc(sizeof (struct sdr_record_list));
3697c18ec02fSPetter Reinholdtsen 		if (sdrr == NULL) {
3698c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "ipmitool: malloc failure");
3699c18ec02fSPetter Reinholdtsen 			break;
3700c18ec02fSPetter Reinholdtsen 		}
3701c18ec02fSPetter Reinholdtsen 		memset(sdrr, 0, sizeof (struct sdr_record_list));
3702c18ec02fSPetter Reinholdtsen 		sdrr->id = header->id;
3703c18ec02fSPetter Reinholdtsen 		sdrr->type = header->type;
3704c18ec02fSPetter Reinholdtsen 
3705c18ec02fSPetter Reinholdtsen 		rec = ipmi_sdr_get_record(intf, header, sdr_list_itr);
3706c18ec02fSPetter Reinholdtsen 		if (rec == NULL) {
3707c18ec02fSPetter Reinholdtsen 			if (sdrr != NULL) {
3708c18ec02fSPetter Reinholdtsen 				free(sdrr);
3709c18ec02fSPetter Reinholdtsen 				sdrr = NULL;
3710c18ec02fSPetter Reinholdtsen 			}
3711c18ec02fSPetter Reinholdtsen 			continue;
3712c18ec02fSPetter Reinholdtsen 		}
3713c18ec02fSPetter Reinholdtsen 
3714c18ec02fSPetter Reinholdtsen 		switch (header->type) {
3715c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FULL_SENSOR:
3716c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_COMPACT_SENSOR:
3717c18ec02fSPetter Reinholdtsen 			sdrr->record.common =
3718c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_common_sensor *) rec;
3719c18ec02fSPetter Reinholdtsen 			break;
3720c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
3721c18ec02fSPetter Reinholdtsen 			sdrr->record.eventonly =
3722c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_eventonly_sensor *) rec;
3723c18ec02fSPetter Reinholdtsen 			break;
3724c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR:
3725c18ec02fSPetter Reinholdtsen 			sdrr->record.genloc =
3726c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_generic_locator *) rec;
3727c18ec02fSPetter Reinholdtsen 			break;
3728c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
3729c18ec02fSPetter Reinholdtsen 			sdrr->record.fruloc =
3730c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_fru_locator *) rec;
3731c18ec02fSPetter Reinholdtsen 			break;
3732c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
3733c18ec02fSPetter Reinholdtsen 			sdrr->record.mcloc =
3734c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_mc_locator *) rec;
3735c18ec02fSPetter Reinholdtsen 			break;
3736c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_ENTITY_ASSOC:
3737c18ec02fSPetter Reinholdtsen 			sdrr->record.entassoc =
3738c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_entity_assoc *) rec;
3739c18ec02fSPetter Reinholdtsen 			break;
3740c18ec02fSPetter Reinholdtsen 		default:
3741c18ec02fSPetter Reinholdtsen 			free(rec);
3742c18ec02fSPetter Reinholdtsen 			rec = NULL;
3743c18ec02fSPetter Reinholdtsen 			if (sdrr != NULL) {
3744c18ec02fSPetter Reinholdtsen 				free(sdrr);
3745c18ec02fSPetter Reinholdtsen 				sdrr = NULL;
3746c18ec02fSPetter Reinholdtsen 			}
3747c18ec02fSPetter Reinholdtsen 			continue;
3748c18ec02fSPetter Reinholdtsen 		}
3749c18ec02fSPetter Reinholdtsen 
3750c18ec02fSPetter Reinholdtsen 		if (header->type == type)
3751c18ec02fSPetter Reinholdtsen 			__sdr_list_add(head, sdrr);
3752c18ec02fSPetter Reinholdtsen 
3753c18ec02fSPetter Reinholdtsen 		/* add to global record list */
3754c18ec02fSPetter Reinholdtsen 		if (sdr_list_head == NULL)
3755c18ec02fSPetter Reinholdtsen 			sdr_list_head = sdrr;
3756c18ec02fSPetter Reinholdtsen 		else
3757c18ec02fSPetter Reinholdtsen 			sdr_list_tail->next = sdrr;
3758c18ec02fSPetter Reinholdtsen 
3759c18ec02fSPetter Reinholdtsen 		sdr_list_tail = sdrr;
3760c18ec02fSPetter Reinholdtsen 	}
3761c18ec02fSPetter Reinholdtsen 
3762c18ec02fSPetter Reinholdtsen 	return head;
3763c18ec02fSPetter Reinholdtsen }
3764c18ec02fSPetter Reinholdtsen 
3765c18ec02fSPetter Reinholdtsen /* ipmi_sdr_find_sdr_byid  -  lookup SDR entry by ID string
3766c18ec02fSPetter Reinholdtsen  *
3767c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
3768c18ec02fSPetter Reinholdtsen  * @id:		string to match for sensor name
3769c18ec02fSPetter Reinholdtsen  *
3770c18ec02fSPetter Reinholdtsen  * returns pointer to SDR list
3771c18ec02fSPetter Reinholdtsen  * returns NULL on error
3772c18ec02fSPetter Reinholdtsen  */
3773c18ec02fSPetter Reinholdtsen struct sdr_record_list *
ipmi_sdr_find_sdr_byid(struct ipmi_intf * intf,char * id)3774c18ec02fSPetter Reinholdtsen ipmi_sdr_find_sdr_byid(struct ipmi_intf *intf, char *id)
3775c18ec02fSPetter Reinholdtsen {
3776c18ec02fSPetter Reinholdtsen 	struct sdr_get_rs *header;
3777c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *e;
3778c18ec02fSPetter Reinholdtsen 	int found = 0;
3779c18ec02fSPetter Reinholdtsen 	int idlen;
3780c18ec02fSPetter Reinholdtsen 
3781c18ec02fSPetter Reinholdtsen 	if (id == NULL)
3782c18ec02fSPetter Reinholdtsen 		return NULL;
3783c18ec02fSPetter Reinholdtsen 
3784c18ec02fSPetter Reinholdtsen 	idlen = strlen(id);
3785c18ec02fSPetter Reinholdtsen 
3786c18ec02fSPetter Reinholdtsen 	if (sdr_list_itr == NULL) {
3787c18ec02fSPetter Reinholdtsen 		sdr_list_itr = ipmi_sdr_start(intf, 0);
3788c18ec02fSPetter Reinholdtsen 		if (sdr_list_itr == NULL) {
3789c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Unable to open SDR for reading");
3790c18ec02fSPetter Reinholdtsen 			return NULL;
3791c18ec02fSPetter Reinholdtsen 		}
3792c18ec02fSPetter Reinholdtsen 	}
3793c18ec02fSPetter Reinholdtsen 
3794c18ec02fSPetter Reinholdtsen 	/* check what we've already read */
3795c18ec02fSPetter Reinholdtsen 	for (e = sdr_list_head; e != NULL; e = e->next) {
3796c18ec02fSPetter Reinholdtsen 		switch (e->type) {
3797c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FULL_SENSOR:
3798c18ec02fSPetter Reinholdtsen 			if (!strncmp((const char *)e->record.full->id_string,
3799c18ec02fSPetter Reinholdtsen 				     (const char *)id,
3800c18ec02fSPetter Reinholdtsen 				     __max(e->record.full->id_code & 0x1f, idlen)))
3801c18ec02fSPetter Reinholdtsen 				return e;
3802c18ec02fSPetter Reinholdtsen 			break;
3803c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_COMPACT_SENSOR:
3804c18ec02fSPetter Reinholdtsen 			if (!strncmp((const char *)e->record.compact->id_string,
3805c18ec02fSPetter Reinholdtsen 				     (const char *)id,
3806c18ec02fSPetter Reinholdtsen 				     __max(e->record.compact->id_code & 0x1f, idlen)))
3807c18ec02fSPetter Reinholdtsen 				return e;
3808c18ec02fSPetter Reinholdtsen 			break;
3809c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
3810c18ec02fSPetter Reinholdtsen 			if (!strncmp((const char *)e->record.eventonly->id_string,
3811c18ec02fSPetter Reinholdtsen 				     (const char *)id,
3812c18ec02fSPetter Reinholdtsen 				     __max(e->record.eventonly->id_code & 0x1f, idlen)))
3813c18ec02fSPetter Reinholdtsen 				return e;
3814c18ec02fSPetter Reinholdtsen 			break;
3815c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR:
3816c18ec02fSPetter Reinholdtsen 			if (!strncmp((const char *)e->record.genloc->id_string,
3817c18ec02fSPetter Reinholdtsen 				     (const char *)id,
3818c18ec02fSPetter Reinholdtsen 				     __max(e->record.genloc->id_code & 0x1f, idlen)))
3819c18ec02fSPetter Reinholdtsen 				return e;
3820c18ec02fSPetter Reinholdtsen 			break;
3821c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
3822c18ec02fSPetter Reinholdtsen 			if (!strncmp((const char *)e->record.fruloc->id_string,
3823c18ec02fSPetter Reinholdtsen 				     (const char *)id,
3824c18ec02fSPetter Reinholdtsen 				     __max(e->record.fruloc->id_code & 0x1f, idlen)))
3825c18ec02fSPetter Reinholdtsen 				return e;
3826c18ec02fSPetter Reinholdtsen 			break;
3827c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
3828c18ec02fSPetter Reinholdtsen 			if (!strncmp((const char *)e->record.mcloc->id_string,
3829c18ec02fSPetter Reinholdtsen 				     (const char *)id,
3830c18ec02fSPetter Reinholdtsen 				     __max(e->record.mcloc->id_code & 0x1f, idlen)))
3831c18ec02fSPetter Reinholdtsen 				return e;
3832c18ec02fSPetter Reinholdtsen 			break;
3833c18ec02fSPetter Reinholdtsen 		}
3834c18ec02fSPetter Reinholdtsen 	}
3835c18ec02fSPetter Reinholdtsen 
3836c18ec02fSPetter Reinholdtsen 	/* now keep looking */
3837c18ec02fSPetter Reinholdtsen 	while ((header = ipmi_sdr_get_next_header(intf, sdr_list_itr)) != NULL) {
3838c18ec02fSPetter Reinholdtsen 		uint8_t *rec;
3839c18ec02fSPetter Reinholdtsen 		struct sdr_record_list *sdrr;
3840c18ec02fSPetter Reinholdtsen 
3841c18ec02fSPetter Reinholdtsen 		sdrr = malloc(sizeof (struct sdr_record_list));
3842c18ec02fSPetter Reinholdtsen 		if (sdrr == NULL) {
3843c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "ipmitool: malloc failure");
3844c18ec02fSPetter Reinholdtsen 			break;
3845c18ec02fSPetter Reinholdtsen 		}
3846c18ec02fSPetter Reinholdtsen 		memset(sdrr, 0, sizeof (struct sdr_record_list));
3847c18ec02fSPetter Reinholdtsen 		sdrr->id = header->id;
3848c18ec02fSPetter Reinholdtsen 		sdrr->type = header->type;
3849c18ec02fSPetter Reinholdtsen 
3850c18ec02fSPetter Reinholdtsen 		rec = ipmi_sdr_get_record(intf, header, sdr_list_itr);
3851c18ec02fSPetter Reinholdtsen 		if (rec == NULL) {
3852c18ec02fSPetter Reinholdtsen 			if (sdrr != NULL) {
3853c18ec02fSPetter Reinholdtsen 				free(sdrr);
3854c18ec02fSPetter Reinholdtsen 				sdrr = NULL;
3855c18ec02fSPetter Reinholdtsen 			}
3856c18ec02fSPetter Reinholdtsen 			continue;
3857c18ec02fSPetter Reinholdtsen 		}
3858c18ec02fSPetter Reinholdtsen 
3859c18ec02fSPetter Reinholdtsen 		switch (header->type) {
3860c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FULL_SENSOR:
3861c18ec02fSPetter Reinholdtsen 			sdrr->record.full =
3862c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_full_sensor *) rec;
3863c18ec02fSPetter Reinholdtsen 			if (!strncmp(
3864c18ec02fSPetter Reinholdtsen 			    (const char *)sdrr->record.full->id_string,
3865c18ec02fSPetter Reinholdtsen 			    (const char *)id,
3866c18ec02fSPetter Reinholdtsen 			    __max(sdrr->record.full->id_code & 0x1f, idlen)))
3867c18ec02fSPetter Reinholdtsen 				found = 1;
3868c18ec02fSPetter Reinholdtsen 			break;
3869c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_COMPACT_SENSOR:
3870c18ec02fSPetter Reinholdtsen 			sdrr->record.compact =
3871c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_compact_sensor *) rec;
3872c18ec02fSPetter Reinholdtsen 			if (!strncmp(
3873c18ec02fSPetter Reinholdtsen 			    (const char *)sdrr->record.compact->id_string,
3874c18ec02fSPetter Reinholdtsen 			    (const char *)id,
3875c18ec02fSPetter Reinholdtsen 			    __max(sdrr->record.compact->id_code & 0x1f,
3876c18ec02fSPetter Reinholdtsen 				   idlen)))
3877c18ec02fSPetter Reinholdtsen 				found = 1;
3878c18ec02fSPetter Reinholdtsen 			break;
3879c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
3880c18ec02fSPetter Reinholdtsen 			sdrr->record.eventonly =
3881c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_eventonly_sensor *) rec;
3882c18ec02fSPetter Reinholdtsen 			if (!strncmp(
3883c18ec02fSPetter Reinholdtsen 			    (const char *)sdrr->record.eventonly->id_string,
3884c18ec02fSPetter Reinholdtsen 			    (const char *)id,
3885c18ec02fSPetter Reinholdtsen 			    __max(sdrr->record.eventonly->id_code & 0x1f,
3886c18ec02fSPetter Reinholdtsen 				   idlen)))
3887c18ec02fSPetter Reinholdtsen 				found = 1;
3888c18ec02fSPetter Reinholdtsen 			break;
3889c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR:
3890c18ec02fSPetter Reinholdtsen 			sdrr->record.genloc =
3891c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_generic_locator *) rec;
3892c18ec02fSPetter Reinholdtsen 			if (!strncmp(
3893c18ec02fSPetter Reinholdtsen 			    (const char *)sdrr->record.genloc->id_string,
3894c18ec02fSPetter Reinholdtsen 			    (const char *)id,
3895c18ec02fSPetter Reinholdtsen 			    __max(sdrr->record.genloc->id_code & 0x1f, idlen)))
3896c18ec02fSPetter Reinholdtsen 				found = 1;
3897c18ec02fSPetter Reinholdtsen 			break;
3898c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
3899c18ec02fSPetter Reinholdtsen 			sdrr->record.fruloc =
3900c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_fru_locator *) rec;
3901c18ec02fSPetter Reinholdtsen 			if (!strncmp(
3902c18ec02fSPetter Reinholdtsen 			    (const char *)sdrr->record.fruloc->id_string,
3903c18ec02fSPetter Reinholdtsen 			    (const char *)id,
3904c18ec02fSPetter Reinholdtsen 			    __max(sdrr->record.fruloc->id_code & 0x1f, idlen)))
3905c18ec02fSPetter Reinholdtsen 				found = 1;
3906c18ec02fSPetter Reinholdtsen 			break;
3907c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
3908c18ec02fSPetter Reinholdtsen 			sdrr->record.mcloc =
3909c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_mc_locator *) rec;
3910c18ec02fSPetter Reinholdtsen 			if (!strncmp(
3911c18ec02fSPetter Reinholdtsen 			    (const char *)sdrr->record.mcloc->id_string,
3912c18ec02fSPetter Reinholdtsen 			    (const char *)id,
3913c18ec02fSPetter Reinholdtsen 			    __max(sdrr->record.mcloc->id_code & 0x1f, idlen)))
3914c18ec02fSPetter Reinholdtsen 				found = 1;
3915c18ec02fSPetter Reinholdtsen 			break;
3916c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_ENTITY_ASSOC:
3917c18ec02fSPetter Reinholdtsen 			sdrr->record.entassoc =
3918c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_entity_assoc *) rec;
3919c18ec02fSPetter Reinholdtsen 			break;
3920c18ec02fSPetter Reinholdtsen 		default:
3921c18ec02fSPetter Reinholdtsen 			free(rec);
3922c18ec02fSPetter Reinholdtsen 			rec = NULL;
3923c18ec02fSPetter Reinholdtsen 			if (sdrr != NULL) {
3924c18ec02fSPetter Reinholdtsen 				free(sdrr);
3925c18ec02fSPetter Reinholdtsen 				sdrr = NULL;
3926c18ec02fSPetter Reinholdtsen 			}
3927c18ec02fSPetter Reinholdtsen 			continue;
3928c18ec02fSPetter Reinholdtsen 		}
3929c18ec02fSPetter Reinholdtsen 
3930c18ec02fSPetter Reinholdtsen 		/* add to global record liset */
3931c18ec02fSPetter Reinholdtsen 		if (sdr_list_head == NULL)
3932c18ec02fSPetter Reinholdtsen 			sdr_list_head = sdrr;
3933c18ec02fSPetter Reinholdtsen 		else
3934c18ec02fSPetter Reinholdtsen 			sdr_list_tail->next = sdrr;
3935c18ec02fSPetter Reinholdtsen 
3936c18ec02fSPetter Reinholdtsen 		sdr_list_tail = sdrr;
3937c18ec02fSPetter Reinholdtsen 
3938c18ec02fSPetter Reinholdtsen 		if (found)
3939c18ec02fSPetter Reinholdtsen 			return sdrr;
3940c18ec02fSPetter Reinholdtsen 	}
3941c18ec02fSPetter Reinholdtsen 
3942c18ec02fSPetter Reinholdtsen 	return NULL;
3943c18ec02fSPetter Reinholdtsen }
3944c18ec02fSPetter Reinholdtsen 
3945c18ec02fSPetter Reinholdtsen /* ipmi_sdr_list_cache_fromfile  -  generate SDR cache for fast lookup from local file
3946c18ec02fSPetter Reinholdtsen  *
3947c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
3948c18ec02fSPetter Reinholdtsen  * @ifile:	input filename
3949c18ec02fSPetter Reinholdtsen  *
3950c18ec02fSPetter Reinholdtsen  * returns pointer to SDR list
3951c18ec02fSPetter Reinholdtsen  * returns NULL on error
3952c18ec02fSPetter Reinholdtsen  */
3953c18ec02fSPetter Reinholdtsen int
ipmi_sdr_list_cache_fromfile(struct ipmi_intf * intf,const char * ifile)3954c18ec02fSPetter Reinholdtsen ipmi_sdr_list_cache_fromfile(struct ipmi_intf *intf, const char *ifile)
3955c18ec02fSPetter Reinholdtsen {
3956c18ec02fSPetter Reinholdtsen 	FILE *fp;
3957c18ec02fSPetter Reinholdtsen 	struct __sdr_header {
3958c18ec02fSPetter Reinholdtsen 		uint16_t id;
3959c18ec02fSPetter Reinholdtsen 		uint8_t version;
3960c18ec02fSPetter Reinholdtsen 		uint8_t type;
3961c18ec02fSPetter Reinholdtsen 		uint8_t length;
3962c18ec02fSPetter Reinholdtsen 	} header;
3963c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *sdrr;
3964c18ec02fSPetter Reinholdtsen 	uint8_t *rec;
3965c18ec02fSPetter Reinholdtsen 	int ret = 0, count = 0, bc = 0;
3966c18ec02fSPetter Reinholdtsen 
3967c18ec02fSPetter Reinholdtsen 	if (ifile == NULL) {
3968c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "No SDR cache filename given");
3969c18ec02fSPetter Reinholdtsen 		return -1;
3970c18ec02fSPetter Reinholdtsen 	}
3971c18ec02fSPetter Reinholdtsen 
3972c18ec02fSPetter Reinholdtsen 	fp = ipmi_open_file_read(ifile);
3973c18ec02fSPetter Reinholdtsen 	if (fp == NULL) {
3974c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Unable to open SDR cache %s for reading",
3975c18ec02fSPetter Reinholdtsen 			ifile);
3976c18ec02fSPetter Reinholdtsen 		return -1;
3977c18ec02fSPetter Reinholdtsen 	}
3978c18ec02fSPetter Reinholdtsen 
3979c18ec02fSPetter Reinholdtsen 	while (feof(fp) == 0) {
3980*55b1a418SZdenek Styblik 		memset(&header, 0, sizeof(header));
3981c18ec02fSPetter Reinholdtsen 		bc = fread(&header, 1, 5, fp);
3982c18ec02fSPetter Reinholdtsen 		if (bc <= 0)
3983c18ec02fSPetter Reinholdtsen 			break;
3984c18ec02fSPetter Reinholdtsen 
3985c18ec02fSPetter Reinholdtsen 		if (bc != 5) {
3986c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "header read %d bytes, expected 5",
3987c18ec02fSPetter Reinholdtsen 				bc);
3988c18ec02fSPetter Reinholdtsen 			ret = -1;
3989c18ec02fSPetter Reinholdtsen 			break;
3990c18ec02fSPetter Reinholdtsen 		}
3991c18ec02fSPetter Reinholdtsen 
3992c18ec02fSPetter Reinholdtsen 		if (header.length == 0)
3993c18ec02fSPetter Reinholdtsen 			continue;
3994c18ec02fSPetter Reinholdtsen 
3995c18ec02fSPetter Reinholdtsen 		if (header.version != 0x51 &&
3996c18ec02fSPetter Reinholdtsen 		    header.version != 0x01 &&
3997c18ec02fSPetter Reinholdtsen 		    header.version != 0x02) {
3998c18ec02fSPetter Reinholdtsen 			lprintf(LOG_WARN, "invalid sdr header version %02x",
3999c18ec02fSPetter Reinholdtsen 				header.version);
4000c18ec02fSPetter Reinholdtsen 			ret = -1;
4001c18ec02fSPetter Reinholdtsen 			break;
4002c18ec02fSPetter Reinholdtsen 		}
4003c18ec02fSPetter Reinholdtsen 
4004c18ec02fSPetter Reinholdtsen 		sdrr = malloc(sizeof (struct sdr_record_list));
4005c18ec02fSPetter Reinholdtsen 		if (sdrr == NULL) {
4006c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "ipmitool: malloc failure");
4007c18ec02fSPetter Reinholdtsen 			ret = -1;
4008c18ec02fSPetter Reinholdtsen 			break;
4009c18ec02fSPetter Reinholdtsen 		}
4010c18ec02fSPetter Reinholdtsen 		memset(sdrr, 0, sizeof (struct sdr_record_list));
4011c18ec02fSPetter Reinholdtsen 
4012c18ec02fSPetter Reinholdtsen 		sdrr->id = header.id;
4013c18ec02fSPetter Reinholdtsen 		sdrr->type = header.type;
4014c18ec02fSPetter Reinholdtsen 
4015c18ec02fSPetter Reinholdtsen 		rec = malloc(header.length + 1);
4016c18ec02fSPetter Reinholdtsen 		if (rec == NULL) {
4017c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "ipmitool: malloc failure");
4018c18ec02fSPetter Reinholdtsen 			ret = -1;
4019c18ec02fSPetter Reinholdtsen 			if (sdrr != NULL) {
4020c18ec02fSPetter Reinholdtsen 				free(sdrr);
4021c18ec02fSPetter Reinholdtsen 				sdrr = NULL;
4022c18ec02fSPetter Reinholdtsen 			}
4023c18ec02fSPetter Reinholdtsen 			break;
4024c18ec02fSPetter Reinholdtsen 		}
4025c18ec02fSPetter Reinholdtsen 		memset(rec, 0, header.length + 1);
4026c18ec02fSPetter Reinholdtsen 
4027c18ec02fSPetter Reinholdtsen 		bc = fread(rec, 1, header.length, fp);
4028c18ec02fSPetter Reinholdtsen 		if (bc != header.length) {
4029c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR,
4030c18ec02fSPetter Reinholdtsen 				"record %04x read %d bytes, expected %d",
4031c18ec02fSPetter Reinholdtsen 				header.id, bc, header.length);
4032c18ec02fSPetter Reinholdtsen 			ret = -1;
4033c18ec02fSPetter Reinholdtsen 			if (sdrr != NULL) {
4034c18ec02fSPetter Reinholdtsen 				free(sdrr);
4035c18ec02fSPetter Reinholdtsen 				sdrr = NULL;
4036c18ec02fSPetter Reinholdtsen 			}
4037c18ec02fSPetter Reinholdtsen 			if (rec != NULL) {
4038c18ec02fSPetter Reinholdtsen 				free(rec);
4039c18ec02fSPetter Reinholdtsen 				rec = NULL;
4040c18ec02fSPetter Reinholdtsen 			}
4041c18ec02fSPetter Reinholdtsen 			break;
4042c18ec02fSPetter Reinholdtsen 		}
4043c18ec02fSPetter Reinholdtsen 
4044c18ec02fSPetter Reinholdtsen 		switch (header.type) {
4045c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FULL_SENSOR:
4046c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_COMPACT_SENSOR:
4047c18ec02fSPetter Reinholdtsen 			sdrr->record.common =
4048c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_common_sensor *) rec;
4049c18ec02fSPetter Reinholdtsen 			break;
4050c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
4051c18ec02fSPetter Reinholdtsen 			sdrr->record.eventonly =
4052c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_eventonly_sensor *) rec;
4053c18ec02fSPetter Reinholdtsen 			break;
4054c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR:
4055c18ec02fSPetter Reinholdtsen 			sdrr->record.genloc =
4056c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_generic_locator *) rec;
4057c18ec02fSPetter Reinholdtsen 			break;
4058c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
4059c18ec02fSPetter Reinholdtsen 			sdrr->record.fruloc =
4060c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_fru_locator *) rec;
4061c18ec02fSPetter Reinholdtsen 			break;
4062c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
4063c18ec02fSPetter Reinholdtsen 			sdrr->record.mcloc =
4064c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_mc_locator *) rec;
4065c18ec02fSPetter Reinholdtsen 			break;
4066c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_ENTITY_ASSOC:
4067c18ec02fSPetter Reinholdtsen 			sdrr->record.entassoc =
4068c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_entity_assoc *) rec;
4069c18ec02fSPetter Reinholdtsen 			break;
4070c18ec02fSPetter Reinholdtsen 		default:
4071c18ec02fSPetter Reinholdtsen 			free(rec);
4072c18ec02fSPetter Reinholdtsen 			rec = NULL;
4073c18ec02fSPetter Reinholdtsen 			if (sdrr != NULL) {
4074c18ec02fSPetter Reinholdtsen 				free(sdrr);
4075c18ec02fSPetter Reinholdtsen 				sdrr = NULL;
4076c18ec02fSPetter Reinholdtsen 			}
4077c18ec02fSPetter Reinholdtsen 			continue;
4078c18ec02fSPetter Reinholdtsen 		}
4079c18ec02fSPetter Reinholdtsen 
4080c18ec02fSPetter Reinholdtsen 		/* add to global record liset */
4081c18ec02fSPetter Reinholdtsen 		if (sdr_list_head == NULL)
4082c18ec02fSPetter Reinholdtsen 			sdr_list_head = sdrr;
4083c18ec02fSPetter Reinholdtsen 		else
4084c18ec02fSPetter Reinholdtsen 			sdr_list_tail->next = sdrr;
4085c18ec02fSPetter Reinholdtsen 
4086c18ec02fSPetter Reinholdtsen 		sdr_list_tail = sdrr;
4087c18ec02fSPetter Reinholdtsen 
4088c18ec02fSPetter Reinholdtsen 		count++;
4089c18ec02fSPetter Reinholdtsen 
4090c18ec02fSPetter Reinholdtsen 		lprintf(LOG_DEBUG, "Read record %04x from file into cache",
4091c18ec02fSPetter Reinholdtsen 			sdrr->id);
4092c18ec02fSPetter Reinholdtsen 	}
4093c18ec02fSPetter Reinholdtsen 
4094c18ec02fSPetter Reinholdtsen 	if (sdr_list_itr == NULL) {
4095c18ec02fSPetter Reinholdtsen 		sdr_list_itr = malloc(sizeof (struct ipmi_sdr_iterator));
4096c18ec02fSPetter Reinholdtsen 		if (sdr_list_itr != NULL) {
4097c18ec02fSPetter Reinholdtsen 			sdr_list_itr->reservation = 0;
4098c18ec02fSPetter Reinholdtsen 			sdr_list_itr->total = count;
4099c18ec02fSPetter Reinholdtsen 			sdr_list_itr->next = 0xffff;
4100c18ec02fSPetter Reinholdtsen 		}
4101c18ec02fSPetter Reinholdtsen 	}
4102c18ec02fSPetter Reinholdtsen 
4103c18ec02fSPetter Reinholdtsen 	fclose(fp);
4104c18ec02fSPetter Reinholdtsen 	return ret;
4105c18ec02fSPetter Reinholdtsen }
4106c18ec02fSPetter Reinholdtsen 
4107c18ec02fSPetter Reinholdtsen /* ipmi_sdr_list_cache  -  generate SDR cache for fast lookup
4108c18ec02fSPetter Reinholdtsen  *
4109c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
4110c18ec02fSPetter Reinholdtsen  *
4111c18ec02fSPetter Reinholdtsen  * returns pointer to SDR list
4112c18ec02fSPetter Reinholdtsen  * returns NULL on error
4113c18ec02fSPetter Reinholdtsen  */
4114c18ec02fSPetter Reinholdtsen int
ipmi_sdr_list_cache(struct ipmi_intf * intf)4115c18ec02fSPetter Reinholdtsen ipmi_sdr_list_cache(struct ipmi_intf *intf)
4116c18ec02fSPetter Reinholdtsen {
4117c18ec02fSPetter Reinholdtsen 	struct sdr_get_rs *header;
4118c18ec02fSPetter Reinholdtsen 
4119c18ec02fSPetter Reinholdtsen 	if (sdr_list_itr == NULL) {
4120c18ec02fSPetter Reinholdtsen 		sdr_list_itr = ipmi_sdr_start(intf, 0);
4121c18ec02fSPetter Reinholdtsen 		if (sdr_list_itr == NULL) {
4122c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Unable to open SDR for reading");
4123c18ec02fSPetter Reinholdtsen 			return -1;
4124c18ec02fSPetter Reinholdtsen 		}
4125c18ec02fSPetter Reinholdtsen 	}
4126c18ec02fSPetter Reinholdtsen 
4127c18ec02fSPetter Reinholdtsen 	while ((header = ipmi_sdr_get_next_header(intf, sdr_list_itr)) != NULL) {
4128c18ec02fSPetter Reinholdtsen 		uint8_t *rec;
4129c18ec02fSPetter Reinholdtsen 		struct sdr_record_list *sdrr;
4130c18ec02fSPetter Reinholdtsen 
4131c18ec02fSPetter Reinholdtsen 		sdrr = malloc(sizeof (struct sdr_record_list));
4132c18ec02fSPetter Reinholdtsen 		if (sdrr == NULL) {
4133c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "ipmitool: malloc failure");
4134c18ec02fSPetter Reinholdtsen 			break;
4135c18ec02fSPetter Reinholdtsen 		}
4136c18ec02fSPetter Reinholdtsen 		memset(sdrr, 0, sizeof (struct sdr_record_list));
4137c18ec02fSPetter Reinholdtsen 		sdrr->id = header->id;
4138c18ec02fSPetter Reinholdtsen 		sdrr->type = header->type;
4139c18ec02fSPetter Reinholdtsen 
4140c18ec02fSPetter Reinholdtsen 		rec = ipmi_sdr_get_record(intf, header, sdr_list_itr);
4141c18ec02fSPetter Reinholdtsen 		if (rec == NULL) {
4142c18ec02fSPetter Reinholdtsen 			if (sdrr != NULL) {
4143c18ec02fSPetter Reinholdtsen 				free(sdrr);
4144c18ec02fSPetter Reinholdtsen 				sdrr = NULL;
4145c18ec02fSPetter Reinholdtsen 			}
4146c18ec02fSPetter Reinholdtsen 			continue;
4147c18ec02fSPetter Reinholdtsen 		}
4148c18ec02fSPetter Reinholdtsen 
4149c18ec02fSPetter Reinholdtsen 		switch (header->type) {
4150c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FULL_SENSOR:
4151c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_COMPACT_SENSOR:
4152c18ec02fSPetter Reinholdtsen 			sdrr->record.common =
4153c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_common_sensor *) rec;
4154c18ec02fSPetter Reinholdtsen 			break;
4155c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
4156c18ec02fSPetter Reinholdtsen 			sdrr->record.eventonly =
4157c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_eventonly_sensor *) rec;
4158c18ec02fSPetter Reinholdtsen 			break;
4159c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR:
4160c18ec02fSPetter Reinholdtsen 			sdrr->record.genloc =
4161c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_generic_locator *) rec;
4162c18ec02fSPetter Reinholdtsen 			break;
4163c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
4164c18ec02fSPetter Reinholdtsen 			sdrr->record.fruloc =
4165c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_fru_locator *) rec;
4166c18ec02fSPetter Reinholdtsen 			break;
4167c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
4168c18ec02fSPetter Reinholdtsen 			sdrr->record.mcloc =
4169c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_mc_locator *) rec;
4170c18ec02fSPetter Reinholdtsen 			break;
4171c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_ENTITY_ASSOC:
4172c18ec02fSPetter Reinholdtsen 			sdrr->record.entassoc =
4173c18ec02fSPetter Reinholdtsen 			    (struct sdr_record_entity_assoc *) rec;
4174c18ec02fSPetter Reinholdtsen 			break;
4175c18ec02fSPetter Reinholdtsen 		default:
4176c18ec02fSPetter Reinholdtsen 			free(rec);
4177c18ec02fSPetter Reinholdtsen 			rec = NULL;
4178c18ec02fSPetter Reinholdtsen 			if (sdrr != NULL) {
4179c18ec02fSPetter Reinholdtsen 				free(sdrr);
4180c18ec02fSPetter Reinholdtsen 				sdrr = NULL;
4181c18ec02fSPetter Reinholdtsen 			}
4182c18ec02fSPetter Reinholdtsen 			continue;
4183c18ec02fSPetter Reinholdtsen 		}
4184c18ec02fSPetter Reinholdtsen 
4185c18ec02fSPetter Reinholdtsen 		/* add to global record liset */
4186c18ec02fSPetter Reinholdtsen 		if (sdr_list_head == NULL)
4187c18ec02fSPetter Reinholdtsen 			sdr_list_head = sdrr;
4188c18ec02fSPetter Reinholdtsen 		else
4189c18ec02fSPetter Reinholdtsen 			sdr_list_tail->next = sdrr;
4190c18ec02fSPetter Reinholdtsen 
4191c18ec02fSPetter Reinholdtsen 		sdr_list_tail = sdrr;
4192c18ec02fSPetter Reinholdtsen 	}
4193c18ec02fSPetter Reinholdtsen 
4194c18ec02fSPetter Reinholdtsen 	return 0;
4195c18ec02fSPetter Reinholdtsen }
4196c18ec02fSPetter Reinholdtsen 
4197c18ec02fSPetter Reinholdtsen /*
4198c18ec02fSPetter Reinholdtsen  * ipmi_sdr_get_info
4199c18ec02fSPetter Reinholdtsen  *
4200c18ec02fSPetter Reinholdtsen  * Execute the GET SDR REPOSITORY INFO command, and populate the sdr_info
4201c18ec02fSPetter Reinholdtsen  * structure.
4202c18ec02fSPetter Reinholdtsen  * See section 33.9 of the IPMI v2 specification for details
4203c18ec02fSPetter Reinholdtsen  *
4204c18ec02fSPetter Reinholdtsen  * returns 0 on success
4205c18ec02fSPetter Reinholdtsen  *         -1 on transport error
4206c18ec02fSPetter Reinholdtsen  *         > 0 for other errors
4207c18ec02fSPetter Reinholdtsen  */
4208c18ec02fSPetter Reinholdtsen int
ipmi_sdr_get_info(struct ipmi_intf * intf,struct get_sdr_repository_info_rsp * sdr_repository_info)4209c18ec02fSPetter Reinholdtsen ipmi_sdr_get_info(struct ipmi_intf *intf,
4210c18ec02fSPetter Reinholdtsen 		  struct get_sdr_repository_info_rsp *sdr_repository_info)
4211c18ec02fSPetter Reinholdtsen {
4212c18ec02fSPetter Reinholdtsen 	struct ipmi_rs *rsp;
4213c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
4214c18ec02fSPetter Reinholdtsen 
4215c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof (req));
4216c18ec02fSPetter Reinholdtsen 
4217c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_STORAGE;	// 0x0A
4218c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_GET_SDR_REPOSITORY_INFO;	// 0x20
4219c18ec02fSPetter Reinholdtsen 	req.msg.data = 0;
4220c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 0;
4221c18ec02fSPetter Reinholdtsen 
4222c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
4223c18ec02fSPetter Reinholdtsen 
4224c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
4225c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get SDR Repository Info command failed");
4226c18ec02fSPetter Reinholdtsen 		return -1;
4227c18ec02fSPetter Reinholdtsen 	}
4228c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
4229c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get SDR Repository Info command failed: %s",
4230c18ec02fSPetter Reinholdtsen 			val2str(rsp->ccode, completion_code_vals));
4231c18ec02fSPetter Reinholdtsen 		return -1;
4232c18ec02fSPetter Reinholdtsen 	}
4233c18ec02fSPetter Reinholdtsen 
4234c18ec02fSPetter Reinholdtsen 	memcpy(sdr_repository_info,
4235c18ec02fSPetter Reinholdtsen 	       rsp->data,
4236c18ec02fSPetter Reinholdtsen 	       __min(sizeof (struct get_sdr_repository_info_rsp),
4237c18ec02fSPetter Reinholdtsen 		     rsp->data_len));
4238c18ec02fSPetter Reinholdtsen 
4239c18ec02fSPetter Reinholdtsen 	return 0;
4240c18ec02fSPetter Reinholdtsen }
4241c18ec02fSPetter Reinholdtsen 
4242c18ec02fSPetter Reinholdtsen /* ipmi_sdr_timestamp  -  return string from timestamp value
4243c18ec02fSPetter Reinholdtsen  *
4244c18ec02fSPetter Reinholdtsen  * @stamp:	32bit timestamp
4245c18ec02fSPetter Reinholdtsen  *
4246c18ec02fSPetter Reinholdtsen  * returns pointer to static buffer
4247c18ec02fSPetter Reinholdtsen  */
4248c18ec02fSPetter Reinholdtsen static char *
ipmi_sdr_timestamp(uint32_t stamp)4249c18ec02fSPetter Reinholdtsen ipmi_sdr_timestamp(uint32_t stamp)
4250c18ec02fSPetter Reinholdtsen {
4251c18ec02fSPetter Reinholdtsen 	static char tbuf[40];
4252c18ec02fSPetter Reinholdtsen 	time_t s = (time_t) stamp;
4253c18ec02fSPetter Reinholdtsen 	memset(tbuf, 0, 40);
4254c18ec02fSPetter Reinholdtsen 	if (stamp)
4255c18ec02fSPetter Reinholdtsen 		strftime(tbuf, sizeof (tbuf), "%m/%d/%Y %H:%M:%S",
4256c18ec02fSPetter Reinholdtsen 			 gmtime(&s));
4257c18ec02fSPetter Reinholdtsen 	return tbuf;
4258c18ec02fSPetter Reinholdtsen }
4259c18ec02fSPetter Reinholdtsen 
4260c18ec02fSPetter Reinholdtsen /*
4261c18ec02fSPetter Reinholdtsen  * ipmi_sdr_print_info
4262c18ec02fSPetter Reinholdtsen  *
4263c18ec02fSPetter Reinholdtsen  * Display the return data of the GET SDR REPOSITORY INFO command
4264c18ec02fSPetter Reinholdtsen  * See section 33.9 of the IPMI v2 specification for details
4265c18ec02fSPetter Reinholdtsen  *
4266c18ec02fSPetter Reinholdtsen  * returns 0 on success
4267c18ec02fSPetter Reinholdtsen  *         -1 on error
4268c18ec02fSPetter Reinholdtsen  */
4269c18ec02fSPetter Reinholdtsen int
ipmi_sdr_print_info(struct ipmi_intf * intf)4270c18ec02fSPetter Reinholdtsen ipmi_sdr_print_info(struct ipmi_intf *intf)
4271c18ec02fSPetter Reinholdtsen {
4272c18ec02fSPetter Reinholdtsen 	uint32_t timestamp;
4273c18ec02fSPetter Reinholdtsen 	uint16_t free_space;
4274c18ec02fSPetter Reinholdtsen 
4275c18ec02fSPetter Reinholdtsen 	struct get_sdr_repository_info_rsp sdr_repository_info;
4276c18ec02fSPetter Reinholdtsen 
4277c18ec02fSPetter Reinholdtsen 	if (ipmi_sdr_get_info(intf, &sdr_repository_info) != 0)
4278c18ec02fSPetter Reinholdtsen 		return -1;
4279c18ec02fSPetter Reinholdtsen 
4280c18ec02fSPetter Reinholdtsen 	printf("SDR Version                         : 0x%x\n",
4281c18ec02fSPetter Reinholdtsen 	       sdr_repository_info.sdr_version);
4282c18ec02fSPetter Reinholdtsen 	printf("Record Count                        : %d\n",
4283c18ec02fSPetter Reinholdtsen 	       (sdr_repository_info.record_count_msb << 8) |
4284c18ec02fSPetter Reinholdtsen 	       sdr_repository_info.record_count_lsb);
4285c18ec02fSPetter Reinholdtsen 
4286c18ec02fSPetter Reinholdtsen 	free_space =
4287c18ec02fSPetter Reinholdtsen 	    (sdr_repository_info.free_space[1] << 8) |
4288c18ec02fSPetter Reinholdtsen 	    sdr_repository_info.free_space[0];
4289c18ec02fSPetter Reinholdtsen 
4290c18ec02fSPetter Reinholdtsen 	printf("Free Space                          : ");
4291c18ec02fSPetter Reinholdtsen 	switch (free_space) {
4292c18ec02fSPetter Reinholdtsen 	case 0x0000:
4293c18ec02fSPetter Reinholdtsen 		printf("none (full)\n");
4294c18ec02fSPetter Reinholdtsen 		break;
4295c18ec02fSPetter Reinholdtsen 	case 0xFFFF:
4296c18ec02fSPetter Reinholdtsen 		printf("unspecified\n");
4297c18ec02fSPetter Reinholdtsen 		break;
4298c18ec02fSPetter Reinholdtsen 	case 0xFFFE:
4299c18ec02fSPetter Reinholdtsen 		printf("> 64Kb - 2 bytes\n");
4300c18ec02fSPetter Reinholdtsen 		break;
4301c18ec02fSPetter Reinholdtsen 	default:
4302c18ec02fSPetter Reinholdtsen 		printf("%d bytes\n", free_space);
4303c18ec02fSPetter Reinholdtsen 		break;
4304c18ec02fSPetter Reinholdtsen 	}
4305c18ec02fSPetter Reinholdtsen 
4306c18ec02fSPetter Reinholdtsen 	timestamp =
4307c18ec02fSPetter Reinholdtsen 	    (sdr_repository_info.most_recent_addition_timestamp[3] << 24) |
4308c18ec02fSPetter Reinholdtsen 	    (sdr_repository_info.most_recent_addition_timestamp[2] << 16) |
4309c18ec02fSPetter Reinholdtsen 	    (sdr_repository_info.most_recent_addition_timestamp[1] << 8) |
4310c18ec02fSPetter Reinholdtsen 	    sdr_repository_info.most_recent_addition_timestamp[0];
4311c18ec02fSPetter Reinholdtsen 	printf("Most recent Addition                : %s\n",
4312c18ec02fSPetter Reinholdtsen 	       ipmi_sdr_timestamp(timestamp));
4313c18ec02fSPetter Reinholdtsen 
4314c18ec02fSPetter Reinholdtsen 	timestamp =
4315c18ec02fSPetter Reinholdtsen 	    (sdr_repository_info.most_recent_erase_timestamp[3] << 24) |
4316c18ec02fSPetter Reinholdtsen 	    (sdr_repository_info.most_recent_erase_timestamp[2] << 16) |
4317c18ec02fSPetter Reinholdtsen 	    (sdr_repository_info.most_recent_erase_timestamp[1] << 8) |
4318c18ec02fSPetter Reinholdtsen 	    sdr_repository_info.most_recent_erase_timestamp[0];
4319c18ec02fSPetter Reinholdtsen 	printf("Most recent Erase                   : %s\n",
4320c18ec02fSPetter Reinholdtsen 	       ipmi_sdr_timestamp(timestamp));
4321c18ec02fSPetter Reinholdtsen 
4322c18ec02fSPetter Reinholdtsen 	printf("SDR overflow                        : %s\n",
4323c18ec02fSPetter Reinholdtsen 	       (sdr_repository_info.overflow_flag ? "yes" : "no"));
4324c18ec02fSPetter Reinholdtsen 
4325c18ec02fSPetter Reinholdtsen 	printf("SDR Repository Update Support       : ");
4326c18ec02fSPetter Reinholdtsen 	switch (sdr_repository_info.modal_update_support) {
4327c18ec02fSPetter Reinholdtsen 	case 0:
4328c18ec02fSPetter Reinholdtsen 		printf("unspecified\n");
4329c18ec02fSPetter Reinholdtsen 		break;
4330c18ec02fSPetter Reinholdtsen 	case 1:
4331c18ec02fSPetter Reinholdtsen 		printf("non-modal\n");
4332c18ec02fSPetter Reinholdtsen 		break;
4333c18ec02fSPetter Reinholdtsen 	case 2:
4334c18ec02fSPetter Reinholdtsen 		printf("modal\n");
4335c18ec02fSPetter Reinholdtsen 		break;
4336c18ec02fSPetter Reinholdtsen 	case 3:
4337c18ec02fSPetter Reinholdtsen 		printf("modal and non-modal\n");
4338c18ec02fSPetter Reinholdtsen 		break;
4339c18ec02fSPetter Reinholdtsen 	default:
4340c18ec02fSPetter Reinholdtsen 		printf("error in response\n");
4341c18ec02fSPetter Reinholdtsen 		break;
4342c18ec02fSPetter Reinholdtsen 	}
4343c18ec02fSPetter Reinholdtsen 
4344c18ec02fSPetter Reinholdtsen 	printf("Delete SDR supported                : %s\n",
4345c18ec02fSPetter Reinholdtsen 	       sdr_repository_info.delete_sdr_supported ? "yes" : "no");
4346c18ec02fSPetter Reinholdtsen 	printf("Partial Add SDR supported           : %s\n",
4347c18ec02fSPetter Reinholdtsen 	       sdr_repository_info.partial_add_sdr_supported ? "yes" : "no");
4348c18ec02fSPetter Reinholdtsen 	printf("Reserve SDR repository supported    : %s\n",
4349c18ec02fSPetter Reinholdtsen 	       sdr_repository_info.
4350c18ec02fSPetter Reinholdtsen 	       reserve_sdr_repository_supported ? "yes" : "no");
4351c18ec02fSPetter Reinholdtsen 	printf("SDR Repository Alloc info supported : %s\n",
4352c18ec02fSPetter Reinholdtsen 	       sdr_repository_info.
4353c18ec02fSPetter Reinholdtsen 				 get_sdr_repository_allo_info_supported ? "yes" : "no");
4354c18ec02fSPetter Reinholdtsen 
4355c18ec02fSPetter Reinholdtsen 	return 0;
4356c18ec02fSPetter Reinholdtsen }
4357c18ec02fSPetter Reinholdtsen 
4358c18ec02fSPetter Reinholdtsen /* ipmi_sdr_dump_bin  -  Write raw SDR to binary file
4359c18ec02fSPetter Reinholdtsen  *
4360c18ec02fSPetter Reinholdtsen  * used for post-processing by other utilities
4361c18ec02fSPetter Reinholdtsen  *
4362c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
4363c18ec02fSPetter Reinholdtsen  * @ofile:	output filename
4364c18ec02fSPetter Reinholdtsen  *
4365c18ec02fSPetter Reinholdtsen  * returns 0 on success
4366c18ec02fSPetter Reinholdtsen  * returns -1 on error
4367c18ec02fSPetter Reinholdtsen  */
4368c18ec02fSPetter Reinholdtsen static int
ipmi_sdr_dump_bin(struct ipmi_intf * intf,const char * ofile)4369c18ec02fSPetter Reinholdtsen ipmi_sdr_dump_bin(struct ipmi_intf *intf, const char *ofile)
4370c18ec02fSPetter Reinholdtsen {
4371c18ec02fSPetter Reinholdtsen 	struct sdr_get_rs *header;
4372c18ec02fSPetter Reinholdtsen 	struct ipmi_sdr_iterator *itr;
4373c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *sdrr;
4374c18ec02fSPetter Reinholdtsen 	FILE *fp;
4375c18ec02fSPetter Reinholdtsen 	int rc = 0;
4376c18ec02fSPetter Reinholdtsen 
4377c18ec02fSPetter Reinholdtsen 	/* open connection to SDR */
4378c18ec02fSPetter Reinholdtsen 	itr = ipmi_sdr_start(intf, 0);
4379c18ec02fSPetter Reinholdtsen 	if (itr == NULL) {
4380c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Unable to open SDR for reading");
4381c18ec02fSPetter Reinholdtsen 		return -1;
4382c18ec02fSPetter Reinholdtsen 	}
4383c18ec02fSPetter Reinholdtsen 
4384c18ec02fSPetter Reinholdtsen 	printf("Dumping Sensor Data Repository to '%s'\n", ofile);
4385c18ec02fSPetter Reinholdtsen 
4386c18ec02fSPetter Reinholdtsen 	/* generate list of records */
4387c18ec02fSPetter Reinholdtsen 	while ((header = ipmi_sdr_get_next_header(intf, itr)) != NULL) {
4388c18ec02fSPetter Reinholdtsen 		sdrr = malloc(sizeof(struct sdr_record_list));
4389c18ec02fSPetter Reinholdtsen 		if (sdrr == NULL) {
4390c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "ipmitool: malloc failure");
4391c18ec02fSPetter Reinholdtsen 			return -1;
4392c18ec02fSPetter Reinholdtsen 		}
4393c18ec02fSPetter Reinholdtsen 		memset(sdrr, 0, sizeof(struct sdr_record_list));
4394c18ec02fSPetter Reinholdtsen 
4395c18ec02fSPetter Reinholdtsen 		lprintf(LOG_INFO, "Record ID %04x (%d bytes)",
4396c18ec02fSPetter Reinholdtsen 			header->id, header->length);
4397c18ec02fSPetter Reinholdtsen 
4398c18ec02fSPetter Reinholdtsen 		sdrr->id = header->id;
4399c18ec02fSPetter Reinholdtsen 		sdrr->version = header->version;
4400c18ec02fSPetter Reinholdtsen 		sdrr->type = header->type;
4401c18ec02fSPetter Reinholdtsen 		sdrr->length = header->length;
4402c18ec02fSPetter Reinholdtsen 		sdrr->raw = ipmi_sdr_get_record(intf, header, itr);
4403c18ec02fSPetter Reinholdtsen 
4404c18ec02fSPetter Reinholdtsen 		if (sdrr->raw == NULL) {
4405c18ec02fSPetter Reinholdtsen 		    lprintf(LOG_ERR, "ipmitool: cannot obtain SDR record %04x", header->id);
4406c18ec02fSPetter Reinholdtsen 				if (sdrr != NULL) {
4407c18ec02fSPetter Reinholdtsen 					free(sdrr);
4408c18ec02fSPetter Reinholdtsen 					sdrr = NULL;
4409c18ec02fSPetter Reinholdtsen 				}
4410c18ec02fSPetter Reinholdtsen 		    return -1;
4411c18ec02fSPetter Reinholdtsen 		}
4412c18ec02fSPetter Reinholdtsen 
4413c18ec02fSPetter Reinholdtsen 		if (sdr_list_head == NULL)
4414c18ec02fSPetter Reinholdtsen 			sdr_list_head = sdrr;
4415c18ec02fSPetter Reinholdtsen 		else
4416c18ec02fSPetter Reinholdtsen 			sdr_list_tail->next = sdrr;
4417c18ec02fSPetter Reinholdtsen 
4418c18ec02fSPetter Reinholdtsen 		sdr_list_tail = sdrr;
4419c18ec02fSPetter Reinholdtsen 	}
4420c18ec02fSPetter Reinholdtsen 
4421c18ec02fSPetter Reinholdtsen 	ipmi_sdr_end(intf, itr);
4422c18ec02fSPetter Reinholdtsen 
4423c18ec02fSPetter Reinholdtsen 	/* now write to file */
4424c18ec02fSPetter Reinholdtsen 	fp = ipmi_open_file_write(ofile);
4425c18ec02fSPetter Reinholdtsen 	if (fp == NULL)
4426c18ec02fSPetter Reinholdtsen 		return -1;
4427c18ec02fSPetter Reinholdtsen 
4428c18ec02fSPetter Reinholdtsen 	for (sdrr = sdr_list_head; sdrr != NULL; sdrr = sdrr->next) {
4429c18ec02fSPetter Reinholdtsen 		int r;
4430c18ec02fSPetter Reinholdtsen 		uint8_t h[5];
4431c18ec02fSPetter Reinholdtsen 
4432c18ec02fSPetter Reinholdtsen 		/* build and write sdr header */
4433c18ec02fSPetter Reinholdtsen 		h[0] = sdrr->id & 0xff;   // LS Byte first
4434c18ec02fSPetter Reinholdtsen 		h[1] = (sdrr->id >> 8) & 0xff;
4435c18ec02fSPetter Reinholdtsen 		h[2] = sdrr->version;
4436c18ec02fSPetter Reinholdtsen 		h[3] = sdrr->type;
4437c18ec02fSPetter Reinholdtsen 		h[4] = sdrr->length;
4438c18ec02fSPetter Reinholdtsen 
4439c18ec02fSPetter Reinholdtsen 		r = fwrite(h, 1, 5, fp);
4440c18ec02fSPetter Reinholdtsen 		if (r != 5) {
4441c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Error writing header "
4442c18ec02fSPetter Reinholdtsen 				"to output file %s", ofile);
4443c18ec02fSPetter Reinholdtsen 			rc = -1;
4444c18ec02fSPetter Reinholdtsen 			break;
4445c18ec02fSPetter Reinholdtsen 		}
4446c18ec02fSPetter Reinholdtsen 
4447c18ec02fSPetter Reinholdtsen 		/* write sdr entry */
4448c18ec02fSPetter Reinholdtsen 		if (!sdrr->raw) {
4449c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Error: raw data is null (length=%d)",
4450c18ec02fSPetter Reinholdtsen 								sdrr->length);
4451c18ec02fSPetter Reinholdtsen 			rc = -1;
4452c18ec02fSPetter Reinholdtsen 			break;
4453c18ec02fSPetter Reinholdtsen 		}
4454c18ec02fSPetter Reinholdtsen 		r = fwrite(sdrr->raw, 1, sdrr->length, fp);
4455c18ec02fSPetter Reinholdtsen 		if (r != sdrr->length) {
4456c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Error writing %d record bytes "
4457c18ec02fSPetter Reinholdtsen 				"to output file %s", sdrr->length, ofile);
4458c18ec02fSPetter Reinholdtsen 			rc = -1;
4459c18ec02fSPetter Reinholdtsen 			break;
4460c18ec02fSPetter Reinholdtsen 		}
4461c18ec02fSPetter Reinholdtsen 	}
4462c18ec02fSPetter Reinholdtsen 	fclose(fp);
4463c18ec02fSPetter Reinholdtsen 
4464c18ec02fSPetter Reinholdtsen 	return rc;
4465c18ec02fSPetter Reinholdtsen }
4466c18ec02fSPetter Reinholdtsen 
4467c18ec02fSPetter Reinholdtsen /* ipmi_sdr_print_type  -  print all sensors of specified type
4468c18ec02fSPetter Reinholdtsen  *
4469c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
4470c18ec02fSPetter Reinholdtsen  * @type:	sensor type
4471c18ec02fSPetter Reinholdtsen  *
4472c18ec02fSPetter Reinholdtsen  * returns 0 on success
4473c18ec02fSPetter Reinholdtsen  * returns -1 on error
4474c18ec02fSPetter Reinholdtsen  */
4475c18ec02fSPetter Reinholdtsen int
ipmi_sdr_print_type(struct ipmi_intf * intf,char * type)4476c18ec02fSPetter Reinholdtsen ipmi_sdr_print_type(struct ipmi_intf *intf, char *type)
4477c18ec02fSPetter Reinholdtsen {
4478c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *list, *entry;
4479c18ec02fSPetter Reinholdtsen 	int rc = 0;
4480c18ec02fSPetter Reinholdtsen 	int x;
4481c18ec02fSPetter Reinholdtsen 	uint8_t sensor_type = 0;
4482c18ec02fSPetter Reinholdtsen 
4483c18ec02fSPetter Reinholdtsen 	if (type == NULL ||
4484c18ec02fSPetter Reinholdtsen 	    strncasecmp(type, "help", 4) == 0 ||
4485c18ec02fSPetter Reinholdtsen 	    strncasecmp(type, "list", 4) == 0) {
4486c18ec02fSPetter Reinholdtsen 		printf("Sensor Types:\n");
4487c18ec02fSPetter Reinholdtsen 		for (x = 1; x < SENSOR_TYPE_MAX; x += 2) {
4488c18ec02fSPetter Reinholdtsen 			printf("\t%-25s (0x%02x)   %-25s (0x%02x)\n",
4489c18ec02fSPetter Reinholdtsen 				sensor_type_desc[x], x,
4490c18ec02fSPetter Reinholdtsen 				sensor_type_desc[x + 1], x + 1);
4491c18ec02fSPetter Reinholdtsen 		}
4492c18ec02fSPetter Reinholdtsen 		return 0;
4493c18ec02fSPetter Reinholdtsen 	}
4494c18ec02fSPetter Reinholdtsen 
4495c18ec02fSPetter Reinholdtsen 	if (strncmp(type, "0x", 2) == 0) {
4496c18ec02fSPetter Reinholdtsen 		/* begins with 0x so let it be entered as raw hex value */
4497c18ec02fSPetter Reinholdtsen 		if (str2uchar(type, &sensor_type) != 0) {
4498c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR,
4499c18ec02fSPetter Reinholdtsen 					"Given type of sensor \"%s\" is either invalid or out of range.",
4500c18ec02fSPetter Reinholdtsen 					type);
4501c18ec02fSPetter Reinholdtsen 			return (-1);
4502c18ec02fSPetter Reinholdtsen 		}
4503c18ec02fSPetter Reinholdtsen 	} else {
4504c18ec02fSPetter Reinholdtsen 		for (x = 1; x < SENSOR_TYPE_MAX; x++) {
4505c18ec02fSPetter Reinholdtsen 			if (strncasecmp(sensor_type_desc[x], type,
4506c18ec02fSPetter Reinholdtsen 					__maxlen(type,
4507c18ec02fSPetter Reinholdtsen 						 sensor_type_desc[x])) == 0) {
4508c18ec02fSPetter Reinholdtsen 				sensor_type = x;
4509c18ec02fSPetter Reinholdtsen 				break;
4510c18ec02fSPetter Reinholdtsen 			}
4511c18ec02fSPetter Reinholdtsen 		}
4512c18ec02fSPetter Reinholdtsen 		if (sensor_type != x) {
4513c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Sensor Type \"%s\" not found.",
4514c18ec02fSPetter Reinholdtsen 				type);
4515c18ec02fSPetter Reinholdtsen 			printf("Sensor Types:\n");
4516c18ec02fSPetter Reinholdtsen 			for (x = 1; x < SENSOR_TYPE_MAX; x += 2) {
4517c18ec02fSPetter Reinholdtsen 				printf("\t%-25s (0x%02x)   %-25s (0x%02x)\n",
4518c18ec02fSPetter Reinholdtsen 					sensor_type_desc[x], x,
4519c18ec02fSPetter Reinholdtsen 					sensor_type_desc[x + 1], x + 1);
4520c18ec02fSPetter Reinholdtsen 			}
4521c18ec02fSPetter Reinholdtsen 			return 0;
4522c18ec02fSPetter Reinholdtsen 		}
4523c18ec02fSPetter Reinholdtsen 	}
4524c18ec02fSPetter Reinholdtsen 
4525c18ec02fSPetter Reinholdtsen 	list = ipmi_sdr_find_sdr_bysensortype(intf, sensor_type);
4526c18ec02fSPetter Reinholdtsen 
4527c18ec02fSPetter Reinholdtsen 	for (entry = list; entry != NULL; entry = entry->next) {
4528c18ec02fSPetter Reinholdtsen 		rc = ipmi_sdr_print_listentry(intf, entry);
4529c18ec02fSPetter Reinholdtsen 	}
4530c18ec02fSPetter Reinholdtsen 
4531c18ec02fSPetter Reinholdtsen 	__sdr_list_empty(list);
4532c18ec02fSPetter Reinholdtsen 
4533c18ec02fSPetter Reinholdtsen 	return rc;
4534c18ec02fSPetter Reinholdtsen }
4535c18ec02fSPetter Reinholdtsen 
4536c18ec02fSPetter Reinholdtsen /* ipmi_sdr_print_entity  -  print entity's for an id/instance
4537c18ec02fSPetter Reinholdtsen  *
4538c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
4539c18ec02fSPetter Reinholdtsen  * @entitystr:	entity id/instance string, i.e. "1.1"
4540c18ec02fSPetter Reinholdtsen  *
4541c18ec02fSPetter Reinholdtsen  * returns 0 on success
4542c18ec02fSPetter Reinholdtsen  * returns -1 on error
4543c18ec02fSPetter Reinholdtsen  */
4544c18ec02fSPetter Reinholdtsen int
ipmi_sdr_print_entity(struct ipmi_intf * intf,char * entitystr)4545c18ec02fSPetter Reinholdtsen ipmi_sdr_print_entity(struct ipmi_intf *intf, char *entitystr)
4546c18ec02fSPetter Reinholdtsen {
4547c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *list, *entry;
4548c18ec02fSPetter Reinholdtsen 	struct entity_id entity;
4549c18ec02fSPetter Reinholdtsen 	unsigned id = 0;
4550c18ec02fSPetter Reinholdtsen 	unsigned instance = 0;
4551c18ec02fSPetter Reinholdtsen 	int rc = 0;
4552c18ec02fSPetter Reinholdtsen 
4553c18ec02fSPetter Reinholdtsen 	if (entitystr == NULL ||
4554c18ec02fSPetter Reinholdtsen 	    strncasecmp(entitystr, "help", 4) == 0 ||
4555c18ec02fSPetter Reinholdtsen 	    strncasecmp(entitystr, "list", 4) == 0) {
4556c18ec02fSPetter Reinholdtsen 		print_valstr_2col(entity_id_vals, "Entity IDs", -1);
4557c18ec02fSPetter Reinholdtsen 		return 0;
4558c18ec02fSPetter Reinholdtsen 	}
4559c18ec02fSPetter Reinholdtsen 
4560c18ec02fSPetter Reinholdtsen 	if (sscanf(entitystr, "%u.%u", &id, &instance) != 2) {
4561c18ec02fSPetter Reinholdtsen 		/* perhaps no instance was passed
4562c18ec02fSPetter Reinholdtsen 		 * in which case we want all instances for this entity
4563c18ec02fSPetter Reinholdtsen 		 * so set entity.instance = 0x7f to indicate this
4564c18ec02fSPetter Reinholdtsen 		 */
4565c18ec02fSPetter Reinholdtsen 		if (sscanf(entitystr, "%u", &id) != 1) {
4566c18ec02fSPetter Reinholdtsen 			int i, j=0;
4567c18ec02fSPetter Reinholdtsen 
4568c18ec02fSPetter Reinholdtsen 			/* now try string input */
4569c18ec02fSPetter Reinholdtsen 			for (i = 0; entity_id_vals[i].str != NULL; i++) {
4570c18ec02fSPetter Reinholdtsen 				if (strncasecmp(entitystr, entity_id_vals[i].str,
4571c18ec02fSPetter Reinholdtsen 						__maxlen(entitystr, entity_id_vals[i].str)) == 0) {
4572c18ec02fSPetter Reinholdtsen 					entity.id = entity_id_vals[i].val;
4573c18ec02fSPetter Reinholdtsen 					entity.instance = 0x7f;
4574c18ec02fSPetter Reinholdtsen 					j=1;
4575c18ec02fSPetter Reinholdtsen 				}
4576c18ec02fSPetter Reinholdtsen 			}
4577c18ec02fSPetter Reinholdtsen 			if (j == 0) {
4578c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, "Invalid entity: %s", entitystr);
4579c18ec02fSPetter Reinholdtsen 				return -1;
4580c18ec02fSPetter Reinholdtsen 			}
4581c18ec02fSPetter Reinholdtsen 		} else {
4582c18ec02fSPetter Reinholdtsen 			entity.id = id;
4583c18ec02fSPetter Reinholdtsen 			entity.instance = 0x7f;
4584c18ec02fSPetter Reinholdtsen 		}
4585c18ec02fSPetter Reinholdtsen 	} else {
4586c18ec02fSPetter Reinholdtsen 		entity.id = id;
4587c18ec02fSPetter Reinholdtsen 		entity.instance = instance;
4588c18ec02fSPetter Reinholdtsen 	}
4589c18ec02fSPetter Reinholdtsen 
4590c18ec02fSPetter Reinholdtsen 	list = ipmi_sdr_find_sdr_byentity(intf, &entity);
4591c18ec02fSPetter Reinholdtsen 
4592c18ec02fSPetter Reinholdtsen 	for (entry = list; entry != NULL; entry = entry->next) {
4593c18ec02fSPetter Reinholdtsen 		rc = ipmi_sdr_print_listentry(intf, entry);
4594c18ec02fSPetter Reinholdtsen 	}
4595c18ec02fSPetter Reinholdtsen 
4596c18ec02fSPetter Reinholdtsen 	__sdr_list_empty(list);
4597c18ec02fSPetter Reinholdtsen 
4598c18ec02fSPetter Reinholdtsen 	return rc;
4599c18ec02fSPetter Reinholdtsen }
4600c18ec02fSPetter Reinholdtsen 
4601c18ec02fSPetter Reinholdtsen /* ipmi_sdr_print_entry_byid  -  print sdr entries identified by sensor id
4602c18ec02fSPetter Reinholdtsen  *
4603c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
4604c18ec02fSPetter Reinholdtsen  * @argc:	number of entries to print
4605c18ec02fSPetter Reinholdtsen  * @argv:	list of sensor ids
4606c18ec02fSPetter Reinholdtsen  *
4607c18ec02fSPetter Reinholdtsen  * returns 0 on success
4608c18ec02fSPetter Reinholdtsen  * returns -1 on error
4609c18ec02fSPetter Reinholdtsen  */
4610c18ec02fSPetter Reinholdtsen static int
ipmi_sdr_print_entry_byid(struct ipmi_intf * intf,int argc,char ** argv)4611c18ec02fSPetter Reinholdtsen ipmi_sdr_print_entry_byid(struct ipmi_intf *intf, int argc, char **argv)
4612c18ec02fSPetter Reinholdtsen {
4613c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *sdr;
4614c18ec02fSPetter Reinholdtsen 	int rc = 0;
4615c18ec02fSPetter Reinholdtsen 	int v, i;
4616c18ec02fSPetter Reinholdtsen 
4617c18ec02fSPetter Reinholdtsen 	if (argc < 1) {
4618c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "No Sensor ID supplied");
4619c18ec02fSPetter Reinholdtsen 		return -1;
4620c18ec02fSPetter Reinholdtsen 	}
4621c18ec02fSPetter Reinholdtsen 
4622c18ec02fSPetter Reinholdtsen 	v = verbose;
4623c18ec02fSPetter Reinholdtsen 	verbose = 1;
4624c18ec02fSPetter Reinholdtsen 
4625c18ec02fSPetter Reinholdtsen 	for (i = 0; i < argc; i++) {
4626c18ec02fSPetter Reinholdtsen 		sdr = ipmi_sdr_find_sdr_byid(intf, argv[i]);
4627c18ec02fSPetter Reinholdtsen 		if (sdr == NULL) {
4628c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Unable to find sensor id '%s'",
4629c18ec02fSPetter Reinholdtsen 				argv[i]);
4630c18ec02fSPetter Reinholdtsen 		} else {
4631c18ec02fSPetter Reinholdtsen 			if (ipmi_sdr_print_listentry(intf, sdr) < 0)
4632c18ec02fSPetter Reinholdtsen 				rc = -1;
4633c18ec02fSPetter Reinholdtsen 		}
4634c18ec02fSPetter Reinholdtsen 	}
4635c18ec02fSPetter Reinholdtsen 
4636c18ec02fSPetter Reinholdtsen 	verbose = v;
4637c18ec02fSPetter Reinholdtsen 
4638c18ec02fSPetter Reinholdtsen 	return rc;
4639c18ec02fSPetter Reinholdtsen }
4640c18ec02fSPetter Reinholdtsen 
4641c18ec02fSPetter Reinholdtsen /* ipmi_sdr_main  -  top-level handler for SDR subsystem
4642c18ec02fSPetter Reinholdtsen  *
4643c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
4644c18ec02fSPetter Reinholdtsen  * @argc:	number of arguments
4645c18ec02fSPetter Reinholdtsen  * @argv:	argument list
4646c18ec02fSPetter Reinholdtsen  *
4647c18ec02fSPetter Reinholdtsen  * returns 0 on success
4648c18ec02fSPetter Reinholdtsen  * returns -1 on error
4649c18ec02fSPetter Reinholdtsen  */
4650c18ec02fSPetter Reinholdtsen int
ipmi_sdr_main(struct ipmi_intf * intf,int argc,char ** argv)4651c18ec02fSPetter Reinholdtsen ipmi_sdr_main(struct ipmi_intf *intf, int argc, char **argv)
4652c18ec02fSPetter Reinholdtsen {
4653c18ec02fSPetter Reinholdtsen 	int rc = 0;
4654c18ec02fSPetter Reinholdtsen 
4655c18ec02fSPetter Reinholdtsen 	/* initialize random numbers used later */
4656c18ec02fSPetter Reinholdtsen 	srand(time(NULL));
4657c18ec02fSPetter Reinholdtsen 
4658c18ec02fSPetter Reinholdtsen 	if (argc == 0)
4659c18ec02fSPetter Reinholdtsen 		return ipmi_sdr_print_sdr(intf, 0xfe);
4660c18ec02fSPetter Reinholdtsen 	else if (strncmp(argv[0], "help", 4) == 0) {
4661c18ec02fSPetter Reinholdtsen 		printf_sdr_usage();
4662c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[0], "list", 4) == 0
4663c18ec02fSPetter Reinholdtsen 		   || strncmp(argv[0], "elist", 5) == 0) {
4664c18ec02fSPetter Reinholdtsen 
4665c18ec02fSPetter Reinholdtsen 		if (strncmp(argv[0], "elist", 5) == 0)
4666c18ec02fSPetter Reinholdtsen 			sdr_extended = 1;
4667c18ec02fSPetter Reinholdtsen 		else
4668c18ec02fSPetter Reinholdtsen 			sdr_extended = 0;
4669c18ec02fSPetter Reinholdtsen 
4670c18ec02fSPetter Reinholdtsen 		if (argc <= 1)
4671c18ec02fSPetter Reinholdtsen 			rc = ipmi_sdr_print_sdr(intf, 0xfe);
4672c18ec02fSPetter Reinholdtsen 		else if (strncmp(argv[1], "all", 3) == 0)
4673c18ec02fSPetter Reinholdtsen 			rc = ipmi_sdr_print_sdr(intf, 0xff);
4674c18ec02fSPetter Reinholdtsen 		else if (strncmp(argv[1], "full", 4) == 0)
4675c18ec02fSPetter Reinholdtsen 			rc = ipmi_sdr_print_sdr(intf,
4676c18ec02fSPetter Reinholdtsen 						SDR_RECORD_TYPE_FULL_SENSOR);
4677c18ec02fSPetter Reinholdtsen 		else if (strncmp(argv[1], "compact", 7) == 0)
4678c18ec02fSPetter Reinholdtsen 			rc = ipmi_sdr_print_sdr(intf,
4679c18ec02fSPetter Reinholdtsen 						SDR_RECORD_TYPE_COMPACT_SENSOR);
4680c18ec02fSPetter Reinholdtsen 		else if (strncmp(argv[1], "event", 5) == 0)
4681c18ec02fSPetter Reinholdtsen 			rc = ipmi_sdr_print_sdr(intf,
4682c18ec02fSPetter Reinholdtsen 						SDR_RECORD_TYPE_EVENTONLY_SENSOR);
4683c18ec02fSPetter Reinholdtsen 		else if (strncmp(argv[1], "mcloc", 5) == 0)
4684c18ec02fSPetter Reinholdtsen 			rc = ipmi_sdr_print_sdr(intf,
4685c18ec02fSPetter Reinholdtsen 						SDR_RECORD_TYPE_MC_DEVICE_LOCATOR);
4686c18ec02fSPetter Reinholdtsen 		else if (strncmp(argv[1], "fru", 3) == 0)
4687c18ec02fSPetter Reinholdtsen 			rc = ipmi_sdr_print_sdr(intf,
4688c18ec02fSPetter Reinholdtsen 						SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR);
4689c18ec02fSPetter Reinholdtsen 		else if (strncmp(argv[1], "generic", 7) == 0)
4690c18ec02fSPetter Reinholdtsen 			rc = ipmi_sdr_print_sdr(intf,
4691c18ec02fSPetter Reinholdtsen 						SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR);
4692c18ec02fSPetter Reinholdtsen 		else if (strcmp(argv[1], "help") == 0) {
4693c18ec02fSPetter Reinholdtsen 			lprintf(LOG_NOTICE,
4694c18ec02fSPetter Reinholdtsen 				"usage: sdr %s [all|full|compact|event|mcloc|fru|generic]",
4695c18ec02fSPetter Reinholdtsen 				argv[0]);
4696c18ec02fSPetter Reinholdtsen 			return 0;
4697c18ec02fSPetter Reinholdtsen 		}
4698c18ec02fSPetter Reinholdtsen 		else {
4699c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR,
4700c18ec02fSPetter Reinholdtsen 				"Invalid SDR %s command: %s",
4701c18ec02fSPetter Reinholdtsen 				argv[0], argv[1]);
4702c18ec02fSPetter Reinholdtsen 			lprintf(LOG_NOTICE,
4703c18ec02fSPetter Reinholdtsen 				"usage: sdr %s [all|full|compact|event|mcloc|fru|generic]",
4704c18ec02fSPetter Reinholdtsen 				argv[0]);
4705c18ec02fSPetter Reinholdtsen 			return (-1);
4706c18ec02fSPetter Reinholdtsen 		}
4707c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[0], "type", 4) == 0) {
4708c18ec02fSPetter Reinholdtsen 		sdr_extended = 1;
4709c18ec02fSPetter Reinholdtsen 		rc = ipmi_sdr_print_type(intf, argv[1]);
4710c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[0], "entity", 6) == 0) {
4711c18ec02fSPetter Reinholdtsen 		sdr_extended = 1;
4712c18ec02fSPetter Reinholdtsen 		rc = ipmi_sdr_print_entity(intf, argv[1]);
4713c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[0], "info", 4) == 0) {
4714c18ec02fSPetter Reinholdtsen 		rc = ipmi_sdr_print_info(intf);
4715c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[0], "get", 3) == 0) {
4716c18ec02fSPetter Reinholdtsen 		rc = ipmi_sdr_print_entry_byid(intf, argc - 1, &argv[1]);
4717c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[0], "dump", 4) == 0) {
4718c18ec02fSPetter Reinholdtsen 		if (argc < 2) {
4719c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Not enough parameters given.");
4720c18ec02fSPetter Reinholdtsen 			lprintf(LOG_NOTICE, "usage: sdr dump <file>");
4721c18ec02fSPetter Reinholdtsen 			return (-1);
4722c18ec02fSPetter Reinholdtsen 		}
4723c18ec02fSPetter Reinholdtsen 		rc = ipmi_sdr_dump_bin(intf, argv[1]);
4724c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[0], "fill", 4) == 0) {
4725c18ec02fSPetter Reinholdtsen 		if (argc <= 1) {
4726c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Not enough parameters given.");
4727c18ec02fSPetter Reinholdtsen 			lprintf(LOG_NOTICE, "usage: sdr fill sensors");
4728c18ec02fSPetter Reinholdtsen 			lprintf(LOG_NOTICE, "usage: sdr fill file <file>");
4729c18ec02fSPetter Reinholdtsen 			lprintf(LOG_NOTICE, "usage: sdr fill range <range>");
4730c18ec02fSPetter Reinholdtsen 			return (-1);
4731c18ec02fSPetter Reinholdtsen 		} else if (strncmp(argv[1], "sensors", 7) == 0) {
4732c18ec02fSPetter Reinholdtsen 			rc = ipmi_sdr_add_from_sensors(intf, 21);
4733c18ec02fSPetter Reinholdtsen 		} else if (strncmp(argv[1], "nosat", 5) == 0) {
4734c18ec02fSPetter Reinholdtsen 			rc = ipmi_sdr_add_from_sensors(intf, 0);
4735c18ec02fSPetter Reinholdtsen 		} else if (strncmp(argv[1], "file", 4) == 0) {
4736c18ec02fSPetter Reinholdtsen 			if (argc < 3) {
4737c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR,
4738c18ec02fSPetter Reinholdtsen 					"Not enough parameters given.");
4739c18ec02fSPetter Reinholdtsen 				lprintf(LOG_NOTICE,
4740c18ec02fSPetter Reinholdtsen 					"usage: sdr fill file <file>");
4741c18ec02fSPetter Reinholdtsen 				return (-1);
4742c18ec02fSPetter Reinholdtsen 			}
4743c18ec02fSPetter Reinholdtsen 			rc = ipmi_sdr_add_from_file(intf, argv[2]);
4744c18ec02fSPetter Reinholdtsen 		} else if (strncmp(argv[1], "range", 4) == 0) {
4745c18ec02fSPetter Reinholdtsen 			if (argc < 3) {
4746c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR,
4747c18ec02fSPetter Reinholdtsen 					"Not enough parameters given.");
4748c18ec02fSPetter Reinholdtsen 				lprintf(LOG_NOTICE,
4749c18ec02fSPetter Reinholdtsen 					"usage: sdr fill range <range>");
4750c18ec02fSPetter Reinholdtsen 				return (-1);
4751c18ec02fSPetter Reinholdtsen 			}
4752c18ec02fSPetter Reinholdtsen 			rc = ipmi_sdr_add_from_list(intf, argv[2]);
4753c18ec02fSPetter Reinholdtsen 		} else {
4754c18ec02fSPetter Reinholdtsen 		    lprintf(LOG_ERR,
4755c18ec02fSPetter Reinholdtsen 			    "Invalid SDR %s command: %s",
4756c18ec02fSPetter Reinholdtsen 			    argv[0], argv[1]);
4757c18ec02fSPetter Reinholdtsen 		    lprintf(LOG_NOTICE,
4758c18ec02fSPetter Reinholdtsen 			    "usage: sdr %s <sensors|nosat|file|range> [options]",
4759c18ec02fSPetter Reinholdtsen 			    argv[0]);
4760c18ec02fSPetter Reinholdtsen 		    return (-1);
4761c18ec02fSPetter Reinholdtsen 		}
4762c18ec02fSPetter Reinholdtsen 	} else {
4763c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Invalid SDR command: %s", argv[0]);
4764c18ec02fSPetter Reinholdtsen 		rc = -1;
4765c18ec02fSPetter Reinholdtsen 	}
4766c18ec02fSPetter Reinholdtsen 
4767c18ec02fSPetter Reinholdtsen 	return rc;
4768c18ec02fSPetter Reinholdtsen }
4769c18ec02fSPetter Reinholdtsen 
4770c18ec02fSPetter Reinholdtsen void
printf_sdr_usage()4771c18ec02fSPetter Reinholdtsen printf_sdr_usage()
4772c18ec02fSPetter Reinholdtsen {
4773c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4774c18ec02fSPetter Reinholdtsen "usage: sdr <command> [options]");
4775c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4776c18ec02fSPetter Reinholdtsen "               list | elist [option]");
4777c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4778c18ec02fSPetter Reinholdtsen "                     all           All SDR Records");
4779c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4780c18ec02fSPetter Reinholdtsen "                     full          Full Sensor Record");
4781c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4782c18ec02fSPetter Reinholdtsen "                     compact       Compact Sensor Record");
4783c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4784c18ec02fSPetter Reinholdtsen "                     event         Event-Only Sensor Record");
4785c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4786c18ec02fSPetter Reinholdtsen "                     mcloc         Management Controller Locator Record");
4787c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4788c18ec02fSPetter Reinholdtsen "                     fru           FRU Locator Record");
4789c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4790c18ec02fSPetter Reinholdtsen "                     generic       Generic Device Locator Record\n");
4791c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4792c18ec02fSPetter Reinholdtsen "               type [option]");
4793c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4794c18ec02fSPetter Reinholdtsen "                     <Sensor_Type> Retrieve the state of specified sensor.");
4795c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4796c18ec02fSPetter Reinholdtsen "                                   Sensor_Type can be specified either as");
4797c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4798c18ec02fSPetter Reinholdtsen "                                   a string or a hex value.");
4799c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4800c18ec02fSPetter Reinholdtsen "                     list          Get a list of available sensor types\n");
4801c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4802c18ec02fSPetter Reinholdtsen "               get <Sensor_ID>");
4803c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4804c18ec02fSPetter Reinholdtsen "                     Retrieve state of the first sensor matched by Sensor_ID\n");
4805c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4806c18ec02fSPetter Reinholdtsen "               info");
4807c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4808c18ec02fSPetter Reinholdtsen "                     Display information about the repository itself\n");
4809c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4810c18ec02fSPetter Reinholdtsen "               entity <Entity_ID>[.<Instance_ID>]");
4811c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4812c18ec02fSPetter Reinholdtsen "                     Display all sensors associated with an entity\n");
4813c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4814c18ec02fSPetter Reinholdtsen "               dump <file>");
4815c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4816c18ec02fSPetter Reinholdtsen "                     Dump raw SDR data to a file\n");
4817c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4818c18ec02fSPetter Reinholdtsen "               fill <option>");
4819c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4820c18ec02fSPetter Reinholdtsen "                     sensors       Creates the SDR repository for the current");
4821c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4822c18ec02fSPetter Reinholdtsen "                                   configuration");
4823c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4824c18ec02fSPetter Reinholdtsen "                     nosat         Creates the SDR repository for the current");
4825c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4826c18ec02fSPetter Reinholdtsen "                                   configuration, without satellite scan");
4827c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4828c18ec02fSPetter Reinholdtsen "                     file <file>   Load SDR repository from a file");
4829c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4830c18ec02fSPetter Reinholdtsen "                     range <range> Load SDR repository from a provided list");
4831c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4832c18ec02fSPetter Reinholdtsen "                                   or range. Use ',' for list or '-' for");
4833c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4834c18ec02fSPetter Reinholdtsen "                                   range, eg. 0x28,0x32,0x40-0x44");
4835c18ec02fSPetter Reinholdtsen }
4836