xref: /openbmc/ipmitool/lib/ipmi_sensor.c (revision 2d79e69f)
1c18ec02fSPetter Reinholdtsen /*
2c18ec02fSPetter Reinholdtsen  * Copyright (c) 2003 Sun Microsystems, Inc.  All Rights Reserved.
3c18ec02fSPetter Reinholdtsen  *
4c18ec02fSPetter Reinholdtsen  * Redistribution and use in source and binary forms, with or without
5c18ec02fSPetter Reinholdtsen  * modification, are permitted provided that the following conditions
6c18ec02fSPetter Reinholdtsen  * are met:
7c18ec02fSPetter Reinholdtsen  *
8c18ec02fSPetter Reinholdtsen  * Redistribution of source code must retain the above copyright
9c18ec02fSPetter Reinholdtsen  * notice, this list of conditions and the following disclaimer.
10c18ec02fSPetter Reinholdtsen  *
11c18ec02fSPetter Reinholdtsen  * Redistribution in binary form must reproduce the above copyright
12c18ec02fSPetter Reinholdtsen  * notice, this list of conditions and the following disclaimer in the
13c18ec02fSPetter Reinholdtsen  * documentation and/or other materials provided with the distribution.
14c18ec02fSPetter Reinholdtsen  *
15c18ec02fSPetter Reinholdtsen  * Neither the name of Sun Microsystems, Inc. or the names of
16c18ec02fSPetter Reinholdtsen  * contributors may be used to endorse or promote products derived
17c18ec02fSPetter Reinholdtsen  * from this software without specific prior written permission.
18c18ec02fSPetter Reinholdtsen  *
19c18ec02fSPetter Reinholdtsen  * This software is provided "AS IS," without a warranty of any kind.
20c18ec02fSPetter Reinholdtsen  * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21c18ec02fSPetter Reinholdtsen  * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22c18ec02fSPetter Reinholdtsen  * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
23c18ec02fSPetter Reinholdtsen  * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
24c18ec02fSPetter Reinholdtsen  * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
25c18ec02fSPetter Reinholdtsen  * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL
26c18ec02fSPetter Reinholdtsen  * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
27c18ec02fSPetter Reinholdtsen  * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
28c18ec02fSPetter Reinholdtsen  * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
29c18ec02fSPetter Reinholdtsen  * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30c18ec02fSPetter Reinholdtsen  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31c18ec02fSPetter Reinholdtsen  */
32c18ec02fSPetter Reinholdtsen 
33c18ec02fSPetter Reinholdtsen #include <string.h>
34c18ec02fSPetter Reinholdtsen #include <math.h>
35c18ec02fSPetter Reinholdtsen 
36c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi.h>
37c18ec02fSPetter Reinholdtsen #include <ipmitool/helper.h>
38c18ec02fSPetter Reinholdtsen #include <ipmitool/log.h>
39c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_intf.h>
40c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sdr.h>
41c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sel.h>
42c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sensor.h>
43c18ec02fSPetter Reinholdtsen 
44c18ec02fSPetter Reinholdtsen extern int verbose;
45aa8bac2dSZdenek Styblik void print_sensor_get_usage();
462b15969dSZdenek Styblik void print_sensor_thresh_usage();
47c18ec02fSPetter Reinholdtsen 
48c18ec02fSPetter Reinholdtsen // Macro's for Reading the current sensor Data.
49c18ec02fSPetter Reinholdtsen #define SCANNING_DISABLED	0x40
50c18ec02fSPetter Reinholdtsen #define READING_UNAVAILABLE	0x20
51c18ec02fSPetter Reinholdtsen #define	INVALID_THRESHOLD	"Invalid Threshold data values. Cannot Set Threshold Data."
52c18ec02fSPetter Reinholdtsen // static
53c18ec02fSPetter Reinholdtsen int
ipmi_sensor_get_sensor_reading_factors(struct ipmi_intf * intf,struct sdr_record_full_sensor * sensor,uint8_t reading)54c18ec02fSPetter Reinholdtsen ipmi_sensor_get_sensor_reading_factors(
55c18ec02fSPetter Reinholdtsen 	struct ipmi_intf * intf,
56c18ec02fSPetter Reinholdtsen 	struct sdr_record_full_sensor * sensor,
57c18ec02fSPetter Reinholdtsen 	uint8_t reading)
58c18ec02fSPetter Reinholdtsen {
59c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
60c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
61c18ec02fSPetter Reinholdtsen 	uint8_t req_data[2];
62c18ec02fSPetter Reinholdtsen 
63c18ec02fSPetter Reinholdtsen 	char id[17];
64c18ec02fSPetter Reinholdtsen 
65c18ec02fSPetter Reinholdtsen 	if (intf == NULL || sensor == NULL)
66c18ec02fSPetter Reinholdtsen 		return -1;
67c18ec02fSPetter Reinholdtsen 
68c18ec02fSPetter Reinholdtsen 	memset(id, 0, sizeof(id));
69c18ec02fSPetter Reinholdtsen 	memcpy(id, sensor->id_string, 16);
70c18ec02fSPetter Reinholdtsen 
71c18ec02fSPetter Reinholdtsen 	req_data[0] = sensor->cmn.keys.sensor_num;
72c18ec02fSPetter Reinholdtsen 	req_data[1] = reading;
73c18ec02fSPetter Reinholdtsen 
74c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
75c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_SE;
76c18ec02fSPetter Reinholdtsen 	req.msg.lun = sensor->cmn.keys.lun;
77c18ec02fSPetter Reinholdtsen 	req.msg.cmd   = GET_SENSOR_FACTORS;
78c18ec02fSPetter Reinholdtsen 	req.msg.data  = req_data;
79c18ec02fSPetter Reinholdtsen 	req.msg.data_len = sizeof(req_data);
80c18ec02fSPetter Reinholdtsen 
81c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
82c18ec02fSPetter Reinholdtsen 
83c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
84c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error updating reading factor for sensor %s (#%02x)",
85c18ec02fSPetter Reinholdtsen 			id, sensor->cmn.keys.sensor_num);
86c18ec02fSPetter Reinholdtsen 		return -1;
87c18ec02fSPetter Reinholdtsen 	} else if (rsp->ccode) {
88c18ec02fSPetter Reinholdtsen 		return -1;
89c18ec02fSPetter Reinholdtsen 	} else {
90c18ec02fSPetter Reinholdtsen 		/* Update SDR copy with updated Reading Factors for this reading */
91c18ec02fSPetter Reinholdtsen 		/* Note:
92c18ec02fSPetter Reinholdtsen 		 * The Format of the returned data is exactly as in the SDR definition (Little Endian Format),
93c18ec02fSPetter Reinholdtsen 		 * therefore we can use raw copy operation here.
94c18ec02fSPetter Reinholdtsen 		 * Note: rsp->data[0] would point to the next valid entry in the sampling table
95c18ec02fSPetter Reinholdtsen 		 */
96c18ec02fSPetter Reinholdtsen 		 // BUGBUG: uses 'hardcoded' length information from SDR Definition
97c18ec02fSPetter Reinholdtsen 		memcpy(&sensor->mtol, &rsp->data[1], sizeof(sensor->mtol));
98c18ec02fSPetter Reinholdtsen 		memcpy(&sensor->bacc, &rsp->data[3], sizeof(sensor->bacc));
99c18ec02fSPetter Reinholdtsen 		return 0;
100c18ec02fSPetter Reinholdtsen 	}
101c18ec02fSPetter Reinholdtsen 
102c18ec02fSPetter Reinholdtsen }
103c18ec02fSPetter Reinholdtsen 
104c18ec02fSPetter Reinholdtsen static
105c18ec02fSPetter Reinholdtsen struct ipmi_rs *
ipmi_sensor_set_sensor_thresholds(struct ipmi_intf * intf,uint8_t sensor,uint8_t threshold,uint8_t setting,uint8_t target,uint8_t lun,uint8_t channel)106c18ec02fSPetter Reinholdtsen ipmi_sensor_set_sensor_thresholds(struct ipmi_intf *intf,
107c18ec02fSPetter Reinholdtsen 				  uint8_t sensor,
108c18ec02fSPetter Reinholdtsen 				  uint8_t threshold, uint8_t setting,
109c18ec02fSPetter Reinholdtsen 				  uint8_t target, uint8_t lun, uint8_t channel)
110c18ec02fSPetter Reinholdtsen {
111c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
112c18ec02fSPetter Reinholdtsen 	static struct sensor_set_thresh_rq set_thresh_rq;
113c18ec02fSPetter Reinholdtsen 	struct ipmi_rs *rsp;
114c18ec02fSPetter Reinholdtsen 	uint8_t  bridged_request = 0;
115c18ec02fSPetter Reinholdtsen 	uint32_t save_addr;
116c18ec02fSPetter Reinholdtsen 	uint32_t save_channel;
117c18ec02fSPetter Reinholdtsen 
118c18ec02fSPetter Reinholdtsen 	memset(&set_thresh_rq, 0, sizeof (set_thresh_rq));
119c18ec02fSPetter Reinholdtsen 	set_thresh_rq.sensor_num = sensor;
120c18ec02fSPetter Reinholdtsen 	set_thresh_rq.set_mask = threshold;
121c18ec02fSPetter Reinholdtsen 	if (threshold == UPPER_NON_RECOV_SPECIFIED)
122c18ec02fSPetter Reinholdtsen 		set_thresh_rq.upper_non_recov = setting;
123c18ec02fSPetter Reinholdtsen 	else if (threshold == UPPER_CRIT_SPECIFIED)
124c18ec02fSPetter Reinholdtsen 		set_thresh_rq.upper_crit = setting;
125c18ec02fSPetter Reinholdtsen 	else if (threshold == UPPER_NON_CRIT_SPECIFIED)
126c18ec02fSPetter Reinholdtsen 		set_thresh_rq.upper_non_crit = setting;
127c18ec02fSPetter Reinholdtsen 	else if (threshold == LOWER_NON_CRIT_SPECIFIED)
128c18ec02fSPetter Reinholdtsen 		set_thresh_rq.lower_non_crit = setting;
129c18ec02fSPetter Reinholdtsen 	else if (threshold == LOWER_CRIT_SPECIFIED)
130c18ec02fSPetter Reinholdtsen 		set_thresh_rq.lower_crit = setting;
131c18ec02fSPetter Reinholdtsen 	else if (threshold == LOWER_NON_RECOV_SPECIFIED)
132c18ec02fSPetter Reinholdtsen 		set_thresh_rq.lower_non_recov = setting;
133c18ec02fSPetter Reinholdtsen 	else
134c18ec02fSPetter Reinholdtsen 		return NULL;
135c18ec02fSPetter Reinholdtsen 
136c18ec02fSPetter Reinholdtsen 	if (BRIDGE_TO_SENSOR(intf, target, channel)) {
137c18ec02fSPetter Reinholdtsen 		bridged_request = 1;
138c18ec02fSPetter Reinholdtsen 		save_addr = intf->target_addr;
139c18ec02fSPetter Reinholdtsen 		intf->target_addr = target;
140c18ec02fSPetter Reinholdtsen 		save_channel = intf->target_channel;
141c18ec02fSPetter Reinholdtsen 		intf->target_channel = channel;
142c18ec02fSPetter Reinholdtsen 	}
143c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof (req));
144c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_SE;
145c18ec02fSPetter Reinholdtsen 	req.msg.lun = lun;
146c18ec02fSPetter Reinholdtsen 	req.msg.cmd = SET_SENSOR_THRESHOLDS;
147c18ec02fSPetter Reinholdtsen 	req.msg.data = (uint8_t *) & set_thresh_rq;
148c18ec02fSPetter Reinholdtsen 	req.msg.data_len = sizeof (set_thresh_rq);
149c18ec02fSPetter Reinholdtsen 
150c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
151c18ec02fSPetter Reinholdtsen 	if (bridged_request) {
152c18ec02fSPetter Reinholdtsen 		intf->target_addr = save_addr;
153c18ec02fSPetter Reinholdtsen 		intf->target_channel = save_channel;
154c18ec02fSPetter Reinholdtsen 	}
155c18ec02fSPetter Reinholdtsen 	return rsp;
156c18ec02fSPetter Reinholdtsen }
157c18ec02fSPetter Reinholdtsen 
158c18ec02fSPetter Reinholdtsen static int
ipmi_sensor_print_fc_discrete(struct ipmi_intf * intf,struct sdr_record_common_sensor * sensor,uint8_t sdr_record_type)159c18ec02fSPetter Reinholdtsen ipmi_sensor_print_fc_discrete(struct ipmi_intf *intf,
160c18ec02fSPetter Reinholdtsen 				struct sdr_record_common_sensor *sensor,
161c18ec02fSPetter Reinholdtsen 				uint8_t sdr_record_type)
162c18ec02fSPetter Reinholdtsen {
163c18ec02fSPetter Reinholdtsen 	struct sensor_reading *sr;
164c18ec02fSPetter Reinholdtsen 
165c18ec02fSPetter Reinholdtsen 	sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 3);
166c18ec02fSPetter Reinholdtsen 
167c18ec02fSPetter Reinholdtsen 	if (sr == NULL) {
168c18ec02fSPetter Reinholdtsen 		return -1;
169c18ec02fSPetter Reinholdtsen 	}
170c18ec02fSPetter Reinholdtsen 
171c18ec02fSPetter Reinholdtsen 	if (csv_output) {
172c18ec02fSPetter Reinholdtsen 		/* NOT IMPLEMENTED */
173c18ec02fSPetter Reinholdtsen 	} else {
174c18ec02fSPetter Reinholdtsen 		if (verbose == 0) {
175c18ec02fSPetter Reinholdtsen 			/* output format
176c18ec02fSPetter Reinholdtsen 			 *   id value units status thresholds....
177c18ec02fSPetter Reinholdtsen 			 */
178c18ec02fSPetter Reinholdtsen 			printf("%-16s ", sr->s_id);
179c18ec02fSPetter Reinholdtsen 			if (sr->s_reading_valid) {
180c18ec02fSPetter Reinholdtsen 				if (sr->s_has_analog_value) {
181c18ec02fSPetter Reinholdtsen 					/* don't show discrete component */
182c18ec02fSPetter Reinholdtsen 					printf("| %-10s | %-10s | %-6s",
183c18ec02fSPetter Reinholdtsen 					       sr->s_a_str, sr->s_a_units, "ok");
184c18ec02fSPetter Reinholdtsen 				} else {
185c18ec02fSPetter Reinholdtsen 					printf("| 0x%-8x | %-10s | 0x%02x%02x",
186c18ec02fSPetter Reinholdtsen 					       sr->s_reading, "discrete",
187c18ec02fSPetter Reinholdtsen 					       sr->s_data2, sr->s_data3);
188c18ec02fSPetter Reinholdtsen 				}
189c18ec02fSPetter Reinholdtsen 			} else {
190c18ec02fSPetter Reinholdtsen 				printf("| %-10s | %-10s | %-6s",
191c18ec02fSPetter Reinholdtsen 				       "na", "discrete", "na");
192c18ec02fSPetter Reinholdtsen 			}
193c18ec02fSPetter Reinholdtsen 			printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s",
194c18ec02fSPetter Reinholdtsen 			       "na", "na", "na", "na", "na", "na");
195c18ec02fSPetter Reinholdtsen 
196c18ec02fSPetter Reinholdtsen 			printf("\n");
197c18ec02fSPetter Reinholdtsen 		} else {
198c18ec02fSPetter Reinholdtsen 			printf("Sensor ID              : %s (0x%x)\n",
199c18ec02fSPetter Reinholdtsen 			       sr->s_id, sensor->keys.sensor_num);
200c18ec02fSPetter Reinholdtsen 			printf(" Entity ID             : %d.%d\n",
201c18ec02fSPetter Reinholdtsen 			       sensor->entity.id, sensor->entity.instance);
202c18ec02fSPetter Reinholdtsen 			printf(" Sensor Type (Discrete): %s\n",
203c18ec02fSPetter Reinholdtsen 			       ipmi_sdr_get_sensor_type_desc(sensor->sensor.
204c18ec02fSPetter Reinholdtsen 							     type));
205c18ec02fSPetter Reinholdtsen 			if( sr->s_reading_valid )
206c18ec02fSPetter Reinholdtsen 			{
207c18ec02fSPetter Reinholdtsen 				if (sr->s_has_analog_value) {
208c18ec02fSPetter Reinholdtsen 					printf(" Sensor Reading        : %s %s\n", sr->s_a_str, sr->s_a_units);
209c18ec02fSPetter Reinholdtsen 				}
210c18ec02fSPetter Reinholdtsen 				ipmi_sdr_print_discrete_state("States Asserted",
211c18ec02fSPetter Reinholdtsen 							sensor->sensor.type,
212c18ec02fSPetter Reinholdtsen 							sensor->event_type,
213c18ec02fSPetter Reinholdtsen 							sr->s_data2,
214c18ec02fSPetter Reinholdtsen 							sr->s_data3);
215c18ec02fSPetter Reinholdtsen 				printf("\n");
216c18ec02fSPetter Reinholdtsen 			} else {
217c18ec02fSPetter Reinholdtsen 			   printf(" Unable to read sensor: Device Not Present\n\n");
218c18ec02fSPetter Reinholdtsen 			}
219c18ec02fSPetter Reinholdtsen 	   }
220c18ec02fSPetter Reinholdtsen 	}
221c18ec02fSPetter Reinholdtsen 
222c18ec02fSPetter Reinholdtsen 	return (sr->s_reading_valid ? 0 : -1 );
223c18ec02fSPetter Reinholdtsen }
224c18ec02fSPetter Reinholdtsen 
225c18ec02fSPetter Reinholdtsen static void
print_thresh_setting(struct sdr_record_full_sensor * full,uint8_t thresh_is_avail,uint8_t setting,const char * field_sep,const char * analog_fmt,const char * discrete_fmt,const char * na_fmt)226c18ec02fSPetter Reinholdtsen print_thresh_setting(struct sdr_record_full_sensor *full,
227c18ec02fSPetter Reinholdtsen 			 uint8_t thresh_is_avail, uint8_t setting,
228c18ec02fSPetter Reinholdtsen 			 const char *field_sep,
229c18ec02fSPetter Reinholdtsen 			 const char *analog_fmt,
230c18ec02fSPetter Reinholdtsen 			 const char *discrete_fmt,
231c18ec02fSPetter Reinholdtsen 			 const char *na_fmt)
232c18ec02fSPetter Reinholdtsen {
233c18ec02fSPetter Reinholdtsen 	printf("%s", field_sep);
234c18ec02fSPetter Reinholdtsen 	if (!thresh_is_avail) {
235c18ec02fSPetter Reinholdtsen 		printf(na_fmt, "na");
236c18ec02fSPetter Reinholdtsen 		return;
237c18ec02fSPetter Reinholdtsen 	}
238c18ec02fSPetter Reinholdtsen 	if (full && !UNITS_ARE_DISCRETE(&full->cmn)) {
239c18ec02fSPetter Reinholdtsen 		printf(analog_fmt, sdr_convert_sensor_reading (full, setting));
240c18ec02fSPetter Reinholdtsen 	} else {
241c18ec02fSPetter Reinholdtsen 		printf(discrete_fmt, setting);
242c18ec02fSPetter Reinholdtsen 	}
243c18ec02fSPetter Reinholdtsen }
244c18ec02fSPetter Reinholdtsen 
245c18ec02fSPetter Reinholdtsen static int
ipmi_sensor_print_fc_threshold(struct ipmi_intf * intf,struct sdr_record_common_sensor * sensor,uint8_t sdr_record_type)246c18ec02fSPetter Reinholdtsen ipmi_sensor_print_fc_threshold(struct ipmi_intf *intf,
247c18ec02fSPetter Reinholdtsen 			      struct sdr_record_common_sensor *sensor,
248c18ec02fSPetter Reinholdtsen 			      uint8_t sdr_record_type)
249c18ec02fSPetter Reinholdtsen {
250c18ec02fSPetter Reinholdtsen 	int thresh_available = 1;
251c18ec02fSPetter Reinholdtsen 	struct ipmi_rs *rsp;
252c18ec02fSPetter Reinholdtsen 	struct sensor_reading *sr;
253c18ec02fSPetter Reinholdtsen 
254c18ec02fSPetter Reinholdtsen 	sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 3);
255c18ec02fSPetter Reinholdtsen 
256c18ec02fSPetter Reinholdtsen 	if (sr == NULL) {
257c18ec02fSPetter Reinholdtsen 		return -1;
258c18ec02fSPetter Reinholdtsen 	}
259c18ec02fSPetter Reinholdtsen 
260c18ec02fSPetter Reinholdtsen 	const char *thresh_status = ipmi_sdr_get_thresh_status(sr, "ns");
261c18ec02fSPetter Reinholdtsen 
262c18ec02fSPetter Reinholdtsen 	/*
263c18ec02fSPetter Reinholdtsen 	 * Get sensor thresholds
264c18ec02fSPetter Reinholdtsen 	 */
265c18ec02fSPetter Reinholdtsen 	rsp = ipmi_sdr_get_sensor_thresholds(intf,
266c18ec02fSPetter Reinholdtsen 				sensor->keys.sensor_num, sensor->keys.owner_id,
267c18ec02fSPetter Reinholdtsen 				sensor->keys.lun, sensor->keys.channel);
268c18ec02fSPetter Reinholdtsen 
269c18ec02fSPetter Reinholdtsen 	if ((rsp == NULL) || (rsp->ccode > 0) || (rsp->data_len == 0))
270c18ec02fSPetter Reinholdtsen 		thresh_available = 0;
271c18ec02fSPetter Reinholdtsen 
272c18ec02fSPetter Reinholdtsen 	if (csv_output) {
273c18ec02fSPetter Reinholdtsen 		/* NOT IMPLEMENTED */
274c18ec02fSPetter Reinholdtsen 	} else {
275c18ec02fSPetter Reinholdtsen 		if (verbose == 0) {
276c18ec02fSPetter Reinholdtsen 			/* output format
277c18ec02fSPetter Reinholdtsen 			 *   id value units status thresholds....
278c18ec02fSPetter Reinholdtsen 			 */
279c18ec02fSPetter Reinholdtsen 			printf("%-16s ", sr->s_id);
280c18ec02fSPetter Reinholdtsen 			if (sr->s_reading_valid) {
281c18ec02fSPetter Reinholdtsen 				if (sr->s_has_analog_value)
282c18ec02fSPetter Reinholdtsen 					printf("| %-10.3f | %-10s | %-6s",
283c18ec02fSPetter Reinholdtsen 					       sr->s_a_val, sr->s_a_units, thresh_status);
284c18ec02fSPetter Reinholdtsen 				else
285c18ec02fSPetter Reinholdtsen 					printf("| 0x%-8x | %-10s | %-6s",
286c18ec02fSPetter Reinholdtsen 					       sr->s_reading, sr->s_a_units, thresh_status);
287c18ec02fSPetter Reinholdtsen 			} else {
288c18ec02fSPetter Reinholdtsen 				printf("| %-10s | %-10s | %-6s",
289c18ec02fSPetter Reinholdtsen 				       "na", sr->s_a_units, "na");
290c18ec02fSPetter Reinholdtsen 			}
291c18ec02fSPetter Reinholdtsen 			if (thresh_available && sr->full) {
292c18ec02fSPetter Reinholdtsen #define PTS(bit, dataidx) {						\
293c18ec02fSPetter Reinholdtsen 	print_thresh_setting(sr->full, rsp->data[0] & (bit),  		\
294c18ec02fSPetter Reinholdtsen 	    rsp->data[(dataidx)], "| ", "%-10.3f", "0x-8x", "%-10s");	\
295c18ec02fSPetter Reinholdtsen }
296c18ec02fSPetter Reinholdtsen 				PTS(LOWER_NON_RECOV_SPECIFIED,	3);
297c18ec02fSPetter Reinholdtsen 				PTS(LOWER_CRIT_SPECIFIED,	2);
298c18ec02fSPetter Reinholdtsen 				PTS(LOWER_NON_CRIT_SPECIFIED,	1);
299c18ec02fSPetter Reinholdtsen 				PTS(UPPER_NON_CRIT_SPECIFIED,	4);
300c18ec02fSPetter Reinholdtsen 				PTS(UPPER_CRIT_SPECIFIED,	5);
301c18ec02fSPetter Reinholdtsen 				PTS(UPPER_NON_RECOV_SPECIFIED,	6);
302c18ec02fSPetter Reinholdtsen #undef PTS
303c18ec02fSPetter Reinholdtsen 			} else {
304c18ec02fSPetter Reinholdtsen 				printf
305c18ec02fSPetter Reinholdtsen 				    ("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s",
306c18ec02fSPetter Reinholdtsen 				     "na", "na", "na", "na", "na", "na");
307c18ec02fSPetter Reinholdtsen 			}
308c18ec02fSPetter Reinholdtsen 
309c18ec02fSPetter Reinholdtsen 			printf("\n");
310c18ec02fSPetter Reinholdtsen 		} else {
311c18ec02fSPetter Reinholdtsen 			printf("Sensor ID              : %s (0x%x)\n",
312c18ec02fSPetter Reinholdtsen 			       sr->s_id, sensor->keys.sensor_num);
313c18ec02fSPetter Reinholdtsen 
314c18ec02fSPetter Reinholdtsen 			printf(" Entity ID             : %d.%d\n",
315c18ec02fSPetter Reinholdtsen 			       sensor->entity.id, sensor->entity.instance);
316c18ec02fSPetter Reinholdtsen 
317c18ec02fSPetter Reinholdtsen 			printf(" Sensor Type (Threshold)  : %s\n",
318c18ec02fSPetter Reinholdtsen 			       ipmi_sdr_get_sensor_type_desc(sensor->sensor.
319c18ec02fSPetter Reinholdtsen 							     type));
320c18ec02fSPetter Reinholdtsen 
321c18ec02fSPetter Reinholdtsen 			printf(" Sensor Reading        : ");
322c18ec02fSPetter Reinholdtsen 			if (sr->s_reading_valid) {
323c18ec02fSPetter Reinholdtsen 				if (sr->full) {
324c18ec02fSPetter Reinholdtsen 					uint16_t raw_tol = __TO_TOL(sr->full->mtol);
325c18ec02fSPetter Reinholdtsen 					if (sr->s_has_analog_value) {
326c18ec02fSPetter Reinholdtsen 						double tol =
327c18ec02fSPetter Reinholdtsen 						    sdr_convert_sensor_tolerance(sr->full,
328c18ec02fSPetter Reinholdtsen 									       raw_tol);
329c18ec02fSPetter Reinholdtsen 						printf("%.*f (+/- %.*f) %s\n",
330c18ec02fSPetter Reinholdtsen 						       (sr->s_a_val == (int)
331c18ec02fSPetter Reinholdtsen 						       sr->s_a_val) ? 0 : 3,
332c18ec02fSPetter Reinholdtsen 						       sr->s_a_val,
333c18ec02fSPetter Reinholdtsen 						       (tol == (int) tol) ? 0 : 3, tol,
334c18ec02fSPetter Reinholdtsen 						       sr->s_a_units);
335c18ec02fSPetter Reinholdtsen 					} else {
336c18ec02fSPetter Reinholdtsen 						printf("0x%x (+/- 0x%x) %s\n",
337c18ec02fSPetter Reinholdtsen 						       sr->s_reading,
338c18ec02fSPetter Reinholdtsen 						       raw_tol,
339c18ec02fSPetter Reinholdtsen 						       sr->s_a_units);
340c18ec02fSPetter Reinholdtsen 					}
341c18ec02fSPetter Reinholdtsen 				} else {
342c18ec02fSPetter Reinholdtsen 					printf("0x%x %s\n", sr->s_reading,
343c18ec02fSPetter Reinholdtsen 					sr->s_a_units);
344c18ec02fSPetter Reinholdtsen 				}
345c18ec02fSPetter Reinholdtsen 				printf(" Status                : %s\n", thresh_status);
346c18ec02fSPetter Reinholdtsen 
347c18ec02fSPetter Reinholdtsen 				if (thresh_available) {
348c18ec02fSPetter Reinholdtsen 					if (sr->full) {
349c18ec02fSPetter Reinholdtsen #define PTS(bit, dataidx, str) { 			\
350c18ec02fSPetter Reinholdtsen print_thresh_setting(sr->full, rsp->data[0] & (bit),	\
351c18ec02fSPetter Reinholdtsen 		     rsp->data[(dataidx)], 		\
352c18ec02fSPetter Reinholdtsen 		    (str), "%.3f\n", "0x%x\n", "%s\n"); \
353c18ec02fSPetter Reinholdtsen }
354c18ec02fSPetter Reinholdtsen 
355c18ec02fSPetter Reinholdtsen 						PTS(LOWER_NON_RECOV_SPECIFIED,	3, " Lower Non-Recoverable : ");
356c18ec02fSPetter Reinholdtsen 						PTS(LOWER_CRIT_SPECIFIED,	2, " Lower Critical        : ");
357c18ec02fSPetter Reinholdtsen 						PTS(LOWER_NON_CRIT_SPECIFIED,	1, " Lower Non-Critical    : ");
358c18ec02fSPetter Reinholdtsen 						PTS(UPPER_NON_CRIT_SPECIFIED,	4, " Upper Non-Critical    : ");
359c18ec02fSPetter Reinholdtsen 						PTS(UPPER_CRIT_SPECIFIED,	5, " Upper Critical        : ");
360c18ec02fSPetter Reinholdtsen 						PTS(UPPER_NON_RECOV_SPECIFIED,	6, " Upper Non-Recoverable : ");
361c18ec02fSPetter Reinholdtsen #undef PTS
362c18ec02fSPetter Reinholdtsen 
363c18ec02fSPetter Reinholdtsen 					}
364c18ec02fSPetter Reinholdtsen 					ipmi_sdr_print_sensor_hysteresis(sensor, sr->full,
365c18ec02fSPetter Reinholdtsen 						sr->full ?  sr->full->threshold.hysteresis.positive :
366c18ec02fSPetter Reinholdtsen 						sr->compact->threshold.hysteresis.positive,
367c18ec02fSPetter Reinholdtsen 						"Positive Hysteresis");
368c18ec02fSPetter Reinholdtsen 
369c18ec02fSPetter Reinholdtsen 					ipmi_sdr_print_sensor_hysteresis(sensor, sr->full,
370c18ec02fSPetter Reinholdtsen 						sr->full ?  sr->full->threshold.hysteresis.negative :
371c18ec02fSPetter Reinholdtsen 						sr->compact->threshold.hysteresis.negative,
372c18ec02fSPetter Reinholdtsen 						"Negative Hysteresis");
373c18ec02fSPetter Reinholdtsen 				} else {
374c18ec02fSPetter Reinholdtsen 					printf(" Sensor Threshold Settings not available\n");
375c18ec02fSPetter Reinholdtsen 				}
376c18ec02fSPetter Reinholdtsen 			} else {
377c18ec02fSPetter Reinholdtsen 			  printf(" Unable to read sensor: Device Not Present\n\n");
378c18ec02fSPetter Reinholdtsen 			}
379c18ec02fSPetter Reinholdtsen 
380c18ec02fSPetter Reinholdtsen 			ipmi_sdr_print_sensor_event_status(intf,
381c18ec02fSPetter Reinholdtsen 							   sensor->keys.
382c18ec02fSPetter Reinholdtsen 							   sensor_num,
383c18ec02fSPetter Reinholdtsen 							   sensor->sensor.type,
384c18ec02fSPetter Reinholdtsen 							   sensor->event_type,
385c18ec02fSPetter Reinholdtsen 							   ANALOG_SENSOR,
386c18ec02fSPetter Reinholdtsen 							   sensor->keys.owner_id,
387c18ec02fSPetter Reinholdtsen 							   sensor->keys.lun,
388c18ec02fSPetter Reinholdtsen 							   sensor->keys.channel);
389c18ec02fSPetter Reinholdtsen 			ipmi_sdr_print_sensor_event_enable(intf,
390c18ec02fSPetter Reinholdtsen 							   sensor->keys.
391c18ec02fSPetter Reinholdtsen 							   sensor_num,
392c18ec02fSPetter Reinholdtsen 							   sensor->sensor.type,
393c18ec02fSPetter Reinholdtsen 							   sensor->event_type,
394c18ec02fSPetter Reinholdtsen 							   ANALOG_SENSOR,
395c18ec02fSPetter Reinholdtsen 							   sensor->keys.owner_id,
396c18ec02fSPetter Reinholdtsen 							   sensor->keys.lun,
397c18ec02fSPetter Reinholdtsen 							   sensor->keys.channel);
398c18ec02fSPetter Reinholdtsen 
399c18ec02fSPetter Reinholdtsen 			printf("\n");
400c18ec02fSPetter Reinholdtsen 		}
401c18ec02fSPetter Reinholdtsen 	}
402c18ec02fSPetter Reinholdtsen 
403c18ec02fSPetter Reinholdtsen 	return (sr->s_reading_valid ? 0 : -1 );
404c18ec02fSPetter Reinholdtsen }
405c18ec02fSPetter Reinholdtsen 
406c18ec02fSPetter Reinholdtsen int
ipmi_sensor_print_fc(struct ipmi_intf * intf,struct sdr_record_common_sensor * sensor,uint8_t sdr_record_type)407c18ec02fSPetter Reinholdtsen ipmi_sensor_print_fc(struct ipmi_intf *intf,
408c18ec02fSPetter Reinholdtsen 		       struct sdr_record_common_sensor *sensor,
409c18ec02fSPetter Reinholdtsen 			uint8_t sdr_record_type)
410c18ec02fSPetter Reinholdtsen {
411c18ec02fSPetter Reinholdtsen 	if (IS_THRESHOLD_SENSOR(sensor))
412c18ec02fSPetter Reinholdtsen 		return ipmi_sensor_print_fc_threshold(intf, sensor, sdr_record_type);
413c18ec02fSPetter Reinholdtsen 	else
414c18ec02fSPetter Reinholdtsen 		return ipmi_sensor_print_fc_discrete(intf, sensor, sdr_record_type);
415c18ec02fSPetter Reinholdtsen }
416c18ec02fSPetter Reinholdtsen 
417c18ec02fSPetter Reinholdtsen static int
ipmi_sensor_list(struct ipmi_intf * intf)418c18ec02fSPetter Reinholdtsen ipmi_sensor_list(struct ipmi_intf *intf)
419c18ec02fSPetter Reinholdtsen {
420c18ec02fSPetter Reinholdtsen 	struct sdr_get_rs *header;
421c18ec02fSPetter Reinholdtsen 	struct ipmi_sdr_iterator *itr;
422c18ec02fSPetter Reinholdtsen 	int rc = 0;
423c18ec02fSPetter Reinholdtsen 
424c18ec02fSPetter Reinholdtsen 	lprintf(LOG_DEBUG, "Querying SDR for sensor list");
425c18ec02fSPetter Reinholdtsen 
426c18ec02fSPetter Reinholdtsen 	itr = ipmi_sdr_start(intf, 0);
427c18ec02fSPetter Reinholdtsen 	if (itr == NULL) {
428c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Unable to open SDR for reading");
429c18ec02fSPetter Reinholdtsen 		return -1;
430c18ec02fSPetter Reinholdtsen 	}
431c18ec02fSPetter Reinholdtsen 
432c18ec02fSPetter Reinholdtsen 	while ((header = ipmi_sdr_get_next_header(intf, itr)) != NULL) {
433c18ec02fSPetter Reinholdtsen 		uint8_t *rec;
434c18ec02fSPetter Reinholdtsen 
435c18ec02fSPetter Reinholdtsen 		rec = ipmi_sdr_get_record(intf, header, itr);
436c18ec02fSPetter Reinholdtsen 		if (rec == NULL) {
437c18ec02fSPetter Reinholdtsen 			lprintf(LOG_DEBUG, "rec == NULL");
438c18ec02fSPetter Reinholdtsen 			continue;
439c18ec02fSPetter Reinholdtsen 		}
440c18ec02fSPetter Reinholdtsen 
441c18ec02fSPetter Reinholdtsen 		switch (header->type) {
442c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FULL_SENSOR:
443c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_COMPACT_SENSOR:
444c18ec02fSPetter Reinholdtsen 			ipmi_sensor_print_fc(intf,
445c18ec02fSPetter Reinholdtsen 						   (struct
446c18ec02fSPetter Reinholdtsen 						    sdr_record_common_sensor *)
447c18ec02fSPetter Reinholdtsen 						   rec,
448c18ec02fSPetter Reinholdtsen 						   header->type);
449c18ec02fSPetter Reinholdtsen 			break;
450c18ec02fSPetter Reinholdtsen 		}
451c18ec02fSPetter Reinholdtsen 		free(rec);
452c18ec02fSPetter Reinholdtsen 		rec = NULL;
453c18ec02fSPetter Reinholdtsen 
454c18ec02fSPetter Reinholdtsen 		/* fix for CR6604909: */
455c18ec02fSPetter Reinholdtsen 		/* mask failure of individual reads in sensor list command */
456c18ec02fSPetter Reinholdtsen 		/* rc = (r == 0) ? rc : r; */
457c18ec02fSPetter Reinholdtsen 	}
458c18ec02fSPetter Reinholdtsen 
459c18ec02fSPetter Reinholdtsen 	ipmi_sdr_end(intf, itr);
460c18ec02fSPetter Reinholdtsen 
461c18ec02fSPetter Reinholdtsen 	return rc;
462c18ec02fSPetter Reinholdtsen }
463c18ec02fSPetter Reinholdtsen 
464c18ec02fSPetter Reinholdtsen static const struct valstr threshold_vals[] = {
465c18ec02fSPetter Reinholdtsen 	{UPPER_NON_RECOV_SPECIFIED, "Upper Non-Recoverable"},
466c18ec02fSPetter Reinholdtsen 	{UPPER_CRIT_SPECIFIED, "Upper Critical"},
467c18ec02fSPetter Reinholdtsen 	{UPPER_NON_CRIT_SPECIFIED, "Upper Non-Critical"},
468c18ec02fSPetter Reinholdtsen 	{LOWER_NON_RECOV_SPECIFIED, "Lower Non-Recoverable"},
469c18ec02fSPetter Reinholdtsen 	{LOWER_CRIT_SPECIFIED, "Lower Critical"},
470c18ec02fSPetter Reinholdtsen 	{LOWER_NON_CRIT_SPECIFIED, "Lower Non-Critical"},
471c18ec02fSPetter Reinholdtsen 	{0x00, NULL},
472c18ec02fSPetter Reinholdtsen };
473c18ec02fSPetter Reinholdtsen 
474c18ec02fSPetter Reinholdtsen static int
__ipmi_sensor_set_threshold(struct ipmi_intf * intf,uint8_t num,uint8_t mask,uint8_t setting,uint8_t target,uint8_t lun,uint8_t channel)475c18ec02fSPetter Reinholdtsen __ipmi_sensor_set_threshold(struct ipmi_intf *intf,
476c18ec02fSPetter Reinholdtsen 			    uint8_t num, uint8_t mask, uint8_t setting,
477c18ec02fSPetter Reinholdtsen 			    uint8_t target, uint8_t lun, uint8_t channel)
478c18ec02fSPetter Reinholdtsen {
479c18ec02fSPetter Reinholdtsen 	struct ipmi_rs *rsp;
480c18ec02fSPetter Reinholdtsen 
481c18ec02fSPetter Reinholdtsen 	rsp = ipmi_sensor_set_sensor_thresholds(intf, num, mask, setting,
482c18ec02fSPetter Reinholdtsen 				  target, lun, channel);
483c18ec02fSPetter Reinholdtsen 
484c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
485c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error setting threshold");
486c18ec02fSPetter Reinholdtsen 		return -1;
487c18ec02fSPetter Reinholdtsen 	}
488c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
489c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error setting threshold: %s",
490c18ec02fSPetter Reinholdtsen 			val2str(rsp->ccode, completion_code_vals));
491c18ec02fSPetter Reinholdtsen 		return -1;
492c18ec02fSPetter Reinholdtsen 	}
493c18ec02fSPetter Reinholdtsen 
494c18ec02fSPetter Reinholdtsen 	return 0;
495c18ec02fSPetter Reinholdtsen }
496c18ec02fSPetter Reinholdtsen 
497c18ec02fSPetter Reinholdtsen static uint8_t
__ipmi_sensor_threshold_value_to_raw(struct sdr_record_full_sensor * full,double value)498c18ec02fSPetter Reinholdtsen __ipmi_sensor_threshold_value_to_raw(struct sdr_record_full_sensor *full, double value)
499c18ec02fSPetter Reinholdtsen {
500c18ec02fSPetter Reinholdtsen 	if (!UNITS_ARE_DISCRETE(&full->cmn)) { /* Has an analog reading */
501c18ec02fSPetter Reinholdtsen 		/* Has an analog reading and supports mx+b */
502c18ec02fSPetter Reinholdtsen 		return sdr_convert_sensor_value_to_raw(full, value);
503c18ec02fSPetter Reinholdtsen 	}
504c18ec02fSPetter Reinholdtsen 	else {
505c18ec02fSPetter Reinholdtsen 		/* Does not have an analog reading and/or does not support mx+b */
506c18ec02fSPetter Reinholdtsen 		if (value > 255) {
507c18ec02fSPetter Reinholdtsen 			return 255;
508c18ec02fSPetter Reinholdtsen 		}
509c18ec02fSPetter Reinholdtsen 		else if (value < 0) {
510c18ec02fSPetter Reinholdtsen 			return 0;
511c18ec02fSPetter Reinholdtsen 		}
512c18ec02fSPetter Reinholdtsen 		else {
513c18ec02fSPetter Reinholdtsen 			return (uint8_t )value;
514c18ec02fSPetter Reinholdtsen 		}
515c18ec02fSPetter Reinholdtsen 	}
516c18ec02fSPetter Reinholdtsen }
517c18ec02fSPetter Reinholdtsen 
518c18ec02fSPetter Reinholdtsen static int
ipmi_sensor_set_threshold(struct ipmi_intf * intf,int argc,char ** argv)519c18ec02fSPetter Reinholdtsen ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv)
520c18ec02fSPetter Reinholdtsen {
521c18ec02fSPetter Reinholdtsen 	char *id, *thresh;
522c18ec02fSPetter Reinholdtsen 	uint8_t settingMask = 0;
523c18ec02fSPetter Reinholdtsen 	double setting1 = 0.0, setting2 = 0.0, setting3 = 0.0;
524c18ec02fSPetter Reinholdtsen 	int allUpper = 0, allLower = 0;
525c18ec02fSPetter Reinholdtsen 	int ret = 0;
526c18ec02fSPetter Reinholdtsen 	struct ipmi_rs *rsp;
527c18ec02fSPetter Reinholdtsen 	int i =0;
528c18ec02fSPetter Reinholdtsen 	double val[10] = {0};
529c18ec02fSPetter Reinholdtsen 
530c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *sdr;
531c18ec02fSPetter Reinholdtsen 
532c18ec02fSPetter Reinholdtsen 	if (argc < 3 || strncmp(argv[0], "help", 4) == 0) {
5332b15969dSZdenek Styblik 		print_sensor_thresh_usage();
534c18ec02fSPetter Reinholdtsen 		return 0;
535c18ec02fSPetter Reinholdtsen 	}
536c18ec02fSPetter Reinholdtsen 
537c18ec02fSPetter Reinholdtsen 	id = argv[0];
538c18ec02fSPetter Reinholdtsen 	thresh = argv[1];
539c18ec02fSPetter Reinholdtsen 
540c18ec02fSPetter Reinholdtsen 	if (strncmp(thresh, "upper", 5) == 0) {
541c18ec02fSPetter Reinholdtsen 		if (argc < 5) {
542c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR,
543c18ec02fSPetter Reinholdtsen 				"usage: sensor thresh <id> upper <unc> <ucr> <unr>");
544c18ec02fSPetter Reinholdtsen 			return -1;
545c18ec02fSPetter Reinholdtsen 		}
546c18ec02fSPetter Reinholdtsen 		allUpper = 1;
547c18ec02fSPetter Reinholdtsen 		if (str2double(argv[2], &setting1) != 0) {
548c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Given unc '%s' is invalid.",
549c18ec02fSPetter Reinholdtsen 					argv[2]);
550c18ec02fSPetter Reinholdtsen 			return (-1);
551c18ec02fSPetter Reinholdtsen 		}
552c18ec02fSPetter Reinholdtsen 		if (str2double(argv[3], &setting2) != 0) {
553c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Given ucr '%s' is invalid.",
554c18ec02fSPetter Reinholdtsen 					argv[3]);
555c18ec02fSPetter Reinholdtsen 			return (-1);
556c18ec02fSPetter Reinholdtsen 		}
557c18ec02fSPetter Reinholdtsen 		if (str2double(argv[4], &setting3) != 0) {
558c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Given unr '%s' is invalid.",
559c18ec02fSPetter Reinholdtsen 					argv[4]);
560c18ec02fSPetter Reinholdtsen 			return (-1);
561c18ec02fSPetter Reinholdtsen 		}
562c18ec02fSPetter Reinholdtsen 	} else if (strncmp(thresh, "lower", 5) == 0) {
563c18ec02fSPetter Reinholdtsen 		if (argc < 5) {
564c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR,
5655c85c7bcSZdenek Styblik 				"usage: sensor thresh <id> lower <lnr> <lcr> <lnc>");
566c18ec02fSPetter Reinholdtsen 			return -1;
567c18ec02fSPetter Reinholdtsen 		}
568c18ec02fSPetter Reinholdtsen 		allLower = 1;
569c18ec02fSPetter Reinholdtsen 		if (str2double(argv[2], &setting1) != 0) {
570c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Given lnc '%s' is invalid.",
571c18ec02fSPetter Reinholdtsen 					argv[2]);
572c18ec02fSPetter Reinholdtsen 			return (-1);
573c18ec02fSPetter Reinholdtsen 		}
574c18ec02fSPetter Reinholdtsen 		if (str2double(argv[3], &setting2) != 0) {
575c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Given lcr '%s' is invalid.",
576c18ec02fSPetter Reinholdtsen 					argv[3]);
577c18ec02fSPetter Reinholdtsen 			return (-1);
578c18ec02fSPetter Reinholdtsen 		}
579c18ec02fSPetter Reinholdtsen 		if (str2double(argv[4], &setting3) != 0) {
580c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Given lnr '%s' is invalid.",
581c18ec02fSPetter Reinholdtsen 					argv[4]);
582c18ec02fSPetter Reinholdtsen 			return (-1);
583c18ec02fSPetter Reinholdtsen 		}
584c18ec02fSPetter Reinholdtsen 	} else {
585c18ec02fSPetter Reinholdtsen 		if (strncmp(thresh, "unr", 3) == 0)
586c18ec02fSPetter Reinholdtsen 			settingMask = UPPER_NON_RECOV_SPECIFIED;
587c18ec02fSPetter Reinholdtsen 		else if (strncmp(thresh, "ucr", 3) == 0)
588c18ec02fSPetter Reinholdtsen 			settingMask = UPPER_CRIT_SPECIFIED;
589c18ec02fSPetter Reinholdtsen 		else if (strncmp(thresh, "unc", 3) == 0)
590c18ec02fSPetter Reinholdtsen 			settingMask = UPPER_NON_CRIT_SPECIFIED;
591c18ec02fSPetter Reinholdtsen 		else if (strncmp(thresh, "lnc", 3) == 0)
592c18ec02fSPetter Reinholdtsen 			settingMask = LOWER_NON_CRIT_SPECIFIED;
593c18ec02fSPetter Reinholdtsen 		else if (strncmp(thresh, "lcr", 3) == 0)
594c18ec02fSPetter Reinholdtsen 			settingMask = LOWER_CRIT_SPECIFIED;
595c18ec02fSPetter Reinholdtsen 		else if (strncmp(thresh, "lnr", 3) == 0)
596c18ec02fSPetter Reinholdtsen 			settingMask = LOWER_NON_RECOV_SPECIFIED;
597c18ec02fSPetter Reinholdtsen 		else {
598c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR,
599c18ec02fSPetter Reinholdtsen 				"Valid threshold '%s' for sensor '%s' not specified!",
600c18ec02fSPetter Reinholdtsen 				thresh, id);
601c18ec02fSPetter Reinholdtsen 			return -1;
602c18ec02fSPetter Reinholdtsen 		}
603c18ec02fSPetter Reinholdtsen 		if (str2double(argv[2], &setting1) != 0) {
604c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR,
605c18ec02fSPetter Reinholdtsen 					"Given %s threshold value '%s' is invalid.",
606c18ec02fSPetter Reinholdtsen 					thresh, argv[2]);
607c18ec02fSPetter Reinholdtsen 			return (-1);
608c18ec02fSPetter Reinholdtsen 		}
609c18ec02fSPetter Reinholdtsen 	}
610c18ec02fSPetter Reinholdtsen 
611c18ec02fSPetter Reinholdtsen 	printf("Locating sensor record '%s'...\n", id);
612c18ec02fSPetter Reinholdtsen 
613c18ec02fSPetter Reinholdtsen 	/* lookup by sensor name */
614c18ec02fSPetter Reinholdtsen 	sdr = ipmi_sdr_find_sdr_byid(intf, id);
615c18ec02fSPetter Reinholdtsen 	if (sdr == NULL) {
616c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Sensor data record not found!");
617c18ec02fSPetter Reinholdtsen 		return -1;
618c18ec02fSPetter Reinholdtsen 	}
619c18ec02fSPetter Reinholdtsen 
620c18ec02fSPetter Reinholdtsen 	if (sdr->type != SDR_RECORD_TYPE_FULL_SENSOR) {
621c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Invalid sensor type %02x", sdr->type);
622c18ec02fSPetter Reinholdtsen 		return -1;
623c18ec02fSPetter Reinholdtsen 	}
624c18ec02fSPetter Reinholdtsen 
625c18ec02fSPetter Reinholdtsen 	if (!IS_THRESHOLD_SENSOR(sdr->record.common)) {
626c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Invalid sensor event type %02x", sdr->record.common->event_type);
627c18ec02fSPetter Reinholdtsen 		return -1;
628c18ec02fSPetter Reinholdtsen 	}
629c18ec02fSPetter Reinholdtsen 
630c18ec02fSPetter Reinholdtsen 
631c18ec02fSPetter Reinholdtsen 	if (allUpper) {
632c18ec02fSPetter Reinholdtsen 		settingMask = UPPER_NON_CRIT_SPECIFIED;
633c18ec02fSPetter Reinholdtsen 		printf("Setting sensor \"%s\" %s threshold to %.3f\n",
634c18ec02fSPetter Reinholdtsen 		       sdr->record.full->id_string,
635c18ec02fSPetter Reinholdtsen 		       val2str(settingMask, threshold_vals), setting1);
636c18ec02fSPetter Reinholdtsen 		ret = __ipmi_sensor_set_threshold(intf,
637c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.
638c18ec02fSPetter Reinholdtsen 						  sensor_num, settingMask,
639c18ec02fSPetter Reinholdtsen 						  __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1),
640c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.owner_id,
641c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.lun,
642c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.channel);
643c18ec02fSPetter Reinholdtsen 
644c18ec02fSPetter Reinholdtsen 		settingMask = UPPER_CRIT_SPECIFIED;
645c18ec02fSPetter Reinholdtsen 		printf("Setting sensor \"%s\" %s threshold to %.3f\n",
646c18ec02fSPetter Reinholdtsen 		       sdr->record.full->id_string,
647c18ec02fSPetter Reinholdtsen 		       val2str(settingMask, threshold_vals), setting2);
648c18ec02fSPetter Reinholdtsen 		ret = __ipmi_sensor_set_threshold(intf,
649c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.
650c18ec02fSPetter Reinholdtsen 						  sensor_num, settingMask,
651c18ec02fSPetter Reinholdtsen 						  __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting2),
652c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.owner_id,
653c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.lun,
654c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.channel);
655c18ec02fSPetter Reinholdtsen 
656c18ec02fSPetter Reinholdtsen 		settingMask = UPPER_NON_RECOV_SPECIFIED;
657c18ec02fSPetter Reinholdtsen 		printf("Setting sensor \"%s\" %s threshold to %.3f\n",
658c18ec02fSPetter Reinholdtsen 		       sdr->record.full->id_string,
659c18ec02fSPetter Reinholdtsen 		       val2str(settingMask, threshold_vals), setting3);
660c18ec02fSPetter Reinholdtsen 		ret = __ipmi_sensor_set_threshold(intf,
661c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.
662c18ec02fSPetter Reinholdtsen 						  sensor_num, settingMask,
663c18ec02fSPetter Reinholdtsen 						  __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting3),
664c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.owner_id,
665c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.lun,
666c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.channel);
667c18ec02fSPetter Reinholdtsen 	} else if (allLower) {
668c18ec02fSPetter Reinholdtsen 		settingMask = LOWER_NON_RECOV_SPECIFIED;
669c18ec02fSPetter Reinholdtsen 		printf("Setting sensor \"%s\" %s threshold to %.3f\n",
670c18ec02fSPetter Reinholdtsen 		       sdr->record.full->id_string,
671c18ec02fSPetter Reinholdtsen 		       val2str(settingMask, threshold_vals), setting1);
672c18ec02fSPetter Reinholdtsen 		ret = __ipmi_sensor_set_threshold(intf,
673c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.
674c18ec02fSPetter Reinholdtsen 						  sensor_num, settingMask,
675c18ec02fSPetter Reinholdtsen 						  __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1),
676c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.owner_id,
677c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.lun,
678c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.channel);
679c18ec02fSPetter Reinholdtsen 
680c18ec02fSPetter Reinholdtsen 		settingMask = LOWER_CRIT_SPECIFIED;
681c18ec02fSPetter Reinholdtsen 		printf("Setting sensor \"%s\" %s threshold to %.3f\n",
682c18ec02fSPetter Reinholdtsen 		       sdr->record.full->id_string,
683c18ec02fSPetter Reinholdtsen 		       val2str(settingMask, threshold_vals), setting2);
684c18ec02fSPetter Reinholdtsen 		ret = __ipmi_sensor_set_threshold(intf,
685c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.
686c18ec02fSPetter Reinholdtsen 						  sensor_num, settingMask,
687c18ec02fSPetter Reinholdtsen 						  __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting2),
688c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.owner_id,
689c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.lun,
690c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.channel);
691c18ec02fSPetter Reinholdtsen 
692c18ec02fSPetter Reinholdtsen 		settingMask = LOWER_NON_CRIT_SPECIFIED;
693c18ec02fSPetter Reinholdtsen 		printf("Setting sensor \"%s\" %s threshold to %.3f\n",
694c18ec02fSPetter Reinholdtsen 		       sdr->record.full->id_string,
695c18ec02fSPetter Reinholdtsen 		       val2str(settingMask, threshold_vals), setting3);
696c18ec02fSPetter Reinholdtsen 		ret = __ipmi_sensor_set_threshold(intf,
697c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.
698c18ec02fSPetter Reinholdtsen 						  sensor_num, settingMask,
699c18ec02fSPetter Reinholdtsen 						  __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting3),
700c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.owner_id,
701c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.lun,
702c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.channel);
703c18ec02fSPetter Reinholdtsen 	} else {
704c18ec02fSPetter Reinholdtsen 
705c18ec02fSPetter Reinholdtsen 	/*
706c18ec02fSPetter Reinholdtsen  	 * Current implementation doesn't check for the valid setting of upper non critical and other thresholds.
707c18ec02fSPetter Reinholdtsen  	 * In the below logic:
708c18ec02fSPetter Reinholdtsen  	 * 	Get all the current reading of the sensor i.e. unc, uc, lc,lnc.
709c18ec02fSPetter Reinholdtsen  	 * 	Validate the values given by the user.
710c18ec02fSPetter Reinholdtsen  	 * 	If the values are not correct, then popup with the Error message and return.
711c18ec02fSPetter Reinholdtsen  	 */
712c18ec02fSPetter Reinholdtsen 	/*
713c18ec02fSPetter Reinholdtsen 	 * Get current reading
714c18ec02fSPetter Reinholdtsen 	 */
715c18ec02fSPetter Reinholdtsen 		rsp = ipmi_sdr_get_sensor_reading_ipmb(intf,
716c18ec02fSPetter Reinholdtsen 					       sdr->record.common->keys.sensor_num,
717c18ec02fSPetter Reinholdtsen 					       sdr->record.common->keys.owner_id,
718c18ec02fSPetter Reinholdtsen 					       sdr->record.common->keys.lun,sdr->record.common->keys.channel);
719c18ec02fSPetter Reinholdtsen 		rsp = ipmi_sdr_get_sensor_thresholds(intf,
720c18ec02fSPetter Reinholdtsen 						sdr->record.common->keys.sensor_num,
721c18ec02fSPetter Reinholdtsen 						sdr->record.common->keys.owner_id,
722c18ec02fSPetter Reinholdtsen 						sdr->record.common->keys.lun,
723c18ec02fSPetter Reinholdtsen 						sdr->record.common->keys.channel);
724c18ec02fSPetter Reinholdtsen 		if ((rsp == NULL) || (rsp->ccode > 0)) {
725c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Sensor data record not found!");
726c18ec02fSPetter Reinholdtsen 				return -1;
727c18ec02fSPetter Reinholdtsen 		}
728c18ec02fSPetter Reinholdtsen 		for(i=1;i<=6;i++) {
729c18ec02fSPetter Reinholdtsen 			val[i] = sdr_convert_sensor_reading(sdr->record.full, rsp->data[i]);
730c18ec02fSPetter Reinholdtsen 			if(val[i] < 0)
731c18ec02fSPetter Reinholdtsen 				val[i] = 0;
732c18ec02fSPetter Reinholdtsen 		}
733c18ec02fSPetter Reinholdtsen 		/* Check for the valid Upper non recovarable Value.*/
734c18ec02fSPetter Reinholdtsen 		if( (settingMask & UPPER_NON_RECOV_SPECIFIED) ) {
735c18ec02fSPetter Reinholdtsen 
736c18ec02fSPetter Reinholdtsen 			if( (rsp->data[0] & UPPER_NON_RECOV_SPECIFIED) &&
737c18ec02fSPetter Reinholdtsen 				(( (rsp->data[0] & UPPER_CRIT_SPECIFIED) && ( setting1 <= val[5])) ||
738c18ec02fSPetter Reinholdtsen 					( (rsp->data[0] & UPPER_NON_CRIT_SPECIFIED) && ( setting1 <= val[4]))) )
739c18ec02fSPetter Reinholdtsen 			{
740c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, INVALID_THRESHOLD);
741c18ec02fSPetter Reinholdtsen 				return -1;
742c18ec02fSPetter Reinholdtsen 			}
743c18ec02fSPetter Reinholdtsen 		} else if( (settingMask & UPPER_CRIT_SPECIFIED) ) { 		/* Check for the valid Upper critical Value.*/
744c18ec02fSPetter Reinholdtsen 			if( (rsp->data[0] & UPPER_CRIT_SPECIFIED) &&
745c18ec02fSPetter Reinholdtsen 				(((rsp->data[0] & UPPER_NON_RECOV_SPECIFIED)&& ( setting1 >= val[6])) ||
746c18ec02fSPetter Reinholdtsen 				((rsp->data[0] & UPPER_NON_CRIT_SPECIFIED)&&( setting1 <= val[4]))) )
747c18ec02fSPetter Reinholdtsen 			{
748c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, INVALID_THRESHOLD);
749c18ec02fSPetter Reinholdtsen 				return -1;
750c18ec02fSPetter Reinholdtsen 			}
751c18ec02fSPetter Reinholdtsen 		} else if( (settingMask & UPPER_NON_CRIT_SPECIFIED) ) {  		/* Check for the valid Upper non critical Value.*/
752c18ec02fSPetter Reinholdtsen 			if( (rsp->data[0] & UPPER_NON_CRIT_SPECIFIED) &&
753c18ec02fSPetter Reinholdtsen 				(((rsp->data[0] & UPPER_NON_RECOV_SPECIFIED)&&( setting1 >= val[6])) ||
754c18ec02fSPetter Reinholdtsen 				((rsp->data[0] & UPPER_CRIT_SPECIFIED)&&( setting1 >= val[5])) ||
755c18ec02fSPetter Reinholdtsen 				((rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)&&( setting1 <= val[1]))) )
756c18ec02fSPetter Reinholdtsen 			{
757c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, INVALID_THRESHOLD);
758c18ec02fSPetter Reinholdtsen 				return -1;
759c18ec02fSPetter Reinholdtsen 			}
760c18ec02fSPetter Reinholdtsen 		} else if( (settingMask & LOWER_NON_CRIT_SPECIFIED) ) {		/* Check for the valid lower non critical Value.*/
761c18ec02fSPetter Reinholdtsen 			if( (rsp->data[0] & LOWER_NON_CRIT_SPECIFIED) &&
762c18ec02fSPetter Reinholdtsen 				(((rsp->data[0] & LOWER_CRIT_SPECIFIED)&&( setting1 <= val[2])) ||
763c18ec02fSPetter Reinholdtsen 				((rsp->data[0] & LOWER_NON_RECOV_SPECIFIED)&&( setting1 <= val[3]))||
764c18ec02fSPetter Reinholdtsen 				((rsp->data[0] & UPPER_NON_CRIT_SPECIFIED)&&( setting1 >= val[4]))) )
765c18ec02fSPetter Reinholdtsen 			{
766c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, INVALID_THRESHOLD);
767c18ec02fSPetter Reinholdtsen 				return -1;
768c18ec02fSPetter Reinholdtsen 			}
769c18ec02fSPetter Reinholdtsen 		} else if( (settingMask & LOWER_CRIT_SPECIFIED) ) {		/* Check for the valid lower critical Value.*/
770c18ec02fSPetter Reinholdtsen 			if( (rsp->data[0] & LOWER_CRIT_SPECIFIED) &&
771c18ec02fSPetter Reinholdtsen 				(((rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)&&( setting1 >= val[1])) ||
772c18ec02fSPetter Reinholdtsen 				((rsp->data[0] & LOWER_NON_RECOV_SPECIFIED)&&( setting1 <= val[3]))) )
773c18ec02fSPetter Reinholdtsen 			{
774c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, INVALID_THRESHOLD);
775c18ec02fSPetter Reinholdtsen 				return -1;
776c18ec02fSPetter Reinholdtsen 			}
777c18ec02fSPetter Reinholdtsen 		} else if( (settingMask & LOWER_NON_RECOV_SPECIFIED) ) {		/* Check for the valid lower non recovarable Value.*/
778c18ec02fSPetter Reinholdtsen 			if( (rsp->data[0] & LOWER_NON_RECOV_SPECIFIED) &&
779c18ec02fSPetter Reinholdtsen 				(((rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)&&( setting1 >= val[1])) ||
780c18ec02fSPetter Reinholdtsen 				((rsp->data[0] & LOWER_CRIT_SPECIFIED)&&( setting1 >= val[2]))) )
781c18ec02fSPetter Reinholdtsen 			{
782c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, INVALID_THRESHOLD);
783c18ec02fSPetter Reinholdtsen 				return -1;
784c18ec02fSPetter Reinholdtsen 			}
785c18ec02fSPetter Reinholdtsen 		} else {			/* None of this Then Return with error messages.*/
786c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, INVALID_THRESHOLD);
787c18ec02fSPetter Reinholdtsen 			return -1;
788c18ec02fSPetter Reinholdtsen 		}
789c18ec02fSPetter Reinholdtsen 
790c18ec02fSPetter Reinholdtsen 
791c18ec02fSPetter Reinholdtsen 		printf("Setting sensor \"%s\" %s threshold to %.3f\n",
792c18ec02fSPetter Reinholdtsen 		       sdr->record.full->id_string,
793c18ec02fSPetter Reinholdtsen 		       val2str(settingMask, threshold_vals), setting1);
794c18ec02fSPetter Reinholdtsen 
795c18ec02fSPetter Reinholdtsen 		ret = __ipmi_sensor_set_threshold(intf,
796c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.
797c18ec02fSPetter Reinholdtsen 						  sensor_num, settingMask,
798c18ec02fSPetter Reinholdtsen 						  __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1),
799c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.owner_id,
800c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.lun,
801c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.channel);
802c18ec02fSPetter Reinholdtsen 	}
803c18ec02fSPetter Reinholdtsen 
804c18ec02fSPetter Reinholdtsen 	return ret;
805c18ec02fSPetter Reinholdtsen }
806c18ec02fSPetter Reinholdtsen 
807c18ec02fSPetter Reinholdtsen static int
ipmi_sensor_get_reading(struct ipmi_intf * intf,int argc,char ** argv)808c18ec02fSPetter Reinholdtsen ipmi_sensor_get_reading(struct ipmi_intf *intf, int argc, char **argv)
809c18ec02fSPetter Reinholdtsen {
810c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *sdr;
811c18ec02fSPetter Reinholdtsen 	int i, rc=0;
812c18ec02fSPetter Reinholdtsen 
813c18ec02fSPetter Reinholdtsen 	if (argc < 1 || strncmp(argv[0], "help", 4) == 0) {
814c18ec02fSPetter Reinholdtsen 		lprintf(LOG_NOTICE, "sensor reading <id> ... [id]");
815c18ec02fSPetter Reinholdtsen 		lprintf(LOG_NOTICE, "   id        : name of desired sensor");
816c18ec02fSPetter Reinholdtsen 		return -1;
817c18ec02fSPetter Reinholdtsen 	}
818c18ec02fSPetter Reinholdtsen 
819c18ec02fSPetter Reinholdtsen 	for (i = 0; i < argc; i++) {
820c18ec02fSPetter Reinholdtsen 		sdr = ipmi_sdr_find_sdr_byid(intf, argv[i]);
821c18ec02fSPetter Reinholdtsen 		if (sdr == NULL) {
822c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Sensor \"%s\" not found!",
823c18ec02fSPetter Reinholdtsen 				argv[i]);
824c18ec02fSPetter Reinholdtsen 			rc = -1;
825c18ec02fSPetter Reinholdtsen 			continue;
826c18ec02fSPetter Reinholdtsen 		}
827c18ec02fSPetter Reinholdtsen 
828c18ec02fSPetter Reinholdtsen 		switch (sdr->type) {
829c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FULL_SENSOR:
830c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_COMPACT_SENSOR:
831c18ec02fSPetter Reinholdtsen 		{
832c18ec02fSPetter Reinholdtsen 			struct sensor_reading *sr;
833c18ec02fSPetter Reinholdtsen 			struct sdr_record_common_sensor	*sensor = sdr->record.common;
834c18ec02fSPetter Reinholdtsen 			sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr->type, 3);
835c18ec02fSPetter Reinholdtsen 
836c18ec02fSPetter Reinholdtsen 			if (sr == NULL) {
837c18ec02fSPetter Reinholdtsen 				rc = -1;
838c18ec02fSPetter Reinholdtsen 				continue;
839c18ec02fSPetter Reinholdtsen 			}
840c18ec02fSPetter Reinholdtsen 
841c18ec02fSPetter Reinholdtsen 			if (!sr->full)
842c18ec02fSPetter Reinholdtsen 				continue;
843c18ec02fSPetter Reinholdtsen 
844c18ec02fSPetter Reinholdtsen 			if (!sr->s_reading_valid)
845c18ec02fSPetter Reinholdtsen 				continue;
846c18ec02fSPetter Reinholdtsen 
847c18ec02fSPetter Reinholdtsen 			if (!sr->s_has_analog_value) {
848c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, "Sensor \"%s\" is a discrete sensor!", argv[i]);
849c18ec02fSPetter Reinholdtsen 				continue;
850c18ec02fSPetter Reinholdtsen 			}
851c18ec02fSPetter Reinholdtsen 			if (csv_output)
852c18ec02fSPetter Reinholdtsen 				printf("%s,%s\n", argv[i], sr->s_a_str);
853c18ec02fSPetter Reinholdtsen 			else
854c18ec02fSPetter Reinholdtsen 				printf("%-16s | %s\n", argv[i], sr->s_a_str);
855c18ec02fSPetter Reinholdtsen 
856c18ec02fSPetter Reinholdtsen 			break;
857c18ec02fSPetter Reinholdtsen 		}
858c18ec02fSPetter Reinholdtsen 		default:
859c18ec02fSPetter Reinholdtsen 			continue;
860c18ec02fSPetter Reinholdtsen 		}
861c18ec02fSPetter Reinholdtsen 	}
862c18ec02fSPetter Reinholdtsen 
863c18ec02fSPetter Reinholdtsen 	return rc;
864c18ec02fSPetter Reinholdtsen }
865c18ec02fSPetter Reinholdtsen 
866c18ec02fSPetter Reinholdtsen static int
ipmi_sensor_get(struct ipmi_intf * intf,int argc,char ** argv)867c18ec02fSPetter Reinholdtsen ipmi_sensor_get(struct ipmi_intf *intf, int argc, char **argv)
868c18ec02fSPetter Reinholdtsen {
869c18ec02fSPetter Reinholdtsen 	int i, v;
870c18ec02fSPetter Reinholdtsen 	int rc = 0;
871c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *sdr;
872c18ec02fSPetter Reinholdtsen 
873c18ec02fSPetter Reinholdtsen 	if (argc < 1) {
874c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Not enough parameters given.");
875aa8bac2dSZdenek Styblik 		print_sensor_get_usage();
876c18ec02fSPetter Reinholdtsen 		return (-1);
877c18ec02fSPetter Reinholdtsen 	} else if (strcmp(argv[0], "help") == 0) {
878aa8bac2dSZdenek Styblik 		print_sensor_get_usage();
879c18ec02fSPetter Reinholdtsen 		return 0;
880c18ec02fSPetter Reinholdtsen 	}
881c18ec02fSPetter Reinholdtsen 	printf("Locating sensor record...\n");
882c18ec02fSPetter Reinholdtsen 	/* lookup by sensor name */
883c18ec02fSPetter Reinholdtsen 	for (i = 0; i < argc; i++) {
884c18ec02fSPetter Reinholdtsen 		sdr = ipmi_sdr_find_sdr_byid(intf, argv[i]);
885c18ec02fSPetter Reinholdtsen 		if (sdr == NULL) {
886c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Sensor data record \"%s\" not found!",
887c18ec02fSPetter Reinholdtsen 					argv[i]);
888c18ec02fSPetter Reinholdtsen 			rc = -1;
889c18ec02fSPetter Reinholdtsen 			continue;
890c18ec02fSPetter Reinholdtsen 		}
891c18ec02fSPetter Reinholdtsen 		/* need to set verbose level to 1 */
892c18ec02fSPetter Reinholdtsen 		v = verbose;
893c18ec02fSPetter Reinholdtsen 		verbose = 1;
894*0eaa2eaeSZdenek Styblik 		switch (sdr->type) {
895*0eaa2eaeSZdenek Styblik 		case SDR_RECORD_TYPE_FULL_SENSOR:
896*0eaa2eaeSZdenek Styblik 		case SDR_RECORD_TYPE_COMPACT_SENSOR:
897*0eaa2eaeSZdenek Styblik 			if (ipmi_sensor_print_fc(intf,
898*0eaa2eaeSZdenek Styblik 					(struct sdr_record_common_sensor *) sdr->record.common,
899*0eaa2eaeSZdenek Styblik 					sdr->type)) {
900*0eaa2eaeSZdenek Styblik 				rc = -1;
901*0eaa2eaeSZdenek Styblik 			}
902*0eaa2eaeSZdenek Styblik 			break;
903*0eaa2eaeSZdenek Styblik 		default:
904c18ec02fSPetter Reinholdtsen 			if (ipmi_sdr_print_listentry(intf, sdr) < 0) {
905c18ec02fSPetter Reinholdtsen 				rc = (-1);
906c18ec02fSPetter Reinholdtsen 			}
907*0eaa2eaeSZdenek Styblik 			break;
908*0eaa2eaeSZdenek Styblik 		}
909c18ec02fSPetter Reinholdtsen 		verbose = v;
910c18ec02fSPetter Reinholdtsen 		sdr = NULL;
911c18ec02fSPetter Reinholdtsen 	}
912c18ec02fSPetter Reinholdtsen 	return rc;
913c18ec02fSPetter Reinholdtsen }
914c18ec02fSPetter Reinholdtsen 
915c18ec02fSPetter Reinholdtsen int
ipmi_sensor_main(struct ipmi_intf * intf,int argc,char ** argv)916c18ec02fSPetter Reinholdtsen ipmi_sensor_main(struct ipmi_intf *intf, int argc, char **argv)
917c18ec02fSPetter Reinholdtsen {
918c18ec02fSPetter Reinholdtsen 	int rc = 0;
919c18ec02fSPetter Reinholdtsen 
920c18ec02fSPetter Reinholdtsen 	if (argc == 0) {
921c18ec02fSPetter Reinholdtsen 		rc = ipmi_sensor_list(intf);
922c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[0], "help", 4) == 0) {
923c18ec02fSPetter Reinholdtsen 		lprintf(LOG_NOTICE, "Sensor Commands:  list thresh get reading");
924c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[0], "list", 4) == 0) {
925c18ec02fSPetter Reinholdtsen 		rc = ipmi_sensor_list(intf);
926c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[0], "thresh", 5) == 0) {
927c18ec02fSPetter Reinholdtsen 		rc = ipmi_sensor_set_threshold(intf, argc - 1, &argv[1]);
928c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[0], "get", 3) == 0) {
929c18ec02fSPetter Reinholdtsen 		rc = ipmi_sensor_get(intf, argc - 1, &argv[1]);
930c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[0], "reading", 7) == 0) {
931c18ec02fSPetter Reinholdtsen 		rc = ipmi_sensor_get_reading(intf, argc - 1, &argv[1]);
932c18ec02fSPetter Reinholdtsen 	} else {
933c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Invalid sensor command: %s", argv[0]);
934c18ec02fSPetter Reinholdtsen 		rc = -1;
935c18ec02fSPetter Reinholdtsen 	}
936c18ec02fSPetter Reinholdtsen 
937c18ec02fSPetter Reinholdtsen 	return rc;
938c18ec02fSPetter Reinholdtsen }
939c18ec02fSPetter Reinholdtsen 
940aa8bac2dSZdenek Styblik /* print_sensor_get_usage - print usage for # ipmitool sensor get NAC;
941c18ec02fSPetter Reinholdtsen  *
942c18ec02fSPetter Reinholdtsen  * @returns: void
943c18ec02fSPetter Reinholdtsen  */
944c18ec02fSPetter Reinholdtsen void
print_sensor_get_usage()945aa8bac2dSZdenek Styblik print_sensor_get_usage()
946c18ec02fSPetter Reinholdtsen {
947c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "sensor get <id> ... [id]");
948c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "   id        : name of desired sensor");
949c18ec02fSPetter Reinholdtsen }
9502b15969dSZdenek Styblik 
951aa8bac2dSZdenek Styblik /* print_sensor_thresh_set_usage - print usage for # ipmitool sensor thresh;
9522b15969dSZdenek Styblik  *
9532b15969dSZdenek Styblik  * @returns: void
9542b15969dSZdenek Styblik  */
9552b15969dSZdenek Styblik void
print_sensor_thresh_usage()9562b15969dSZdenek Styblik print_sensor_thresh_usage()
9572b15969dSZdenek Styblik {
9582b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9592b15969dSZdenek Styblik "sensor thresh <id> <threshold> <setting>");
9602b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9612b15969dSZdenek Styblik "   id        : name of the sensor for which threshold is to be set");
9622b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9632b15969dSZdenek Styblik "   threshold : which threshold to set");
9642b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9652b15969dSZdenek Styblik "                 unr = upper non-recoverable");
9662b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9672b15969dSZdenek Styblik "                 ucr = upper critical");
9682b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9692b15969dSZdenek Styblik "                 unc = upper non-critical");
9702b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9712b15969dSZdenek Styblik "                 lnc = lower non-critical");
9722b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9732b15969dSZdenek Styblik "                 lcr = lower critical");
9742b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9752b15969dSZdenek Styblik "                 lnr = lower non-recoverable");
9762b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9772b15969dSZdenek Styblik "   setting   : the value to set the threshold to");
9782b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9792b15969dSZdenek Styblik "");
9802b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9812b15969dSZdenek Styblik "sensor thresh <id> lower <lnr> <lcr> <lnc>");
9822b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9832b15969dSZdenek Styblik "   Set all lower thresholds at the same time");
9842b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9852b15969dSZdenek Styblik "");
9862b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9872b15969dSZdenek Styblik "sensor thresh <id> upper <unc> <ucr> <unr>");
9882b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9892b15969dSZdenek Styblik "   Set all upper thresholds at the same time");
9902b15969dSZdenek Styblik 	lprintf(LOG_NOTICE, "");
9912b15969dSZdenek Styblik }
992