xref: /openbmc/ipmitool/lib/ipmi_sensor.c (revision 5c85c7bc)
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
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 *
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
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 	const char *id;
164c18ec02fSPetter Reinholdtsen 	struct sensor_reading *sr;
165c18ec02fSPetter Reinholdtsen 
166c18ec02fSPetter Reinholdtsen 	sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 3);
167c18ec02fSPetter Reinholdtsen 
168c18ec02fSPetter Reinholdtsen 	if (sr == NULL) {
169c18ec02fSPetter Reinholdtsen 		return -1;
170c18ec02fSPetter Reinholdtsen 	}
171c18ec02fSPetter Reinholdtsen 
172c18ec02fSPetter Reinholdtsen 	if (csv_output) {
173c18ec02fSPetter Reinholdtsen 		/* NOT IMPLEMENTED */
174c18ec02fSPetter Reinholdtsen 	} else {
175c18ec02fSPetter Reinholdtsen 		if (verbose == 0) {
176c18ec02fSPetter Reinholdtsen 			/* output format
177c18ec02fSPetter Reinholdtsen 			 *   id value units status thresholds....
178c18ec02fSPetter Reinholdtsen 			 */
179c18ec02fSPetter Reinholdtsen 			printf("%-16s ", sr->s_id);
180c18ec02fSPetter Reinholdtsen 			if (sr->s_reading_valid) {
181c18ec02fSPetter Reinholdtsen 				if (sr->s_has_analog_value) {
182c18ec02fSPetter Reinholdtsen 					/* don't show discrete component */
183c18ec02fSPetter Reinholdtsen 					printf("| %-10s | %-10s | %-6s",
184c18ec02fSPetter Reinholdtsen 					       sr->s_a_str, sr->s_a_units, "ok");
185c18ec02fSPetter Reinholdtsen 				} else {
186c18ec02fSPetter Reinholdtsen 					printf("| 0x%-8x | %-10s | 0x%02x%02x",
187c18ec02fSPetter Reinholdtsen 					       sr->s_reading, "discrete",
188c18ec02fSPetter Reinholdtsen 					       sr->s_data2, sr->s_data3);
189c18ec02fSPetter Reinholdtsen 				}
190c18ec02fSPetter Reinholdtsen 			} else {
191c18ec02fSPetter Reinholdtsen 				printf("| %-10s | %-10s | %-6s",
192c18ec02fSPetter Reinholdtsen 				       "na", "discrete", "na");
193c18ec02fSPetter Reinholdtsen 			}
194c18ec02fSPetter Reinholdtsen 			printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s",
195c18ec02fSPetter Reinholdtsen 			       "na", "na", "na", "na", "na", "na");
196c18ec02fSPetter Reinholdtsen 
197c18ec02fSPetter Reinholdtsen 			printf("\n");
198c18ec02fSPetter Reinholdtsen 		} else {
199c18ec02fSPetter Reinholdtsen 			printf("Sensor ID              : %s (0x%x)\n",
200c18ec02fSPetter Reinholdtsen 			       sr->s_id, sensor->keys.sensor_num);
201c18ec02fSPetter Reinholdtsen 			printf(" Entity ID             : %d.%d\n",
202c18ec02fSPetter Reinholdtsen 			       sensor->entity.id, sensor->entity.instance);
203c18ec02fSPetter Reinholdtsen 			printf(" Sensor Type (Discrete): %s\n",
204c18ec02fSPetter Reinholdtsen 			       ipmi_sdr_get_sensor_type_desc(sensor->sensor.
205c18ec02fSPetter Reinholdtsen 							     type));
206c18ec02fSPetter Reinholdtsen 			if( sr->s_reading_valid )
207c18ec02fSPetter Reinholdtsen 			{
208c18ec02fSPetter Reinholdtsen 				if (sr->s_has_analog_value) {
209c18ec02fSPetter Reinholdtsen 					printf(" Sensor Reading        : %s %s\n", sr->s_a_str, sr->s_a_units);
210c18ec02fSPetter Reinholdtsen 				}
211c18ec02fSPetter Reinholdtsen 				ipmi_sdr_print_discrete_state("States Asserted",
212c18ec02fSPetter Reinholdtsen 							sensor->sensor.type,
213c18ec02fSPetter Reinholdtsen 							sensor->event_type,
214c18ec02fSPetter Reinholdtsen 							sr->s_data2,
215c18ec02fSPetter Reinholdtsen 							sr->s_data3);
216c18ec02fSPetter Reinholdtsen 				printf("\n");
217c18ec02fSPetter Reinholdtsen 			} else {
218c18ec02fSPetter Reinholdtsen 			   printf(" Unable to read sensor: Device Not Present\n\n");
219c18ec02fSPetter Reinholdtsen 			}
220c18ec02fSPetter Reinholdtsen 	   }
221c18ec02fSPetter Reinholdtsen 	}
222c18ec02fSPetter Reinholdtsen 
223c18ec02fSPetter Reinholdtsen 	return (sr->s_reading_valid ? 0 : -1 );
224c18ec02fSPetter Reinholdtsen }
225c18ec02fSPetter Reinholdtsen 
226c18ec02fSPetter Reinholdtsen static void
227c18ec02fSPetter Reinholdtsen print_thresh_setting(struct sdr_record_full_sensor *full,
228c18ec02fSPetter Reinholdtsen 			 uint8_t thresh_is_avail, uint8_t setting,
229c18ec02fSPetter Reinholdtsen 			 const char *field_sep,
230c18ec02fSPetter Reinholdtsen 			 const char *analog_fmt,
231c18ec02fSPetter Reinholdtsen 			 const char *discrete_fmt,
232c18ec02fSPetter Reinholdtsen 			 const char *na_fmt)
233c18ec02fSPetter Reinholdtsen {
234c18ec02fSPetter Reinholdtsen 	printf("%s", field_sep);
235c18ec02fSPetter Reinholdtsen 	if (!thresh_is_avail) {
236c18ec02fSPetter Reinholdtsen 		printf(na_fmt, "na");
237c18ec02fSPetter Reinholdtsen 		return;
238c18ec02fSPetter Reinholdtsen 	}
239c18ec02fSPetter Reinholdtsen 	if (full && !UNITS_ARE_DISCRETE(&full->cmn)) {
240c18ec02fSPetter Reinholdtsen 		printf(analog_fmt, sdr_convert_sensor_reading (full, setting));
241c18ec02fSPetter Reinholdtsen 	} else {
242c18ec02fSPetter Reinholdtsen 		printf(discrete_fmt, setting);
243c18ec02fSPetter Reinholdtsen 	}
244c18ec02fSPetter Reinholdtsen }
245c18ec02fSPetter Reinholdtsen 
246c18ec02fSPetter Reinholdtsen static int
247c18ec02fSPetter Reinholdtsen ipmi_sensor_print_fc_threshold(struct ipmi_intf *intf,
248c18ec02fSPetter Reinholdtsen 			      struct sdr_record_common_sensor *sensor,
249c18ec02fSPetter Reinholdtsen 			      uint8_t sdr_record_type)
250c18ec02fSPetter Reinholdtsen {
251c18ec02fSPetter Reinholdtsen 	int thresh_available = 1;
252c18ec02fSPetter Reinholdtsen 	struct ipmi_rs *rsp;
253c18ec02fSPetter Reinholdtsen 	struct sensor_reading *sr;
254c18ec02fSPetter Reinholdtsen 
255c18ec02fSPetter Reinholdtsen 	sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 3);
256c18ec02fSPetter Reinholdtsen 
257c18ec02fSPetter Reinholdtsen 	if (sr == NULL) {
258c18ec02fSPetter Reinholdtsen 		return -1;
259c18ec02fSPetter Reinholdtsen 	}
260c18ec02fSPetter Reinholdtsen 
261c18ec02fSPetter Reinholdtsen 	const char *thresh_status = ipmi_sdr_get_thresh_status(sr, "ns");
262c18ec02fSPetter Reinholdtsen 
263c18ec02fSPetter Reinholdtsen 	/*
264c18ec02fSPetter Reinholdtsen 	 * Get sensor thresholds
265c18ec02fSPetter Reinholdtsen 	 */
266c18ec02fSPetter Reinholdtsen 	rsp = ipmi_sdr_get_sensor_thresholds(intf,
267c18ec02fSPetter Reinholdtsen 				sensor->keys.sensor_num, sensor->keys.owner_id,
268c18ec02fSPetter Reinholdtsen 				sensor->keys.lun, sensor->keys.channel);
269c18ec02fSPetter Reinholdtsen 
270c18ec02fSPetter Reinholdtsen 	if ((rsp == NULL) || (rsp->ccode > 0) || (rsp->data_len == 0))
271c18ec02fSPetter Reinholdtsen 		thresh_available = 0;
272c18ec02fSPetter Reinholdtsen 
273c18ec02fSPetter Reinholdtsen 	if (csv_output) {
274c18ec02fSPetter Reinholdtsen 		/* NOT IMPLEMENTED */
275c18ec02fSPetter Reinholdtsen 	} else {
276c18ec02fSPetter Reinholdtsen 		if (verbose == 0) {
277c18ec02fSPetter Reinholdtsen 			/* output format
278c18ec02fSPetter Reinholdtsen 			 *   id value units status thresholds....
279c18ec02fSPetter Reinholdtsen 			 */
280c18ec02fSPetter Reinholdtsen 			printf("%-16s ", sr->s_id);
281c18ec02fSPetter Reinholdtsen 			if (sr->s_reading_valid) {
282c18ec02fSPetter Reinholdtsen 				if (sr->s_has_analog_value)
283c18ec02fSPetter Reinholdtsen 					printf("| %-10.3f | %-10s | %-6s",
284c18ec02fSPetter Reinholdtsen 					       sr->s_a_val, sr->s_a_units, thresh_status);
285c18ec02fSPetter Reinholdtsen 				else
286c18ec02fSPetter Reinholdtsen 					printf("| 0x%-8x | %-10s | %-6s",
287c18ec02fSPetter Reinholdtsen 					       sr->s_reading, sr->s_a_units, thresh_status);
288c18ec02fSPetter Reinholdtsen 			} else {
289c18ec02fSPetter Reinholdtsen 				printf("| %-10s | %-10s | %-6s",
290c18ec02fSPetter Reinholdtsen 				       "na", sr->s_a_units, "na");
291c18ec02fSPetter Reinholdtsen 			}
292c18ec02fSPetter Reinholdtsen 			if (thresh_available && sr->full) {
293c18ec02fSPetter Reinholdtsen #define PTS(bit, dataidx) {						\
294c18ec02fSPetter Reinholdtsen 	print_thresh_setting(sr->full, rsp->data[0] & (bit),  		\
295c18ec02fSPetter Reinholdtsen 	    rsp->data[(dataidx)], "| ", "%-10.3f", "0x-8x", "%-10s");	\
296c18ec02fSPetter Reinholdtsen }
297c18ec02fSPetter Reinholdtsen 				PTS(LOWER_NON_RECOV_SPECIFIED,	3);
298c18ec02fSPetter Reinholdtsen 				PTS(LOWER_CRIT_SPECIFIED,	2);
299c18ec02fSPetter Reinholdtsen 				PTS(LOWER_NON_CRIT_SPECIFIED,	1);
300c18ec02fSPetter Reinholdtsen 				PTS(UPPER_NON_CRIT_SPECIFIED,	4);
301c18ec02fSPetter Reinholdtsen 				PTS(UPPER_CRIT_SPECIFIED,	5);
302c18ec02fSPetter Reinholdtsen 				PTS(UPPER_NON_RECOV_SPECIFIED,	6);
303c18ec02fSPetter Reinholdtsen #undef PTS
304c18ec02fSPetter Reinholdtsen 			} else {
305c18ec02fSPetter Reinholdtsen 				printf
306c18ec02fSPetter Reinholdtsen 				    ("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s",
307c18ec02fSPetter Reinholdtsen 				     "na", "na", "na", "na", "na", "na");
308c18ec02fSPetter Reinholdtsen 			}
309c18ec02fSPetter Reinholdtsen 
310c18ec02fSPetter Reinholdtsen 			printf("\n");
311c18ec02fSPetter Reinholdtsen 		} else {
312c18ec02fSPetter Reinholdtsen 			printf("Sensor ID              : %s (0x%x)\n",
313c18ec02fSPetter Reinholdtsen 			       sr->s_id, sensor->keys.sensor_num);
314c18ec02fSPetter Reinholdtsen 
315c18ec02fSPetter Reinholdtsen 			printf(" Entity ID             : %d.%d\n",
316c18ec02fSPetter Reinholdtsen 			       sensor->entity.id, sensor->entity.instance);
317c18ec02fSPetter Reinholdtsen 
318c18ec02fSPetter Reinholdtsen 			printf(" Sensor Type (Threshold)  : %s\n",
319c18ec02fSPetter Reinholdtsen 			       ipmi_sdr_get_sensor_type_desc(sensor->sensor.
320c18ec02fSPetter Reinholdtsen 							     type));
321c18ec02fSPetter Reinholdtsen 
322c18ec02fSPetter Reinholdtsen 			printf(" Sensor Reading        : ");
323c18ec02fSPetter Reinholdtsen 			if (sr->s_reading_valid) {
324c18ec02fSPetter Reinholdtsen 				if (sr->full) {
325c18ec02fSPetter Reinholdtsen 					uint16_t raw_tol = __TO_TOL(sr->full->mtol);
326c18ec02fSPetter Reinholdtsen 					if (sr->s_has_analog_value) {
327c18ec02fSPetter Reinholdtsen 						double tol =
328c18ec02fSPetter Reinholdtsen 						    sdr_convert_sensor_tolerance(sr->full,
329c18ec02fSPetter Reinholdtsen 									       raw_tol);
330c18ec02fSPetter Reinholdtsen 						printf("%.*f (+/- %.*f) %s\n",
331c18ec02fSPetter Reinholdtsen 						       (sr->s_a_val == (int)
332c18ec02fSPetter Reinholdtsen 						       sr->s_a_val) ? 0 : 3,
333c18ec02fSPetter Reinholdtsen 						       sr->s_a_val,
334c18ec02fSPetter Reinholdtsen 						       (tol == (int) tol) ? 0 : 3, tol,
335c18ec02fSPetter Reinholdtsen 						       sr->s_a_units);
336c18ec02fSPetter Reinholdtsen 					} else {
337c18ec02fSPetter Reinholdtsen 						printf("0x%x (+/- 0x%x) %s\n",
338c18ec02fSPetter Reinholdtsen 						       sr->s_reading,
339c18ec02fSPetter Reinholdtsen 						       raw_tol,
340c18ec02fSPetter Reinholdtsen 						       sr->s_a_units);
341c18ec02fSPetter Reinholdtsen 					}
342c18ec02fSPetter Reinholdtsen 				} else {
343c18ec02fSPetter Reinholdtsen 					printf("0x%x %s\n", sr->s_reading,
344c18ec02fSPetter Reinholdtsen 					sr->s_a_units);
345c18ec02fSPetter Reinholdtsen 				}
346c18ec02fSPetter Reinholdtsen 				printf(" Status                : %s\n", thresh_status);
347c18ec02fSPetter Reinholdtsen 
348c18ec02fSPetter Reinholdtsen 				if (thresh_available) {
349c18ec02fSPetter Reinholdtsen 					if (sr->full) {
350c18ec02fSPetter Reinholdtsen #define PTS(bit, dataidx, str) { 			\
351c18ec02fSPetter Reinholdtsen print_thresh_setting(sr->full, rsp->data[0] & (bit),	\
352c18ec02fSPetter Reinholdtsen 		     rsp->data[(dataidx)], 		\
353c18ec02fSPetter Reinholdtsen 		    (str), "%.3f\n", "0x%x\n", "%s\n"); \
354c18ec02fSPetter Reinholdtsen }
355c18ec02fSPetter Reinholdtsen 
356c18ec02fSPetter Reinholdtsen 						PTS(LOWER_NON_RECOV_SPECIFIED,	3, " Lower Non-Recoverable : ");
357c18ec02fSPetter Reinholdtsen 						PTS(LOWER_CRIT_SPECIFIED,	2, " Lower Critical        : ");
358c18ec02fSPetter Reinholdtsen 						PTS(LOWER_NON_CRIT_SPECIFIED,	1, " Lower Non-Critical    : ");
359c18ec02fSPetter Reinholdtsen 						PTS(UPPER_NON_CRIT_SPECIFIED,	4, " Upper Non-Critical    : ");
360c18ec02fSPetter Reinholdtsen 						PTS(UPPER_CRIT_SPECIFIED,	5, " Upper Critical        : ");
361c18ec02fSPetter Reinholdtsen 						PTS(UPPER_NON_RECOV_SPECIFIED,	6, " Upper Non-Recoverable : ");
362c18ec02fSPetter Reinholdtsen #undef PTS
363c18ec02fSPetter Reinholdtsen 
364c18ec02fSPetter Reinholdtsen 					}
365c18ec02fSPetter Reinholdtsen 					ipmi_sdr_print_sensor_hysteresis(sensor, sr->full,
366c18ec02fSPetter Reinholdtsen 						sr->full ?  sr->full->threshold.hysteresis.positive :
367c18ec02fSPetter Reinholdtsen 						sr->compact->threshold.hysteresis.positive,
368c18ec02fSPetter Reinholdtsen 						"Positive Hysteresis");
369c18ec02fSPetter Reinholdtsen 
370c18ec02fSPetter Reinholdtsen 					ipmi_sdr_print_sensor_hysteresis(sensor, sr->full,
371c18ec02fSPetter Reinholdtsen 						sr->full ?  sr->full->threshold.hysteresis.negative :
372c18ec02fSPetter Reinholdtsen 						sr->compact->threshold.hysteresis.negative,
373c18ec02fSPetter Reinholdtsen 						"Negative Hysteresis");
374c18ec02fSPetter Reinholdtsen 				} else {
375c18ec02fSPetter Reinholdtsen 					printf(" Sensor Threshold Settings not available\n");
376c18ec02fSPetter Reinholdtsen 				}
377c18ec02fSPetter Reinholdtsen 			} else {
378c18ec02fSPetter Reinholdtsen 			  printf(" Unable to read sensor: Device Not Present\n\n");
379c18ec02fSPetter Reinholdtsen 			}
380c18ec02fSPetter Reinholdtsen 
381c18ec02fSPetter Reinholdtsen 			ipmi_sdr_print_sensor_event_status(intf,
382c18ec02fSPetter Reinholdtsen 							   sensor->keys.
383c18ec02fSPetter Reinholdtsen 							   sensor_num,
384c18ec02fSPetter Reinholdtsen 							   sensor->sensor.type,
385c18ec02fSPetter Reinholdtsen 							   sensor->event_type,
386c18ec02fSPetter Reinholdtsen 							   ANALOG_SENSOR,
387c18ec02fSPetter Reinholdtsen 							   sensor->keys.owner_id,
388c18ec02fSPetter Reinholdtsen 							   sensor->keys.lun,
389c18ec02fSPetter Reinholdtsen 							   sensor->keys.channel);
390c18ec02fSPetter Reinholdtsen 			ipmi_sdr_print_sensor_event_enable(intf,
391c18ec02fSPetter Reinholdtsen 							   sensor->keys.
392c18ec02fSPetter Reinholdtsen 							   sensor_num,
393c18ec02fSPetter Reinholdtsen 							   sensor->sensor.type,
394c18ec02fSPetter Reinholdtsen 							   sensor->event_type,
395c18ec02fSPetter Reinholdtsen 							   ANALOG_SENSOR,
396c18ec02fSPetter Reinholdtsen 							   sensor->keys.owner_id,
397c18ec02fSPetter Reinholdtsen 							   sensor->keys.lun,
398c18ec02fSPetter Reinholdtsen 							   sensor->keys.channel);
399c18ec02fSPetter Reinholdtsen 
400c18ec02fSPetter Reinholdtsen 			printf("\n");
401c18ec02fSPetter Reinholdtsen 		}
402c18ec02fSPetter Reinholdtsen 	}
403c18ec02fSPetter Reinholdtsen 
404c18ec02fSPetter Reinholdtsen 	return (sr->s_reading_valid ? 0 : -1 );
405c18ec02fSPetter Reinholdtsen }
406c18ec02fSPetter Reinholdtsen 
407c18ec02fSPetter Reinholdtsen int
408c18ec02fSPetter Reinholdtsen ipmi_sensor_print_fc(struct ipmi_intf *intf,
409c18ec02fSPetter Reinholdtsen 		       struct sdr_record_common_sensor *sensor,
410c18ec02fSPetter Reinholdtsen 			uint8_t sdr_record_type)
411c18ec02fSPetter Reinholdtsen {
412c18ec02fSPetter Reinholdtsen 	if (IS_THRESHOLD_SENSOR(sensor))
413c18ec02fSPetter Reinholdtsen 		return ipmi_sensor_print_fc_threshold(intf, sensor, sdr_record_type);
414c18ec02fSPetter Reinholdtsen 	else
415c18ec02fSPetter Reinholdtsen 		return ipmi_sensor_print_fc_discrete(intf, sensor, sdr_record_type);
416c18ec02fSPetter Reinholdtsen }
417c18ec02fSPetter Reinholdtsen 
418c18ec02fSPetter Reinholdtsen static int
419c18ec02fSPetter Reinholdtsen ipmi_sensor_list(struct ipmi_intf *intf)
420c18ec02fSPetter Reinholdtsen {
421c18ec02fSPetter Reinholdtsen 	struct sdr_get_rs *header;
422c18ec02fSPetter Reinholdtsen 	struct ipmi_sdr_iterator *itr;
423c18ec02fSPetter Reinholdtsen 	int rc = 0;
424c18ec02fSPetter Reinholdtsen 
425c18ec02fSPetter Reinholdtsen 	lprintf(LOG_DEBUG, "Querying SDR for sensor list");
426c18ec02fSPetter Reinholdtsen 
427c18ec02fSPetter Reinholdtsen 	itr = ipmi_sdr_start(intf, 0);
428c18ec02fSPetter Reinholdtsen 	if (itr == NULL) {
429c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Unable to open SDR for reading");
430c18ec02fSPetter Reinholdtsen 		return -1;
431c18ec02fSPetter Reinholdtsen 	}
432c18ec02fSPetter Reinholdtsen 
433c18ec02fSPetter Reinholdtsen 	while ((header = ipmi_sdr_get_next_header(intf, itr)) != NULL) {
434c18ec02fSPetter Reinholdtsen 		uint8_t *rec;
435c18ec02fSPetter Reinholdtsen 
436c18ec02fSPetter Reinholdtsen 		rec = ipmi_sdr_get_record(intf, header, itr);
437c18ec02fSPetter Reinholdtsen 		if (rec == NULL) {
438c18ec02fSPetter Reinholdtsen 			lprintf(LOG_DEBUG, "rec == NULL");
439c18ec02fSPetter Reinholdtsen 			continue;
440c18ec02fSPetter Reinholdtsen 		}
441c18ec02fSPetter Reinholdtsen 
442c18ec02fSPetter Reinholdtsen 		switch (header->type) {
443c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FULL_SENSOR:
444c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_COMPACT_SENSOR:
445c18ec02fSPetter Reinholdtsen 			ipmi_sensor_print_fc(intf,
446c18ec02fSPetter Reinholdtsen 						   (struct
447c18ec02fSPetter Reinholdtsen 						    sdr_record_common_sensor *)
448c18ec02fSPetter Reinholdtsen 						   rec,
449c18ec02fSPetter Reinholdtsen 						   header->type);
450c18ec02fSPetter Reinholdtsen 			break;
451c18ec02fSPetter Reinholdtsen 		}
452c18ec02fSPetter Reinholdtsen 		free(rec);
453c18ec02fSPetter Reinholdtsen 		rec = NULL;
454c18ec02fSPetter Reinholdtsen 
455c18ec02fSPetter Reinholdtsen 		/* fix for CR6604909: */
456c18ec02fSPetter Reinholdtsen 		/* mask failure of individual reads in sensor list command */
457c18ec02fSPetter Reinholdtsen 		/* rc = (r == 0) ? rc : r; */
458c18ec02fSPetter Reinholdtsen 	}
459c18ec02fSPetter Reinholdtsen 
460c18ec02fSPetter Reinholdtsen 	ipmi_sdr_end(intf, itr);
461c18ec02fSPetter Reinholdtsen 
462c18ec02fSPetter Reinholdtsen 	return rc;
463c18ec02fSPetter Reinholdtsen }
464c18ec02fSPetter Reinholdtsen 
465c18ec02fSPetter Reinholdtsen static const struct valstr threshold_vals[] = {
466c18ec02fSPetter Reinholdtsen 	{UPPER_NON_RECOV_SPECIFIED, "Upper Non-Recoverable"},
467c18ec02fSPetter Reinholdtsen 	{UPPER_CRIT_SPECIFIED, "Upper Critical"},
468c18ec02fSPetter Reinholdtsen 	{UPPER_NON_CRIT_SPECIFIED, "Upper Non-Critical"},
469c18ec02fSPetter Reinholdtsen 	{LOWER_NON_RECOV_SPECIFIED, "Lower Non-Recoverable"},
470c18ec02fSPetter Reinholdtsen 	{LOWER_CRIT_SPECIFIED, "Lower Critical"},
471c18ec02fSPetter Reinholdtsen 	{LOWER_NON_CRIT_SPECIFIED, "Lower Non-Critical"},
472c18ec02fSPetter Reinholdtsen 	{0x00, NULL},
473c18ec02fSPetter Reinholdtsen };
474c18ec02fSPetter Reinholdtsen 
475c18ec02fSPetter Reinholdtsen static int
476c18ec02fSPetter Reinholdtsen __ipmi_sensor_set_threshold(struct ipmi_intf *intf,
477c18ec02fSPetter Reinholdtsen 			    uint8_t num, uint8_t mask, uint8_t setting,
478c18ec02fSPetter Reinholdtsen 			    uint8_t target, uint8_t lun, uint8_t channel)
479c18ec02fSPetter Reinholdtsen {
480c18ec02fSPetter Reinholdtsen 	struct ipmi_rs *rsp;
481c18ec02fSPetter Reinholdtsen 
482c18ec02fSPetter Reinholdtsen 	rsp = ipmi_sensor_set_sensor_thresholds(intf, num, mask, setting,
483c18ec02fSPetter Reinholdtsen 				  target, lun, channel);
484c18ec02fSPetter Reinholdtsen 
485c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
486c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error setting threshold");
487c18ec02fSPetter Reinholdtsen 		return -1;
488c18ec02fSPetter Reinholdtsen 	}
489c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
490c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error setting threshold: %s",
491c18ec02fSPetter Reinholdtsen 			val2str(rsp->ccode, completion_code_vals));
492c18ec02fSPetter Reinholdtsen 		return -1;
493c18ec02fSPetter Reinholdtsen 	}
494c18ec02fSPetter Reinholdtsen 
495c18ec02fSPetter Reinholdtsen 	return 0;
496c18ec02fSPetter Reinholdtsen }
497c18ec02fSPetter Reinholdtsen 
498c18ec02fSPetter Reinholdtsen static uint8_t
499c18ec02fSPetter Reinholdtsen __ipmi_sensor_threshold_value_to_raw(struct sdr_record_full_sensor *full, double value)
500c18ec02fSPetter Reinholdtsen {
501c18ec02fSPetter Reinholdtsen 	if (!UNITS_ARE_DISCRETE(&full->cmn)) { /* Has an analog reading */
502c18ec02fSPetter Reinholdtsen 		/* Has an analog reading and supports mx+b */
503c18ec02fSPetter Reinholdtsen 		return sdr_convert_sensor_value_to_raw(full, value);
504c18ec02fSPetter Reinholdtsen 	}
505c18ec02fSPetter Reinholdtsen 	else {
506c18ec02fSPetter Reinholdtsen 		/* Does not have an analog reading and/or does not support mx+b */
507c18ec02fSPetter Reinholdtsen 		if (value > 255) {
508c18ec02fSPetter Reinholdtsen 			return 255;
509c18ec02fSPetter Reinholdtsen 		}
510c18ec02fSPetter Reinholdtsen 		else if (value < 0) {
511c18ec02fSPetter Reinholdtsen 			return 0;
512c18ec02fSPetter Reinholdtsen 		}
513c18ec02fSPetter Reinholdtsen 		else {
514c18ec02fSPetter Reinholdtsen 			return (uint8_t )value;
515c18ec02fSPetter Reinholdtsen 		}
516c18ec02fSPetter Reinholdtsen 	}
517c18ec02fSPetter Reinholdtsen }
518c18ec02fSPetter Reinholdtsen 
519c18ec02fSPetter Reinholdtsen static int
520c18ec02fSPetter Reinholdtsen ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv)
521c18ec02fSPetter Reinholdtsen {
522c18ec02fSPetter Reinholdtsen 	char *id, *thresh;
523c18ec02fSPetter Reinholdtsen 	uint8_t settingMask = 0;
524c18ec02fSPetter Reinholdtsen 	double setting1 = 0.0, setting2 = 0.0, setting3 = 0.0;
525c18ec02fSPetter Reinholdtsen 	int allUpper = 0, allLower = 0;
526c18ec02fSPetter Reinholdtsen 	int ret = 0;
527c18ec02fSPetter Reinholdtsen 	struct ipmi_rs *rsp;
528c18ec02fSPetter Reinholdtsen 	int i =0;
529c18ec02fSPetter Reinholdtsen 	double val[10] = {0};
530c18ec02fSPetter Reinholdtsen 
531c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *sdr;
532c18ec02fSPetter Reinholdtsen 
533c18ec02fSPetter Reinholdtsen 	if (argc < 3 || strncmp(argv[0], "help", 4) == 0) {
5342b15969dSZdenek Styblik 		print_sensor_thresh_usage();
535c18ec02fSPetter Reinholdtsen 		return 0;
536c18ec02fSPetter Reinholdtsen 	}
537c18ec02fSPetter Reinholdtsen 
538c18ec02fSPetter Reinholdtsen 	id = argv[0];
539c18ec02fSPetter Reinholdtsen 	thresh = argv[1];
540c18ec02fSPetter Reinholdtsen 
541c18ec02fSPetter Reinholdtsen 	if (strncmp(thresh, "upper", 5) == 0) {
542c18ec02fSPetter Reinholdtsen 		if (argc < 5) {
543c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR,
544c18ec02fSPetter Reinholdtsen 				"usage: sensor thresh <id> upper <unc> <ucr> <unr>");
545c18ec02fSPetter Reinholdtsen 			return -1;
546c18ec02fSPetter Reinholdtsen 		}
547c18ec02fSPetter Reinholdtsen 		allUpper = 1;
548c18ec02fSPetter Reinholdtsen 		if (str2double(argv[2], &setting1) != 0) {
549c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Given unc '%s' is invalid.",
550c18ec02fSPetter Reinholdtsen 					argv[2]);
551c18ec02fSPetter Reinholdtsen 			return (-1);
552c18ec02fSPetter Reinholdtsen 		}
553c18ec02fSPetter Reinholdtsen 		if (str2double(argv[3], &setting2) != 0) {
554c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Given ucr '%s' is invalid.",
555c18ec02fSPetter Reinholdtsen 					argv[3]);
556c18ec02fSPetter Reinholdtsen 			return (-1);
557c18ec02fSPetter Reinholdtsen 		}
558c18ec02fSPetter Reinholdtsen 		if (str2double(argv[4], &setting3) != 0) {
559c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Given unr '%s' is invalid.",
560c18ec02fSPetter Reinholdtsen 					argv[4]);
561c18ec02fSPetter Reinholdtsen 			return (-1);
562c18ec02fSPetter Reinholdtsen 		}
563c18ec02fSPetter Reinholdtsen 	} else if (strncmp(thresh, "lower", 5) == 0) {
564c18ec02fSPetter Reinholdtsen 		if (argc < 5) {
565c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR,
566*5c85c7bcSZdenek Styblik 				"usage: sensor thresh <id> lower <lnr> <lcr> <lnc>");
567c18ec02fSPetter Reinholdtsen 			return -1;
568c18ec02fSPetter Reinholdtsen 		}
569c18ec02fSPetter Reinholdtsen 		allLower = 1;
570c18ec02fSPetter Reinholdtsen 		if (str2double(argv[2], &setting1) != 0) {
571c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Given lnc '%s' is invalid.",
572c18ec02fSPetter Reinholdtsen 					argv[2]);
573c18ec02fSPetter Reinholdtsen 			return (-1);
574c18ec02fSPetter Reinholdtsen 		}
575c18ec02fSPetter Reinholdtsen 		if (str2double(argv[3], &setting2) != 0) {
576c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Given lcr '%s' is invalid.",
577c18ec02fSPetter Reinholdtsen 					argv[3]);
578c18ec02fSPetter Reinholdtsen 			return (-1);
579c18ec02fSPetter Reinholdtsen 		}
580c18ec02fSPetter Reinholdtsen 		if (str2double(argv[4], &setting3) != 0) {
581c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Given lnr '%s' is invalid.",
582c18ec02fSPetter Reinholdtsen 					argv[4]);
583c18ec02fSPetter Reinholdtsen 			return (-1);
584c18ec02fSPetter Reinholdtsen 		}
585c18ec02fSPetter Reinholdtsen 	} else {
586c18ec02fSPetter Reinholdtsen 		if (strncmp(thresh, "unr", 3) == 0)
587c18ec02fSPetter Reinholdtsen 			settingMask = UPPER_NON_RECOV_SPECIFIED;
588c18ec02fSPetter Reinholdtsen 		else if (strncmp(thresh, "ucr", 3) == 0)
589c18ec02fSPetter Reinholdtsen 			settingMask = UPPER_CRIT_SPECIFIED;
590c18ec02fSPetter Reinholdtsen 		else if (strncmp(thresh, "unc", 3) == 0)
591c18ec02fSPetter Reinholdtsen 			settingMask = UPPER_NON_CRIT_SPECIFIED;
592c18ec02fSPetter Reinholdtsen 		else if (strncmp(thresh, "lnc", 3) == 0)
593c18ec02fSPetter Reinholdtsen 			settingMask = LOWER_NON_CRIT_SPECIFIED;
594c18ec02fSPetter Reinholdtsen 		else if (strncmp(thresh, "lcr", 3) == 0)
595c18ec02fSPetter Reinholdtsen 			settingMask = LOWER_CRIT_SPECIFIED;
596c18ec02fSPetter Reinholdtsen 		else if (strncmp(thresh, "lnr", 3) == 0)
597c18ec02fSPetter Reinholdtsen 			settingMask = LOWER_NON_RECOV_SPECIFIED;
598c18ec02fSPetter Reinholdtsen 		else {
599c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR,
600c18ec02fSPetter Reinholdtsen 				"Valid threshold '%s' for sensor '%s' not specified!",
601c18ec02fSPetter Reinholdtsen 				thresh, id);
602c18ec02fSPetter Reinholdtsen 			return -1;
603c18ec02fSPetter Reinholdtsen 		}
604c18ec02fSPetter Reinholdtsen 		if (str2double(argv[2], &setting1) != 0) {
605c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR,
606c18ec02fSPetter Reinholdtsen 					"Given %s threshold value '%s' is invalid.",
607c18ec02fSPetter Reinholdtsen 					thresh, argv[2]);
608c18ec02fSPetter Reinholdtsen 			return (-1);
609c18ec02fSPetter Reinholdtsen 		}
610c18ec02fSPetter Reinholdtsen 	}
611c18ec02fSPetter Reinholdtsen 
612c18ec02fSPetter Reinholdtsen 	printf("Locating sensor record '%s'...\n", id);
613c18ec02fSPetter Reinholdtsen 
614c18ec02fSPetter Reinholdtsen 	/* lookup by sensor name */
615c18ec02fSPetter Reinholdtsen 	sdr = ipmi_sdr_find_sdr_byid(intf, id);
616c18ec02fSPetter Reinholdtsen 	if (sdr == NULL) {
617c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Sensor data record not found!");
618c18ec02fSPetter Reinholdtsen 		return -1;
619c18ec02fSPetter Reinholdtsen 	}
620c18ec02fSPetter Reinholdtsen 
621c18ec02fSPetter Reinholdtsen 	if (sdr->type != SDR_RECORD_TYPE_FULL_SENSOR) {
622c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Invalid sensor type %02x", sdr->type);
623c18ec02fSPetter Reinholdtsen 		return -1;
624c18ec02fSPetter Reinholdtsen 	}
625c18ec02fSPetter Reinholdtsen 
626c18ec02fSPetter Reinholdtsen 	if (!IS_THRESHOLD_SENSOR(sdr->record.common)) {
627c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Invalid sensor event type %02x", sdr->record.common->event_type);
628c18ec02fSPetter Reinholdtsen 		return -1;
629c18ec02fSPetter Reinholdtsen 	}
630c18ec02fSPetter Reinholdtsen 
631c18ec02fSPetter Reinholdtsen 
632c18ec02fSPetter Reinholdtsen 	if (allUpper) {
633c18ec02fSPetter Reinholdtsen 		settingMask = UPPER_NON_CRIT_SPECIFIED;
634c18ec02fSPetter Reinholdtsen 		printf("Setting sensor \"%s\" %s threshold to %.3f\n",
635c18ec02fSPetter Reinholdtsen 		       sdr->record.full->id_string,
636c18ec02fSPetter Reinholdtsen 		       val2str(settingMask, threshold_vals), setting1);
637c18ec02fSPetter Reinholdtsen 		ret = __ipmi_sensor_set_threshold(intf,
638c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.
639c18ec02fSPetter Reinholdtsen 						  sensor_num, settingMask,
640c18ec02fSPetter Reinholdtsen 						  __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1),
641c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.owner_id,
642c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.lun,
643c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.channel);
644c18ec02fSPetter Reinholdtsen 
645c18ec02fSPetter Reinholdtsen 		settingMask = UPPER_CRIT_SPECIFIED;
646c18ec02fSPetter Reinholdtsen 		printf("Setting sensor \"%s\" %s threshold to %.3f\n",
647c18ec02fSPetter Reinholdtsen 		       sdr->record.full->id_string,
648c18ec02fSPetter Reinholdtsen 		       val2str(settingMask, threshold_vals), setting2);
649c18ec02fSPetter Reinholdtsen 		ret = __ipmi_sensor_set_threshold(intf,
650c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.
651c18ec02fSPetter Reinholdtsen 						  sensor_num, settingMask,
652c18ec02fSPetter Reinholdtsen 						  __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting2),
653c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.owner_id,
654c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.lun,
655c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.channel);
656c18ec02fSPetter Reinholdtsen 
657c18ec02fSPetter Reinholdtsen 		settingMask = UPPER_NON_RECOV_SPECIFIED;
658c18ec02fSPetter Reinholdtsen 		printf("Setting sensor \"%s\" %s threshold to %.3f\n",
659c18ec02fSPetter Reinholdtsen 		       sdr->record.full->id_string,
660c18ec02fSPetter Reinholdtsen 		       val2str(settingMask, threshold_vals), setting3);
661c18ec02fSPetter Reinholdtsen 		ret = __ipmi_sensor_set_threshold(intf,
662c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.
663c18ec02fSPetter Reinholdtsen 						  sensor_num, settingMask,
664c18ec02fSPetter Reinholdtsen 						  __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting3),
665c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.owner_id,
666c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.lun,
667c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.channel);
668c18ec02fSPetter Reinholdtsen 	} else if (allLower) {
669c18ec02fSPetter Reinholdtsen 		settingMask = LOWER_NON_RECOV_SPECIFIED;
670c18ec02fSPetter Reinholdtsen 		printf("Setting sensor \"%s\" %s threshold to %.3f\n",
671c18ec02fSPetter Reinholdtsen 		       sdr->record.full->id_string,
672c18ec02fSPetter Reinholdtsen 		       val2str(settingMask, threshold_vals), setting1);
673c18ec02fSPetter Reinholdtsen 		ret = __ipmi_sensor_set_threshold(intf,
674c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.
675c18ec02fSPetter Reinholdtsen 						  sensor_num, settingMask,
676c18ec02fSPetter Reinholdtsen 						  __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1),
677c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.owner_id,
678c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.lun,
679c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.channel);
680c18ec02fSPetter Reinholdtsen 
681c18ec02fSPetter Reinholdtsen 		settingMask = LOWER_CRIT_SPECIFIED;
682c18ec02fSPetter Reinholdtsen 		printf("Setting sensor \"%s\" %s threshold to %.3f\n",
683c18ec02fSPetter Reinholdtsen 		       sdr->record.full->id_string,
684c18ec02fSPetter Reinholdtsen 		       val2str(settingMask, threshold_vals), setting2);
685c18ec02fSPetter Reinholdtsen 		ret = __ipmi_sensor_set_threshold(intf,
686c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.
687c18ec02fSPetter Reinholdtsen 						  sensor_num, settingMask,
688c18ec02fSPetter Reinholdtsen 						  __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting2),
689c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.owner_id,
690c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.lun,
691c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.channel);
692c18ec02fSPetter Reinholdtsen 
693c18ec02fSPetter Reinholdtsen 		settingMask = LOWER_NON_CRIT_SPECIFIED;
694c18ec02fSPetter Reinholdtsen 		printf("Setting sensor \"%s\" %s threshold to %.3f\n",
695c18ec02fSPetter Reinholdtsen 		       sdr->record.full->id_string,
696c18ec02fSPetter Reinholdtsen 		       val2str(settingMask, threshold_vals), setting3);
697c18ec02fSPetter Reinholdtsen 		ret = __ipmi_sensor_set_threshold(intf,
698c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.
699c18ec02fSPetter Reinholdtsen 						  sensor_num, settingMask,
700c18ec02fSPetter Reinholdtsen 						  __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting3),
701c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.owner_id,
702c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.lun,
703c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.channel);
704c18ec02fSPetter Reinholdtsen 	} else {
705c18ec02fSPetter Reinholdtsen 
706c18ec02fSPetter Reinholdtsen 	/*
707c18ec02fSPetter Reinholdtsen  	 * Current implementation doesn't check for the valid setting of upper non critical and other thresholds.
708c18ec02fSPetter Reinholdtsen  	 * In the below logic:
709c18ec02fSPetter Reinholdtsen  	 * 	Get all the current reading of the sensor i.e. unc, uc, lc,lnc.
710c18ec02fSPetter Reinholdtsen  	 * 	Validate the values given by the user.
711c18ec02fSPetter Reinholdtsen  	 * 	If the values are not correct, then popup with the Error message and return.
712c18ec02fSPetter Reinholdtsen  	 */
713c18ec02fSPetter Reinholdtsen 	/*
714c18ec02fSPetter Reinholdtsen 	 * Get current reading
715c18ec02fSPetter Reinholdtsen 	 */
716c18ec02fSPetter Reinholdtsen 		rsp = ipmi_sdr_get_sensor_reading_ipmb(intf,
717c18ec02fSPetter Reinholdtsen 					       sdr->record.common->keys.sensor_num,
718c18ec02fSPetter Reinholdtsen 					       sdr->record.common->keys.owner_id,
719c18ec02fSPetter Reinholdtsen 					       sdr->record.common->keys.lun,sdr->record.common->keys.channel);
720c18ec02fSPetter Reinholdtsen 		rsp = ipmi_sdr_get_sensor_thresholds(intf,
721c18ec02fSPetter Reinholdtsen 						sdr->record.common->keys.sensor_num,
722c18ec02fSPetter Reinholdtsen 						sdr->record.common->keys.owner_id,
723c18ec02fSPetter Reinholdtsen 						sdr->record.common->keys.lun,
724c18ec02fSPetter Reinholdtsen 						sdr->record.common->keys.channel);
725c18ec02fSPetter Reinholdtsen 		if ((rsp == NULL) || (rsp->ccode > 0)) {
726c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Sensor data record not found!");
727c18ec02fSPetter Reinholdtsen 				return -1;
728c18ec02fSPetter Reinholdtsen 		}
729c18ec02fSPetter Reinholdtsen 		for(i=1;i<=6;i++) {
730c18ec02fSPetter Reinholdtsen 			val[i] = sdr_convert_sensor_reading(sdr->record.full, rsp->data[i]);
731c18ec02fSPetter Reinholdtsen 			if(val[i] < 0)
732c18ec02fSPetter Reinholdtsen 				val[i] = 0;
733c18ec02fSPetter Reinholdtsen 		}
734c18ec02fSPetter Reinholdtsen 		/* Check for the valid Upper non recovarable Value.*/
735c18ec02fSPetter Reinholdtsen 		if( (settingMask & UPPER_NON_RECOV_SPECIFIED) ) {
736c18ec02fSPetter Reinholdtsen 
737c18ec02fSPetter Reinholdtsen 			if( (rsp->data[0] & UPPER_NON_RECOV_SPECIFIED) &&
738c18ec02fSPetter Reinholdtsen 				(( (rsp->data[0] & UPPER_CRIT_SPECIFIED) && ( setting1 <= val[5])) ||
739c18ec02fSPetter Reinholdtsen 					( (rsp->data[0] & UPPER_NON_CRIT_SPECIFIED) && ( setting1 <= val[4]))) )
740c18ec02fSPetter Reinholdtsen 			{
741c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, INVALID_THRESHOLD);
742c18ec02fSPetter Reinholdtsen 				return -1;
743c18ec02fSPetter Reinholdtsen 			}
744c18ec02fSPetter Reinholdtsen 		} else if( (settingMask & UPPER_CRIT_SPECIFIED) ) { 		/* Check for the valid Upper critical Value.*/
745c18ec02fSPetter Reinholdtsen 			if( (rsp->data[0] & UPPER_CRIT_SPECIFIED) &&
746c18ec02fSPetter Reinholdtsen 				(((rsp->data[0] & UPPER_NON_RECOV_SPECIFIED)&& ( setting1 >= val[6])) ||
747c18ec02fSPetter Reinholdtsen 				((rsp->data[0] & UPPER_NON_CRIT_SPECIFIED)&&( setting1 <= val[4]))) )
748c18ec02fSPetter Reinholdtsen 			{
749c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, INVALID_THRESHOLD);
750c18ec02fSPetter Reinholdtsen 				return -1;
751c18ec02fSPetter Reinholdtsen 			}
752c18ec02fSPetter Reinholdtsen 		} else if( (settingMask & UPPER_NON_CRIT_SPECIFIED) ) {  		/* Check for the valid Upper non critical Value.*/
753c18ec02fSPetter Reinholdtsen 			if( (rsp->data[0] & UPPER_NON_CRIT_SPECIFIED) &&
754c18ec02fSPetter Reinholdtsen 				(((rsp->data[0] & UPPER_NON_RECOV_SPECIFIED)&&( setting1 >= val[6])) ||
755c18ec02fSPetter Reinholdtsen 				((rsp->data[0] & UPPER_CRIT_SPECIFIED)&&( setting1 >= val[5])) ||
756c18ec02fSPetter Reinholdtsen 				((rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)&&( setting1 <= val[1]))) )
757c18ec02fSPetter Reinholdtsen 			{
758c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, INVALID_THRESHOLD);
759c18ec02fSPetter Reinholdtsen 				return -1;
760c18ec02fSPetter Reinholdtsen 			}
761c18ec02fSPetter Reinholdtsen 		} else if( (settingMask & LOWER_NON_CRIT_SPECIFIED) ) {		/* Check for the valid lower non critical Value.*/
762c18ec02fSPetter Reinholdtsen 			if( (rsp->data[0] & LOWER_NON_CRIT_SPECIFIED) &&
763c18ec02fSPetter Reinholdtsen 				(((rsp->data[0] & LOWER_CRIT_SPECIFIED)&&( setting1 <= val[2])) ||
764c18ec02fSPetter Reinholdtsen 				((rsp->data[0] & LOWER_NON_RECOV_SPECIFIED)&&( setting1 <= val[3]))||
765c18ec02fSPetter Reinholdtsen 				((rsp->data[0] & UPPER_NON_CRIT_SPECIFIED)&&( setting1 >= val[4]))) )
766c18ec02fSPetter Reinholdtsen 			{
767c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, INVALID_THRESHOLD);
768c18ec02fSPetter Reinholdtsen 				return -1;
769c18ec02fSPetter Reinholdtsen 			}
770c18ec02fSPetter Reinholdtsen 		} else if( (settingMask & LOWER_CRIT_SPECIFIED) ) {		/* Check for the valid lower critical Value.*/
771c18ec02fSPetter Reinholdtsen 			if( (rsp->data[0] & LOWER_CRIT_SPECIFIED) &&
772c18ec02fSPetter Reinholdtsen 				(((rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)&&( setting1 >= val[1])) ||
773c18ec02fSPetter Reinholdtsen 				((rsp->data[0] & LOWER_NON_RECOV_SPECIFIED)&&( setting1 <= val[3]))) )
774c18ec02fSPetter Reinholdtsen 			{
775c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, INVALID_THRESHOLD);
776c18ec02fSPetter Reinholdtsen 				return -1;
777c18ec02fSPetter Reinholdtsen 			}
778c18ec02fSPetter Reinholdtsen 		} else if( (settingMask & LOWER_NON_RECOV_SPECIFIED) ) {		/* Check for the valid lower non recovarable Value.*/
779c18ec02fSPetter Reinholdtsen 			if( (rsp->data[0] & LOWER_NON_RECOV_SPECIFIED) &&
780c18ec02fSPetter Reinholdtsen 				(((rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)&&( setting1 >= val[1])) ||
781c18ec02fSPetter Reinholdtsen 				((rsp->data[0] & LOWER_CRIT_SPECIFIED)&&( setting1 >= val[2]))) )
782c18ec02fSPetter Reinholdtsen 			{
783c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, INVALID_THRESHOLD);
784c18ec02fSPetter Reinholdtsen 				return -1;
785c18ec02fSPetter Reinholdtsen 			}
786c18ec02fSPetter Reinholdtsen 		} else {			/* None of this Then Return with error messages.*/
787c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, INVALID_THRESHOLD);
788c18ec02fSPetter Reinholdtsen 			return -1;
789c18ec02fSPetter Reinholdtsen 		}
790c18ec02fSPetter Reinholdtsen 
791c18ec02fSPetter Reinholdtsen 
792c18ec02fSPetter Reinholdtsen 		printf("Setting sensor \"%s\" %s threshold to %.3f\n",
793c18ec02fSPetter Reinholdtsen 		       sdr->record.full->id_string,
794c18ec02fSPetter Reinholdtsen 		       val2str(settingMask, threshold_vals), setting1);
795c18ec02fSPetter Reinholdtsen 
796c18ec02fSPetter Reinholdtsen 		ret = __ipmi_sensor_set_threshold(intf,
797c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.
798c18ec02fSPetter Reinholdtsen 						  sensor_num, settingMask,
799c18ec02fSPetter Reinholdtsen 						  __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1),
800c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.owner_id,
801c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.lun,
802c18ec02fSPetter Reinholdtsen 						  sdr->record.common->keys.channel);
803c18ec02fSPetter Reinholdtsen 	}
804c18ec02fSPetter Reinholdtsen 
805c18ec02fSPetter Reinholdtsen 	return ret;
806c18ec02fSPetter Reinholdtsen }
807c18ec02fSPetter Reinholdtsen 
808c18ec02fSPetter Reinholdtsen static int
809c18ec02fSPetter Reinholdtsen ipmi_sensor_get_reading(struct ipmi_intf *intf, int argc, char **argv)
810c18ec02fSPetter Reinholdtsen {
811c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *sdr;
812c18ec02fSPetter Reinholdtsen 	int i, rc=0;
813c18ec02fSPetter Reinholdtsen 
814c18ec02fSPetter Reinholdtsen 	if (argc < 1 || strncmp(argv[0], "help", 4) == 0) {
815c18ec02fSPetter Reinholdtsen 		lprintf(LOG_NOTICE, "sensor reading <id> ... [id]");
816c18ec02fSPetter Reinholdtsen 		lprintf(LOG_NOTICE, "   id        : name of desired sensor");
817c18ec02fSPetter Reinholdtsen 		return -1;
818c18ec02fSPetter Reinholdtsen 	}
819c18ec02fSPetter Reinholdtsen 
820c18ec02fSPetter Reinholdtsen 	for (i = 0; i < argc; i++) {
821c18ec02fSPetter Reinholdtsen 		sdr = ipmi_sdr_find_sdr_byid(intf, argv[i]);
822c18ec02fSPetter Reinholdtsen 		if (sdr == NULL) {
823c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Sensor \"%s\" not found!",
824c18ec02fSPetter Reinholdtsen 				argv[i]);
825c18ec02fSPetter Reinholdtsen 			rc = -1;
826c18ec02fSPetter Reinholdtsen 			continue;
827c18ec02fSPetter Reinholdtsen 		}
828c18ec02fSPetter Reinholdtsen 
829c18ec02fSPetter Reinholdtsen 		switch (sdr->type) {
830c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_FULL_SENSOR:
831c18ec02fSPetter Reinholdtsen 		case SDR_RECORD_TYPE_COMPACT_SENSOR:
832c18ec02fSPetter Reinholdtsen 		{
833c18ec02fSPetter Reinholdtsen 			struct sensor_reading *sr;
834c18ec02fSPetter Reinholdtsen 			struct sdr_record_common_sensor	*sensor = sdr->record.common;
835c18ec02fSPetter Reinholdtsen 			sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr->type, 3);
836c18ec02fSPetter Reinholdtsen 
837c18ec02fSPetter Reinholdtsen 			if (sr == NULL) {
838c18ec02fSPetter Reinholdtsen 				rc = -1;
839c18ec02fSPetter Reinholdtsen 				continue;
840c18ec02fSPetter Reinholdtsen 			}
841c18ec02fSPetter Reinholdtsen 
842c18ec02fSPetter Reinholdtsen 			if (!sr->full)
843c18ec02fSPetter Reinholdtsen 				continue;
844c18ec02fSPetter Reinholdtsen 
845c18ec02fSPetter Reinholdtsen 			if (!sr->s_reading_valid)
846c18ec02fSPetter Reinholdtsen 				continue;
847c18ec02fSPetter Reinholdtsen 
848c18ec02fSPetter Reinholdtsen 			if (!sr->s_has_analog_value) {
849c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, "Sensor \"%s\" is a discrete sensor!", argv[i]);
850c18ec02fSPetter Reinholdtsen 				continue;
851c18ec02fSPetter Reinholdtsen 			}
852c18ec02fSPetter Reinholdtsen 			if (csv_output)
853c18ec02fSPetter Reinholdtsen 				printf("%s,%s\n", argv[i], sr->s_a_str);
854c18ec02fSPetter Reinholdtsen 			else
855c18ec02fSPetter Reinholdtsen 				printf("%-16s | %s\n", argv[i], sr->s_a_str);
856c18ec02fSPetter Reinholdtsen 
857c18ec02fSPetter Reinholdtsen 			break;
858c18ec02fSPetter Reinholdtsen 		}
859c18ec02fSPetter Reinholdtsen 		default:
860c18ec02fSPetter Reinholdtsen 			continue;
861c18ec02fSPetter Reinholdtsen 		}
862c18ec02fSPetter Reinholdtsen 	}
863c18ec02fSPetter Reinholdtsen 
864c18ec02fSPetter Reinholdtsen 	return rc;
865c18ec02fSPetter Reinholdtsen }
866c18ec02fSPetter Reinholdtsen 
867c18ec02fSPetter Reinholdtsen static int
868c18ec02fSPetter Reinholdtsen ipmi_sensor_get(struct ipmi_intf *intf, int argc, char **argv)
869c18ec02fSPetter Reinholdtsen {
870c18ec02fSPetter Reinholdtsen 	int i, v;
871c18ec02fSPetter Reinholdtsen 	int rc = 0;
872c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *sdr;
873c18ec02fSPetter Reinholdtsen 
874c18ec02fSPetter Reinholdtsen 	if (argc < 1) {
875c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Not enough parameters given.");
876aa8bac2dSZdenek Styblik 		print_sensor_get_usage();
877c18ec02fSPetter Reinholdtsen 		return (-1);
878c18ec02fSPetter Reinholdtsen 	} else if (strcmp(argv[0], "help") == 0) {
879aa8bac2dSZdenek Styblik 		print_sensor_get_usage();
880c18ec02fSPetter Reinholdtsen 		return 0;
881c18ec02fSPetter Reinholdtsen 	}
882c18ec02fSPetter Reinholdtsen 	printf("Locating sensor record...\n");
883c18ec02fSPetter Reinholdtsen 	/* lookup by sensor name */
884c18ec02fSPetter Reinholdtsen 	for (i = 0; i < argc; i++) {
885c18ec02fSPetter Reinholdtsen 		sdr = ipmi_sdr_find_sdr_byid(intf, argv[i]);
886c18ec02fSPetter Reinholdtsen 		if (sdr == NULL) {
887c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Sensor data record \"%s\" not found!",
888c18ec02fSPetter Reinholdtsen 					argv[i]);
889c18ec02fSPetter Reinholdtsen 			rc = -1;
890c18ec02fSPetter Reinholdtsen 			continue;
891c18ec02fSPetter Reinholdtsen 		}
892c18ec02fSPetter Reinholdtsen 		/* need to set verbose level to 1 */
893c18ec02fSPetter Reinholdtsen 		v = verbose;
894c18ec02fSPetter Reinholdtsen 		verbose = 1;
895c18ec02fSPetter Reinholdtsen 		if (ipmi_sdr_print_listentry(intf, sdr) < 0) {
896c18ec02fSPetter Reinholdtsen 			rc = (-1);
897c18ec02fSPetter Reinholdtsen 		}
898c18ec02fSPetter Reinholdtsen 		verbose = v;
899c18ec02fSPetter Reinholdtsen 		sdr = NULL;
900c18ec02fSPetter Reinholdtsen 	}
901c18ec02fSPetter Reinholdtsen 	return rc;
902c18ec02fSPetter Reinholdtsen }
903c18ec02fSPetter Reinholdtsen 
904c18ec02fSPetter Reinholdtsen int
905c18ec02fSPetter Reinholdtsen ipmi_sensor_main(struct ipmi_intf *intf, int argc, char **argv)
906c18ec02fSPetter Reinholdtsen {
907c18ec02fSPetter Reinholdtsen 	int rc = 0;
908c18ec02fSPetter Reinholdtsen 
909c18ec02fSPetter Reinholdtsen 	if (argc == 0) {
910c18ec02fSPetter Reinholdtsen 		rc = ipmi_sensor_list(intf);
911c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[0], "help", 4) == 0) {
912c18ec02fSPetter Reinholdtsen 		lprintf(LOG_NOTICE, "Sensor Commands:  list thresh get reading");
913c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[0], "list", 4) == 0) {
914c18ec02fSPetter Reinholdtsen 		rc = ipmi_sensor_list(intf);
915c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[0], "thresh", 5) == 0) {
916c18ec02fSPetter Reinholdtsen 		rc = ipmi_sensor_set_threshold(intf, argc - 1, &argv[1]);
917c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[0], "get", 3) == 0) {
918c18ec02fSPetter Reinholdtsen 		rc = ipmi_sensor_get(intf, argc - 1, &argv[1]);
919c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[0], "reading", 7) == 0) {
920c18ec02fSPetter Reinholdtsen 		rc = ipmi_sensor_get_reading(intf, argc - 1, &argv[1]);
921c18ec02fSPetter Reinholdtsen 	} else {
922c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Invalid sensor command: %s", argv[0]);
923c18ec02fSPetter Reinholdtsen 		rc = -1;
924c18ec02fSPetter Reinholdtsen 	}
925c18ec02fSPetter Reinholdtsen 
926c18ec02fSPetter Reinholdtsen 	return rc;
927c18ec02fSPetter Reinholdtsen }
928c18ec02fSPetter Reinholdtsen 
929aa8bac2dSZdenek Styblik /* print_sensor_get_usage - print usage for # ipmitool sensor get NAC;
930c18ec02fSPetter Reinholdtsen  *
931c18ec02fSPetter Reinholdtsen  * @returns: void
932c18ec02fSPetter Reinholdtsen  */
933c18ec02fSPetter Reinholdtsen void
934aa8bac2dSZdenek Styblik print_sensor_get_usage()
935c18ec02fSPetter Reinholdtsen {
936c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "sensor get <id> ... [id]");
937c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "   id        : name of desired sensor");
938c18ec02fSPetter Reinholdtsen }
9392b15969dSZdenek Styblik 
940aa8bac2dSZdenek Styblik /* print_sensor_thresh_set_usage - print usage for # ipmitool sensor thresh;
9412b15969dSZdenek Styblik  *
9422b15969dSZdenek Styblik  * @returns: void
9432b15969dSZdenek Styblik  */
9442b15969dSZdenek Styblik void
9452b15969dSZdenek Styblik print_sensor_thresh_usage()
9462b15969dSZdenek Styblik {
9472b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9482b15969dSZdenek Styblik "sensor thresh <id> <threshold> <setting>");
9492b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9502b15969dSZdenek Styblik "   id        : name of the sensor for which threshold is to be set");
9512b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9522b15969dSZdenek Styblik "   threshold : which threshold to set");
9532b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9542b15969dSZdenek Styblik "                 unr = upper non-recoverable");
9552b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9562b15969dSZdenek Styblik "                 ucr = upper critical");
9572b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9582b15969dSZdenek Styblik "                 unc = upper non-critical");
9592b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9602b15969dSZdenek Styblik "                 lnc = lower non-critical");
9612b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9622b15969dSZdenek Styblik "                 lcr = lower critical");
9632b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9642b15969dSZdenek Styblik "                 lnr = lower non-recoverable");
9652b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9662b15969dSZdenek Styblik "   setting   : the value to set the threshold to");
9672b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9682b15969dSZdenek Styblik "");
9692b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9702b15969dSZdenek Styblik "sensor thresh <id> lower <lnr> <lcr> <lnc>");
9712b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9722b15969dSZdenek Styblik "   Set all lower thresholds at the same time");
9732b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9742b15969dSZdenek Styblik "");
9752b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9762b15969dSZdenek Styblik "sensor thresh <id> upper <unc> <ucr> <unr>");
9772b15969dSZdenek Styblik 	lprintf(LOG_NOTICE,
9782b15969dSZdenek Styblik "   Set all upper thresholds at the same time");
9792b15969dSZdenek Styblik 	lprintf(LOG_NOTICE, "");
9802b15969dSZdenek Styblik }
981