1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef	_ENVD_H
28 #define	_ENVD_H
29 
30 #include <sys/types.h>
31 #include <libintl.h>
32 
33 #ifdef	__cplusplus
34 extern "C" {
35 #endif
36 
37 #define	SENSORPOLL_INTERVAL	4
38 #define	INTERRUPTPOLL_INTERVAL	2
39 #define	WARNING_INTERVAL	30
40 #define	SHUTDOWN_INTERVAL	60
41 #define	ENV_CONF_FILE		"envmodel.conf"
42 #define	TUNABLE_CONF_FILE	"piclenvd.conf"
43 #define	PM_DEVICE		"/dev/pm"
44 #define	SHUTDOWN_CMD		"/usr/sbin/shutdown -y -g 60 -i 5"
45 #define	PICL_PLUGINS_NODE	"plugins"
46 #define	PICL_ENVIRONMENTAL_NODE	"environmental"
47 
48 /*
49  * ADC Sample of ADM in Khz, currently 11.2 KHz
50  */
51 #define	ADCSAMPLE		11250
52 
53 /*
54  * Taco Platform Details
55  */
56 #define	MAX_SENSORS	3
57 #define	MAX_FANS	2
58 #define	MAX_HWMS	1
59 
60 /*
61  * ADM1031 Hardware Monitor IDs
62  * Used as index into arrays
63  */
64 #define	CPU_HWM_ID	0
65 
66 #define	CPU_HWM_DEVFS	\
67 	"/devices/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c:control"
68 
69 #define	HWM_FAN1	0
70 #define	HWM_FAN2	1
71 
72 /*
73  * Taco sensor IDs as used in FRUID segment
74  */
75 #define	SYS_IN_SENSOR_ID	0
76 #define	CPU_SENSOR_ID		1
77 #define	INT_AMB_SENSOR_ID	2
78 #define	MAX_SENSOR_ID		2
79 
80 /*
81  * Taco fan IDs used in FRUID segment
82  */
83 #define	SYSTEM_FAN_ID		0
84 #define	CPU_FAN_ID		1
85 #define	MAX_FAN_ID		1
86 
87 /*
88  * devfs-path for various fans and their min/max speeds
89  */
90 #define	ENV_CPU_FAN_DEVFS	\
91 	"/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c:fan_2"
92 #define	ENV_SYSTEM_FAN_DEVFS	\
93 	"/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c:fan_1"
94 
95 #define	FAN_RANGE_DEFAULT	4
96 #define	CPU_FAN_SPEED_MIN	14
97 #define	CPU_FAN_SPEED_MAX	100
98 
99 #define	SYSTEM_OUT_FAN_SPEED_MIN	14
100 #define	SYSTEM_OUT_FAN_SPEED_MAX	100
101 
102 #define	SYSTEM_INTAKE_FAN_SPEED_MIN	14
103 #define	SYSTEM_INTAKE_FAN_SPEED_MAX	100
104 
105 
106 
107 /*
108  * devfs-path for various temperature sensors and CPU platform path
109  */
110 #define	SENSOR_CPU_DIE_DEVFS	\
111 	"/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c:remote_2"
112 #define	SENSOR_SYS_IN_DEVFS	\
113 	"/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c:remote_1"
114 #define	SENSOR_INT_AMB_DEVFS	\
115 	"/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c:local"
116 
117 /*
118  * Temperature type
119  */
120 typedef int16_t tempr_t;
121 
122 
123 /*
124  * Fan names
125  */
126 #define	ENV_SYSTEM_INTAKE_FAN	"intake-fan"
127 #define	ENV_SYSTEM_OUT_FAN	"outtake-fan"
128 #define	ENV_CPU_FAN		"cpu-fan"
129 #define	ENV_SYSTEM_IN_OUT_FANS	"intake-outtake-fans"
130 
131 /*
132  * Sensor names
133  */
134 #define	SENSOR_CPU_DIE		"cpu"
135 #define	SENSOR_SYS_IN		"sys-in"
136 #define	SENSOR_INT_AMB		"int-amb"
137 
138 /* Bit Map of ADM 1031 Status 1/2 Registers */
139 typedef enum adm1031 {
140 	FANFAULT = 0x2,
141 	REMOTEHIGH = 0x4,
142 	REMOTELOW = 0x8,
143 	REMOTETHERN = 0x10,
144 	LHIGH = 0x40,
145 	LLOW  = 0x80
146 } adm1031_t;
147 
148 /* ADM Stat 1/2 Mask */
149 typedef enum adm1031Mask {
150 	STAT1MASK = 0xdc,
151 	STAT2MASK = 0x1c
152 } adm1031Mask_t;
153 
154 /*
155  * ES segment related structures
156  */
157 typedef struct id_off {
158 	uint_t id;
159 	ushort_t offset;
160 } id_off_t;
161 
162 typedef struct fan_ctl_pair {
163 	uchar_t tMin;
164 	uchar_t tRange;
165 } fan_ctl_pair_t;
166 
167 typedef struct Correction_Pair {
168 	uchar_t measured;
169 	uchar_t corrected;
170 } Correction_Pair_t;
171 
172 #define	ES_SENSOR_POLICY_LEN	8
173 #define	ES_CORRECTION_PAIRS	12
174 
175 typedef struct sensor_ctrl_blk {
176 	uchar_t  high_power_off;
177 	uchar_t  high_shutdown;
178 	uchar_t  high_warning;
179 	uchar_t  low_warning;
180 	uchar_t  low_shutdown;
181 	uchar_t  low_power_off;
182 	uchar_t  sensorPolicy[ES_SENSOR_POLICY_LEN];
183 	ushort_t correctionEntries;
184 	Correction_Pair_t correctionPair[ES_CORRECTION_PAIRS];
185 } sensor_ctrl_blk_t;
186 
187 
188 #define	ES_FAN_CTL_PAIRS	4
189 
190 typedef struct fan_ctrl_blk {
191 	uchar_t  tSpinUp;
192 	uchar_t  minFanSpeed;
193 	ushort_t setPoint;
194 	ushort_t loopGain;
195 	ushort_t loopBias;
196 	ushort_t hysteresis;
197 	ushort_t fanViabTestInt;
198 	ushort_t fanViabTestThresh;
199 	ushort_t grossFanThresh;
200 	uchar_t no_ctl_pairs;
201 	fan_ctl_pair_t fan_ctl_pairs[ES_FAN_CTL_PAIRS];
202 } fan_ctrl_blk_t;
203 
204 #define	TEMP_IN_WARNING_RANGE(val, sensorp) \
205 	((val) > (sensorp)->es_ptr->high_warning || \
206 		(val) < (char)((sensorp)->es_ptr->low_warning))
207 
208 #define	TEMP_IN_SHUTDOWN_RANGE(val, sensorp) \
209 	((val) > (sensorp)->es_ptr->high_shutdown || \
210 		(val) < (char)((sensorp)->es_ptr->low_shutdown))
211 
212 /*
213  * Macros to fetch 16 and 32 bit data from unaligned address
214  */
215 #define	GET_UNALIGN16(addr)	\
216 	(((*(uint8_t *)addr) << 8) | *((uint8_t *)addr + 1))
217 
218 #define	GET_UNALIGN32(addr)	\
219 	(((*(uint8_t *)addr) << 24) | (*((uint8_t *)addr + 1) << 16) | \
220 	((*((uint8_t *)addr + 2)) << 8) | (*((uint8_t *)addr + 3)))
221 
222 /*
223  * SEEPROM section header layout and location
224  */
225 typedef struct {
226 	uint8_t		header_tag;		/* section header tag */
227 	uint8_t		header_version[2];	/* header version (msb) */
228 	uint8_t		header_length;		/* header length */
229 	uint8_t		header_crc8;		/* crc8 */
230 	uint8_t		segment_count;		/* total number of segments */
231 } section_layout_t;
232 
233 #define	SECTION_HDR_OFFSET	0x1800
234 #define	SECTION_HDR_TAG		0x08
235 #define	SECTION_HDR_VER		0x0001
236 #define	SECTION_HDR_LENGTH	0x06
237 
238 /*
239  * SEEPROM segment header layout
240  */
241 typedef struct {
242 	uint16_t	name;		/* segment name */
243 	uint16_t	descriptor[2];	/* descriptor (msb) */
244 	uint16_t	offset;		/* segment data offset */
245 	uint16_t	length;		/* segment length */
246 } segment_layout_t;
247 
248 #define	ENVSEG_NAME		0x4553	/* environmental segment name */
249 #define	ENVSEG_VERSION		2	/* environmental segment version */
250 
251 #define	SENSOR_WARN		1
252 #define	SENSOR_OK		0
253 
254 /*
255  * SEEPROM environmental segment header layout
256  */
257 typedef struct {
258 	uint16_t	sensor_id[2];	/* unique sensor ID (on this FRU) */
259 	uint16_t	offset;		/* sensor data record offset */
260 } envseg_sensor_t;
261 
262 typedef struct {
263 	uint8_t		version;	/* envseg version */
264 	uint8_t		sensor_count;	/* total number of sensor records */
265 	envseg_sensor_t	sensors[1];	/* sensor table (variable length) */
266 } envseg_layout_t;
267 
268 /*
269  * FRU envseg list
270  */
271 typedef struct fruenvseg {
272 	struct fruenvseg	*next;		/* next entry */
273 	char			*fru;		/* FRU SEEPROM path */
274 	void			*envsegbufp;	/* envseg data buffer */
275 	int			envseglen;	/* envseg length */
276 } fruenvseg_t;
277 
278 #define	I2C_DEVFS	"/devices/pci@1e,600000/isa@7/i2c@0,320"
279 #define	MBFRU_DEV	"/motherboard-fru-prom@0,a8:motherboard-fru-prom"
280 #define	FRU_SEEPROM_NAME	"motherboard-fru-prom"
281 /*
282  * Table data structures
283  */
284 typedef struct {
285 	int32_t	x;
286 	int32_t	y;
287 } point_t;
288 
289 typedef struct {
290 	int	nentries;
291 	point_t	*xymap;
292 } table_t;
293 
294 /*
295  * Temperature sensor related data structure
296  */
297 typedef struct env_sensor {
298 	char		*name;			/* sensor name */
299 	char		*devfs_path;		/* sensor device devfs path */
300 	sensor_ctrl_blk_t *es_ptr;
301 	uchar_t		id;
302 	int		hwm_id;
303 	void		*fanp;
304 	int		fd;			/* device file descriptor */
305 	int		error;			/* error flag */
306 	boolean_t	present;		/* sensor present */
307 	tempr_t		cur_temp;		/* current temperature */
308 	time_t		warning_tstamp;		/* last warning time (secs) */
309 	time_t		shutdown_tstamp;	/* shutdown temp time (secs) */
310 	boolean_t	shutdown_initiated;	/* shutdown initated */
311 	table_t		*crtbl;			/* Correction table */
312 	tempr_t		tmin;
313 } env_sensor_t;
314 
315 extern	env_sensor_t *sensor_lookup(char *sensor_name);
316 extern	int get_temperature(env_sensor_t *, tempr_t *);
317 
318 /*
319  * Fan information data structure
320  */
321 typedef int fanspeed_t;
322 
323 typedef struct env_fan {
324 	char		*name;			/* fan name */
325 	char		*devfs_path;		/* fan device devfs path */
326 	fan_ctrl_blk_t	*es_ptr;
327 	uchar_t		id;
328 	fanspeed_t	speed_min;		/* minimum speed */
329 	fanspeed_t	speed_max;		/* maximum speed */
330 	int		forced_speed;		/* forced (fixed) speed */
331 	int		fd;			/* device file descriptor */
332 	boolean_t	present;		/* fan present */
333 	int		speedrange;		/* speed range N */
334 	int		fanstat;		/* Fan status */
335 	uint8_t		cspeed;			/* Current speed (tach) */
336 	uint8_t		lspeed;			/* Last speed (tach) */
337 	int		conccnt;		/* Concurrent tach count */
338 } env_fan_t;
339 
340 /*
341  * Tuneables
342  */
343 typedef struct env_tuneable {
344 	char		*name;
345 	char		type;
346 	void		*value;
347 	int		(*rfunc)(ptree_rarg_t *, void *);
348 	int		(*wfunc)(ptree_warg_t *, const void *);
349 	int		nbytes;
350 	picl_prophdl_t proph;
351 } env_tuneable_t;
352 
353 extern	env_fan_t *fan_lookup(char *fan_name);
354 extern	int get_fan_speed(env_fan_t *, fanspeed_t *);
355 extern	int set_fan_speed(env_fan_t *, fanspeed_t);
356 
357 extern int env_debug;
358 extern void envd_log(int pri, const char *fmt, ...);
359 
360 /*
361  * Various messages
362  */
363 #define	ENVD_PLUGIN_INIT_FAILED		\
364 	gettext("SUNW_piclenvd: initialization failed!\n")
365 
366 #define	ENVD_PICL_SETUP_FAILED		\
367 	gettext("SUNW_piclenvd: PICL setup failed!\n")
368 
369 #define	PM_THREAD_CREATE_FAILED		\
370 	gettext("SUNW_piclenvd: pmthr thread creation failed!\n")
371 
372 #define	PM_THREAD_EXITING		\
373 	gettext("SUNW_piclenvd: pmthr exiting! errno:%d %s\n")
374 
375 #define	ENVTHR_THREAD_CREATE_FAILED		\
376 	gettext("SUNW_piclenvd: envthr thread creation failed!\n")
377 
378 #define	ENV_SHUTDOWN_MSG		\
379 	gettext("SUNW_piclenvd: '%s' sensor temperature %d outside safe " \
380 	"limits (%d...%d). Shutting down the system.\n")
381 
382 #define	ENV_WARNING_MSG			\
383 	gettext("SUNW_piclenvd: '%s' sensor temperature %d outside safe " \
384 	"operating limits (%d...%d).\n")
385 
386 #define	ENV_FAN_OPEN_FAIL		\
387 	gettext("SUNW_piclenvd: can't open '%s' fan path:%s errno:%d %s\n")
388 
389 #define	ENV_SENSOR_OPEN_FAIL		\
390 	gettext("SUNW_piclenvd: can't open '%s' sensor path:%s errno:%d %s\n")
391 
392 #define	ENV_SENSOR_ACCESS_FAIL		\
393 	gettext("SUNW_piclenvd: can't access '%s' sensor errno:%d %s\n")
394 
395 #define	ENV_SENSOR_ACCESS_OK		\
396 	gettext("SUNW_piclenvd: '%s' sensor is accessible now.\n")
397 
398 #define	ENV_FRU_OPEN_FAIL		\
399 	gettext("SUNW_piclenvd: can't open FRU SEEPROM path:%s errno:%d %s\n")
400 
401 #define	ENV_FRU_BAD_ENVSEG		\
402 	gettext("SUNW_piclenvd: version mismatch or environmental segment " \
403 	"header too short in FRU SEEPROM %s\n")
404 
405 #define	ENV_FRU_BAD_SENSOR_ENTRY	\
406 	gettext("SUNW_piclenvd: discarding bad sensor entry (sensor_id " \
407 	"%x sensor '%s') in FRU SEEPROM %s\n")
408 
409 #define	ENV_FRU_SENSOR_MAP_NOMEM	\
410 	gettext("SUNW_piclenvd: out of memory, discarding sensor map for " \
411 	"sensor_id %x (sensor '%s') in FRU SEEPROM %s\n")
412 
413 #define	ENV_ADM_OPEN_FAIL		\
414 	gettext("SUNW_piclenvd: can't open hwm path:%s errno:%d %s\n")
415 
416 #define	ENV_ADM_MANUAL_MODE \
417 	gettext("SUNW_piclenvd: Cannot change the ADM Chip to Manual mode")
418 
419 #define	ENV_ADM_AUTO_MODE \
420 	gettext("SUNW_piclenvd: Cannot change the ADM Chip to Auto mode")
421 
422 #define	ENV_FAN_FAULT \
423 	gettext("SUNW_piclenvd: ADM %s, Fan %s Fault")
424 #ifdef	__cplusplus
425 }
426 #endif
427 
428 #endif	/* _ENVD_H */
429