xref: /illumos-gate/usr/src/uts/sun4u/tazmo/io/envctrl.c (revision eb6b10e6)
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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 
28 /*
29  * ENVCTRL_ Environment Monitoring driver for i2c
30  *
31  */
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <sys/signal.h>
35 #include <sys/errno.h>
36 #include <sys/file.h>
37 #include <sys/termio.h>
38 #include <sys/termios.h>
39 #include <sys/cmn_err.h>
40 #include <sys/stream.h>
41 #include <sys/strsun.h>
42 #include <sys/stropts.h>
43 #include <sys/strtty.h>
44 #include <sys/debug.h>
45 #include <sys/eucioctl.h>
46 #include <sys/cred.h>
47 #include <sys/uio.h>
48 #include <sys/stat.h>
49 #include <sys/kmem.h>
50 
51 #include <sys/ddi.h>
52 #include <sys/sunddi.h>
53 #include <sys/obpdefs.h>
54 #include <sys/conf.h>		/* req. by dev_ops flags MTSAFE etc. */
55 #include <sys/modctl.h>		/* for modldrv */
56 #include <sys/stat.h>		/* ddi_create_minor_node S_IFCHR */
57 #include <sys/open.h>		/* for open params.	 */
58 #include <sys/uio.h>		/* for read/write */
59 #include <sys/envctrl.h>	/* Environment header */
60 
61 /* driver entry point fn definitions */
62 static int	envctrl_open(queue_t *, dev_t *, int, int, cred_t *);
63 static int	envctrl_close(queue_t *, int, cred_t *);
64 static uint_t	envctrl_bus_isr(caddr_t);
65 static uint_t	envctrl_dev_isr(caddr_t);
66 
67 /* configuration entry point fn definitions */
68 static int	envctrl_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
69 static int	envctrl_attach(dev_info_t *, ddi_attach_cmd_t);
70 static int	envctrl_detach(dev_info_t *, ddi_detach_cmd_t);
71 
72 /* Driver private routines */
73 static void	envctrl_init_bus(struct envctrlunit *);
74 static int	envctrl_xmit(struct envctrlunit *, caddr_t *, int);
75 static void	envctrl_recv(struct envctrlunit *, caddr_t *, int);
76 static void	envctrl_get_sys_temperatures(struct envctrlunit *, uint8_t *);
77 static int	envctrl_get_lm75_temp(struct envctrlunit *);
78 static int	envctrl_get_ps_temp(struct envctrlunit *, uint8_t);
79 static int	envctrl_get_cpu_temp(struct envctrlunit *, int);
80 static void	envctrl_fan_fail_service(struct envctrlunit *);
81 static void	envctrl_PS_intr_service(struct envctrlunit *, uint8_t);
82 static void	envctrl_ps_probe(struct envctrlunit *);
83 static void	envctrl_tempr_poll(void *);
84 static void	envctrl_pshotplug_poll(void *);
85 static void	envctrl_led_blink(void *);
86 static void	envctrl_reset_dflop(struct envctrlunit *);
87 static void	envctrl_enable_devintrs(struct envctrlunit *);
88 static void	envctrl_stop_clock(struct envctrlunit *);
89 static void	envctrl_reset_watchdog(struct envctrlunit *, uint8_t *);
90 static void	envctrl_abort_seq_handler(char *msg);
91 static uint8_t	envctrl_get_fpm_status(struct envctrlunit *);
92 static void	envctrl_set_fsp(struct envctrlunit *, uint8_t *);
93 static int	envctrl_set_dskled(struct envctrlunit *,
94 				struct envctrl_pcf8574_chip *);
95 static int	envctrl_get_dskled(struct envctrlunit *,
96 				struct envctrl_pcf8574_chip *);
97 static void	envctrl_probe_cpus(struct envctrlunit *);
98 static int	envctrl_match_cpu(dev_info_t *, void *);
99 static int	envctrl_isother_fault_led(struct envctrlunit *,
100 		    uint8_t, uint8_t);
101 
102 /* Kstat routines */
103 static void	envctrl_add_kstats(struct envctrlunit *);
104 static int	envctrl_ps_kstat_update(kstat_t *, int);
105 static int	envctrl_fanstat_kstat_update(kstat_t *, int);
106 static int	envctrl_encl_kstat_update(kstat_t *, int);
107 static void	envctrl_init_fan_kstats(struct envctrlunit *);
108 static void	envctrl_init_encl_kstats(struct envctrlunit *);
109 static void	envctrl_add_encl_kstats(struct envctrlunit *, int, int,
110 			uint8_t);
111 static void	envctrl_mod_encl_kstats(struct envctrlunit *, int, int,
112 			uint8_t);
113 
114 
115 /* Streams Routines */
116 static int	envctrl_wput(queue_t *, mblk_t *);
117 
118 /* External routines */
119 extern void power_down(const char *);
120 extern int prom_getprop();
121 extern int prom_getproplen();
122 extern	void	prom_printf(const char *fmt, ...);
123 extern void (*abort_seq_handler)();
124 
125 static void    *envctrlsoft_statep;
126 
127 /* Local Variables */
128 /* Indicates whether or not the overtemp thread has been started */
129 static int	envctrl_debug_flags = 0;
130 static int	envctrl_afb_present = 0;
131 static int	envctrl_power_off_overide = 0;
132 static int	envctrl_max_retries = 100;
133 static int	envctrl_allow_detach = 0;
134 static int	envctrl_numcpus = 1;
135 static int	envctrl_p0_enclosure = 0; /* set to 1 if it is a P0 */
136 static int envctrl_handler = 1; /* 1 is the default */
137 static clock_t overtemp_timeout_hz;
138 static clock_t blink_timeout_hz;
139 static clock_t pshotplug_timeout_hz;
140 static int controller_present[] = {-1, -1, -1};
141 #ifdef MULTIFAN
142 static int	envctrl_fan_debug = 0;
143 #endif
144 static int	eHc_debug = 0;
145 static int	power_supply_previous_state[] = {-1, -1, -1};
146 
147 extern void	pci_thermal_rem_intr(dev_info_t *, uint_t);
148 
149 #define	LOOP_TIMEOUT 25
150 #define	INIT_FAN_VAL 35
151 #define	DCMNERR if (eHc_debug & 0x1) cmn_err
152 #define	DCMN2ERR if (eHc_debug & 0x2) cmn_err
153 #define	MAX_FAN_FAIL_RETRY 3
154 
155 uint8_t backaddrs[] = {ENVCTRL_PCF8574_DEV0, ENVCTRL_PCF8574_DEV1,
156     ENVCTRL_PCF8574_DEV2};
157 
158 struct module_info envctrlinfo = {
159 	/* id, name, min pkt siz, max pkt siz, hi water, low water */
160 	42, "envctrl", 0, 2048, (1024 * 20), (1024 * 1)
161 };
162 
163 static struct qinit envctrl_rinit = {
164 	putq, NULL, envctrl_open, envctrl_close, NULL, &envctrlinfo, NULL
165 };
166 
167 static struct qinit envctrl_wint = {
168 	envctrl_wput, NULL, envctrl_open, envctrl_close,
169 	    NULL, &envctrlinfo, NULL
170 };
171 
172 struct streamtab envctrl_str_info = {
173 	&envctrl_rinit, &envctrl_wint, NULL, NULL
174 };
175 
176 static struct cb_ops envctrl_cb_ops = {
177 	nodev,			/* cb_open */
178 	nodev,			/* cb_close */
179 	nodev,			/* cb_strategy */
180 	nodev,			/* cb_print */
181 	nodev,			/* cb_dump */
182 	nodev,			/* cb_read */
183 	nodev,			/* cb_write */
184 	nodev,			/* cb_ioctl */
185 	nodev,			/* cb_devmap */
186 	nodev,			/* cb_mmap */
187 	nodev,			/* cb_segmap */
188 	nochpoll,		/* cb_chpoll */
189 	ddi_prop_op,		/* cb_prop_op */
190 	&envctrl_str_info,	/* cb_stream */
191 	D_MP			/* cb_flag */
192 };
193 
194 /*
195  * Declare ops vectors for auto configuration.
196  */
197 struct dev_ops  envctrl_ops = {
198 	DEVO_REV,		/* devo_rev */
199 	0,			/* devo_refcnt */
200 	envctrl_getinfo,	/* devo_getinfo */
201 	nulldev,		/* devo_identify */
202 	nulldev,		/* devo_probe */
203 	envctrl_attach,		/* devo_attach */
204 	envctrl_detach,		/* devo_detach */
205 	nodev,			/* devo_reset */
206 	&envctrl_cb_ops,	/* devo_cb_ops */
207 	(struct bus_ops *)NULL,	/* devo_bus_ops */
208 	nulldev,		/* devo_power */
209 	ddi_quiesce_not_supported,	/* devo_quiesce */
210 };
211 
212 extern struct mod_ops mod_driverops;
213 
214 static struct modldrv envctrlmodldrv = {
215 	&mod_driverops,		/* type of module - driver */
216 	"I2C ENVCTRL_driver",
217 	&envctrl_ops,
218 };
219 
220 static struct modlinkage envctrlmodlinkage = {
221 	MODREV_1,
222 	&envctrlmodldrv,
223 	0
224 };
225 
226 /*
227  * The following defines are for the i2c protocol routines.
228  * This section of defines should be removed once the envctrl_targets.c
229  * file is included.
230  */
231 
232 #define	EHC_SUCCESS 0
233 #define	EHC_FAILURE (-1)
234 #define	EHC_NO_SLAVE_ACK 3
235 
236 #define	EHC_MAX_WAIT 7 /* decimal */
237 
238 #define	EHC_S1_PIN 0x80
239 #define	EHC_S1_ES1 0x20
240 #define	EHC_S1_ES0 0x40
241 #define	EHC_S1_NBB 0x01
242 #define	EHC_S1_ACK 0x01
243 #define	EHC_S1_STA 0x04
244 #define	EHC_S1_STO 0x02
245 #define	EHC_S1_LRB 0x08
246 #define	EHC_S1_BER 0x10
247 #define	EHC_S1_LAB 0x02
248 
249 #define	EHC_S0_OWN 0x55
250 #define	EHC_S0_CLK 0x1c
251 
252 #define	EHC_BYTE_READ 0x01
253 
254 #define	EHC_LONGEST_MSG 1000 /* decimal */
255 
256 /*
257  * PCF8591 Chip Used for temperature sensors
258  *
259  * Addressing Register definition.
260  * A0-A2 valid range is 0-7
261  *
262  *  7    6  5   4    3     2     1      0
263  * ------------------------------------------------
264  * | 1 | 0 | 0 | 1 | A2 | A1 | A0 | R/W |
265  * ------------------------------------------------
266  */
267 
268 
269 #define	EHC_PCF8591_MAX_DEVS	0x08
270 
271 #define	EHC_DEV0	0x00
272 #define	EHC_DEV1	0x02
273 #define	EHC_DEV2	0x04
274 #define	EHC_DEV3	0x06
275 #define	EHC_DEV4	0x08
276 #define	EHC_DEV5	0x0A
277 #define	EHC_DEV6	0x0C
278 #define	EHC_DEV7	0x0E
279 
280 
281 /*
282  *		CONTROL OF CHIP
283  * PCF8591 Temp sensing control register definitions
284  *
285  *   7      6     5   4  3   2      1   0
286  * ---------------------------------------------
287  * | 0 | AOE | X | X | 0 | AIF | X | X |
288  * ---------------------------------------------
289  * AOE = Analog out enable.. not used on out implementation
290  * 5 & 4 = Analog Input Programming.. see data sheet for bits..
291  *
292  * AIF = Auto increment flag
293  * bits 1 & 0 are for the Chennel number.
294  */
295 
296 #define	EHC_PCF8591_ANALOG_OUTPUT_EN	0x40
297 #define	EHC_PCF8591_ANALOG_INPUT_EN	0x00
298 #define	EHC_PCF8591_READ_BIT		0x01
299 
300 
301 #define	EHC_PCF8591_AUTO_INCR 0x04
302 #define	EHC_PCF8591_OSCILATOR 0x40
303 
304 #define	EHC_PCF8591_MAX_PORTS	0x04
305 
306 #define	EHC_PCF8591_CH_0	0x00
307 #define	EHC_PCF8591_CH_1	0x01
308 #define	EHC_PCF8591_CH_2	0x02
309 #define	EHC_PCF8591_CH_3	0x03
310 
311 
312 /*
313  * PCF8574 Fan Fail, Power Supply Fail Detector
314  * This device is driven by interrupts. Each time it interrupts
315  * you must look at the CSR to see which ports caused the interrupt
316  * they are indicated by a 1.
317  *
318  * Address map of this chip
319  *
320  * -------------------------------------------
321  * | 0 | 1 | 1 | 1 | A2 | A1 | A0 | 0 |
322  * -------------------------------------------
323  *
324  */
325 
326 #define	EHC_PCF8574_PORT0	0x01
327 #define	EHC_PCF8574_PORT1	0x02
328 #define	EHC_PCF8574_PORT2	0x04
329 #define	EHC_PCF8574_PORT3	0x08
330 #define	EHC_PCF8574_PORT4	0x10
331 #define	EHC_PCF8574_PORT5	0x20
332 #define	EHC_PCF8574_PORT6	0x40
333 #define	EHC_PCF8574_PORT7	0x80
334 
335 /*
336  * Defines for the PCF8583 Clock Calendar Chip.
337  */
338 #define	EHC_PCF8583_READ_BIT	0x01
339 #define	ALARM_CTR_REG_MINS	0x03
340 #define	ALARM_REG_MINS		0x0B
341 #define	ALARM_TIMER_REG		0x0F
342 
343 struct eHc_pcd8584_regs {
344 	uint8_t s0;		/* Own Address S0' */
345 	uint8_t s1;		/* Control Status register */
346 	uint8_t clock_s2;	/* Clock programming register */
347 };
348 
349 struct eHc_envcunit {
350 	struct eHc_pcd8584_regs *bus_ctl_regs;
351 	ddi_acc_handle_t ctlr_handle;
352 	kmutex_t umutex;
353 };
354 
355 
356 /*
357  * Prototypes for static routines
358  */
359 
360 static int eHc_write_tda8444(struct eHc_envcunit *, int, int, int, uint8_t *,
361 	int);
362 static int eHc_read_pcf8591(struct eHc_envcunit *, int, int, int, int, int,
363 	uint8_t *, int);
364 static int eHc_read_pcf8574a(struct eHc_envcunit *, int, uint8_t *, int);
365 static int eHc_write_pcf8574a(struct eHc_envcunit *, int, uint8_t *, int);
366 static int eHc_read_pcf8574(struct eHc_envcunit *, int, uint8_t *, int);
367 static int eHc_write_pcf8574(struct eHc_envcunit *, int, uint8_t *, int);
368 static int eHc_read_lm75(struct eHc_envcunit *, int, uint8_t *, int);
369 static int eHc_write_pcf8583(struct eHc_envcunit *, int, uint8_t *, int);
370 
371 static int eHc_start_pcf8584(struct eHc_envcunit *, uint8_t);
372 static void eHc_stop_pcf8584(struct eHc_envcunit *);
373 static int eHc_read_pcf8584(struct eHc_envcunit *, uint8_t *);
374 static int eHc_write_pcf8584(struct eHc_envcunit *, uint8_t);
375 static int eHc_after_read_pcf8584(struct eHc_envcunit *, uint8_t *);
376 
377 /*
378  * End of i2c protocol definitions section
379  */
380 
381 int
_init(void)382 _init(void)
383 {
384 	int    error;
385 
386 	if ((error = mod_install(&envctrlmodlinkage)) == 0) {
387 		(void) ddi_soft_state_init(&envctrlsoft_statep,
388 		    sizeof (struct envctrlunit), 1);
389 	}
390 
391 	return (error);
392 }
393 
394 int
_fini(void)395 _fini(void)
396 {
397 	int    error;
398 
399 	if ((error = mod_remove(&envctrlmodlinkage)) == 0)
400 		ddi_soft_state_fini(&envctrlsoft_statep);
401 
402 	return (error);
403 }
404 
405 int
_info(struct modinfo * modinfop)406 _info(struct modinfo *modinfop)
407 {
408 	return (mod_info(&envctrlmodlinkage, modinfop));
409 }
410 
411 static int
envctrl_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)412 envctrl_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
413 {
414 	int	instance;
415 	char		name[16];
416 	uint8_t fspval;
417 	struct	envctrlunit *unitp;
418 	struct ddi_device_acc_attr attr;
419 	int *reg_prop;
420 	uchar_t *creg_prop;
421 	uint_t len, tblsz;
422 	int i, cputemp, status;
423 	uint8_t buf[3];
424 
425 	status = len = tblsz = 0;
426 
427 	attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
428 	attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
429 
430 	attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
431 
432 	instance = ddi_get_instance(dip);
433 
434 	switch (cmd) {
435 	case DDI_ATTACH:
436 		break;
437 	case DDI_RESUME:
438 		if (!(unitp = ddi_get_soft_state(envctrlsoft_statep, instance)))
439 			return (DDI_FAILURE);
440 		mutex_enter(&unitp->umutex);
441 		if (!unitp->suspended) {
442 			mutex_exit(&unitp->umutex);
443 			return (DDI_FAILURE);
444 		}
445 		unitp->suspended = 0;
446 		mutex_exit(&unitp->umutex);
447 		unitp->initting = B_TRUE;
448 		envctrl_init_bus(unitp);
449 		unitp->initting = B_FALSE;
450 
451 		mutex_enter(&unitp->umutex);
452 		envctrl_ps_probe(unitp);
453 		envctrl_probe_cpus(unitp);
454 		mutex_exit(&unitp->umutex);
455 
456 		return (DDI_SUCCESS);
457 
458 	default:
459 		return (DDI_FAILURE);
460 	}
461 
462 	/* Set up timer values */
463 	overtemp_timeout_hz = drv_usectohz(OVERTEMP_TIMEOUT_USEC);
464 	blink_timeout_hz = drv_usectohz(BLINK_TIMEOUT_USEC);
465 	pshotplug_timeout_hz = drv_usectohz(BLINK_TIMEOUT_USEC * 6);
466 
467 	if (ddi_soft_state_zalloc(envctrlsoft_statep, instance) != 0) {
468 		cmn_err(CE_WARN, "envctrl failed to zalloc softstate\n");
469 		goto failed;
470 	}
471 
472 	unitp = ddi_get_soft_state(envctrlsoft_statep, instance);
473 
474 	if (ddi_regs_map_setup(dip, 0, (caddr_t *)&unitp->bus_ctl_regs, 0,
475 	    sizeof (struct envctrl_pcd8584_regs), &attr,
476 	    &unitp->ctlr_handle) != DDI_SUCCESS) {
477 		cmn_err(CE_WARN, "I2c failed to map in bus_control regs\n");
478 		return (DDI_FAILURE);
479 	}
480 
481 	/*
482 	 * If the PCI nexus has added a thermal interrupt, we first need
483 	 * to remove that interrupt handler.
484 	 *
485 	 * WARNING: Removing another driver's interrupt handler is not
486 	 * allowed. The pci_thermal_rem_intr() call below is needed to retain
487 	 * the legacy behavior on Tazmo systems.
488 	 */
489 
490 	pci_thermal_rem_intr(dip, (uint_t)0);
491 
492 	/* add interrupts */
493 
494 	if (ddi_get_iblock_cookie(dip, 1,
495 	    &unitp->ic_trap_cookie) != DDI_SUCCESS)  {
496 		cmn_err(CE_WARN, "ddi_get_iblock_cookie FAILED \n");
497 		goto failed;
498 	}
499 
500 	mutex_init(&unitp->umutex, NULL, MUTEX_DRIVER,
501 	    (void *)unitp->ic_trap_cookie);
502 
503 
504 	if (ddi_add_intr(dip, 0, &unitp->ic_trap_cookie, NULL, envctrl_bus_isr,
505 	    (caddr_t)unitp) != DDI_SUCCESS) {
506 		cmn_err(CE_WARN, "envctrl_attach failed to add hard intr %d\n",
507 		    instance);
508 		goto remlock;
509 	}
510 
511 
512 	if (ddi_add_intr(dip, 1, &unitp->ic_trap_cookie, NULL, envctrl_dev_isr,
513 	    (caddr_t)unitp) != DDI_SUCCESS) {
514 		cmn_err(CE_WARN, "envctrl_attach failed to add hard intr %d\n",
515 		    instance);
516 		goto remhardintr;
517 	}
518 
519 
520 	(void) sprintf(name, "envctrl%d", instance);
521 
522 	if (ddi_create_minor_node(dip, name, S_IFCHR, instance, DDI_PSEUDO,
523 	    0) == DDI_FAILURE) {
524 		ddi_remove_minor_node(dip, NULL);
525 		goto remhardintr1;
526 	}
527 
528 	mutex_enter(&unitp->umutex);
529 	switch (ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
530 	    ENVCTRL_LED_BLINK, -1)) {
531 	case 1:
532 		unitp->activity_led_blink = B_TRUE;
533 		break;
534 	case 0:
535 	default:
536 		unitp->activity_led_blink = B_FALSE;
537 		break;
538 	}
539 	unitp->shutdown = B_FALSE;
540 	unitp->num_ps_present = unitp->num_encl_present = 0;
541 	unitp->num_fans_present = MIN_FAN_BANKS;
542 	unitp->num_fans_failed = ENVCTRL_CHAR_ZERO;
543 	unitp->AFB_present = B_TRUE;
544 	unitp->dip = dip;
545 
546 #ifdef	DEBUG
547 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
548 	    DDI_PROP_DONTPASS, ENVCTRL_PANEL_LEDS_PR,
549 	    &reg_prop, &len) == DDI_PROP_SUCCESS)
550 		ddi_prop_free((void *)reg_prop);
551 	ASSERT(len != 0);
552 
553 	len = 0;
554 
555 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
556 	    DDI_PROP_DONTPASS, ENVCTRL_PANEL_LEDS_STA,
557 	    &reg_prop, &len) == DDI_PROP_SUCCESS)
558 		ddi_prop_free((void *)reg_prop);
559 	ASSERT(len != 0);
560 
561 	len = 0;
562 
563 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
564 	    DDI_PROP_DONTPASS, ENVCTRL_DISK_LEDS_STA,
565 	    &reg_prop, &len) == DDI_PROP_SUCCESS)
566 		ddi_prop_free((void *)reg_prop);
567 	ASSERT(len != 0);
568 #endif	/* DEBUG */
569 
570 	/*
571 	 * if we have prom fan tables, overide the static tables in
572 	 * header file.
573 	 */
574 
575 	if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip,
576 	    DDI_PROP_DONTPASS, "cpu-fan-speeds",
577 	    &creg_prop, &len) == DDI_PROP_SUCCESS) {
578 
579 		tblsz = (sizeof (acme_cpu_fanspd) / sizeof (short));
580 
581 		if (len <= tblsz) {
582 			for (i = 0; i < len; i++) {
583 				acme_cpu_fanspd[i] = creg_prop[i];
584 			}
585 		}
586 		ddi_prop_free((void *)creg_prop);
587 	}
588 
589 	len = 0;
590 
591 	if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip,
592 	    DDI_PROP_DONTPASS, "ps-fan-speeds",
593 	    &creg_prop, &len) == DDI_PROP_SUCCESS) {
594 
595 		tblsz = (sizeof (acme_ps_fanspd) / sizeof (short));
596 
597 		if (len <= tblsz) {
598 			for (i = 0; i < len; i++) {
599 				acme_ps_fanspd[i] = creg_prop[i];
600 			}
601 		}
602 		ddi_prop_free((void *)creg_prop);
603 	}
604 
605 	switch (ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
606 	    "fan-override", -1)) {
607 	case 1:
608 	case 2:
609 		unitp->AFB_present = B_TRUE;
610 		break;
611 	case 0:
612 	default:
613 		unitp->AFB_present = B_FALSE;
614 		break;
615 	}
616 
617 	/* For debug */
618 	if (envctrl_afb_present) {
619 		unitp->AFB_present = B_TRUE;
620 	}
621 
622 	if (unitp->AFB_present == B_TRUE)
623 		unitp->num_fans_present++;
624 
625 	/* initialize the envctrl bus controller */
626 	mutex_exit(&unitp->umutex);
627 
628 	unitp->initting = B_TRUE;
629 	envctrl_init_bus(unitp);
630 	unitp->initting = B_FALSE;
631 	drv_usecwait(1000);
632 
633 	mutex_enter(&unitp->umutex);
634 
635 	/* Initialize the PCF8583 eggtimer registers */
636 	buf[0] = ALARM_CTR_REG_MINS;
637 	buf[1] = 0x0;
638 	status = eHc_write_pcf8583((struct eHc_envcunit *)unitp,
639 	    PCF8583_BASE_ADDR | 0, buf, 2);
640 	if (status != DDI_SUCCESS)
641 		cmn_err(CE_WARN, "write to PCF8583 failed\n");
642 
643 	buf[0] = ALARM_REG_MINS;
644 	buf[1] = 0x58;
645 	status = eHc_write_pcf8583((struct eHc_envcunit *)unitp,
646 	    PCF8583_BASE_ADDR | 0, buf, 2);
647 	if (status != DDI_SUCCESS)
648 		cmn_err(CE_WARN, "write to PCF8583 failed\n");
649 
650 	buf[0] = ALARM_TIMER_REG;
651 	buf[1] = 0x80;
652 	status = eHc_write_pcf8583((struct eHc_envcunit *)unitp,
653 	    PCF8583_BASE_ADDR | 0, buf, 2);
654 	if (status != DDI_SUCCESS)
655 		cmn_err(CE_WARN, "write to PCF8583 failed\n");
656 
657 	unitp->timeout_id = 0;
658 	unitp->blink_timeout_id = 0;
659 
660 	if (envctrl_numcpus > 1) {
661 		unitp->num_cpus_present = envctrl_numcpus;
662 	}
663 	envctrl_probe_cpus(unitp);
664 	envctrl_ps_probe(unitp);
665 	/*
666 	 * clear the fan failures, if any before we do
667 	 * real work
668 	 */
669 
670 	unitp->initting = B_TRUE;
671 	envctrl_fan_fail_service(unitp);
672 	unitp->initting = B_FALSE;
673 
674 	/*
675 	 * we need to init the fan kstats before the tempr_poll
676 	 */
677 	envctrl_add_kstats(unitp);
678 	envctrl_init_fan_kstats(unitp);
679 	envctrl_init_encl_kstats(unitp);
680 	if (unitp->activity_led_blink == B_TRUE) {
681 		unitp->present_led_state = B_FALSE;
682 		mutex_exit(&unitp->umutex);
683 		envctrl_led_blink((void *)unitp);
684 		mutex_enter(&unitp->umutex);
685 	} else {
686 		fspval = ENVCTRL_FSP_ACTIVE;
687 		envctrl_set_fsp(unitp, &fspval);
688 	}
689 
690 #ifndef TESTBED
691 	for (i = 0; i < ENVCTRL_MAX_CPUS; i++) {
692 		if (unitp->cpu_pr_location[i] == B_TRUE) {
693 			cputemp = envctrl_get_cpu_temp(unitp, i);
694 			envctrl_add_encl_kstats(unitp, ENVCTRL_ENCL_CPUTEMPR,
695 			    i, cputemp);
696 			if (cputemp >= MAX_CPU_TEMP) {
697 				if (!(envctrl_power_off_overide)) {
698 					cmn_err(CE_WARN,
699 					    "CPU %d OVERHEATING!!", i);
700 					unitp->shutdown = B_TRUE;
701 				} else {
702 					cmn_err(CE_WARN,
703 					    "CPU %d OVERHEATING!!", i);
704 				}
705 			}
706 		}
707 	}
708 #else
709 	cputemp = envctrl_get_cpu_temp(unitp, 0);
710 	envctrl_add_encl_kstats(unitp, ENVCTRL_ENCL_CPUTEMPR, INSTANCE_0,
711 	    cputemp);
712 #endif
713 	mutex_exit(&unitp->umutex);
714 
715 	envctrl_tempr_poll((void *)unitp);
716 
717 	/*
718 	 * interpose envctrl's abort sequence handler
719 	 */
720 	if (envctrl_handler) {
721 		abort_seq_handler = envctrl_abort_seq_handler;
722 	}
723 
724 	ddi_report_dev(dip);
725 
726 	return (DDI_SUCCESS);
727 
728 remhardintr1:
729 	ddi_remove_intr(dip, (uint_t)1, unitp->ic_trap_cookie);
730 remhardintr:
731 	ddi_remove_intr(dip, (uint_t)0, unitp->ic_trap_cookie);
732 
733 remlock:
734 	mutex_destroy(&unitp->umutex);
735 
736 failed:
737 	if (unitp->ctlr_handle)
738 		ddi_regs_map_free(&unitp->ctlr_handle);
739 
740 	cmn_err(CE_WARN, "envctrl_attach:failed.\n");
741 
742 	return (DDI_FAILURE);
743 
744 }
745 
746 static int
envctrl_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)747 envctrl_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
748 {
749 	int		instance;
750 	struct envctrlunit *unitp;
751 
752 	instance = ddi_get_instance(dip);
753 	unitp = ddi_get_soft_state(envctrlsoft_statep, instance);
754 
755 	switch (cmd) {
756 	case DDI_DETACH:
757 		if (envctrl_allow_detach) {
758 
759 			if (unitp->psksp != NULL) {
760 				kstat_delete(unitp->psksp);
761 			}
762 			if (unitp->fanksp != NULL) {
763 				kstat_delete(unitp->fanksp);
764 			}
765 			if (unitp->enclksp != NULL) {
766 				kstat_delete(unitp->enclksp);
767 			}
768 
769 			if (unitp->timeout_id != 0) {
770 				(void) untimeout(unitp->timeout_id);
771 				unitp->timeout_id = 0;
772 			}
773 			if (unitp->blink_timeout_id != 0) {
774 				(void) untimeout(unitp->blink_timeout_id);
775 				unitp->blink_timeout_id = 0;
776 			}
777 
778 			ddi_remove_minor_node(dip, NULL);
779 
780 			ddi_remove_intr(dip, (uint_t)0, unitp->ic_trap_cookie);
781 			ddi_remove_intr(dip, (uint_t)1, unitp->ic_trap_cookie);
782 
783 			ddi_regs_map_free(&unitp->ctlr_handle);
784 
785 			mutex_destroy(&unitp->umutex);
786 
787 			return (DDI_SUCCESS);
788 		} else {
789 			return (DDI_FAILURE);
790 		}
791 
792 	case DDI_SUSPEND:
793 		if (!(unitp = ddi_get_soft_state(envctrlsoft_statep, instance)))
794 			return (DDI_FAILURE);
795 		mutex_enter(&unitp->umutex);
796 		if (unitp->suspended) {
797 			cmn_err(CE_WARN, "envctrl already suspended\n");
798 			mutex_exit(&unitp->umutex);
799 			return (DDI_FAILURE);
800 		}
801 		unitp->suspended = 1;
802 		mutex_exit(&unitp->umutex);
803 		return (DDI_SUCCESS);
804 
805 	default:
806 		cmn_err(CE_WARN, "envctrl suspend general fault\n");
807 		return (DDI_FAILURE);
808 	}
809 
810 
811 }
812 
813 /* ARGSUSED */
814 int
envctrl_getinfo(dev_info_t * dip,ddi_info_cmd_t infocmd,void * arg,void ** result)815 envctrl_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
816     void **result)
817 {
818 	dev_t	dev = (dev_t)arg;
819 	struct envctrlunit *unitp;
820 	int	ret;
821 	minor_t instance = getminor(dev);
822 
823 	switch (infocmd) {
824 		case DDI_INFO_DEVT2DEVINFO:
825 			if ((unitp = (struct envctrlunit *)
826 			    ddi_get_soft_state(envctrlsoft_statep,
827 			    instance)) != NULL) {
828 				*result = unitp->dip;
829 				ret = DDI_SUCCESS;
830 			} else {
831 				*result = NULL;
832 				ret = DDI_FAILURE;
833 			}
834 			break;
835 		case DDI_INFO_DEVT2INSTANCE:
836 			*result = (void *)(uintptr_t)instance;
837 			ret = DDI_SUCCESS;
838 			break;
839 		default:
840 			ret = DDI_FAILURE;
841 			break;
842 	}
843 
844 	return (ret);
845 }
846 
847 /* ARGSUSED */
848 static int
envctrl_open(queue_t * q,dev_t * dev,int flag,int sflag,cred_t * credp)849 envctrl_open(queue_t *q, dev_t *dev, int flag, int sflag, cred_t *credp)
850 {
851 	struct envctrlunit *unitp;
852 	int status = 0;
853 	int	instance;
854 
855 	instance = getminor(*dev);
856 	if (instance < 0)
857 		return (ENXIO);
858 	unitp = (struct envctrlunit *)
859 	    ddi_get_soft_state(envctrlsoft_statep, instance);
860 
861 	if (unitp == NULL)
862 		return (ENXIO);
863 
864 	mutex_enter(&unitp->umutex);
865 
866 	if (flag & FWRITE) {
867 		if ((unitp->oflag & FWRITE)) {
868 			mutex_exit(&unitp->umutex);
869 			return (EBUSY);
870 		} else {
871 			unitp->oflag |= FWRITE;
872 		}
873 	}
874 
875 	q->q_ptr = WR(q)->q_ptr = (caddr_t)unitp;
876 
877 	/*
878 	 * if device is open with O_NONBLOCK flag set, let read(2) return 0
879 	 * if no data waiting to be read.  Writes will block on flow control.
880 	 */
881 
882 	/* enable the stream */
883 	qprocson(q);
884 
885 	unitp->readq = RD(q);
886 	unitp->writeq = WR(q);
887 	unitp->msg = (mblk_t *)NULL;
888 
889 	mutex_exit(&unitp->umutex);
890 	return (status);
891 }
892 
893 /* ARGSUSED */
894 static int
envctrl_close(queue_t * q,int flag,cred_t * cred_p)895 envctrl_close(queue_t *q, int flag, cred_t *cred_p)
896 {
897 	struct envctrlunit *unitp;
898 
899 	unitp = (struct envctrlunit *)q->q_ptr;
900 
901 	mutex_enter(&unitp->umutex);
902 
903 	unitp->oflag = B_FALSE;
904 	unitp->current_mode = ENVCTRL_NORMAL_MODE;
905 
906 	/* disable the stream */
907 	q->q_ptr = WR(q)->q_ptr = NULL;
908 	qprocsoff(q);
909 
910 	mutex_exit(&unitp->umutex);
911 	return (DDI_SUCCESS);
912 }
913 
914 /*
915  * standard put procedure for envctrl
916  */
917 static int
envctrl_wput(queue_t * q,mblk_t * mp)918 envctrl_wput(queue_t *q, mblk_t *mp)
919 {
920 	struct msgb *mp1;
921 	struct envctrlunit *unitp;
922 	struct iocblk *iocp;
923 	struct copyresp *csp;
924 	struct envctrl_tda8444t_chip *fanspeed;
925 	struct envctrl_pcf8574_chip *ledchip;
926 	struct envctrl_pcf8591_chip *temp, *a_fanspeed;
927 	struct copyreq *cqp;
928 	int cmd;
929 
930 	unitp = (struct envctrlunit *)q->q_ptr;
931 
932 	switch (DB_TYPE(mp)) {
933 
934 	case M_DATA:
935 
936 		while (mp) {
937 			DB_TYPE(mp) = M_DATA;
938 			mp1 = unlinkb(mp);
939 			mp->b_cont = NULL;
940 			if ((mp->b_wptr - mp->b_rptr) <= 0) {
941 				freemsg(mp);
942 			} else {
943 				(void) putq(q, mp);
944 			}
945 			mp = mp1;
946 		}
947 
948 		break;
949 
950 	case M_IOCTL:
951 	{
952 		iocp = (struct iocblk *)(void *)mp->b_rptr;
953 		cmd = iocp->ioc_cmd;
954 
955 		switch (cmd) {
956 		case ENVCTRL_IOC_SETMODE:
957 		case ENVCTRL_IOC_GETMODE:
958 			if (iocp->ioc_count == TRANSPARENT) {
959 				mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr,
960 				    sizeof (uchar_t), NULL);
961 				qreply(q, mp);
962 			} else {
963 				miocnak(q, mp, 0, EINVAL);
964 			}
965 			break;
966 		case ENVCTRL_IOC_RESETTMPR:
967 			/*
968 			 * For diags, cancel the current temp poll
969 			 * and reset it for a new one.
970 			 */
971 			if (unitp->current_mode == ENVCTRL_DIAG_MODE) {
972 				if (unitp->timeout_id != 0) {
973 					(void) untimeout(unitp->timeout_id);
974 					unitp->timeout_id = 0;
975 				}
976 				envctrl_tempr_poll((void *)unitp);
977 				miocack(q, mp, 0, 0);
978 			} else {
979 				miocnak(q, mp, 0, EINVAL);
980 			}
981 			break;
982 		case ENVCTRL_IOC_GETTEMP:
983 			if (iocp->ioc_count == TRANSPARENT) {
984 				mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr,
985 				    sizeof (struct envctrl_pcf8591_chip), NULL);
986 				qreply(q, mp);
987 			} else {
988 				miocnak(q, mp, 0, EINVAL);
989 			}
990 			break;
991 		case ENVCTRL_IOC_SETTEMP:
992 			if (unitp->current_mode == ENVCTRL_DIAG_MODE &&
993 			    iocp->ioc_count == TRANSPARENT) {
994 				mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr,
995 				    sizeof (uint8_t), NULL);
996 				qreply(q, mp);
997 			} else {
998 				miocnak(q, mp, 0, EINVAL);
999 			}
1000 			break;
1001 		case ENVCTRL_IOC_SETWDT:
1002 			if (unitp->current_mode == ENVCTRL_DIAG_MODE &&
1003 			    iocp->ioc_count == TRANSPARENT) {
1004 				mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr,
1005 				    sizeof (uint8_t), NULL);
1006 				qreply(q, mp);
1007 			} else {
1008 				miocnak(q, mp, 0, EINVAL);
1009 			}
1010 			break;
1011 		case ENVCTRL_IOC_SETFAN:
1012 			/*
1013 			 * we must be in diag mode before we can
1014 			 * set any fan speeds.
1015 			 */
1016 			if (unitp->current_mode == ENVCTRL_DIAG_MODE &&
1017 			    iocp->ioc_count == TRANSPARENT) {
1018 				mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr,
1019 				    sizeof (struct envctrl_tda8444t_chip),
1020 				    NULL);
1021 				qreply(q, mp);
1022 			} else {
1023 				miocnak(q, mp, 0, EINVAL);
1024 			}
1025 			break;
1026 		case ENVCTRL_IOC_GETFAN:
1027 			if (iocp->ioc_count == TRANSPARENT) {
1028 				mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr,
1029 				    sizeof (struct envctrl_pcf8591_chip), NULL);
1030 				qreply(q, mp);
1031 			} else {
1032 				miocnak(q, mp, 0, EINVAL);
1033 			}
1034 			break;
1035 		case ENVCTRL_IOC_SETFSP:
1036 			if (iocp->ioc_count == TRANSPARENT) {
1037 				mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr,
1038 				    sizeof (uint8_t), NULL);
1039 				qreply(q, mp);
1040 			} else {
1041 				miocnak(q, mp, 0, EINVAL);
1042 			}
1043 			break;
1044 		case ENVCTRL_IOC_SETDSKLED:
1045 		case ENVCTRL_IOC_GETDSKLED:
1046 			if (iocp->ioc_count == TRANSPARENT) {
1047 				mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr,
1048 				    sizeof (struct envctrl_pcf8574_chip), NULL);
1049 				qreply(q, mp);
1050 			} else {
1051 				miocnak(q, mp, 0, EINVAL);
1052 			}
1053 			break;
1054 		default:
1055 			miocnak(q, mp, 0, EINVAL);
1056 			break;
1057 		}
1058 
1059 		break;
1060 
1061 	}
1062 	case M_IOCDATA:
1063 	{
1064 		uint8_t *tempr, *wdval;
1065 		long state;
1066 
1067 		csp = (struct copyresp *)(void *)mp->b_rptr;
1068 
1069 		/*
1070 		 * If copy request failed, quit now
1071 		 */
1072 		if (csp->cp_rval != 0) {
1073 			miocnak(q, mp, 0, EINVAL);
1074 			return (0);
1075 		}
1076 
1077 		cqp = (struct copyreq *)(void *)mp->b_rptr;
1078 
1079 		cmd = csp->cp_cmd;
1080 		state = (long)cqp->cq_private;
1081 
1082 		switch (cmd) {
1083 		case ENVCTRL_IOC_SETFAN:
1084 			fanspeed = (struct envctrl_tda8444t_chip *)
1085 			    (void *)mp->b_cont->b_rptr;
1086 			mutex_enter(&unitp->umutex);
1087 			if (envctrl_xmit(unitp, (caddr_t *)(void *)fanspeed,
1088 			    fanspeed->type) == DDI_FAILURE) {
1089 				/*
1090 				 * Fix for a ADF bug
1091 				 * move mutex to after fan fail call
1092 				 * bugid 4016121
1093 				 */
1094 				envctrl_fan_fail_service(unitp);
1095 				mutex_exit(&unitp->umutex);
1096 				miocnak(q, mp, 0, EINVAL);
1097 			} else {
1098 				mutex_exit(&unitp->umutex);
1099 				miocack(q, mp, 0, 0);
1100 			}
1101 			break;
1102 		case ENVCTRL_IOC_SETFSP:
1103 			wdval = (uint8_t *)(void *)mp->b_cont->b_rptr;
1104 			mutex_enter(&unitp->umutex);
1105 			/*
1106 			 * If a user is in normal mode and they try
1107 			 * to set anything other than a disk fault or
1108 			 * a gen fault it is an invalid operation.
1109 			 * in diag mode we allow everything to be
1110 			 * twiddled.
1111 			 */
1112 			if (unitp->current_mode == ENVCTRL_NORMAL_MODE) {
1113 				if (*wdval & ~ENVCTRL_FSP_USRMASK) {
1114 					mutex_exit(&unitp->umutex);
1115 					miocnak(q, mp, 0, EINVAL);
1116 					break;
1117 				}
1118 			}
1119 			envctrl_set_fsp(unitp, wdval);
1120 			mutex_exit(&unitp->umutex);
1121 			miocack(q, mp, 0, 0);
1122 			break;
1123 		case ENVCTRL_IOC_SETDSKLED:
1124 			ledchip = (struct envctrl_pcf8574_chip *)
1125 			    (void *)mp->b_cont->b_rptr;
1126 			mutex_enter(&unitp->umutex);
1127 			if (envctrl_set_dskled(unitp, ledchip)) {
1128 				miocnak(q, mp, 0, EINVAL);
1129 			} else {
1130 				miocack(q, mp, 0, 0);
1131 			}
1132 			mutex_exit(&unitp->umutex);
1133 			break;
1134 		case ENVCTRL_IOC_GETDSKLED:
1135 			if (state  == -1) {
1136 				miocack(q, mp, 0, 0);
1137 				break;
1138 			}
1139 			ledchip = (struct envctrl_pcf8574_chip *)
1140 			    (void *)mp->b_cont->b_rptr;
1141 			mutex_enter(&unitp->umutex);
1142 			if (envctrl_get_dskled(unitp, ledchip)) {
1143 				miocnak(q, mp, 0, EINVAL);
1144 			} else {
1145 				mcopyout(mp, (void *)-1,
1146 				    sizeof (struct envctrl_pcf8574_chip),
1147 				    csp->cp_private, NULL);
1148 				qreply(q, mp);
1149 			}
1150 			mutex_exit(&unitp->umutex);
1151 			break;
1152 		case ENVCTRL_IOC_GETTEMP:
1153 			/* Get the user buffer address */
1154 
1155 			if (state  == -1) {
1156 				miocack(q, mp, 0, 0);
1157 				break;
1158 			}
1159 			temp = (struct envctrl_pcf8591_chip *)
1160 			    (void *)mp->b_cont->b_rptr;
1161 			mutex_enter(&unitp->umutex);
1162 			envctrl_recv(unitp, (caddr_t *)(void *)temp, PCF8591);
1163 			mutex_exit(&unitp->umutex);
1164 			mcopyout(mp, (void *)-1,
1165 			    sizeof (struct envctrl_pcf8591_chip),
1166 			    csp->cp_private, NULL);
1167 			qreply(q, mp);
1168 			break;
1169 		case ENVCTRL_IOC_GETFAN:
1170 			/* Get the user buffer address */
1171 
1172 			if (state == -1) {
1173 				miocack(q, mp, 0, 0);
1174 				break;
1175 			}
1176 			a_fanspeed = (struct envctrl_pcf8591_chip *)
1177 			    (void *)mp->b_cont->b_rptr;
1178 			mutex_enter(&unitp->umutex);
1179 			envctrl_recv(unitp, (caddr_t *)(void *)a_fanspeed,
1180 			    PCF8591);
1181 			mutex_exit(&unitp->umutex);
1182 			mcopyout(mp, (void *)-1,
1183 			    sizeof (struct envctrl_pcf8591_chip),
1184 			    csp->cp_private, NULL);
1185 			qreply(q, mp);
1186 			break;
1187 		case ENVCTRL_IOC_SETTEMP:
1188 			tempr = (uint8_t *)(void *)mp->b_cont->b_rptr;
1189 			if (*tempr > MAX_DIAG_TEMPR) {
1190 				miocnak(q, mp, 0, EINVAL);
1191 			} else {
1192 				mutex_enter(&unitp->umutex);
1193 				envctrl_get_sys_temperatures(unitp, tempr);
1194 				mutex_exit(&unitp->umutex);
1195 				miocack(q, mp, 0, 0);
1196 			}
1197 			break;
1198 		case ENVCTRL_IOC_SETWDT:
1199 			/* reset watchdog timeout period */
1200 			wdval = (uint8_t *)(void *)mp->b_cont->b_rptr;
1201 			if (*wdval > MAX_CL_VAL) {
1202 				miocnak(q, mp, 0, EINVAL);
1203 			} else {
1204 				mutex_enter(&unitp->umutex);
1205 				envctrl_reset_watchdog(unitp, wdval);
1206 				mutex_exit(&unitp->umutex);
1207 				miocack(q, mp, 0, 0);
1208 			}
1209 			break;
1210 		case ENVCTRL_IOC_GETMODE:
1211 			/* Get the user buffer address */
1212 
1213 			if (state == -1) {
1214 				miocack(q, mp, 0, 0);
1215 				break;
1216 			}
1217 			tempr = (uchar_t *)(void *)mp->b_cont->b_rptr;
1218 			*tempr = unitp->current_mode;
1219 			mcopyout(mp, (void *)-1, sizeof (uchar_t),
1220 			    csp->cp_private, NULL);
1221 			qreply(q, mp);
1222 			break;
1223 		case ENVCTRL_IOC_SETMODE:
1224 			/* Set mode */
1225 			wdval = (uint8_t *)(void *)mp->b_cont->b_rptr;
1226 			if (*wdval == ENVCTRL_DIAG_MODE || *wdval ==
1227 			    ENVCTRL_NORMAL_MODE) {
1228 				mutex_enter(&unitp->umutex);
1229 				unitp->current_mode = *wdval;
1230 				if (unitp->timeout_id != 0 &&
1231 				    *wdval == ENVCTRL_DIAG_MODE) {
1232 					(void) untimeout(unitp->timeout_id);
1233 					unitp->timeout_id =
1234 					    (timeout(envctrl_tempr_poll,
1235 					    (caddr_t)unitp,
1236 					    overtemp_timeout_hz));
1237 
1238 				}
1239 				if (*wdval == ENVCTRL_NORMAL_MODE) {
1240 					envctrl_get_sys_temperatures(unitp,
1241 					    (uint8_t *)NULL);
1242 					/*
1243 					 * going to normal mode we
1244 					 * need to go to diag mode
1245 					 * just in case we have
1246 					 * injected a fan fault. It
1247 					 * may not be cleared and if
1248 					 * we call fan_failsrvc it will
1249 					 * power off the ystem if we are
1250 					 * in NORMAL_MODE. Also we need
1251 					 * to delay 1 bit of time here
1252 					 * to  allow the fans to rotate
1253 					 * back up and clear the intr
1254 					 * after we get the sys temps.
1255 					 */
1256 					unitp->current_mode =
1257 					    ENVCTRL_DIAG_MODE;
1258 					envctrl_fan_fail_service(unitp);
1259 					unitp->current_mode =
1260 					    ENVCTRL_NORMAL_MODE;
1261 				}
1262 				mutex_exit(&unitp->umutex);
1263 				miocack(q, mp, 0, 0);
1264 			} else {
1265 				miocnak(q, mp, 0, EINVAL);
1266 			}
1267 			break;
1268 		default:
1269 			freemsg(mp);
1270 			break;
1271 		}
1272 
1273 		break;
1274 	}
1275 
1276 	case M_FLUSH:
1277 		if (*mp->b_rptr & FLUSHR) {
1278 			*mp->b_rptr &= ~FLUSHW;
1279 			qreply(q, mp);
1280 		} else {
1281 			freemsg(mp);
1282 		}
1283 		break;
1284 
1285 	default:
1286 		freemsg(mp);
1287 		break;
1288 	}
1289 
1290 	return (0);
1291 }
1292 
1293 uint_t
envctrl_bus_isr(caddr_t arg)1294 envctrl_bus_isr(caddr_t arg)
1295 {
1296 	struct envctrlunit *unitp = (struct envctrlunit *)(void *)arg;
1297 	int ic = DDI_INTR_UNCLAIMED;
1298 
1299 	mutex_enter(&unitp->umutex);
1300 
1301 	/*
1302 	 * NOT USED
1303 	 */
1304 
1305 	mutex_exit(&unitp->umutex);
1306 	return (ic);
1307 }
1308 
1309 uint_t
envctrl_dev_isr(caddr_t arg)1310 envctrl_dev_isr(caddr_t arg)
1311 {
1312 	struct envctrlunit *unitp = (struct envctrlunit *)(void *)arg;
1313 	uint8_t recv_data;
1314 	int ic;
1315 	int retrys = 0;
1316 	int status;
1317 
1318 	ic = DDI_INTR_UNCLAIMED;
1319 
1320 	mutex_enter(&unitp->umutex);
1321 
1322 	/*
1323 	 * First check to see if it is an interrupt for us by
1324 	 * looking at the "ganged" interrrupt and vector
1325 	 * according to the major type
1326 	 * 0x70 is the addr of the ganged interrupt controller.
1327 	 * Address map for the port byte read is as follows
1328 	 * MSB
1329 	 * -------------------------
1330 	 * |  |  |  |  |  |  |  |  |
1331 	 * -------------------------
1332 	 *  P7 P6 P5 P4 P3 P2 P1 P0
1333 	 * P0 = Power Supply 1 intr
1334 	 * P1 = Power Supply 2 intr
1335 	 * P2 = Power Supply 3 intr
1336 	 * P3 = Dlfop enable for fan sped set
1337 	 * P4 = ENVCTRL_ Fan Fail intr
1338 	 * P5 =	Front Panel Interrupt
1339 	 * P6 = Power Fail Detect Low.
1340 	 * P7 = Enable Interrupts to system
1341 	 */
1342 
1343 retry:
1344 
1345 	status = eHc_read_pcf8574a((struct eHc_envcunit *)unitp,
1346 	    PCF8574A_BASE_ADDR | ENVCTRL_PCF8574_DEV0, &recv_data, 1);
1347 
1348 	/*
1349 	 * This extra read is needed since the first read is discarded
1350 	 * and the second read seems to return 0xFF.
1351 	 */
1352 	if (recv_data == 0xFF) {
1353 		status = eHc_read_pcf8574a((struct eHc_envcunit *)unitp,
1354 		    PCF8574A_BASE_ADDR | ENVCTRL_PCF8574_DEV0, &recv_data, 1);
1355 	}
1356 	if (envctrl_debug_flags)
1357 		cmn_err(CE_WARN, "envctrl_dev_isr: status= %d, data = %x\n",
1358 		    status, recv_data);
1359 
1360 	/*
1361 	 * if the i2c bus is hung it is imperative that this
1362 	 * be cleared on an interrupt or else it will
1363 	 * hang the system with continuous interrupts
1364 	 */
1365 
1366 	if (status == DDI_FAILURE) {
1367 		drv_usecwait(1000);
1368 		if (retrys < envctrl_max_retries) {
1369 			retrys++;
1370 			goto retry;
1371 		} else {
1372 			if (envctrl_debug_flags)
1373 				cmn_err(CE_WARN,
1374 				    "DEVISR FAILED received 0x%x\n", recv_data);
1375 			mutex_exit(&unitp->umutex);
1376 			envctrl_init_bus(unitp);
1377 			mutex_enter(&unitp->umutex);
1378 			envctrl_ps_probe(unitp);
1379 			mutex_exit(&unitp->umutex);
1380 			ic = DDI_INTR_CLAIMED;
1381 			return (ic);
1382 		}
1383 	}
1384 
1385 	/*
1386 	 * Port 0 = PS1 interrupt
1387 	 * Port 1 = PS2 Interrupt
1388 	 * Port 2 = PS3 Interrupt
1389 	 * Port 3 = SPARE
1390 	 * Port 4 = Fan Fail Intr
1391 	 * Port 5 = Front Panle Module intr
1392 	 * Port 6 = Keyswitch Intr
1393 	 * Port 7 = ESINTR ENABLE ???
1394 	 */
1395 
1396 	if (!(recv_data & ENVCTRL_PCF8574_PORT0)) {
1397 		envctrl_PS_intr_service(unitp, PS1);
1398 		ic = DDI_INTR_CLAIMED;
1399 	}
1400 
1401 	if (!(recv_data & ENVCTRL_PCF8574_PORT1)) {
1402 		envctrl_PS_intr_service(unitp, PS2);
1403 		ic = DDI_INTR_CLAIMED;
1404 	}
1405 
1406 	if (!(recv_data & ENVCTRL_PCF8574_PORT2)) {
1407 		envctrl_PS_intr_service(unitp, PS3);
1408 		ic = DDI_INTR_CLAIMED;
1409 	}
1410 
1411 	if (!(recv_data & ENVCTRL_PCF8574_PORT3)) {
1412 		ic = DDI_INTR_CLAIMED;
1413 	}
1414 
1415 	if (!(recv_data & ENVCTRL_PCF8574_PORT4)) {
1416 		/*
1417 		 * Check for a fan fail
1418 		 * Single fan fail
1419 		 * shutdown system
1420 		 */
1421 		envctrl_fan_fail_service(unitp);
1422 		ic = DDI_INTR_CLAIMED;
1423 	}
1424 
1425 	if (!(recv_data & ENVCTRL_PCF8574_PORT5)) {
1426 		(void) envctrl_get_fpm_status(unitp);
1427 		ic = DDI_INTR_CLAIMED;
1428 	}
1429 
1430 	if (!(recv_data & ENVCTRL_PCF8574_PORT6)) {
1431 		ic = DDI_INTR_CLAIMED;
1432 	}
1433 
1434 	if (!(recv_data & ENVCTRL_PCF8574_PORT7)) {
1435 		ic = DDI_INTR_CLAIMED;
1436 	}
1437 
1438 	if ((recv_data == 0xFF)) {
1439 		ic = DDI_INTR_CLAIMED;
1440 	}
1441 
1442 	mutex_exit(&unitp->umutex);
1443 	return (ic);
1444 
1445 }
1446 
1447 static void
envctrl_init_bus(struct envctrlunit * unitp)1448 envctrl_init_bus(struct envctrlunit *unitp)
1449 {
1450 
1451 	int i;
1452 	uint8_t noval = 0;
1453 	struct envctrl_tda8444t_chip fan;
1454 	int fans[] = {ENVCTRL_CPU_FANS, ENVCTRL_PS_FANS, ENVCTRL_AFB_FANS};
1455 
1456 	mutex_enter(&unitp->umutex);
1457 	/* Sets the Mode to 808x type bus */
1458 	ddi_put8(unitp->ctlr_handle,
1459 	    &unitp->bus_ctl_regs->s0, ENVCTRL_CHAR_ZERO);
1460 
1461 	/* SET UP SLAVE ADDR XXX Required..send 0x80 */
1462 
1463 	ddi_put8(unitp->ctlr_handle, &unitp->bus_ctl_regs->s1,
1464 	    ENVCTRL_BUS_INIT0);
1465 	(void) ddi_put8(unitp->ctlr_handle, &unitp->bus_ctl_regs->s0,
1466 	    ENVCTRL_BUS_INIT1);
1467 
1468 	/* Set the clock now */
1469 	ddi_put8(unitp->ctlr_handle,
1470 	    &unitp->bus_ctl_regs->s1, ENVCTRL_BUS_CLOCK0);
1471 
1472 	/* S0 is now S2  necause of the previous write to S1 */
1473 	/* clock= 12MHz, SCL=90KHz */
1474 	ddi_put8(unitp->ctlr_handle,
1475 	    &unitp->bus_ctl_regs->s0, ENVCTRL_BUS_CLOCK1);
1476 
1477 	/* Enable serial interface */
1478 	ddi_put8(unitp->ctlr_handle,
1479 	    &unitp->bus_ctl_regs->s1, ENVCTRL_BUS_ESI);
1480 
1481 	envctrl_stop_clock(unitp);
1482 
1483 	/*
1484 	 * This has been added here because the DAC is powered
1485 	 * on at "0". When the reset_dflop routine is called
1486 	 * this switched the  fans from blast to DAC control.
1487 	 * if the DAC is at "0", then the fans momentarily lose
1488 	 * power until the temp polling and fan set routine is
1489 	 * first called. If the fans lose power, then there is
1490 	 * a fan fault generated and the system will power off.
1491 	 * We only want to do this IF the bus is first being
1492 	 * initted. This will cause errors in Sunvts if we reset
1493 	 * the fan speed under normal operation. Sometimes we need
1494 	 * to be able to induce fan faults. Init bus is a common
1495 	 * routine to unwedge the i2c bus in some cases.
1496 	 */
1497 
1498 	if (unitp->initting == B_TRUE) {
1499 		fan.chip_num = ENVCTRL_TDA8444T_DEV7;
1500 		fan.val = INIT_FAN_VAL;
1501 
1502 		for (i = 0; i < sizeof (fans)/sizeof (int); i++) {
1503 			fan.fan_num = fans[i];
1504 			if ((fans[i] == ENVCTRL_AFB_FANS) &&
1505 			    (unitp->AFB_present == B_FALSE))
1506 				continue;
1507 			(void) envctrl_xmit(unitp, (caddr_t *)(void *)&fan,
1508 			    TDA8444T);
1509 		}
1510 	}
1511 
1512 	envctrl_reset_dflop(unitp);
1513 
1514 	envctrl_enable_devintrs(unitp);
1515 
1516 	unitp->current_mode = ENVCTRL_NORMAL_MODE;
1517 	envctrl_reset_watchdog(unitp, &noval);
1518 
1519 	mutex_exit(&unitp->umutex);
1520 }
1521 
1522 static int
envctrl_xmit(struct envctrlunit * unitp,caddr_t * data,int chip_type)1523 envctrl_xmit(struct envctrlunit *unitp, caddr_t *data, int chip_type)
1524 {
1525 
1526 	struct envctrl_tda8444t_chip *fanspeed;
1527 	struct envctrl_pcf8574_chip *ioport;
1528 	uint8_t slave_addr;
1529 	uint8_t buf[2];
1530 	int retrys = 0;
1531 	int status;
1532 
1533 	ASSERT(MUTEX_HELD(&unitp->umutex));
1534 
1535 	switch (chip_type) {
1536 	case TDA8444T:
1537 
1538 		fanspeed = (struct envctrl_tda8444t_chip *)data;
1539 
1540 		if (fanspeed->chip_num > ENVCTRL_FAN_ADDR_MAX) {
1541 			return (DDI_FAILURE);
1542 		}
1543 
1544 		if (fanspeed->fan_num > ENVCTRL_PORT7) {
1545 			return (DDI_FAILURE);
1546 		}
1547 
1548 		if (fanspeed->val > MAX_FAN_VAL) {
1549 			return (DDI_FAILURE);
1550 		}
1551 
1552 retry0:
1553 		slave_addr = (TDA8444T_BASE_ADDR | fanspeed->chip_num);
1554 		buf[0] = fanspeed->val;
1555 
1556 		status = eHc_write_tda8444((struct eHc_envcunit *)unitp,
1557 		    TDA8444T_BASE_ADDR | fanspeed->chip_num, 0xF,
1558 		    fanspeed->fan_num, buf, 1);
1559 		if (status != DDI_SUCCESS) {
1560 			drv_usecwait(1000);
1561 			if (retrys < envctrl_max_retries) {
1562 				retrys++;
1563 				goto retry0;
1564 			} else {
1565 				mutex_exit(&unitp->umutex);
1566 				envctrl_init_bus(unitp);
1567 				mutex_enter(&unitp->umutex);
1568 				if (envctrl_debug_flags)
1569 					cmn_err(CE_WARN,
1570 					    "envctrl_xmit: Write to TDA8444 " \
1571 					    "failed\n");
1572 				return (DDI_FAILURE);
1573 			}
1574 		}
1575 
1576 		/*
1577 		 * Update the kstats.
1578 		 */
1579 		switch (fanspeed->fan_num) {
1580 		case ENVCTRL_CPU_FANS:
1581 			unitp->fan_kstats[ENVCTRL_FAN_TYPE_CPU].fanspeed =
1582 			    fanspeed->val;
1583 			break;
1584 		case ENVCTRL_PS_FANS:
1585 			unitp->fan_kstats[ENVCTRL_FAN_TYPE_PS].fanspeed =
1586 			    fanspeed->val;
1587 			break;
1588 		case ENVCTRL_AFB_FANS:
1589 			unitp->fan_kstats[ENVCTRL_FAN_TYPE_AFB].fanspeed =
1590 			    fanspeed->val;
1591 			break;
1592 		default:
1593 			break;
1594 		}
1595 		break;
1596 	case PCF8574:
1597 		ioport = (struct envctrl_pcf8574_chip *)data;
1598 		buf[0] = ioport->val;
1599 		if (ioport->chip_num > ENVCTRL_PCF8574_DEV7)
1600 			return (DDI_FAILURE);
1601 
1602 retry:
1603 		if (ioport->type == PCF8574A) {
1604 			slave_addr = (PCF8574A_BASE_ADDR | ioport->chip_num);
1605 			status =
1606 			    eHc_write_pcf8574a((struct eHc_envcunit *)unitp,
1607 			    PCF8574A_BASE_ADDR | ioport->chip_num, buf, 1);
1608 		} else {
1609 			slave_addr = (PCF8574_BASE_ADDR | ioport->chip_num);
1610 			status = eHc_write_pcf8574((struct eHc_envcunit *)unitp,
1611 			    PCF8574_BASE_ADDR | ioport->chip_num, buf, 1);
1612 		}
1613 
1614 		if (status != DDI_SUCCESS) {
1615 			drv_usecwait(1000);
1616 			if (retrys < envctrl_max_retries) {
1617 				retrys++;
1618 				goto retry;
1619 			} else {
1620 				mutex_exit(&unitp->umutex);
1621 				envctrl_init_bus(unitp);
1622 				mutex_enter(&unitp->umutex);
1623 				if (envctrl_debug_flags)
1624 					cmn_err(CE_WARN, "Write to PCF8574 " \
1625 					    "failed, addr = %X\n", slave_addr);
1626 				if (envctrl_debug_flags)
1627 					cmn_err(CE_WARN, "envctrl_xmit: PCF8574\
1628 						dev = %d, port = %d\n",
1629 					    ioport->chip_num, ioport->type);
1630 				return (DDI_FAILURE);
1631 			}
1632 		}
1633 		break;
1634 
1635 	default:
1636 		return (DDI_FAILURE);
1637 	}
1638 
1639 	return (DDI_SUCCESS);
1640 }
1641 
1642 static void
envctrl_recv(struct envctrlunit * unitp,caddr_t * data,int chip_type)1643 envctrl_recv(struct envctrlunit *unitp, caddr_t *data, int chip_type)
1644 {
1645 
1646 	struct envctrl_pcf8591_chip *temp;
1647 	struct envctrl_pcf8574_chip *ioport;
1648 	uint8_t slave_addr, recv_data;
1649 	int retrys = 0;
1650 	int status;
1651 	uint8_t buf[1];
1652 
1653 	ASSERT(MUTEX_HELD(&unitp->umutex));
1654 
1655 	switch (chip_type) {
1656 	case PCF8591:
1657 		temp = (struct envctrl_pcf8591_chip *)data;
1658 		slave_addr = (PCF8591_BASE_ADDR | temp->chip_num);
1659 
1660 retry:
1661 		status = eHc_read_pcf8591((struct eHc_envcunit *)unitp,
1662 		    PCF8591_BASE_ADDR | temp->chip_num & 0xF,
1663 		    temp->sensor_num, 0, 0, 1, &recv_data, 1);
1664 
1665 		/*
1666 		 * another place to catch the i2c bus hang on an 8591 read
1667 		 * In this instance we will just return the data that is read
1668 		 * after the max_retry because this could be a valid value.
1669 		 */
1670 		if (status != DDI_SUCCESS) {
1671 			drv_usecwait(1000);
1672 			if (retrys < envctrl_max_retries) {
1673 				retrys++;
1674 				goto retry;
1675 			} else {
1676 				mutex_exit(&unitp->umutex);
1677 				envctrl_init_bus(unitp);
1678 				mutex_enter(&unitp->umutex);
1679 				if (envctrl_debug_flags)
1680 					cmn_err(CE_WARN, "Read from PCF8591 " \
1681 					    "failed, slave_addr = %x\n",
1682 					    slave_addr);
1683 			}
1684 		}
1685 		temp->temp_val = recv_data;
1686 		break;
1687 	case TDA8444T:
1688 		printf("envctrl_recv: attempting to read TDA8444T\n");
1689 		return;
1690 	case PCF8574:
1691 		ioport = (struct envctrl_pcf8574_chip *)data;
1692 
1693 retry1:
1694 		if (ioport->chip_num > ENVCTRL_PCF8574_DEV7)
1695 			cmn_err(CE_WARN, "envctrl: dev out of range 0x%x\n",
1696 			    ioport->chip_num);
1697 
1698 		if (ioport->type == PCF8574A) {
1699 			slave_addr = (PCF8574_READ_BIT | PCF8574A_BASE_ADDR |
1700 			    ioport->chip_num);
1701 			status = eHc_read_pcf8574a((struct eHc_envcunit *)unitp,
1702 			    PCF8574A_BASE_ADDR | ioport->chip_num, buf, 1);
1703 		} else {
1704 			slave_addr = (PCF8574_READ_BIT | PCF8574_BASE_ADDR |
1705 			    ioport->chip_num);
1706 			status = eHc_read_pcf8574((struct eHc_envcunit *)unitp,
1707 			    PCF8574_BASE_ADDR | ioport->chip_num, buf, 1);
1708 		}
1709 
1710 		if (status != DDI_SUCCESS) {
1711 			drv_usecwait(1000);
1712 			if (retrys < envctrl_max_retries) {
1713 				retrys++;
1714 				goto retry1;
1715 			} else {
1716 				mutex_exit(&unitp->umutex);
1717 				envctrl_init_bus(unitp);
1718 				mutex_enter(&unitp->umutex);
1719 				if (envctrl_debug_flags)
1720 					cmn_err(CE_WARN, "Read from PCF8574 "\
1721 					    "failed, addr = %X\n", slave_addr);
1722 				if (envctrl_debug_flags)
1723 					cmn_err(CE_WARN, "envctrl_recv: PCF8574\
1724 						dev = %d, port = %d\n",
1725 					    ioport->chip_num, ioport->type);
1726 			}
1727 		}
1728 		ioport->val = buf[0];
1729 		break;
1730 	default:
1731 		break;
1732 	}
1733 }
1734 
1735 static int
envctrl_get_ps_temp(struct envctrlunit * unitp,uint8_t psaddr)1736 envctrl_get_ps_temp(struct envctrlunit *unitp, uint8_t psaddr)
1737 {
1738 	uint8_t tempr;
1739 	int i, retrys;
1740 	int status;
1741 	uint8_t buf[4];
1742 
1743 	ASSERT(MUTEX_HELD(&unitp->umutex));
1744 
1745 	tempr = 0;
1746 	retrys = 0;
1747 
1748 retry:
1749 	status = eHc_read_pcf8591((struct eHc_envcunit *)unitp,
1750 	    PCF8591_BASE_ADDR | psaddr & 0xF, 0, 1, 0, 1, buf, 4);
1751 
1752 	tempr = 0;
1753 	for (i = 0; i < PCF8591_MAX_PORTS; i++) {
1754 		/*
1755 		 * The pcf8591 will return 0xff if no port
1756 		 * is there.. this is bogus for setting temps.
1757 		 * so just ignore it!
1758 		 */
1759 		if (envctrl_debug_flags) {
1760 			cmn_err(CE_WARN, "PS addr 0x%x recvd 0x%x on port %d\n",
1761 			    psaddr, buf[i], i);
1762 		}
1763 		if (buf[i] > tempr && buf[i] < MAX_PS_ADVAL) {
1764 			tempr = buf[i];
1765 		}
1766 	}
1767 
1768 	/*
1769 	 * This routine is a safeguard to make sure that if the
1770 	 * powersupply temps cannot be read that we do something
1771 	 * to make sure that the system will notify the user and
1772 	 * it will stay running with the fans at 100%. The calling
1773 	 * routine should take care of that.
1774 	 */
1775 	if (status != DDI_SUCCESS) {
1776 		drv_usecwait(1000);
1777 		if (retrys < envctrl_max_retries) {
1778 			retrys++;
1779 			goto retry;
1780 		} else {
1781 			mutex_exit(&unitp->umutex);
1782 			envctrl_init_bus(unitp);
1783 			mutex_enter(&unitp->umutex);
1784 			if (envctrl_debug_flags)
1785 				cmn_err(CE_WARN,
1786 				    "Cannot read Power Supply Temps addr = %X",
1787 				    psaddr);
1788 			return (PS_DEFAULT_VAL);
1789 		}
1790 	}
1791 
1792 	return (ps_temps[tempr]);
1793 }
1794 
1795 static int
envctrl_get_cpu_temp(struct envctrlunit * unitp,int cpunum)1796 envctrl_get_cpu_temp(struct envctrlunit *unitp, int cpunum)
1797 {
1798 	uint8_t recv_data;
1799 	int retrys;
1800 	int status;
1801 
1802 	ASSERT(MUTEX_HELD(&unitp->umutex));
1803 
1804 	/*
1805 	 * This routine takes in the number of the port that
1806 	 * we want to read in the 8591. This should be the
1807 	 * location of the COU thermistor for one of the 4
1808 	 * cpu's. It will return the temperature in degrees C
1809 	 * to the caller.
1810 	 */
1811 
1812 	retrys = 0;
1813 
1814 retry:
1815 	status = eHc_read_pcf8591((struct eHc_envcunit *)unitp,
1816 	    PCF8591_BASE_ADDR | PCF8591_DEV7, cpunum, 0, 0, 0,
1817 	    &recv_data, 1);
1818 
1819 	/*
1820 	 * We need to take a sledge hammer to the bus if we get back
1821 	 * value of the chip. This means that the i2c bus got wedged.
1822 	 * On the 1.4 systems this happens sometimes while running
1823 	 * sunvts. We will return the max cpu temp minus 10 to make
1824 	 * the fans run at full speed so that we don;t cook the
1825 	 * system.
1826 	 * At this point this is a workaround for hardware glitch.
1827 	 */
1828 	if (status == DDI_FAILURE) {
1829 		drv_usecwait(1000);
1830 		if (retrys < envctrl_max_retries) {
1831 			retrys++;
1832 			goto retry;
1833 		} else {
1834 			mutex_exit(&unitp->umutex);
1835 			envctrl_init_bus(unitp);
1836 			mutex_enter(&unitp->umutex);
1837 			if (envctrl_debug_flags)
1838 				cmn_err(CE_WARN, "envctrl CPU TEMP read " \
1839 				    "failed\n");
1840 			/* we don't want to power off the system */
1841 			return (MAX_CPU_TEMP - 10);
1842 		}
1843 	}
1844 
1845 	return (cpu_temps[recv_data]);
1846 }
1847 
1848 static int
envctrl_get_lm75_temp(struct envctrlunit * unitp)1849 envctrl_get_lm75_temp(struct envctrlunit *unitp)
1850 {
1851 
1852 	int k;
1853 	ushort_t lmval;
1854 	uint8_t tmp1;
1855 	uint8_t tmp2;
1856 	int status;
1857 	uint8_t buf[2];
1858 
1859 
1860 	ASSERT(MUTEX_HELD(&unitp->umutex));
1861 
1862 	status = eHc_read_lm75((struct eHc_envcunit *)unitp,
1863 	    LM75_BASE_ADDR | LM75_CONFIG_ADDRA, buf, 2);
1864 	if (status != DDI_SUCCESS)
1865 		cmn_err(CE_WARN, "read of LM75 failed\n");
1866 
1867 	tmp1 = buf[0];
1868 	tmp2 = buf[1];
1869 
1870 	/*
1871 	 * Store the forst 8 bits in the upper nibble of the
1872 	 * short, then store the lower 8 bits in the lower nibble
1873 	 * of the short, shift 7 to the right to get the 9 bit value
1874 	 * that the lm75 is really sending.
1875 	 */
1876 	lmval = tmp1 << 8;
1877 	lmval = (lmval | tmp2);
1878 	lmval = (lmval >> 7);
1879 	/*
1880 	 * Check the 9th bit to see if it is a negative
1881 	 * temperature. If so change into 2's compliment
1882 	 * and divide by 2 since each value is equal to a
1883 	 * half degree strp in degrees C
1884 	 */
1885 	if (lmval & LM75_COMP_MASK) {
1886 		tmp1 = (lmval & LM75_COMP_MASK_UPPER);
1887 		tmp1 = -tmp1;
1888 		tmp1 = tmp1/2;
1889 		k = 0 - tmp1;
1890 	} else {
1891 		k = lmval /2;
1892 	}
1893 	return (k);
1894 }
1895 
1896 
1897 static void
envctrl_tempr_poll(void * arg)1898 envctrl_tempr_poll(void *arg)
1899 {
1900 	int diag_flag = 0;
1901 	struct envctrlunit *unitp = (struct envctrlunit *)arg;
1902 
1903 	mutex_enter(&unitp->umutex);
1904 
1905 	if (unitp->shutdown == B_TRUE) {
1906 		(void) power_down("Fatal System Environmental Control Error");
1907 	}
1908 
1909 	/*
1910 	 * if we are in diag mode and the temp poll thread goes off,
1911 	 * this means that the system is too heavily loaded and the 60 second
1912 	 * window to execute the test is failing. We will change the fanspeed
1913 	 * but will not check for a fanfault. This will cause a system shutdown
1914 	 * if the system has had a fanfault injected.
1915 	 */
1916 	if (unitp->current_mode == ENVCTRL_DIAG_MODE) {
1917 		diag_flag++;
1918 		if (envctrl_debug_flags) {
1919 			cmn_err(CE_WARN,
1920 			    "Tempr poll went off while in DIAG MODE");
1921 		}
1922 	}
1923 	unitp->current_mode = ENVCTRL_NORMAL_MODE;
1924 	envctrl_get_sys_temperatures(unitp, (uint8_t *)NULL);
1925 	if (diag_flag == 0) {
1926 		envctrl_fan_fail_service(unitp);
1927 	}
1928 	/* now have this thread sleep for a while */
1929 	unitp->timeout_id = (timeout(envctrl_tempr_poll,
1930 	    (caddr_t)unitp, overtemp_timeout_hz));
1931 
1932 	mutex_exit(&unitp->umutex);
1933 }
1934 
1935 static void
envctrl_led_blink(void * arg)1936 envctrl_led_blink(void *arg)
1937 {
1938 	struct envctrl_pcf8574_chip fspchip;
1939 	struct envctrlunit *unitp = (struct envctrlunit *)arg;
1940 
1941 	mutex_enter(&unitp->umutex);
1942 
1943 	fspchip.type = PCF8574A;
1944 	fspchip.chip_num = ENVCTRL_PCF8574_DEV6; /* 0x01 port 1 */
1945 	envctrl_recv(unitp, (caddr_t *)(void *)&fspchip, PCF8574);
1946 
1947 	if (unitp->present_led_state == B_TRUE) {
1948 		/*
1949 		 * Now we need to "or" in fault bits of the FSP
1950 		 * module for the mass storage fault led.
1951 		 * and set it.
1952 		 */
1953 		fspchip.val = (fspchip.val & ~(ENVCTRL_PCF8574_PORT4) |
1954 		    0xC0);
1955 		unitp->present_led_state = B_FALSE;
1956 	} else {
1957 		fspchip.val = (fspchip.val | ENVCTRL_PCF8574_PORT4 | 0xC0);
1958 		unitp->present_led_state = B_TRUE;
1959 	}
1960 
1961 	(void) envctrl_xmit(unitp, (caddr_t *)(void *)&fspchip, PCF8574);
1962 
1963 	/* now have this thread sleep for a while */
1964 	unitp->blink_timeout_id = (timeout(envctrl_led_blink,
1965 	    (caddr_t)unitp, blink_timeout_hz));
1966 
1967 	mutex_exit(&unitp->umutex);
1968 }
1969 
1970 /* called with mutex held */
1971 static void
envctrl_get_sys_temperatures(struct envctrlunit * unitp,uint8_t * diag_tempr)1972 envctrl_get_sys_temperatures(struct envctrlunit *unitp, uint8_t *diag_tempr)
1973 {
1974 	int temperature, tmptemp, cputemp, hicputemp, ambtemp;
1975 	int i;
1976 	struct envctrl_tda8444t_chip fan;
1977 	uint8_t psaddr[] = {PSTEMP3, PSTEMP2, PSTEMP1, PSTEMP0};
1978 	uint8_t noval = 0;
1979 	uint8_t fspval;
1980 
1981 	ASSERT(MUTEX_HELD(&unitp->umutex));
1982 
1983 	fan.fan_num = ENVCTRL_CPU_FANS;
1984 	fan.chip_num = ENVCTRL_TDA8444T_DEV7;
1985 
1986 	tmptemp = 0;	/* Right init value ?? */
1987 
1988 	/*
1989 	 * THis routine is caled once every minute
1990 	 * we wil re-se the watchdog timer each time
1991 	 * we poll the temps. The watchdog timer is
1992 	 * set up for 3 minutes. Should the kernel thread
1993 	 * wedge, for some reason the watchdog will go off
1994 	 * and blast the fans.
1995 	 */
1996 
1997 	if (unitp->current_mode == ENVCTRL_DIAG_MODE) {
1998 		unitp->current_mode = ENVCTRL_NORMAL_MODE;
1999 		envctrl_reset_watchdog(unitp, &noval);
2000 		unitp->current_mode = ENVCTRL_DIAG_MODE;
2001 	} else {
2002 		envctrl_reset_watchdog(unitp, &noval);
2003 	}
2004 
2005 	/*
2006 	 * we need to reset the dflop to allow the fans to be
2007 	 * set if the watchdog goes of and the kernel resumes
2008 	 * resetting the dflop alos resets the device interrupts
2009 	 * we need to reenable them also.
2010 	 */
2011 	envctrl_reset_dflop(unitp);
2012 
2013 	envctrl_enable_devintrs(unitp);
2014 
2015 	/*
2016 	 * If we are in diag mode we allow the system to be
2017 	 * faked out as to what the temperature is
2018 	 * to see if the fans speed up.
2019 	 */
2020 	if (unitp->current_mode == ENVCTRL_DIAG_MODE && diag_tempr != NULL) {
2021 		if (unitp->timeout_id != 0) {
2022 			(void) untimeout(unitp->timeout_id);
2023 		}
2024 
2025 		ambtemp = *diag_tempr;
2026 		unitp->timeout_id = (timeout(envctrl_tempr_poll,
2027 		    (caddr_t)unitp, overtemp_timeout_hz));
2028 	} else {
2029 		ambtemp = envctrl_get_lm75_temp(unitp);
2030 		/*
2031 		 * Sometimes when we read the temp it comes back bogus
2032 		 * to fix this we just need to reset the envctrl bus
2033 		 */
2034 		if (ambtemp == -100) {
2035 			mutex_exit(&unitp->umutex);
2036 			envctrl_init_bus(unitp);
2037 			mutex_enter(&unitp->umutex);
2038 			ambtemp = envctrl_get_lm75_temp(unitp);
2039 		}
2040 	}
2041 
2042 	envctrl_mod_encl_kstats(unitp, ENVCTRL_ENCL_AMBTEMPR, INSTANCE_0,
2043 	    ambtemp);
2044 
2045 	fspval = envctrl_get_fpm_status(unitp);
2046 
2047 	if (ambtemp > MAX_AMB_TEMP) {
2048 		fspval |= (ENVCTRL_FSP_TEMP_ERR | ENVCTRL_FSP_GEN_ERR);
2049 		if (!(envctrl_power_off_overide) &&
2050 		    unitp->current_mode == ENVCTRL_NORMAL_MODE) {
2051 			unitp->shutdown = B_TRUE;
2052 		}
2053 		if (unitp->current_mode == ENVCTRL_NORMAL_MODE) {
2054 			cmn_err(CE_WARN,
2055 			    "Ambient Temperature is %d C, shutdown now\n",
2056 			    ambtemp);
2057 		}
2058 	} else {
2059 		if (envctrl_isother_fault_led(unitp, fspval,
2060 		    ENVCTRL_FSP_TEMP_ERR)) {
2061 			fspval &= ~(ENVCTRL_FSP_TEMP_ERR);
2062 		} else {
2063 			fspval &= ~(ENVCTRL_FSP_TEMP_ERR | ENVCTRL_FSP_GEN_ERR);
2064 		}
2065 	}
2066 
2067 	envctrl_set_fsp(unitp, &fspval);
2068 
2069 	cputemp = hicputemp = 0;
2070 #ifndef TESTBED
2071 	for (i = 0; i < ENVCTRL_MAX_CPUS; i++) {
2072 		if (unitp->cpu_pr_location[i] == B_TRUE) {
2073 			cputemp = envctrl_get_cpu_temp(unitp, i);
2074 			envctrl_mod_encl_kstats(unitp, ENVCTRL_ENCL_CPUTEMPR,
2075 			    i, cputemp);
2076 			if (cputemp >= MAX_CPU_TEMP) {
2077 				if (!(envctrl_power_off_overide)) {
2078 					unitp->shutdown = B_TRUE;
2079 				}
2080 				cmn_err(CE_WARN,
2081 				    "CPU %d OVERHEATING!!!", i);
2082 			}
2083 
2084 			if (cputemp > hicputemp) {
2085 				hicputemp = cputemp;
2086 			}
2087 		}
2088 	}
2089 #else
2090 	cputemp = envctrl_get_cpu_temp(unitp, 0);
2091 	envctrl_mod_encl_kstats(unitp, ENVCTRL_ENCL_CPUTEMPR, 0, cputemp);
2092 #endif
2093 
2094 	fspval = envctrl_get_fpm_status(unitp);
2095 
2096 	/*
2097 	 * We first look at the ambient temp. If the system is at idle
2098 	 * the cpu temps will be approx 20 degrees above ambient.
2099 	 * If the cpu's rise above 20, then the CPU fans are set
2100 	 * according to the cpu temp minus 20 degrees C.
2101 	 */
2102 	if (unitp->current_mode == ENVCTRL_DIAG_MODE && diag_tempr != NULL) {
2103 		temperature = ambtemp;
2104 	} else {
2105 		temperature = hicputemp - CPU_AMB_RISE;
2106 	}
2107 
2108 	if (temperature < 0) {
2109 		fan.val = MAX_FAN_SPEED;	/* blast it is out of range */
2110 	} else if (temperature > MAX_AMB_TEMP) {
2111 		fan.val = MAX_FAN_SPEED;
2112 		fspval |= (ENVCTRL_FSP_TEMP_ERR | ENVCTRL_FSP_GEN_ERR);
2113 
2114 		if (unitp->current_mode == ENVCTRL_NORMAL_MODE) {
2115 			cmn_err(CE_WARN,
2116 			    "CPU Fans set to MAX. CPU Temp is %d C\n",
2117 			    hicputemp);
2118 		}
2119 	} else if (ambtemp < MAX_AMB_TEMP) {
2120 		if (!envctrl_p0_enclosure) {
2121 			fan.val = acme_cpu_fanspd[temperature];
2122 		} else {
2123 			fan.val = fan_speed[temperature];
2124 		}
2125 		if (envctrl_isother_fault_led(unitp, fspval,
2126 		    ENVCTRL_FSP_TEMP_ERR)) {
2127 			fspval &= ~(ENVCTRL_FSP_TEMP_ERR);
2128 		} else {
2129 			fspval &= ~(ENVCTRL_FSP_TEMP_ERR | ENVCTRL_FSP_GEN_ERR);
2130 		}
2131 	}
2132 
2133 	envctrl_set_fsp(unitp, &fspval);
2134 
2135 	/*
2136 	 * Update temperature kstats. FSP kstats are updated in the
2137 	 * set and get routine.
2138 	 */
2139 
2140 	unitp->fan_kstats[ENVCTRL_FAN_TYPE_CPU].fanspeed = fan.val;
2141 
2142 	/* CPU FANS */
2143 	(void) envctrl_xmit(unitp, (caddr_t *)(void *)&fan, TDA8444T);
2144 
2145 	/* The afb Fan is always at max */
2146 	if (unitp->AFB_present == B_TRUE) {
2147 		fan.val = AFB_MAX;
2148 		/* AFB FANS */
2149 		unitp->fan_kstats[ENVCTRL_FAN_TYPE_AFB].fanspeed = fan.val;
2150 		fan.fan_num = ENVCTRL_AFB_FANS;
2151 		(void) envctrl_xmit(unitp, (caddr_t *)(void *)&fan, TDA8444T);
2152 	}
2153 
2154 	/*
2155 	 * Now set the Powersupply fans
2156 	 */
2157 
2158 	tmptemp = temperature = 0;
2159 	for (i = 0; i <= MAXPS; i++) {
2160 		if (unitp->ps_present[i]) {
2161 			tmptemp = envctrl_get_ps_temp(unitp, psaddr[i]);
2162 			unitp->ps_kstats[i].ps_tempr = tmptemp & 0xFFFF;
2163 			if (tmptemp > temperature) {
2164 				temperature = tmptemp;
2165 			}
2166 			if (temperature >= MAX_PS_TEMP) {
2167 				if (!(envctrl_power_off_overide)) {
2168 					unitp->shutdown = B_TRUE;
2169 				}
2170 				cmn_err(CE_WARN,
2171 				    "Power Supply %d OVERHEATING!!!\
2172 				    Temp is %d C", i, temperature);
2173 			}
2174 		}
2175 	}
2176 
2177 
2178 	fan.fan_num = ENVCTRL_PS_FANS;
2179 	if (temperature > PS_TEMP_WARN) {
2180 		fspval = envctrl_get_fpm_status(unitp);
2181 		fspval |= (ENVCTRL_FSP_TEMP_ERR | ENVCTRL_FSP_GEN_ERR);
2182 		envctrl_set_fsp(unitp, &fspval);
2183 		fan.val = MAX_FAN_SPEED;
2184 		cmn_err(CE_WARN, "A Power Supply is close to  OVERHEATING!!!");
2185 	} else {
2186 		if (temperature - ambtemp > PS_AMB_RISE) {
2187 			ambtemp = temperature - PS_AMB_RISE;
2188 		}
2189 		if (!envctrl_p0_enclosure) {
2190 			fan.val = acme_ps_fanspd[ambtemp];
2191 		} else {
2192 			fan.val = ps_fans[ambtemp];
2193 		}
2194 	}
2195 
2196 	/*
2197 	 * XXX add in error condition for ps overtemp
2198 	 */
2199 
2200 	unitp->fan_kstats[ENVCTRL_FAN_TYPE_PS].fanspeed = fan.val;
2201 	(void) envctrl_xmit(unitp, (caddr_t *)(void *)&fan, TDA8444T);
2202 }
2203 
2204 /* called with mutex held */
2205 static void
envctrl_fan_fail_service(struct envctrlunit * unitp)2206 envctrl_fan_fail_service(struct envctrlunit *unitp)
2207 {
2208 	uint8_t recv_data, fpmstat;
2209 	int fantype;
2210 	int psfanflt, cpufanflt, afbfanflt;
2211 	int retries = 0, max_retry_count;
2212 	int status;
2213 
2214 	psfanflt = cpufanflt = afbfanflt = 0;
2215 	/*
2216 	 * The fan fail sensor is located at address 0x70
2217 	 * on the envctrl bus.
2218 	 */
2219 
2220 	ASSERT(MUTEX_HELD(&unitp->umutex));
2221 
2222 retry:
2223 	status = eHc_read_pcf8574a((struct eHc_envcunit *)unitp,
2224 	    PCF8574A_BASE_ADDR | ENVCTRL_PCF8574_DEV4, &recv_data, 1);
2225 	if (status != DDI_SUCCESS)
2226 		cmn_err(CE_WARN, "fan_fail_service: status = %d, data = %x\n",
2227 		    status, recv_data);
2228 
2229 	/*
2230 	 * If all fan ports are high (0xff) then we don't have any
2231 	 * fan faults. Reset the kstats
2232 	 */
2233 	if (recv_data == 0xff) {
2234 		unitp->fan_kstats[ENVCTRL_FAN_TYPE_PS].fans_ok = B_TRUE;
2235 		unitp->fan_kstats[ENVCTRL_FAN_TYPE_CPU].fans_ok = B_TRUE;
2236 		unitp->fan_kstats[ENVCTRL_FAN_TYPE_AFB].fans_ok = B_TRUE;
2237 		unitp->fan_kstats[ENVCTRL_FAN_TYPE_PS].fanflt_num = 0;
2238 		unitp->fan_kstats[ENVCTRL_FAN_TYPE_CPU].fanflt_num = 0;
2239 		unitp->fan_kstats[ENVCTRL_FAN_TYPE_AFB].fanflt_num = 0;
2240 		unitp->num_fans_failed = 0;
2241 		fpmstat = envctrl_get_fpm_status(unitp);
2242 		if (!(envctrl_isother_fault_led(unitp, fpmstat, 0))) {
2243 			fpmstat &= ~(ENVCTRL_FSP_GEN_ERR);
2244 		}
2245 		if (unitp->shutdown != B_TRUE) {
2246 			envctrl_set_fsp(unitp, &fpmstat);
2247 		}
2248 		return;
2249 	}
2250 
2251 	fantype = ENVCTRL_FAN_TYPE_PS;
2252 
2253 	if (!(recv_data & ENVCTRL_PCF8574_PORT0)) {
2254 		psfanflt = PS_FAN_3;
2255 	}
2256 	if (!(recv_data & ENVCTRL_PCF8574_PORT1)) {
2257 		psfanflt = PS_FAN_2;
2258 	}
2259 	if (!(recv_data & ENVCTRL_PCF8574_PORT2)) {
2260 		psfanflt = PS_FAN_1;
2261 	}
2262 
2263 	if (psfanflt != 0) {
2264 		unitp->fan_kstats[fantype].fans_ok = B_FALSE;
2265 		unitp->fan_kstats[fantype].fanflt_num = psfanflt - 1;
2266 		if (retries == MAX_FAN_FAIL_RETRY && status == DDI_SUCCESS &&
2267 		    unitp->current_mode == ENVCTRL_NORMAL_MODE) {
2268 			cmn_err(CE_WARN, "PS Fan Number %d Failed",
2269 			    psfanflt - 1);
2270 		}
2271 	} else {
2272 		unitp->fan_kstats[fantype].fans_ok = B_TRUE;
2273 		unitp->fan_kstats[fantype].fanflt_num = 0;
2274 	}
2275 
2276 	fantype = ENVCTRL_FAN_TYPE_CPU;
2277 
2278 	if (!(recv_data & ENVCTRL_PCF8574_PORT3)) {
2279 		cpufanflt = CPU_FAN_1;
2280 	}
2281 	if (!(recv_data & ENVCTRL_PCF8574_PORT4)) {
2282 		cpufanflt = CPU_FAN_2;
2283 	}
2284 	if (!(recv_data & ENVCTRL_PCF8574_PORT5)) {
2285 		cpufanflt = CPU_FAN_3;
2286 	}
2287 
2288 	if (cpufanflt != 0) {
2289 		unitp->fan_kstats[fantype].fans_ok = B_FALSE;
2290 		unitp->fan_kstats[fantype].fanflt_num = cpufanflt - 1;
2291 		if (retries == MAX_FAN_FAIL_RETRY && status == DDI_SUCCESS &&
2292 		    unitp->current_mode == ENVCTRL_NORMAL_MODE) {
2293 			cmn_err(CE_WARN, "CPU Fan Number %d Failed",
2294 			    cpufanflt - 1);
2295 		}
2296 	} else {
2297 		unitp->fan_kstats[fantype].fans_ok = B_TRUE;
2298 		unitp->fan_kstats[fantype].fanflt_num = 0;
2299 	}
2300 
2301 	if (!(recv_data & ENVCTRL_PCF8574_PORT6) &&
2302 	    (unitp->AFB_present == B_TRUE)) {
2303 		/*
2304 		 * If the afb is present and the afb fan fails,
2305 		 * we need to power off or else it will melt!
2306 		 * If it isn't present just log the error.
2307 		 * We make the decision off of the afbfanflt
2308 		 * flag later on in an if statement.
2309 		 */
2310 		afbfanflt++;
2311 		unitp->fan_kstats[ENVCTRL_FAN_TYPE_AFB].fans_ok
2312 		    = B_FALSE;
2313 		unitp->fan_kstats[ENVCTRL_FAN_TYPE_AFB].fanflt_num =
2314 		    AFB_FAN_1;
2315 		if (unitp->current_mode == ENVCTRL_NORMAL_MODE) {
2316 			cmn_err(CE_WARN, "AFB Fan Failed");
2317 		}
2318 
2319 	}
2320 
2321 	/*
2322 	 * If we have no Fan Faults Clear the LED's
2323 	 * If we have fan faults set the Gen Fault LED.
2324 	 */
2325 	if (psfanflt == 0 && cpufanflt == 0 && afbfanflt == 0 &&
2326 	    unitp->num_fans_failed != 0) {
2327 		fpmstat = envctrl_get_fpm_status(unitp);
2328 		if (!(envctrl_isother_fault_led(unitp,
2329 		    fpmstat, 0))) {
2330 			fpmstat &= ~(ENVCTRL_FSP_GEN_ERR);
2331 		}
2332 		envctrl_set_fsp(unitp, &fpmstat);
2333 	} else if (psfanflt != 0 || cpufanflt != 0 || afbfanflt != 0) {
2334 		fpmstat = envctrl_get_fpm_status(unitp);
2335 		fpmstat |= ENVCTRL_FSP_GEN_ERR;
2336 		envctrl_set_fsp(unitp, &fpmstat);
2337 	}
2338 
2339 	if (unitp->AFB_present == B_FALSE) {
2340 		afbfanflt = 0;
2341 	}
2342 
2343 	if ((cpufanflt > 0 || psfanflt > 0 || afbfanflt > 0 ||
2344 	    (status != DDI_SUCCESS)) && !unitp->initting &&
2345 	    unitp->current_mode == ENVCTRL_NORMAL_MODE) {
2346 		if (status != DDI_SUCCESS)
2347 			max_retry_count = envctrl_max_retries;
2348 		else
2349 			max_retry_count = MAX_FAN_FAIL_RETRY;
2350 		if (retries <= max_retry_count) {
2351 			retries++;
2352 			drv_usecwait(1000);
2353 			if (retries == max_retry_count) {
2354 				cmn_err(CE_WARN,
2355 				    "Fan Fail is 0x%x, retries = %d\n",
2356 				    recv_data, retries);
2357 			}
2358 			envctrl_get_sys_temperatures(unitp,
2359 			    (uint8_t *)NULL);
2360 			goto retry;
2361 		}
2362 		if (!(envctrl_power_off_overide)) {
2363 			unitp->shutdown = B_TRUE;
2364 		}
2365 		cmn_err(CE_WARN, "Fan Failure(s), System Shutdown");
2366 	}
2367 
2368 	unitp->num_fans_failed = (psfanflt + cpufanflt + afbfanflt);
2369 
2370 }
2371 
2372 /*
2373  * Check for power supply insertion and failure.
2374  * This is a bit tricky, because a power supply insertion will
2375  * trigger a load share interrupt as well as PS present in the
2376  * new supply. if we detect an insertion clear
2377  * interrupts, disable interrupts, wait for a couple of seconds
2378  * come back and see if the PSOK bit is set, PS_PRESENT is set
2379  * and the share fail interrupts are gone. If not this is a
2380  * real load share fail event.
2381  * Called with mutex held
2382  */
2383 
2384 static void
envctrl_PS_intr_service(struct envctrlunit * unitp,uint8_t psaddr)2385 envctrl_PS_intr_service(struct envctrlunit *unitp, uint8_t psaddr)
2386 {
2387 	uint8_t recv_data;
2388 	int status, retrys = 0;
2389 
2390 	ASSERT(MUTEX_HELD(&unitp->umutex));
2391 
2392 	if (unitp->current_mode == ENVCTRL_DIAG_MODE) {
2393 		return;
2394 	}
2395 
2396 retry:
2397 	status = eHc_read_pcf8574a((struct eHc_envcunit *)unitp,
2398 	    PCF8574A_BASE_ADDR | psaddr & 0xF, &recv_data, 1);
2399 	if (status != DDI_SUCCESS) {
2400 		drv_usecwait(1000);
2401 		if (retrys < envctrl_max_retries) {
2402 			retrys++;
2403 			goto retry;
2404 		} else {
2405 			mutex_exit(&unitp->umutex);
2406 			envctrl_init_bus(unitp);
2407 			mutex_enter(&unitp->umutex);
2408 			if (envctrl_debug_flags)
2409 				cmn_err(CE_WARN,
2410 				    "PS_intr_service: Read from 8574A " \
2411 				"failed\n");
2412 		}
2413 	}
2414 
2415 	/*
2416 	 * setup a timeout thread to poll the ps after a
2417 	 * couple of seconds. This allows for the PS to settle
2418 	 * and doesn't report false errors on a hotplug
2419 	 */
2420 
2421 	unitp->pshotplug_id = (timeout(envctrl_pshotplug_poll,
2422 	    (caddr_t)unitp, pshotplug_timeout_hz));
2423 
2424 }
2425 
2426 /* called with mutex held */
2427 static void
envctrl_reset_dflop(struct envctrlunit * unitp)2428 envctrl_reset_dflop(struct envctrlunit *unitp)
2429 {
2430 	struct envctrl_pcf8574_chip initval;
2431 
2432 	ASSERT(MUTEX_HELD(&unitp->umutex));
2433 
2434 	/*
2435 	 * This initialization sequence allows a
2436 	 * to change state to stop the fans from
2437 	 * blastion upon poweron. If this isn't
2438 	 * done the writes to the 8444 will not complete
2439 	 * to the hardware because the dflop will
2440 	 * be closed
2441 	 */
2442 	initval.chip_num = ENVCTRL_PCF8574_DEV0; /* 0x01 port 1 */
2443 	initval.type = PCF8574A;
2444 
2445 	initval.val = ENVCTRL_DFLOP_INIT0;
2446 	(void) envctrl_xmit(unitp, (caddr_t *)(void *)&initval, PCF8574);
2447 
2448 	initval.val = ENVCTRL_DFLOP_INIT1;
2449 	(void) envctrl_xmit(unitp, (caddr_t *)(void *)&initval, PCF8574);
2450 }
2451 
2452 static void
envctrl_add_encl_kstats(struct envctrlunit * unitp,int type,int instance,uint8_t val)2453 envctrl_add_encl_kstats(struct envctrlunit *unitp, int type,
2454     int instance, uint8_t val)
2455 {
2456 	int i = 0;
2457 	boolean_t inserted = B_FALSE;
2458 
2459 	ASSERT(MUTEX_HELD(&unitp->umutex));
2460 
2461 	while (i < MAX_DEVS && inserted == B_FALSE) {
2462 		if (unitp->encl_kstats[i].instance == I2C_NODEV) {
2463 			unitp->encl_kstats[i].instance = instance;
2464 			unitp->encl_kstats[i].type = type;
2465 			unitp->encl_kstats[i].value = val;
2466 			inserted = B_TRUE;
2467 		}
2468 		i++;
2469 	}
2470 	unitp->num_encl_present++;
2471 }
2472 
2473 /* called with mutex held */
2474 static void
envctrl_enable_devintrs(struct envctrlunit * unitp)2475 envctrl_enable_devintrs(struct envctrlunit *unitp)
2476 {
2477 	struct envctrl_pcf8574_chip initval;
2478 
2479 	ASSERT(MUTEX_HELD(&unitp->umutex));
2480 
2481 	/*
2482 	 * This initialization sequence allows a
2483 	 * to change state to stop the fans from
2484 	 * blastion upon poweron. If this isn't
2485 	 * done the writes to the 8444 will not complete
2486 	 * to the hardware because the dflop will
2487 	 * be closed
2488 	 */
2489 	initval.chip_num = ENVCTRL_PCF8574_DEV0; /* 0x01 port 1 */
2490 	initval.type = PCF8574A;
2491 
2492 	initval.val = ENVCTRL_DEVINTR_INTI0;
2493 	(void) envctrl_xmit(unitp, (caddr_t *)(void *)&initval, PCF8574);
2494 
2495 	/*
2496 	 * set lowerbits all high p0 = PS1, p1 = PS2
2497 	 * p2 = PS3 p4 = envctrl intr_ctrl
2498 	 */
2499 	initval.val = ENVCTRL_DEVINTR_INTI1;
2500 	(void) envctrl_xmit(unitp, (caddr_t *)(void *)&initval, PCF8574);
2501 }
2502 
2503 /* called with mutex held */
2504 static void
envctrl_stop_clock(struct envctrlunit * unitp)2505 envctrl_stop_clock(struct envctrlunit *unitp)
2506 {
2507 	int status;
2508 	uint8_t buf[2];
2509 
2510 	/*
2511 	 * This routine talks to the PCF8583 which
2512 	 * is a clock calendar chip on the envctrl bus.
2513 	 * We use this chip as a watchdog timer for the
2514 	 * fan control. At reset this chip pulses the interrupt
2515 	 * line every 1 second. We need to be able to shut
2516 	 * this off.
2517 	 */
2518 
2519 	ASSERT(MUTEX_HELD(&unitp->umutex));
2520 
2521 	buf[0] = CLOCK_CSR_REG;
2522 	buf[1] = CLOCK_DISABLE;
2523 
2524 	status = eHc_write_pcf8583((struct eHc_envcunit *)unitp,
2525 	    PCF8583_BASE_ADDR | 0, buf, 2);
2526 	if (status != DDI_SUCCESS)
2527 		cmn_err(CE_WARN, "write to PCF8583 failed\n");
2528 }
2529 
2530 static void
envctrl_reset_watchdog(struct envctrlunit * unitp,uint8_t * wdval)2531 envctrl_reset_watchdog(struct envctrlunit *unitp, uint8_t *wdval)
2532 {
2533 
2534 	uint8_t w, r;
2535 	uint8_t res = 0;
2536 	int status;
2537 	uint8_t buf[3];
2538 
2539 	ASSERT(MUTEX_HELD(&unitp->umutex));
2540 
2541 	/* the clock MUST be stopped before we re-set it */
2542 	envctrl_stop_clock(unitp);
2543 
2544 	/*
2545 	 * Reset the minutes counter to 0.
2546 	 */
2547 	buf[0] = ALARM_CTR_REG_MINS;
2548 	buf[1] = 0x0;
2549 	status = eHc_write_pcf8583((struct eHc_envcunit *)unitp,
2550 	    PCF8583_BASE_ADDR | 0, buf, 2);
2551 	if (status != DDI_SUCCESS)
2552 		cmn_err(CE_WARN, "write to PCF8583 failed\n");
2553 
2554 	/*
2555 	 * set up the alarm timer for 3 minutes
2556 	 * start by setting reg 8 ALARM_CTRL_REG
2557 	 * If we are in diag mode, we set the timer in
2558 	 * seconds. Valid values are 40-99. The timer
2559 	 * counts up to 99. 40 would be 59 seconds
2560 	 */
2561 	buf[0] = CLOCK_ALARM_REG_A;
2562 	if (unitp->current_mode == ENVCTRL_DIAG_MODE) {
2563 		if (unitp->timeout_id != 0) {
2564 			(void) untimeout(unitp->timeout_id);
2565 			unitp->timeout_id = 0;
2566 			unitp->timeout_id = (timeout(envctrl_tempr_poll,
2567 			    (caddr_t)unitp, overtemp_timeout_hz));
2568 		}
2569 		buf[1] = CLOCK_ENABLE_TIMER_S;
2570 	} else {
2571 		buf[1] = CLOCK_ENABLE_TIMER;
2572 	}
2573 
2574 	/* STEP 10: End Transmission */
2575 	status = eHc_write_pcf8583((struct eHc_envcunit *)unitp,
2576 	    PCF8583_BASE_ADDR | 0, buf, 2);
2577 	if (status != DDI_SUCCESS)
2578 		cmn_err(CE_WARN, "Reset envctrl watchdog failed\n");
2579 
2580 	/*
2581 	 * Now set up the alarm timer register it
2582 	 * counts from 0-99 with an intr triggered
2583 	 * when it gets to overflow.. or 99. It will
2584 	 * also count from a pre-set value which is
2585 	 * where we are seting from. We want a 3 minute fail
2586 	 * safe so our value is 99-3 or 96.
2587 	 * we are programming register 7 in the 8583.
2588 	 */
2589 
2590 	buf[0] = ALARM_CTRL_REG;
2591 	/*
2592 	 * Allow the diagnostic to set the egg timer val.
2593 	 * never allow it to be set greater than the default.
2594 	 */
2595 	if (unitp->current_mode == ENVCTRL_DIAG_MODE) {
2596 		if (*wdval > MAX_CL_VAL) {
2597 			buf[1] = EGG_TIMER_VAL;
2598 		} else {
2599 
2600 			w = *wdval/10;
2601 			r = *wdval%10;
2602 
2603 			res = res | r;
2604 			res = (0x99 - (res | (w << 4)));
2605 			buf[1] = res;
2606 		}
2607 	} else {
2608 		buf[1] = EGG_TIMER_VAL;
2609 	}
2610 
2611 	status = eHc_write_pcf8583((struct eHc_envcunit *)unitp,
2612 	    PCF8583_BASE_ADDR | 0, buf, 2);
2613 	if (status != DDI_SUCCESS)
2614 		cmn_err(CE_WARN, "Reset envctrl watchdog failed\n");
2615 
2616 
2617 	/*
2618 	 * Now that we have set up.. it is time
2619 	 * to re-start the clock in the CSR.
2620 	 */
2621 
2622 	buf[0] = CLOCK_CSR_REG;
2623 	buf[1] = CLOCK_ENABLE;
2624 	status = eHc_write_pcf8583((struct eHc_envcunit *)unitp,
2625 	    PCF8583_BASE_ADDR | 0, buf, 2);
2626 	if (status != DDI_SUCCESS)
2627 		cmn_err(CE_WARN, "Reset envctrl watchdog failed\n");
2628 
2629 }
2630 
2631 /* Called with unip mutex held */
2632 static void
envctrl_ps_probe(struct envctrlunit * unitp)2633 envctrl_ps_probe(struct envctrlunit *unitp)
2634 {
2635 
2636 	uint8_t recv_data, fpmstat;
2637 	uint8_t psaddr[] = {PS1, PS2, PS3, PSTEMP0};
2638 	int i;
2639 	int ps_error = 0, retrys = 0;
2640 	int devaddr;
2641 	int status;
2642 	int twotimes = 0;
2643 
2644 	ASSERT(MUTEX_HELD(&unitp->umutex));
2645 
2646 	unitp->num_ps_present = 0;
2647 
2648 	for (i = 0; i <= MAXPS; i++) {
2649 		unitp->ps_present[i] = B_FALSE;
2650 		unitp->ps_kstats[i].ps_rating = 0;
2651 		unitp->ps_kstats[i].ps_tempr = 0;
2652 
2653 		switch (psaddr[i]) {
2654 		case PS1:
2655 			devaddr = ENVCTRL_PCF8574_DEV3;
2656 			break;
2657 		case PS2:
2658 			devaddr = ENVCTRL_PCF8574_DEV2;
2659 			break;
2660 		case PS3:
2661 			devaddr = ENVCTRL_PCF8574_DEV1;
2662 			break;
2663 		case PSTEMP0:
2664 			devaddr = 0;
2665 			break;
2666 		}
2667 		retrys = 0;
2668 retry:
2669 		status = eHc_read_pcf8574a((struct eHc_envcunit *)unitp,
2670 		    PCF8574A_BASE_ADDR | devaddr, &recv_data, 1);
2671 		if (status != DDI_SUCCESS) {
2672 			drv_usecwait(1000);
2673 			if (retrys < envctrl_max_retries) {
2674 				retrys++;
2675 				goto retry;
2676 			} else {
2677 				mutex_exit(&unitp->umutex);
2678 				envctrl_init_bus(unitp);
2679 				mutex_enter(&unitp->umutex);
2680 				/*
2681 				 * If we just reset the bus we need to reread
2682 				 * the status.  If a second attempt still fails
2683 				 * then report the read failure.
2684 				 */
2685 				if (twotimes == 0) {
2686 					twotimes++;
2687 					retrys = 0;
2688 					goto retry;
2689 				} else {
2690 					cmn_err(CE_WARN,
2691 					"PS_probe: Read from 8574A failed\n");
2692 				}
2693 			}
2694 		}
2695 
2696 		/*
2697 		 * Port 0 = PS Present
2698 		 * Port 1 = PS Type
2699 		 * Port 2 = PS Type
2700 		 * Port 3 = PS TYpe
2701 		 * Port 4 = DC Status
2702 		 * Port 5 = Current Limit
2703 		 * Port 6 = Current Share
2704 		 * Port 7 = SPARE
2705 		 */
2706 
2707 		/*
2708 		 * Port 0 = PS Present
2709 		 * Port is pulled LOW "0" to indicate
2710 		 * present.
2711 		 */
2712 
2713 		if (!(recv_data & ENVCTRL_PCF8574_PORT0)) {
2714 			unitp->ps_present[i] = B_TRUE;
2715 			/* update unit kstat array */
2716 			unitp->ps_kstats[i].instance = i;
2717 			unitp->ps_kstats[i].ps_tempr = ENVCTRL_INIT_TEMPR;
2718 			++unitp->num_ps_present;
2719 
2720 			if (power_supply_previous_state[i] == 0) {
2721 				cmn_err(CE_NOTE,
2722 				    "Power Supply %d inserted\n", i);
2723 			}
2724 			power_supply_previous_state[i] = 1;
2725 
2726 			if (!(recv_data & ENVCTRL_PCF8574_PORT1)) {
2727 				unitp->ps_kstats[i].ps_rating = ENVCTRL_PS_550;
2728 			}
2729 			if (!(recv_data & ENVCTRL_PCF8574_PORT2)) {
2730 				unitp->ps_kstats[i].ps_rating = ENVCTRL_PS_650;
2731 			}
2732 			if (!(recv_data & ENVCTRL_PCF8574_PORT3)) {
2733 				cmn_err(CE_WARN,
2734 				    "Power Supply %d NOT okay\n", i);
2735 				unitp->ps_kstats[i].ps_ok = B_FALSE;
2736 				ps_error++;
2737 			} else {
2738 				unitp->ps_kstats[i].ps_ok = B_TRUE;
2739 			}
2740 			if (!(recv_data & ENVCTRL_PCF8574_PORT4)) {
2741 				cmn_err(CE_WARN,
2742 				    "Power Supply %d Overloaded\n", i);
2743 				unitp->ps_kstats[i].limit_ok = B_FALSE;
2744 				ps_error++;
2745 			} else {
2746 				unitp->ps_kstats[i].limit_ok = B_TRUE;
2747 			}
2748 			if (!(recv_data & ENVCTRL_PCF8574_PORT5)) {
2749 				cmn_err(CE_WARN,
2750 				    "Power Supply %d load share err\n", i);
2751 				unitp->ps_kstats[i].curr_share_ok = B_FALSE;
2752 				ps_error++;
2753 			} else {
2754 				unitp->ps_kstats[i].curr_share_ok = B_TRUE;
2755 			}
2756 
2757 			if (!(recv_data & ENVCTRL_PCF8574_PORT6)) {
2758 				cmn_err(CE_WARN,
2759 				    "PS %d Shouln't interrupt\n", i);
2760 				ps_error++;
2761 			}
2762 
2763 			if (!(recv_data & ENVCTRL_PCF8574_PORT7)) {
2764 				cmn_err(CE_WARN,
2765 				    "PS %d Shouln't interrupt\n", i);
2766 				ps_error++;
2767 			}
2768 		} else {
2769 			/* No power supply present */
2770 			if (power_supply_previous_state[i] == 1) {
2771 				cmn_err(CE_NOTE,
2772 				    "Power Supply %d removed\n", i);
2773 			}
2774 			power_supply_previous_state[i] = 0;
2775 		}
2776 	}
2777 
2778 	fpmstat = envctrl_get_fpm_status(unitp);
2779 	if (ps_error) {
2780 		fpmstat |= (ENVCTRL_FSP_PS_ERR | ENVCTRL_FSP_GEN_ERR);
2781 	} else {
2782 		if (envctrl_isother_fault_led(unitp, fpmstat,
2783 		    ENVCTRL_FSP_PS_ERR)) {
2784 			fpmstat &= ~(ENVCTRL_FSP_PS_ERR);
2785 		} else {
2786 			fpmstat &= ~(ENVCTRL_FSP_PS_ERR |
2787 			    ENVCTRL_FSP_GEN_ERR);
2788 		}
2789 
2790 	}
2791 	envctrl_set_fsp(unitp, &fpmstat);
2792 
2793 	/*
2794 	 * We need to reset all of the fans etc when a supply is
2795 	 * interrupted and added, but we don't want to reset the
2796 	 * fans if we are in DIAG mode. This will mess up SUNVTS.
2797 	 */
2798 	if (unitp->current_mode == ENVCTRL_NORMAL_MODE) {
2799 		envctrl_get_sys_temperatures(unitp, (uint8_t *)NULL);
2800 	}
2801 }
2802 
2803 /*
2804  * consider key switch position when handling an abort sequence
2805  */
2806 static void
envctrl_abort_seq_handler(char * msg)2807 envctrl_abort_seq_handler(char *msg)
2808 {
2809 	struct envctrlunit *unitp;
2810 	int i;
2811 	uint8_t secure = 0;
2812 
2813 	/*
2814 	 * Find the instance of the device available on this host.
2815 	 * Note that there may be only one, but the instance may
2816 	 * not be zero.
2817 	 */
2818 	for (i = 0; i < MAX_DEVS; i++) {
2819 		if (unitp = (struct envctrlunit *)
2820 		    ddi_get_soft_state(envctrlsoft_statep, i))
2821 			break;
2822 	}
2823 
2824 	ASSERT(unitp);
2825 
2826 	for (i = 0; i < MAX_DEVS; i++) {
2827 		if ((unitp->encl_kstats[i].type == ENVCTRL_ENCL_FSP) &&
2828 		    (unitp->encl_kstats[i].instance != I2C_NODEV)) {
2829 			secure = unitp->encl_kstats[i].value;
2830 			break;
2831 		}
2832 	}
2833 
2834 	/*
2835 	 * take the logical not because we are in hardware mode only
2836 	 */
2837 
2838 	if ((secure & ENVCTRL_FSP_KEYMASK) == ENVCTRL_FSP_KEYLOCKED) {
2839 			cmn_err(CE_CONT,
2840 			    "!envctrl: ignoring debug enter sequence\n");
2841 	} else {
2842 		if (envctrl_debug_flags) {
2843 			cmn_err(CE_CONT, "!envctrl: allowing debug enter\n");
2844 		}
2845 		debug_enter(msg);
2846 	}
2847 }
2848 
2849 /*
2850  * get the front Panel module LED and keyswitch status.
2851  * this part is addressed at 0x7C on the i2c bus.
2852  * called with mutex held
2853  */
2854 static uint8_t
envctrl_get_fpm_status(struct envctrlunit * unitp)2855 envctrl_get_fpm_status(struct envctrlunit *unitp)
2856 {
2857 	uint8_t recv_data;
2858 	int status, retrys = 0;
2859 
2860 	ASSERT(MUTEX_HELD(&unitp->umutex));
2861 
2862 retry:
2863 	status = eHc_read_pcf8574a((struct eHc_envcunit *)unitp,
2864 	    PCF8574A_BASE_ADDR | ENVCTRL_PCF8574_DEV6, &recv_data, 1);
2865 
2866 	/*
2867 	 * yet another place where a read can cause the
2868 	 * the SDA line of the i2c bus to get stuck low.
2869 	 * this funky sequence frees the SDA line.
2870 	 */
2871 	if (status != DDI_SUCCESS) {
2872 		drv_usecwait(1000);
2873 		if (retrys < envctrl_max_retries) {
2874 			retrys++;
2875 			goto retry;
2876 		} else {
2877 			mutex_exit(&unitp->umutex);
2878 			envctrl_init_bus(unitp);
2879 			mutex_enter(&unitp->umutex);
2880 			if (envctrl_debug_flags)
2881 				cmn_err(CE_WARN, "Read from PCF8574 (FPM) "\
2882 				    "failed\n");
2883 		}
2884 	}
2885 	recv_data = ~recv_data;
2886 	envctrl_mod_encl_kstats(unitp, ENVCTRL_ENCL_FSP,
2887 	    INSTANCE_0, recv_data);
2888 
2889 	return (recv_data);
2890 }
2891 
2892 static void
envctrl_set_fsp(struct envctrlunit * unitp,uint8_t * val)2893 envctrl_set_fsp(struct envctrlunit *unitp, uint8_t *val)
2894 {
2895 	struct envctrl_pcf8574_chip chip;
2896 
2897 	ASSERT(MUTEX_HELD(&unitp->umutex));
2898 
2899 	chip.val = ENVCTRL_FSP_OFF; /* init all values to off */
2900 	chip.chip_num = ENVCTRL_PCF8574_DEV6; /* 0x01 port 1 */
2901 	chip.type = PCF8574A;
2902 
2903 	/*
2904 	 * strip off bits that are R/O
2905 	 */
2906 	chip.val = (~(ENVCTRL_FSP_KEYMASK | ENVCTRL_FSP_POMASK) & (*val));
2907 
2908 	chip.val = ~chip.val;
2909 	(void) envctrl_xmit(unitp, (caddr_t *)(void *)&chip, PCF8574);
2910 
2911 }
2912 
2913 static int
envctrl_get_dskled(struct envctrlunit * unitp,struct envctrl_pcf8574_chip * chip)2914 envctrl_get_dskled(struct envctrlunit *unitp, struct envctrl_pcf8574_chip *chip)
2915 {
2916 	uint_t oldtype;
2917 
2918 	ASSERT(MUTEX_HELD(&unitp->umutex));
2919 
2920 	if (chip->chip_num > ENVCTRL_PCF8574_DEV2 ||
2921 	    chip->type != ENVCTRL_ENCL_BACKPLANE4 &&
2922 	    chip->type != ENVCTRL_ENCL_BACKPLANE8) {
2923 		return (DDI_FAILURE);
2924 	}
2925 	oldtype = chip->type;
2926 	chip->type = PCF8574;
2927 	envctrl_recv(unitp, (caddr_t *)(void *)chip, PCF8574);
2928 	chip->type = oldtype;
2929 	chip->val = ~chip->val;
2930 
2931 	return (DDI_SUCCESS);
2932 }
2933 static int
envctrl_set_dskled(struct envctrlunit * unitp,struct envctrl_pcf8574_chip * chip)2934 envctrl_set_dskled(struct envctrlunit *unitp, struct envctrl_pcf8574_chip *chip)
2935 {
2936 
2937 	struct envctrl_pcf8574_chip fspchip;
2938 	struct envctrl_pcf8574_chip backchip;
2939 	int i, instance;
2940 	int diskfault = 0;
2941 	uint8_t controller_addr[] = {ENVCTRL_PCF8574_DEV0, ENVCTRL_PCF8574_DEV1,
2942 	    ENVCTRL_PCF8574_DEV2};
2943 
2944 	/*
2945 	 * We need to check the type of disk led being set. If it
2946 	 * is a 4 slot backplane then the upper 4 bits (7, 6, 5, 4) are
2947 	 * invalid.
2948 	 */
2949 	ASSERT(MUTEX_HELD(&unitp->umutex));
2950 
2951 
2952 	if (chip->chip_num > ENVCTRL_PCF8574_DEV2 ||
2953 	    chip->val > ENVCTRL_DISK8LED_ALLOFF ||
2954 	    chip->val < ENVCTRL_CHAR_ZERO) {
2955 		return (DDI_FAILURE);
2956 	}
2957 
2958 	if (chip->type != ENVCTRL_ENCL_BACKPLANE4 &&
2959 	    chip->type != ENVCTRL_ENCL_BACKPLANE8) {
2960 		return (DDI_FAILURE);
2961 	}
2962 
2963 	/*
2964 	 * Check all of the other controllwes LED states to make sure
2965 	 * that there are no disk faults. If so then if the user is
2966 	 * clearing the disk faults on this contoller, turn off
2967 	 * the mass storage fault led.
2968 	 */
2969 
2970 	backchip.type = PCF8574;
2971 	for (i = 0; i <= MAX_TAZ_CONTROLLERS; i++) {
2972 		if (controller_present[i] == -1)
2973 			continue;
2974 		backchip.chip_num = controller_addr[i];
2975 		envctrl_recv(unitp, (caddr_t *)(void *)&backchip, PCF8574);
2976 		if (chip->chip_num == controller_addr[i]) {
2977 			if (chip->val != ENVCTRL_CHAR_ZERO)
2978 				diskfault++;
2979 		} else if ((~backchip.val & 0xFF) != ENVCTRL_CHAR_ZERO) {
2980 			diskfault++;
2981 		}
2982 	}
2983 
2984 	fspchip.type = PCF8574A;
2985 	fspchip.chip_num = ENVCTRL_PCF8574_DEV6; /* 0x01 port 1 */
2986 	envctrl_recv(unitp, (caddr_t *)(void *)&fspchip, PCF8574);
2987 
2988 	if (diskfault) {
2989 		if (!(envctrl_isother_fault_led(unitp, fspchip.val & 0xFF,
2990 		    ENVCTRL_FSP_DISK_ERR))) {
2991 			fspchip.val &= ~(ENVCTRL_FSP_DISK_ERR);
2992 		} else {
2993 			fspchip.val &= ~(ENVCTRL_FSP_DISK_ERR |
2994 			    ENVCTRL_FSP_GEN_ERR);
2995 		}
2996 		fspchip.val = (fspchip.val &
2997 		    ~(ENVCTRL_FSP_DISK_ERR | ENVCTRL_FSP_GEN_ERR));
2998 	} else {
2999 		fspchip.val = (fspchip.val |
3000 		    (ENVCTRL_FSP_DISK_ERR | ENVCTRL_FSP_GEN_ERR));
3001 	}
3002 	fspchip.type = PCF8574A;
3003 	fspchip.chip_num = ENVCTRL_PCF8574_DEV6; /* 0x01 port 1 */
3004 	(void) envctrl_xmit(unitp, (caddr_t *)(void *)&fspchip, PCF8574);
3005 
3006 	for (i = 0; i < (sizeof (backaddrs) / sizeof (uint8_t)); i++) {
3007 		if (chip->chip_num == backaddrs[i]) {
3008 			instance =  i;
3009 		}
3010 	}
3011 
3012 	switch (chip->type) {
3013 	case ENVCTRL_ENCL_BACKPLANE4:
3014 		envctrl_mod_encl_kstats(unitp, ENVCTRL_ENCL_BACKPLANE4,
3015 		    instance, chip->val);
3016 		break;
3017 	case ENVCTRL_ENCL_BACKPLANE8:
3018 		envctrl_mod_encl_kstats(unitp, ENVCTRL_ENCL_BACKPLANE8,
3019 		    instance, chip->val);
3020 		break;
3021 	default:
3022 		break;
3023 	}
3024 	chip->type = PCF8574;
3025 	/*
3026 	 * we take the ones compliment of the val passed in
3027 	 * because the hardware thinks that a "low" or "0"
3028 	 * is the way to indicate a fault. of course software
3029 	 * knows that a 1 is a TRUE state or fault. ;-)
3030 	 */
3031 	chip->val = ~(chip->val);
3032 	(void) envctrl_xmit(unitp, (caddr_t *)(void *)chip, PCF8574);
3033 	return (DDI_SUCCESS);
3034 }
3035 
3036 void
envctrl_add_kstats(struct envctrlunit * unitp)3037 envctrl_add_kstats(struct envctrlunit *unitp)
3038 {
3039 
3040 	ASSERT(MUTEX_HELD(&unitp->umutex));
3041 
3042 	if ((unitp->enclksp = kstat_create(ENVCTRL_MODULE_NAME, unitp->instance,
3043 	    ENVCTRL_KSTAT_ENCL, "misc", KSTAT_TYPE_RAW,
3044 	    sizeof (unitp->encl_kstats),
3045 	    KSTAT_FLAG_PERSISTENT)) == NULL) {
3046 		cmn_err(CE_WARN, "envctrl%d: encl raw kstat_create failed",
3047 		    unitp->instance);
3048 		return;
3049 	}
3050 
3051 	unitp->enclksp->ks_update = envctrl_encl_kstat_update;
3052 	unitp->enclksp->ks_private = (void *)unitp;
3053 	kstat_install(unitp->enclksp);
3054 
3055 
3056 	if ((unitp->fanksp = kstat_create(ENVCTRL_MODULE_NAME, unitp->instance,
3057 	    ENVCTRL_KSTAT_FANSTAT, "misc", KSTAT_TYPE_RAW,
3058 	    sizeof (unitp->fan_kstats),
3059 	    KSTAT_FLAG_PERSISTENT)) == NULL) {
3060 		cmn_err(CE_WARN, "envctrl%d: fans kstat_create failed",
3061 		    unitp->instance);
3062 		return;
3063 	}
3064 
3065 	unitp->fanksp->ks_update = envctrl_fanstat_kstat_update;
3066 	unitp->fanksp->ks_private = (void *)unitp;
3067 	kstat_install(unitp->fanksp);
3068 
3069 	if ((unitp->psksp = kstat_create(ENVCTRL_MODULE_NAME, unitp->instance,
3070 	    ENVCTRL_KSTAT_PSNAME, "misc", KSTAT_TYPE_RAW,
3071 	    sizeof (unitp->ps_kstats),
3072 	    KSTAT_FLAG_PERSISTENT)) == NULL) {
3073 		cmn_err(CE_WARN, "envctrl%d: ps name kstat_create failed",
3074 		    unitp->instance);
3075 		return;
3076 	}
3077 
3078 	unitp->psksp->ks_update = envctrl_ps_kstat_update;
3079 	unitp->psksp->ks_private = (void *)unitp;
3080 	kstat_install(unitp->psksp);
3081 
3082 }
3083 
3084 int
envctrl_ps_kstat_update(kstat_t * ksp,int rw)3085 envctrl_ps_kstat_update(kstat_t *ksp, int rw)
3086 {
3087 	struct envctrlunit *unitp;
3088 	char *kstatp;
3089 
3090 
3091 
3092 	unitp = (struct envctrlunit *)ksp->ks_private;
3093 
3094 	mutex_enter(&unitp->umutex);
3095 	ASSERT(MUTEX_HELD(&unitp->umutex));
3096 
3097 	kstatp = (char *)ksp->ks_data;
3098 
3099 	if (rw == KSTAT_WRITE) {
3100 		return (EACCES);
3101 	} else {
3102 
3103 		unitp->psksp->ks_ndata = unitp->num_ps_present;
3104 		bcopy(&unitp->ps_kstats, kstatp, sizeof (unitp->ps_kstats));
3105 	}
3106 	mutex_exit(&unitp->umutex);
3107 	return (DDI_SUCCESS);
3108 }
3109 int
envctrl_fanstat_kstat_update(kstat_t * ksp,int rw)3110 envctrl_fanstat_kstat_update(kstat_t *ksp, int rw)
3111 {
3112 	struct envctrlunit *unitp;
3113 	char *kstatp;
3114 
3115 	kstatp = (char *)ksp->ks_data;
3116 	unitp = (struct envctrlunit *)ksp->ks_private;
3117 
3118 	mutex_enter(&unitp->umutex);
3119 	ASSERT(MUTEX_HELD(&unitp->umutex));
3120 
3121 	if (rw == KSTAT_WRITE) {
3122 		return (EACCES);
3123 	} else {
3124 		unitp->fanksp->ks_ndata = unitp->num_fans_present;
3125 		bcopy(unitp->fan_kstats, kstatp, sizeof (unitp->fan_kstats));
3126 	}
3127 	mutex_exit(&unitp->umutex);
3128 	return (DDI_SUCCESS);
3129 }
3130 
3131 int
envctrl_encl_kstat_update(kstat_t * ksp,int rw)3132 envctrl_encl_kstat_update(kstat_t *ksp, int rw)
3133 {
3134 	struct envctrlunit *unitp;
3135 	char *kstatp;
3136 
3137 
3138 	kstatp = (char *)ksp->ks_data;
3139 	unitp = (struct envctrlunit *)ksp->ks_private;
3140 
3141 	mutex_enter(&unitp->umutex);
3142 	ASSERT(MUTEX_HELD(&unitp->umutex));
3143 
3144 	if (rw == KSTAT_WRITE) {
3145 		return (EACCES);
3146 	} else {
3147 
3148 		unitp->enclksp->ks_ndata = unitp->num_encl_present;
3149 		(void) envctrl_get_fpm_status(unitp);
3150 		/* XXX Need to ad disk updates too ??? */
3151 		bcopy(unitp->encl_kstats, kstatp, sizeof (unitp->encl_kstats));
3152 	}
3153 	mutex_exit(&unitp->umutex);
3154 	return (DDI_SUCCESS);
3155 }
3156 
3157 /*
3158  * called with unitp lock held
3159  * type, fanspeed and fanflt will be set by the service routines
3160  */
3161 static void
envctrl_init_fan_kstats(struct envctrlunit * unitp)3162 envctrl_init_fan_kstats(struct envctrlunit *unitp)
3163 {
3164 	int i;
3165 
3166 	ASSERT(MUTEX_HELD(&unitp->umutex));
3167 
3168 	for (i = 0; i < unitp->num_fans_present; i++) {
3169 		unitp->fan_kstats[i].instance = 0;
3170 		unitp->fan_kstats[i].type = 0;
3171 		unitp->fan_kstats[i].fans_ok = B_TRUE;
3172 		unitp->fan_kstats[i].fanflt_num = B_FALSE;
3173 		unitp->fan_kstats[i].fanspeed = B_FALSE;
3174 	}
3175 
3176 	unitp->fan_kstats[ENVCTRL_FAN_TYPE_PS].type = ENVCTRL_FAN_TYPE_PS;
3177 	unitp->fan_kstats[ENVCTRL_FAN_TYPE_CPU].type = ENVCTRL_FAN_TYPE_CPU;
3178 	if (unitp->AFB_present == B_TRUE)
3179 		unitp->fan_kstats[ENVCTRL_FAN_TYPE_AFB].type =
3180 		    ENVCTRL_FAN_TYPE_AFB;
3181 }
3182 
3183 static void
envctrl_init_encl_kstats(struct envctrlunit * unitp)3184 envctrl_init_encl_kstats(struct envctrlunit *unitp)
3185 {
3186 
3187 	int i;
3188 	uint8_t val;
3189 	struct envctrl_pcf8574_chip chip;
3190 	int *reg_prop;
3191 	uint_t len = 0;
3192 
3193 	ASSERT(MUTEX_HELD(&unitp->umutex));
3194 
3195 	for (i = 0; i < MAX_DEVS; i++) {
3196 		unitp->encl_kstats[i].instance = I2C_NODEV;
3197 	}
3198 
3199 	/*
3200 	 * add in kstats now
3201 	 * We ALWAYS HAVE THE FOLLOWING
3202 	 * 1. FSP
3203 	 * 2. AMB TEMPR
3204 	 * 3. (1) CPU TEMPR
3205 	 * 4. (1) 4 slot disk backplane
3206 	 * OPTIONAL
3207 	 * 8 slot backplane
3208 	 * more cpu's
3209 	 */
3210 
3211 	chip.type = PCF8574A;
3212 	chip.chip_num = ENVCTRL_PCF8574_DEV6; /* 0x01 port 1 */
3213 	envctrl_recv(unitp, (caddr_t *)(void *)&chip, PCF8574);
3214 
3215 	envctrl_add_encl_kstats(unitp, ENVCTRL_ENCL_FSP, INSTANCE_0,
3216 	    chip.val & 0xFF);
3217 
3218 	val = envctrl_get_lm75_temp(unitp) & 0xFF;
3219 	envctrl_add_encl_kstats(unitp, ENVCTRL_ENCL_AMBTEMPR, INSTANCE_0, val);
3220 
3221 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, unitp->dip,
3222 	    DDI_PROP_DONTPASS, ENVCTRL_DISK_LEDS_PR,
3223 	    &reg_prop, &len) != DDI_PROP_SUCCESS) {
3224 		cmn_err(CE_WARN, "prop lookup of %s failed\n",
3225 		    ENVCTRL_DISK_LEDS_PR);
3226 		return;
3227 	}
3228 
3229 	ASSERT(len != 0);
3230 
3231 	chip.type = PCF8574;
3232 
3233 	for (i = 0; i < len; i++) {
3234 		chip.chip_num = backaddrs[i];
3235 		if (reg_prop[i] == ENVCTRL_4SLOT_BACKPLANE) {
3236 			envctrl_recv(unitp, (caddr_t *)(void *)&chip, PCF8574);
3237 			envctrl_add_encl_kstats(unitp, ENVCTRL_ENCL_BACKPLANE4,
3238 			    i, ~chip.val);
3239 			controller_present[i] = 1;
3240 		}
3241 		if (reg_prop[i] == ENVCTRL_8SLOT_BACKPLANE) {
3242 			envctrl_recv(unitp, (caddr_t *)(void *)&chip, PCF8574);
3243 			envctrl_add_encl_kstats(unitp, ENVCTRL_ENCL_BACKPLANE8,
3244 			    i, ~chip.val);
3245 			controller_present[i] = 1;
3246 		}
3247 	}
3248 	ddi_prop_free((void *)reg_prop);
3249 
3250 }
3251 
3252 static void
envctrl_mod_encl_kstats(struct envctrlunit * unitp,int type,int instance,uint8_t val)3253 envctrl_mod_encl_kstats(struct envctrlunit *unitp, int type,
3254     int instance, uint8_t val)
3255 {
3256 	int i = 0;
3257 	boolean_t inserted = B_FALSE;
3258 
3259 	ASSERT(MUTEX_HELD(&unitp->umutex));
3260 
3261 	while (i < MAX_DEVS && inserted == B_FALSE) {
3262 		if (unitp->encl_kstats[i].instance == instance &&
3263 		    unitp->encl_kstats[i].type == type) {
3264 			unitp->encl_kstats[i].value = val;
3265 			inserted = B_TRUE;
3266 		}
3267 		i++;
3268 	}
3269 }
3270 
3271 static void
envctrl_probe_cpus(struct envctrlunit * unitp)3272 envctrl_probe_cpus(struct envctrlunit *unitp)
3273 {
3274 	int instance;
3275 
3276 	/*
3277 	 * The cpu search is as follows:
3278 	 * If there is only 1 CPU module it is named as
3279 	 * SUNW,UltraSPARC. If this is a match we still don't
3280 	 * know what slot the cpu module is in therefore
3281 	 * we need to check the "upa-portid" property.
3282 	 * If we have more than 1 cpu, then they are appended by
3283 	 * instance numbers and slot locations. e.g.
3284 	 * SUNW,UltraSPARC@1,0 (slot 1). it would have been
3285 	 * nice to have the naming consistent for one CPU e.g.
3286 	 * SUNW,UltraSPARC@0,0...sigh
3287 	 */
3288 
3289 	for (instance = 0; instance < ENVCTRL_MAX_CPUS; instance++) {
3290 		unitp->cpu_pr_location[instance] = B_FALSE;
3291 	}
3292 
3293 	ddi_walk_devs(ddi_root_node(), envctrl_match_cpu, unitp);
3294 }
3295 
3296 static int
envctrl_match_cpu(dev_info_t * dip,void * arg)3297 envctrl_match_cpu(dev_info_t *dip, void *arg)
3298 {
3299 
3300 	int cpu_slot;
3301 	char name[32];
3302 	char name1[32];
3303 	struct envctrlunit *unitp = (struct envctrlunit *)arg;
3304 
3305 	(void) sprintf(name, "%s", ENVCTRL_TAZCPU_STRING);
3306 	(void) sprintf(name1, "%s", ENVCTRL_TAZBLKBRDCPU_STRING);
3307 
3308 	if ((strcmp(ddi_node_name(dip), name) == 0) ||
3309 	    (strcmp(ddi_node_name(dip), name1) == 0)) {
3310 		if ((cpu_slot = (int)ddi_getprop(DDI_DEV_T_ANY, dip,
3311 		    DDI_PROP_DONTPASS, "upa-portid", -1)) == -1) {
3312 			cmn_err(CE_WARN, "envctrl no cpu upa-portid");
3313 		} else {
3314 			unitp->cpu_pr_location[cpu_slot] = B_TRUE;
3315 			unitp->num_cpus_present++;
3316 		}
3317 	}
3318 
3319 	return (DDI_WALK_CONTINUE);
3320 }
3321 
3322 /*
3323  * This routine returns TRUE if some other error condition
3324  * has set the GEN_ERR FAULT LED. Tp further complicate this
3325  * LED panel we have overloaded the GEN_ERR LED to indicate
3326  * that a fan fault has occurred without having a fan fault
3327  * LED as does all other error conditions. So we just take the
3328  * software state and return true. The whole purpose of this functon
3329  * is to tell us wehther or not we can shut off the GEN_FAULT LED.
3330  * NOTE: this ledval is usually one of the following FSP vals
3331  * EXCEPT in the case of the fan fail.. we pass in a "0".
3332  */
3333 
3334 static int
envctrl_isother_fault_led(struct envctrlunit * unitp,uint8_t fspval,uint8_t thisled)3335 envctrl_isother_fault_led(struct envctrlunit *unitp, uint8_t fspval,
3336     uint8_t thisled)
3337 {
3338 	int status = B_FALSE;
3339 
3340 	if (fspval != 0) {
3341 		fspval = (fspval & ~(thisled));
3342 	}
3343 	if (unitp->num_fans_failed > 0 && thisled != 0) {
3344 		status = B_TRUE;
3345 	} else if (fspval & ENVCTRL_FSP_DISK_ERR) {
3346 		status = B_TRUE;
3347 	} else if (fspval & ENVCTRL_FSP_PS_ERR) {
3348 		status = B_TRUE;
3349 	} else if (fspval & ENVCTRL_FSP_TEMP_ERR) {
3350 		status = B_TRUE;
3351 	}
3352 	return (status);
3353 }
3354 
3355 static void
envctrl_pshotplug_poll(void * arg)3356 envctrl_pshotplug_poll(void *arg)
3357 {
3358 	struct envctrlunit *unitp = (struct envctrlunit *)arg;
3359 
3360 	mutex_enter(&unitp->umutex);
3361 
3362 	envctrl_ps_probe(unitp);
3363 
3364 	mutex_exit(&unitp->umutex);
3365 }
3366 
3367 /*
3368  * The following routines implement the i2c protocol.
3369  * They should be removed once the envctrl_targets.c file is included.
3370  */
3371 
3372 /*
3373  * put host interface into master mode
3374  */
3375 static int
eHc_start_pcf8584(struct eHc_envcunit * ehcp,uint8_t byteaddress)3376 eHc_start_pcf8584(struct eHc_envcunit *ehcp, uint8_t byteaddress)
3377 {
3378 	uint8_t poll_status;
3379 	uint8_t discard;
3380 	int i;
3381 
3382 	/* wait if bus is busy */
3383 
3384 	i = 0;
3385 	do {
3386 		drv_usecwait(1000);
3387 		poll_status =
3388 		    ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
3389 		i++;
3390 	} while (((poll_status & EHC_S1_NBB) == 0) && i < EHC_MAX_WAIT);
3391 
3392 	if (i == EHC_MAX_WAIT) {
3393 		DCMNERR(CE_WARN, "eHc_start_pcf8584: I2C bus busy");
3394 		return (EHC_FAILURE);
3395 	}
3396 
3397 	if (poll_status & EHC_S1_BER) {
3398 		DCMN2ERR(CE_WARN, "eHc_start_pcf8584: I2C bus error");
3399 		return (EHC_FAILURE);
3400 	}
3401 
3402 	if (poll_status & EHC_S1_LAB) {
3403 		DCMN2ERR(CE_WARN, "eHc_start_pcf8584: Lost arbitration");
3404 		return (EHC_FAILURE);
3405 	}
3406 
3407 	/* load the slave address */
3408 	ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0, byteaddress);
3409 
3410 	/* generate the "start condition" and clock out the slave address */
3411 	ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1,
3412 	    EHC_S1_PIN | EHC_S1_ES0 | EHC_S1_STA | EHC_S1_ACK);
3413 
3414 	/* wait for completion of transmission */
3415 	i = 0;
3416 	do {
3417 		drv_usecwait(1000);
3418 		poll_status =
3419 		    ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
3420 		i++;
3421 	} while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
3422 
3423 	if (i == EHC_MAX_WAIT) {
3424 		DCMNERR(CE_WARN, "eHc_start_pcf8584: I2C bus busy");
3425 		return (EHC_FAILURE);
3426 	}
3427 
3428 	if (poll_status & EHC_S1_BER) {
3429 		DCMN2ERR(CE_WARN, "eHc_start_pcf8584: I2C bus error");
3430 		return (EHC_FAILURE);
3431 	}
3432 
3433 	if (poll_status & EHC_S1_LAB) {
3434 		DCMN2ERR(CE_WARN, "eHc_start_pcf8584: Lost arbitration");
3435 		return (EHC_FAILURE);
3436 	}
3437 
3438 	if (poll_status & EHC_S1_LRB) {
3439 		DCMNERR(CE_WARN, "eHc_start_pcf8584: No slave ACK");
3440 		return (EHC_NO_SLAVE_ACK);
3441 	}
3442 
3443 	/*
3444 	 * If this is a read we are setting up for (as indicated by
3445 	 * the least significant byte being set), read
3446 	 * and discard the first byte off the bus - this
3447 	 * is the slave address.
3448 	 */
3449 
3450 	i = 0;
3451 	if (byteaddress & EHC_BYTE_READ) {
3452 		discard = ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0);
3453 #ifdef lint
3454 		discard = discard;
3455 #endif
3456 
3457 		/* wait for completion of transmission */
3458 		do {
3459 			drv_usecwait(1000);
3460 			poll_status = ddi_get8(ehcp->ctlr_handle,
3461 			    &ehcp->bus_ctl_regs->s1);
3462 			i++;
3463 		} while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
3464 
3465 		if (i == EHC_MAX_WAIT) {
3466 			DCMNERR(CE_WARN, "eHc_start_pcf8584: I2C bus busy");
3467 			return (EHC_FAILURE);
3468 		}
3469 
3470 		if (poll_status & EHC_S1_BER) {
3471 			DCMN2ERR(CE_WARN,
3472 			    "eHc_start_pcf8584: I2C bus error");
3473 			return (EHC_FAILURE);
3474 		}
3475 
3476 		if (poll_status & EHC_S1_LAB) {
3477 			DCMN2ERR(CE_WARN,
3478 			    "eHc_start_pcf8584: Lost arbitration");
3479 			return (EHC_FAILURE);
3480 		}
3481 	}
3482 
3483 	return (EHC_SUCCESS);
3484 }
3485 
3486 /*
3487  * put host interface into slave/receiver mode
3488  */
3489 static void
eHc_stop_pcf8584(struct eHc_envcunit * ehcp)3490 eHc_stop_pcf8584(struct eHc_envcunit *ehcp)
3491 {
3492 	ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1,
3493 	    EHC_S1_PIN | EHC_S1_ES0 | EHC_S1_STO | EHC_S1_ACK);
3494 }
3495 
3496 static int
eHc_read_pcf8584(struct eHc_envcunit * ehcp,uint8_t * data)3497 eHc_read_pcf8584(struct eHc_envcunit *ehcp, uint8_t *data)
3498 {
3499 	uint8_t poll_status;
3500 	int i = 0;
3501 
3502 	/* Read the byte of interest */
3503 	*data = ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0);
3504 
3505 	/* wait for completion of transmission */
3506 	do {
3507 		drv_usecwait(1000);
3508 		poll_status =
3509 		    ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
3510 		i++;
3511 	} while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
3512 
3513 	if (i == EHC_MAX_WAIT) {
3514 		DCMNERR(CE_WARN, "eHc_read_pcf8584: I2C bus busy");
3515 		return (EHC_FAILURE);
3516 	}
3517 
3518 	if (poll_status & EHC_S1_BER) {
3519 		DCMN2ERR(CE_WARN, "eHc_read_pcf8584: I2C bus error");
3520 		return (EHC_FAILURE);
3521 	}
3522 
3523 	if (poll_status & EHC_S1_LAB) {
3524 		DCMN2ERR(CE_WARN, "eHc_read_pcf8584: Lost arbitration");
3525 		return (EHC_FAILURE);
3526 	}
3527 
3528 	return (EHC_SUCCESS);
3529 }
3530 
3531 /*
3532  * host interface is in transmitter state, thus mode is master/transmitter
3533  * NOTE to Bill: this check the LRB bit (only done in transmit mode).
3534  */
3535 
3536 static int
eHc_write_pcf8584(struct eHc_envcunit * ehcp,uint8_t data)3537 eHc_write_pcf8584(struct eHc_envcunit *ehcp, uint8_t data)
3538 {
3539 	uint8_t poll_status;
3540 	int i = 0;
3541 
3542 	/* send the data, EHC_S1_PIN should go to "1" immediately */
3543 	ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0, data);
3544 
3545 	/* wait for completion of transmission */
3546 	do {
3547 		drv_usecwait(1000);
3548 		poll_status =
3549 		    ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
3550 		i++;
3551 	} while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
3552 
3553 	if (i == EHC_MAX_WAIT) {
3554 		DCMNERR(CE_WARN, "eHc_write_pcf8584: I2C bus busy");
3555 		return (EHC_FAILURE);
3556 	}
3557 
3558 	if (poll_status & EHC_S1_BER) {
3559 		DCMN2ERR(CE_WARN, "eHc_write_pcf8584: I2C bus error");
3560 		return (EHC_FAILURE);
3561 	}
3562 
3563 	if (poll_status & EHC_S1_LAB) {
3564 		DCMN2ERR(CE_WARN, "eHc_write_pcf8584: Lost arbitration");
3565 		return (EHC_FAILURE);
3566 	}
3567 
3568 	if (poll_status & EHC_S1_LRB) {
3569 		DCMNERR(CE_WARN, "eHc_write_pcf8584: No slave ACK");
3570 		return (EHC_NO_SLAVE_ACK);
3571 	}
3572 
3573 	return (EHC_SUCCESS);
3574 }
3575 
3576 static int
eHc_after_read_pcf8584(struct eHc_envcunit * ehcp,uint8_t * data)3577 eHc_after_read_pcf8584(struct eHc_envcunit *ehcp, uint8_t *data)
3578 {
3579 	uint8_t discard;
3580 	uint8_t poll_status;
3581 	int i = 0;
3582 
3583 	/* set ACK in register S1 to 0 */
3584 	ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1, EHC_S1_ES0);
3585 
3586 	/*
3587 	 * Read the "byte-before-the-last-byte" - sets PIN bit to '1'
3588 	 */
3589 
3590 	*data = ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0);
3591 
3592 	/* wait for completion of transmission */
3593 	do {
3594 		drv_usecwait(1000);
3595 		poll_status =
3596 		    ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
3597 		i++;
3598 	} while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
3599 
3600 	if (i == EHC_MAX_WAIT) {
3601 		DCMNERR(CE_WARN, "eHc_after_read_pcf8584: I2C bus busy");
3602 		return (EHC_FAILURE);
3603 	}
3604 
3605 	if (poll_status & EHC_S1_BER) {
3606 		DCMN2ERR(CE_WARN,
3607 		    "eHc_after_read_pcf8584: I2C bus error");
3608 		return (EHC_FAILURE);
3609 	}
3610 
3611 	if (poll_status & EHC_S1_LAB) {
3612 		DCMN2ERR(CE_WARN, "eHc_after_read_pcf8584: Lost arbitration");
3613 		return (EHC_FAILURE);
3614 	}
3615 
3616 	/*
3617 	 * Generate the "stop" condition.
3618 	 */
3619 	eHc_stop_pcf8584(ehcp);
3620 
3621 	/*
3622 	 * Read the "last" byte.
3623 	 */
3624 	discard = ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0);
3625 #ifdef lint
3626 	discard = discard;
3627 #endif
3628 
3629 	return (EHC_SUCCESS);
3630 }
3631 
3632 /*
3633  * Write to the TDA8444 chip.
3634  * byteaddress = chip type base address | chip offset address.
3635  */
3636 static int
eHc_write_tda8444(struct eHc_envcunit * ehcp,int byteaddress,int instruction,int subaddress,uint8_t * buf,int size)3637 eHc_write_tda8444(struct eHc_envcunit *ehcp, int byteaddress, int instruction,
3638     int subaddress, uint8_t *buf, int size)
3639 {
3640 	uint8_t control;
3641 	int i, status;
3642 
3643 	ASSERT((byteaddress & 0x1) == 0);
3644 	ASSERT(subaddress < 8);
3645 	ASSERT(instruction == 0xf || instruction == 0x0);
3646 	ASSERT(MUTEX_HELD(&ehcp->umutex));
3647 
3648 	control = (instruction << 4) | subaddress;
3649 
3650 	if ((status = eHc_start_pcf8584(ehcp, byteaddress)) != EHC_SUCCESS) {
3651 		if (status == EHC_NO_SLAVE_ACK) {
3652 			/*
3653 			 * Send the "stop" condition.
3654 			 */
3655 			eHc_stop_pcf8584(ehcp);
3656 		}
3657 		return (EHC_FAILURE);
3658 	}
3659 
3660 	if ((status = eHc_write_pcf8584(ehcp, control)) != EHC_SUCCESS) {
3661 		if (status == EHC_NO_SLAVE_ACK) {
3662 		/*
3663 		 * Send the "stop" condition.
3664 		 */
3665 		eHc_stop_pcf8584(ehcp);
3666 		}
3667 		return (EHC_FAILURE);
3668 	}
3669 
3670 	for (i = 0; i < size; i++) {
3671 		if ((status = eHc_write_pcf8584(ehcp, (buf[i] & 0x3f))) !=
3672 		    EHC_SUCCESS) {
3673 			if (status == EHC_NO_SLAVE_ACK)
3674 				eHc_stop_pcf8584(ehcp);
3675 			return (EHC_FAILURE);
3676 		}
3677 	}
3678 
3679 	eHc_stop_pcf8584(ehcp);
3680 
3681 	return (EHC_SUCCESS);
3682 }
3683 
3684 /*
3685  * Read from PCF8574A chip.
3686  * byteaddress = chip type base address | chip offset address.
3687  */
3688 static int
eHc_read_pcf8574a(struct eHc_envcunit * ehcp,int byteaddress,uint8_t * buf,int size)3689 eHc_read_pcf8574a(struct eHc_envcunit *ehcp, int byteaddress, uint8_t *buf,
3690     int size)
3691 {
3692 	int i;
3693 	int status;
3694 	uint8_t discard;
3695 
3696 	ASSERT((byteaddress & 0x1) == 0);
3697 	ASSERT(MUTEX_HELD(&ehcp->umutex));
3698 
3699 	/*
3700 	 * Put the bus into the start condition
3701 	 */
3702 	if ((status = eHc_start_pcf8584(ehcp, EHC_BYTE_READ | byteaddress)) !=
3703 	    EHC_SUCCESS) {
3704 		if (status == EHC_NO_SLAVE_ACK) {
3705 			/*
3706 			 * Send the "stop" condition.
3707 			 */
3708 			eHc_stop_pcf8584(ehcp);
3709 			/*
3710 			 * Read the last byte - discard it.
3711 			 */
3712 			discard = ddi_get8(ehcp->ctlr_handle,
3713 			    &ehcp->bus_ctl_regs->s0);
3714 #ifdef lint
3715 			discard = discard;
3716 #endif
3717 		}
3718 		return (EHC_FAILURE);
3719 	}
3720 
3721 	for (i = 0; i < size - 1; i++) {
3722 		if ((status = eHc_read_pcf8584(ehcp, &buf[i])) != EHC_SUCCESS) {
3723 			return (EHC_FAILURE);
3724 		}
3725 	}
3726 
3727 	/*
3728 	 * Handle the part of the bus protocol which comes
3729 	 * after a read, including reading the last byte.
3730 	 */
3731 
3732 	if (eHc_after_read_pcf8584(ehcp, &buf[i]) != EHC_SUCCESS) {
3733 		return (EHC_FAILURE);
3734 	}
3735 
3736 	return (EHC_SUCCESS);
3737 }
3738 
3739 /*
3740  * Write to the PCF8574A chip.
3741  * byteaddress = chip type base address | chip offset address.
3742  */
3743 static int
eHc_write_pcf8574a(struct eHc_envcunit * ehcp,int byteaddress,uint8_t * buf,int size)3744 eHc_write_pcf8574a(struct eHc_envcunit *ehcp, int byteaddress, uint8_t *buf,
3745     int size)
3746 {
3747 	int i;
3748 	int status;
3749 
3750 	ASSERT((byteaddress & 0x1) == 0);
3751 	ASSERT(MUTEX_HELD(&ehcp->umutex));
3752 
3753 	/*
3754 	 * Put the bus into the start condition (write)
3755 	 */
3756 	if ((status = eHc_start_pcf8584(ehcp, byteaddress)) != EHC_SUCCESS) {
3757 		if (status == EHC_NO_SLAVE_ACK) {
3758 			/*
3759 			 * Send the "stop" condition.
3760 			 */
3761 			eHc_stop_pcf8584(ehcp);
3762 		}
3763 		return (EHC_FAILURE);
3764 	}
3765 
3766 	/*
3767 	 * Send the data - poll as needed.
3768 	 */
3769 	for (i = 0; i < size; i++) {
3770 		if ((status = eHc_write_pcf8584(ehcp, buf[i])) != EHC_SUCCESS) {
3771 			if (status == EHC_NO_SLAVE_ACK)
3772 				eHc_stop_pcf8584(ehcp);
3773 			return (EHC_FAILURE);
3774 		}
3775 	}
3776 
3777 	/*
3778 	 * Transmission complete - generate stop condition and
3779 	 * put device back into slave receiver mode.
3780 	 */
3781 	eHc_stop_pcf8584(ehcp);
3782 
3783 	return (EHC_SUCCESS);
3784 }
3785 
3786 /*
3787  * Read from the PCF8574 chip.
3788  * byteaddress = chip type base address | chip offset address.
3789  */
3790 static int
eHc_read_pcf8574(struct eHc_envcunit * ehcp,int byteaddress,uint8_t * buf,int size)3791 eHc_read_pcf8574(struct eHc_envcunit *ehcp, int byteaddress, uint8_t *buf,
3792     int size)
3793 {
3794 	int i;
3795 	int status;
3796 	uint8_t discard;
3797 
3798 	ASSERT((byteaddress & 0x1) == 0);
3799 	ASSERT(MUTEX_HELD(&ehcp->umutex));
3800 
3801 	/*
3802 	 * Put the bus into the start condition
3803 	 */
3804 	if ((status = eHc_start_pcf8584(ehcp, EHC_BYTE_READ | byteaddress)) !=
3805 	    EHC_SUCCESS) {
3806 		if (status == EHC_NO_SLAVE_ACK) {
3807 			/*
3808 			 * Send the "stop" condition.
3809 			 */
3810 			eHc_stop_pcf8584(ehcp);
3811 			/*
3812 			 * Read the last byte - discard it.
3813 			 */
3814 			discard = ddi_get8(ehcp->ctlr_handle,
3815 			    &ehcp->bus_ctl_regs->s0);
3816 #ifdef lint
3817 			discard = discard;
3818 #endif
3819 		}
3820 		return (EHC_FAILURE);
3821 	}
3822 
3823 	for (i = 0; i < size - 1; i++) {
3824 		if ((status = eHc_read_pcf8584(ehcp, &buf[i])) != EHC_SUCCESS) {
3825 		return (EHC_FAILURE);
3826 		}
3827 	}
3828 
3829 	/*
3830 	 * Handle the part of the bus protocol which comes
3831 	 * after a read.
3832 	 */
3833 
3834 	if (eHc_after_read_pcf8584(ehcp, &buf[i]) != EHC_SUCCESS) {
3835 		return (EHC_FAILURE);
3836 	}
3837 
3838 	return (EHC_SUCCESS);
3839 }
3840 
3841 /*
3842  * Write to the PCF8574 chip.
3843  * byteaddress = chip type base address | chip offset address.
3844  */
3845 static int
eHc_write_pcf8574(struct eHc_envcunit * ehcp,int byteaddress,uint8_t * buf,int size)3846 eHc_write_pcf8574(struct eHc_envcunit *ehcp, int byteaddress, uint8_t *buf,
3847     int size)
3848 {
3849 	int i;
3850 	int status;
3851 
3852 	ASSERT((byteaddress & 0x1) == 0);
3853 	ASSERT(MUTEX_HELD(&ehcp->umutex));
3854 
3855 	/*
3856 	 * Put the bus into the start condition (write)
3857 	 */
3858 	if ((status = eHc_start_pcf8584(ehcp, byteaddress)) != EHC_SUCCESS) {
3859 		if (status == EHC_NO_SLAVE_ACK) {
3860 			/*
3861 			 * Send the "stop" condition.
3862 			 */
3863 			eHc_stop_pcf8584(ehcp);
3864 		}
3865 		return (EHC_FAILURE);
3866 	}
3867 
3868 	/*
3869 	 * Send the data - poll as needed.
3870 	 */
3871 	for (i = 0; i < size; i++) {
3872 		if ((status = eHc_write_pcf8584(ehcp, buf[i])) != EHC_SUCCESS) {
3873 			if (status == EHC_NO_SLAVE_ACK)
3874 				eHc_stop_pcf8584(ehcp);
3875 			return (EHC_FAILURE);
3876 		}
3877 	}
3878 	/*
3879 	 * Transmission complete - generate stop condition and
3880 	 * put device back into slave receiver mode.
3881 	 */
3882 	eHc_stop_pcf8584(ehcp);
3883 
3884 	return (EHC_SUCCESS);
3885 }
3886 
3887 /*
3888  * Read from the LM75
3889  * byteaddress = chip type base address | chip offset address.
3890  */
3891 static int
eHc_read_lm75(struct eHc_envcunit * ehcp,int byteaddress,uint8_t * buf,int size)3892 eHc_read_lm75(struct eHc_envcunit *ehcp, int byteaddress, uint8_t *buf,
3893     int size)
3894 {
3895 	int i;
3896 	int status;
3897 	uint8_t discard;
3898 
3899 	ASSERT((byteaddress & 0x1) == 0);
3900 	ASSERT(MUTEX_HELD(&ehcp->umutex));
3901 
3902 	/*
3903 	 * Put the bus into the start condition
3904 	 */
3905 	if ((status = eHc_start_pcf8584(ehcp, EHC_BYTE_READ | byteaddress)) !=
3906 	    EHC_SUCCESS) {
3907 		if (status == EHC_NO_SLAVE_ACK) {
3908 			/*
3909 			 * Send the stop condition.
3910 			 */
3911 			eHc_stop_pcf8584(ehcp);
3912 			/*
3913 			 * Read the last byte - discard it.
3914 			 */
3915 			discard = ddi_get8(ehcp->ctlr_handle,
3916 			    &ehcp->bus_ctl_regs->s0);
3917 #ifdef lint
3918 			discard = discard;
3919 #endif
3920 		}
3921 		return (EHC_FAILURE);
3922 	}
3923 
3924 	for (i = 0; i < size - 1; i++) {
3925 		if ((status = eHc_read_pcf8584(ehcp, &buf[i])) != EHC_SUCCESS) {
3926 		return (EHC_FAILURE);
3927 		}
3928 	}
3929 
3930 	/*
3931 	 * Handle the part of the bus protocol which comes
3932 	 * after a read.
3933 	 */
3934 	if (eHc_after_read_pcf8584(ehcp, &buf[i]) != EHC_SUCCESS) {
3935 		return (EHC_FAILURE);
3936 	}
3937 
3938 	return (EHC_SUCCESS);
3939 }
3940 
3941 /*
3942  * Write to the PCF8583 chip.
3943  * byteaddress = chip type base address | chip offset address.
3944  */
3945 static int
eHc_write_pcf8583(struct eHc_envcunit * ehcp,int byteaddress,uint8_t * buf,int size)3946 eHc_write_pcf8583(struct eHc_envcunit *ehcp, int byteaddress, uint8_t *buf,
3947     int size)
3948 {
3949 	int i;
3950 	int status;
3951 
3952 	ASSERT((byteaddress & 0x1) == 0);
3953 	ASSERT(MUTEX_HELD(&ehcp->umutex));
3954 
3955 	if ((status = eHc_start_pcf8584(ehcp, byteaddress)) != EHC_SUCCESS) {
3956 		if (status == EHC_NO_SLAVE_ACK) {
3957 			/*
3958 			 * Send the "stop" condition.
3959 			 */
3960 			eHc_stop_pcf8584(ehcp);
3961 		}
3962 		return (EHC_FAILURE);
3963 	}
3964 
3965 	/*
3966 	 * Send the data - poll as needed.
3967 	 */
3968 	for (i = 0; i < size; i++) {
3969 		if ((status = eHc_write_pcf8584(ehcp, buf[i])) != EHC_SUCCESS) {
3970 			if (status == EHC_NO_SLAVE_ACK)
3971 				eHc_stop_pcf8584(ehcp);
3972 			return (EHC_FAILURE);
3973 		}
3974 	}
3975 
3976 	/*
3977 	 * Transmission complete - generate stop condition and
3978 	 * put device back into slave receiver mode.
3979 	 */
3980 	eHc_stop_pcf8584(ehcp);
3981 
3982 	return (EHC_SUCCESS);
3983 }
3984 
3985 /*
3986  * Read from the PCF8581 chip.
3987  * byteaddress = chip type base address | chip offset address.
3988  */
3989 static int
eHc_read_pcf8591(struct eHc_envcunit * ehcp,int byteaddress,int channel,int autoinc,int amode,int aenable,uint8_t * buf,int size)3990 eHc_read_pcf8591(struct eHc_envcunit *ehcp, int byteaddress, int channel,
3991     int autoinc, int amode, int aenable, uint8_t *buf, int size)
3992 {
3993 	int i;
3994 	int status;
3995 	uint8_t control;
3996 	uint8_t discard;
3997 
3998 	ASSERT((byteaddress & 0x1) == 0);
3999 	ASSERT(channel < 4);
4000 	ASSERT(amode < 4);
4001 	ASSERT(MUTEX_HELD(&ehcp->umutex));
4002 
4003 	/*
4004 	 * Write the control word to the PCF8591.
4005 	 * Follow the control word with a repeated START byte
4006 	 * rather than a STOP so that reads can follow without giving
4007 	 * up the bus.
4008 	 */
4009 
4010 	control = ((aenable << 6) | (amode << 4) | (autoinc << 2) | channel);
4011 
4012 	if ((status = eHc_start_pcf8584(ehcp, byteaddress)) != EHC_SUCCESS) {
4013 		if (status == EHC_NO_SLAVE_ACK) {
4014 			eHc_stop_pcf8584(ehcp);
4015 		}
4016 		return (EHC_FAILURE);
4017 	}
4018 
4019 	if ((status = eHc_write_pcf8584(ehcp, control)) != EHC_SUCCESS) {
4020 		if (status == EHC_NO_SLAVE_ACK)
4021 			eHc_stop_pcf8584(ehcp);
4022 		return (EHC_FAILURE);
4023 	}
4024 
4025 	/*
4026 	 * The following two operations, 0x45 to S1, and the byteaddress
4027 	 * to S0, will result in a repeated START being sent out on the bus.
4028 	 * Refer to Fig.8 of Philips Semiconductors PCF8584 product spec.
4029 	 */
4030 
4031 	ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1,
4032 	    EHC_S1_ES0 | EHC_S1_STA | EHC_S1_ACK);
4033 
4034 	ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0,
4035 	    EHC_BYTE_READ | byteaddress);
4036 
4037 	i = 0;
4038 
4039 	do {
4040 		drv_usecwait(1000);
4041 		status =
4042 		    ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
4043 		i++;
4044 	} while ((status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
4045 
4046 	if (i == EHC_MAX_WAIT) {
4047 		DCMNERR(CE_WARN, "eHc_read_pcf8591(): read of S1 failed");
4048 		return (EHC_FAILURE);
4049 	}
4050 
4051 	if (status & EHC_S1_LRB) {
4052 		DCMNERR(CE_WARN, "eHc_read_pcf8591(): No slave ACK");
4053 		/*
4054 		 * Send the stop condition.
4055 		 */
4056 		eHc_stop_pcf8584(ehcp);
4057 		/*
4058 		 * Read the last byte - discard it.
4059 		 */
4060 		discard = ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0);
4061 #ifdef lint
4062 		discard = discard;
4063 #endif
4064 		return (EHC_FAILURE);
4065 	}
4066 
4067 	if (status & EHC_S1_BER) {
4068 		DCMN2ERR(CE_WARN, "eHc_read_pcf8591(): Bus error");
4069 		return (EHC_FAILURE);
4070 	}
4071 
4072 	if (status & EHC_S1_LAB) {
4073 		DCMN2ERR(CE_WARN, "eHc_read_pcf8591(): Lost Arbitration");
4074 		return (EHC_FAILURE);
4075 	}
4076 
4077 	/*
4078 	 * Discard first read as per PCF8584 master receiver protocol.
4079 	 * This is normally done in the eHc_start_pcf8584() routine.
4080 	 */
4081 	if ((status = eHc_read_pcf8584(ehcp, &discard)) != EHC_SUCCESS) {
4082 		return (EHC_FAILURE);
4083 	}
4084 
4085 	/* Discard second read as per PCF8591 protocol */
4086 	if ((status = eHc_read_pcf8584(ehcp, &discard)) != EHC_SUCCESS) {
4087 		return (EHC_FAILURE);
4088 	}
4089 
4090 	for (i = 0; i < size - 1; i++) {
4091 		if ((status = eHc_read_pcf8584(ehcp, &buf[i])) != EHC_SUCCESS) {
4092 			return (EHC_FAILURE);
4093 		}
4094 	}
4095 
4096 	if (eHc_after_read_pcf8584(ehcp, &buf[i]) != EHC_SUCCESS) {
4097 		return (EHC_FAILURE);
4098 	}
4099 
4100 	return (EHC_SUCCESS);
4101 }
4102