xref: /titanic_52/usr/src/uts/sun4u/tazmo/io/envctrl.c (revision 342440ec94087b8c751c580ab9ed6c693d31d418)
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 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * ENVCTRL_ Environment Monitoring driver for i2c
31  *
32  */
33 #include <sys/param.h>
34 #include <sys/types.h>
35 #include <sys/signal.h>
36 #include <sys/errno.h>
37 #include <sys/file.h>
38 #include <sys/termio.h>
39 #include <sys/termios.h>
40 #include <sys/cmn_err.h>
41 #include <sys/stream.h>
42 #include <sys/strsun.h>
43 #include <sys/stropts.h>
44 #include <sys/strtty.h>
45 #include <sys/debug.h>
46 #include <sys/eucioctl.h>
47 #include <sys/cred.h>
48 #include <sys/uio.h>
49 #include <sys/stat.h>
50 #include <sys/kmem.h>
51 
52 #include <sys/ddi.h>
53 #include <sys/sunddi.h>
54 #include <sys/obpdefs.h>
55 #include <sys/conf.h>		/* req. by dev_ops flags MTSAFE etc. */
56 #include <sys/modctl.h>		/* for modldrv */
57 #include <sys/stat.h>		/* ddi_create_minor_node S_IFCHR */
58 #include <sys/open.h>		/* for open params.	 */
59 #include <sys/uio.h>		/* for read/write */
60 #include <sys/envctrl.h>	/* Environment header */
61 
62 /* driver entry point fn definitions */
63 static int 	envctrl_open(queue_t *, dev_t *, int, int, cred_t *);
64 static int	envctrl_close(queue_t *, int, cred_t *);
65 static uint_t 	envctrl_bus_isr(caddr_t);
66 static uint_t 	envctrl_dev_isr(caddr_t);
67 
68 /* configuration entry point fn definitions */
69 static int 	envctrl_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
70 static int	envctrl_attach(dev_info_t *, ddi_attach_cmd_t);
71 static int	envctrl_detach(dev_info_t *, ddi_detach_cmd_t);
72 
73 /* Driver private routines */
74 static void	envctrl_init_bus(struct envctrlunit *);
75 static int	envctrl_xmit(struct envctrlunit *, caddr_t *, int);
76 static void	envctrl_recv(struct envctrlunit *, caddr_t *, int);
77 static void	envctrl_get_sys_temperatures(struct envctrlunit *, uint8_t *);
78 static int	envctrl_get_lm75_temp(struct envctrlunit *);
79 static int	envctrl_get_ps_temp(struct envctrlunit *, uint8_t);
80 static int	envctrl_get_cpu_temp(struct envctrlunit *, int);
81 static void	envctrl_fan_fail_service(struct envctrlunit *);
82 static void	envctrl_PS_intr_service(struct envctrlunit *, uint8_t);
83 static void	envctrl_ps_probe(struct envctrlunit *);
84 static void	envctrl_tempr_poll(void *);
85 static void	envctrl_pshotplug_poll(void *);
86 static void	envctrl_led_blink(void *);
87 static void	envctrl_reset_dflop(struct envctrlunit *);
88 static void	envctrl_enable_devintrs(struct envctrlunit *);
89 static void	envctrl_stop_clock(struct envctrlunit *);
90 static void	envctrl_reset_watchdog(struct envctrlunit *, uint8_t *);
91 static void	envctrl_abort_seq_handler(char *msg);
92 static uint8_t	envctrl_get_fpm_status(struct envctrlunit *);
93 static void	envctrl_set_fsp(struct envctrlunit *, uint8_t *);
94 static int	envctrl_set_dskled(struct envctrlunit *,
95 				struct envctrl_pcf8574_chip *);
96 static int	envctrl_get_dskled(struct envctrlunit *,
97 				struct envctrl_pcf8574_chip *);
98 static void	envctrl_probe_cpus(struct envctrlunit *);
99 static int	envctrl_match_cpu(dev_info_t *, void *);
100 static int	envctrl_isother_fault_led(struct envctrlunit *,
101 		    uint8_t, uint8_t);
102 
103 /* Kstat routines */
104 static void	envctrl_add_kstats(struct envctrlunit *);
105 static int	envctrl_ps_kstat_update(kstat_t *, int);
106 static int	envctrl_fanstat_kstat_update(kstat_t *, int);
107 static int	envctrl_encl_kstat_update(kstat_t *, int);
108 static void	envctrl_init_fan_kstats(struct envctrlunit *);
109 static void	envctrl_init_encl_kstats(struct envctrlunit *);
110 static void	envctrl_add_encl_kstats(struct envctrlunit *, int, int,
111 			uint8_t);
112 static void	envctrl_mod_encl_kstats(struct envctrlunit *, int, int,
113 			uint8_t);
114 
115 
116 /* Streams Routines */
117 static int	envctrl_wput(queue_t *, mblk_t *);
118 
119 /* External routines */
120 extern void power_down(const char *);
121 extern int prom_getprop();
122 extern int prom_getproplen();
123 extern	void	prom_printf(const char *fmt, ...);
124 extern void (*abort_seq_handler)();
125 
126 static void    *envctrlsoft_statep;
127 
128 /* Local Variables */
129 /* Indicates whether or not the overtemp thread has been started */
130 static int	envctrl_debug_flags = 0;
131 static int	envctrl_afb_present = 0;
132 static int	envctrl_power_off_overide = 0;
133 static int	envctrl_max_retries = 100;
134 static int	envctrl_allow_detach = 0;
135 static int	envctrl_numcpus = 1;
136 static int	envctrl_p0_enclosure = 0; /* set to 1 if it is a P0 */
137 static int envctrl_handler = 1; /* 1 is the default */
138 static clock_t overtemp_timeout_hz;
139 static clock_t blink_timeout_hz;
140 static clock_t pshotplug_timeout_hz;
141 static int controller_present[] = {-1, -1, -1};
142 #ifdef MULTIFAN
143 static int	envctrl_fan_debug = 0;
144 #endif
145 static int 	eHc_debug = 0;
146 static int	power_supply_previous_state[] = {-1, -1, -1};
147 
148 extern void	pci_thermal_rem_intr(dev_info_t *, uint_t);
149 
150 #define	LOOP_TIMEOUT 25
151 #define	INIT_FAN_VAL 35
152 #define	DCMNERR if (eHc_debug & 0x1) cmn_err
153 #define	DCMN2ERR if (eHc_debug & 0x2) cmn_err
154 #define	MAX_FAN_FAIL_RETRY 3
155 
156 uint8_t backaddrs[] = {ENVCTRL_PCF8574_DEV0, ENVCTRL_PCF8574_DEV1,
157     ENVCTRL_PCF8574_DEV2};
158 
159 struct module_info envctrlinfo = {
160 	/* id, name, min pkt siz, max pkt siz, hi water, low water */
161 	42, "envctrl", 0, 2048, (1024 * 20), (1024 * 1)
162 };
163 
164 static struct qinit envctrl_rinit = {
165 	putq, NULL, envctrl_open, envctrl_close, NULL, &envctrlinfo, NULL
166 };
167 
168 static struct qinit envctrl_wint = {
169 	envctrl_wput, NULL, envctrl_open, envctrl_close,
170 	    NULL, &envctrlinfo, NULL
171 };
172 
173 struct streamtab envctrl_str_info = {
174 	&envctrl_rinit, &envctrl_wint, NULL, NULL
175 };
176 
177 static struct cb_ops envctrl_cb_ops = {
178 	nodev,			/* cb_open */
179 	nodev,			/* cb_close */
180 	nodev,			/* cb_strategy */
181 	nodev,			/* cb_print */
182 	nodev,			/* cb_dump */
183 	nodev,			/* cb_read */
184 	nodev,			/* cb_write */
185 	nodev,			/* cb_ioctl */
186 	nodev,			/* cb_devmap */
187 	nodev,			/* cb_mmap */
188 	nodev,			/* cb_segmap */
189 	nochpoll,		/* cb_chpoll */
190 	ddi_prop_op,		/* cb_prop_op */
191 	&envctrl_str_info,	/* cb_stream */
192 	D_MP			/* cb_flag */
193 };
194 
195 /*
196  * Declare ops vectors for auto configuration.
197  */
198 struct dev_ops  envctrl_ops = {
199 	DEVO_REV,		/* devo_rev */
200 	0,			/* devo_refcnt */
201 	envctrl_getinfo,	/* devo_getinfo */
202 	nulldev,		/* devo_identify */
203 	nulldev,		/* devo_probe */
204 	envctrl_attach,		/* devo_attach */
205 	envctrl_detach,		/* devo_detach */
206 	nodev,			/* devo_reset */
207 	&envctrl_cb_ops,	/* devo_cb_ops */
208 	(struct bus_ops *)NULL,	/* devo_bus_ops */
209 	nulldev			/* devo_power */
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: %I% %E%",
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
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
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
406 _info(struct modinfo *modinfop)
407 {
408 	return (mod_info(&envctrlmodlinkage, modinfop));
409 }
410 
411 static int
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 			NULL) == 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
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
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
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
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
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, overtemp_timeout_hz));
1236 
1237 				}
1238 				if (*wdval == ENVCTRL_NORMAL_MODE) {
1239 					envctrl_get_sys_temperatures(unitp,
1240 					    (uint8_t *)NULL);
1241 					/*
1242 					 * going to normal mode we
1243 					 * need to go to diag mode
1244 					 * just in case we have
1245 					 * injected a fan fault. It
1246 					 * may not be cleared and if
1247 					 * we call fan_failsrvc it will
1248 					 * power off the ystem if we are
1249 					 * in NORMAL_MODE. Also we need
1250 					 * to delay 1 bit of time here
1251 					 * to  allow the fans to rotate
1252 					 * back up and clear the intr
1253 					 * after we get the sys temps.
1254 					 */
1255 					unitp->current_mode =
1256 					    ENVCTRL_DIAG_MODE;
1257 					envctrl_fan_fail_service(unitp);
1258 					unitp->current_mode =
1259 					    ENVCTRL_NORMAL_MODE;
1260 				}
1261 				mutex_exit(&unitp->umutex);
1262 				miocack(q, mp, 0, 0);
1263 			} else {
1264 				miocnak(q, mp, 0, EINVAL);
1265 			}
1266 			break;
1267 		default:
1268 			freemsg(mp);
1269 			break;
1270 		}
1271 
1272 		break;
1273 	}
1274 
1275 	case M_FLUSH:
1276 		if (*mp->b_rptr & FLUSHR) {
1277 			*mp->b_rptr &= ~FLUSHW;
1278 			qreply(q, mp);
1279 		} else {
1280 			freemsg(mp);
1281 		}
1282 		break;
1283 
1284 	default:
1285 		freemsg(mp);
1286 		break;
1287 	}
1288 
1289 	return (0);
1290 }
1291 
1292 uint_t
1293 envctrl_bus_isr(caddr_t arg)
1294 {
1295 	struct envctrlunit *unitp = (struct envctrlunit *)(void *)arg;
1296 	int ic = DDI_INTR_UNCLAIMED;
1297 
1298 	mutex_enter(&unitp->umutex);
1299 
1300 	/*
1301 	 * NOT USED
1302 	 */
1303 
1304 	mutex_exit(&unitp->umutex);
1305 	return (ic);
1306 }
1307 
1308 uint_t
1309 envctrl_dev_isr(caddr_t arg)
1310 {
1311 	struct envctrlunit *unitp = (struct envctrlunit *)(void *)arg;
1312 	uint8_t recv_data;
1313 	int ic;
1314 	int retrys = 0;
1315 	int status;
1316 
1317 	ic = DDI_INTR_UNCLAIMED;
1318 
1319 	mutex_enter(&unitp->umutex);
1320 
1321 	/*
1322 	 * First check to see if it is an interrupt for us by
1323 	 * looking at the "ganged" interrrupt and vector
1324 	 * according to the major type
1325 	 * 0x70 is the addr of the ganged interrupt controller.
1326 	 * Address map for the port byte read is as follows
1327 	 * MSB
1328 	 * -------------------------
1329 	 * |  |  |  |  |  |  |  |  |
1330 	 * -------------------------
1331 	 *  P7 P6 P5 P4 P3 P2 P1 P0
1332 	 * P0 = Power Supply 1 intr
1333 	 * P1 = Power Supply 2 intr
1334 	 * P2 = Power Supply 3 intr
1335 	 * P3 = Dlfop enable for fan sped set
1336 	 * P4 = ENVCTRL_ Fan Fail intr
1337 	 * P5 =	Front Panel Interrupt
1338 	 * P6 = Power Fail Detect Low.
1339 	 * P7 = Enable Interrupts to system
1340 	 */
1341 
1342 retry:
1343 
1344 	status = eHc_read_pcf8574a((struct eHc_envcunit *)unitp,
1345 		PCF8574A_BASE_ADDR | ENVCTRL_PCF8574_DEV0, &recv_data, 1);
1346 
1347 	/*
1348 	 * This extra read is needed since the first read is discarded
1349 	 * and the second read seems to return 0xFF.
1350 	 */
1351 	if (recv_data == 0xFF) {
1352 		status = eHc_read_pcf8574a((struct eHc_envcunit *)unitp,
1353 		PCF8574A_BASE_ADDR | ENVCTRL_PCF8574_DEV0, &recv_data, 1);
1354 	}
1355 	if (envctrl_debug_flags)
1356 		cmn_err(CE_WARN, "envctrl_dev_isr: status= %d, data = %x\n",
1357 			status, recv_data);
1358 
1359 	/*
1360 	 * if the i2c bus is hung it is imperative that this
1361 	 * be cleared on an interrupt or else it will
1362 	 * hang the system with continuous interrupts
1363 	 */
1364 
1365 	if (status == DDI_FAILURE) {
1366 		drv_usecwait(1000);
1367 		if (retrys < envctrl_max_retries) {
1368 			retrys++;
1369 			goto retry;
1370 		} else {
1371 			if (envctrl_debug_flags)
1372 				cmn_err(CE_WARN,
1373 				    "DEVISR FAILED received 0x%x\n", recv_data);
1374 			mutex_exit(&unitp->umutex);
1375 			envctrl_init_bus(unitp);
1376 			mutex_enter(&unitp->umutex);
1377 			envctrl_ps_probe(unitp);
1378 			mutex_exit(&unitp->umutex);
1379 			ic = DDI_INTR_CLAIMED;
1380 			return (ic);
1381 		}
1382 	}
1383 
1384 	/*
1385 	 * Port 0 = PS1 interrupt
1386 	 * Port 1 = PS2 Interrupt
1387 	 * Port 2 = PS3 Interrupt
1388 	 * Port 3 = SPARE
1389 	 * Port 4 = Fan Fail Intr
1390 	 * Port 5 = Front Panle Module intr
1391 	 * Port 6 = Keyswitch Intr
1392 	 * Port 7 = ESINTR ENABLE ???
1393 	 */
1394 
1395 	if (!(recv_data & ENVCTRL_PCF8574_PORT0)) {
1396 		envctrl_PS_intr_service(unitp, PS1);
1397 		ic = DDI_INTR_CLAIMED;
1398 	}
1399 
1400 	if (!(recv_data & ENVCTRL_PCF8574_PORT1)) {
1401 		envctrl_PS_intr_service(unitp, PS2);
1402 		ic = DDI_INTR_CLAIMED;
1403 	}
1404 
1405 	if (!(recv_data & ENVCTRL_PCF8574_PORT2)) {
1406 		envctrl_PS_intr_service(unitp, PS3);
1407 		ic = DDI_INTR_CLAIMED;
1408 	}
1409 
1410 	if (!(recv_data & ENVCTRL_PCF8574_PORT3)) {
1411 		ic = DDI_INTR_CLAIMED;
1412 	}
1413 
1414 	if (!(recv_data & ENVCTRL_PCF8574_PORT4)) {
1415 		/*
1416 		 * Check for a fan fail
1417 		 * Single fan fail
1418 		 * shutdown system
1419 		 */
1420 		envctrl_fan_fail_service(unitp);
1421 		ic = DDI_INTR_CLAIMED;
1422 	}
1423 
1424 	if (!(recv_data & ENVCTRL_PCF8574_PORT5)) {
1425 		(void) envctrl_get_fpm_status(unitp);
1426 		ic = DDI_INTR_CLAIMED;
1427 	}
1428 
1429 	if (!(recv_data & ENVCTRL_PCF8574_PORT6)) {
1430 		ic = DDI_INTR_CLAIMED;
1431 	}
1432 
1433 	if (!(recv_data & ENVCTRL_PCF8574_PORT7)) {
1434 		ic = DDI_INTR_CLAIMED;
1435 	}
1436 
1437 	if ((recv_data == 0xFF)) {
1438 		ic = DDI_INTR_CLAIMED;
1439 	}
1440 
1441 	mutex_exit(&unitp->umutex);
1442 	return (ic);
1443 
1444 }
1445 
1446 static void
1447 envctrl_init_bus(struct envctrlunit *unitp)
1448 {
1449 
1450 	int i;
1451 	uint8_t noval = NULL;
1452 	struct envctrl_tda8444t_chip fan;
1453 	int fans[] = {ENVCTRL_CPU_FANS, ENVCTRL_PS_FANS, ENVCTRL_AFB_FANS};
1454 
1455 	mutex_enter(&unitp->umutex);
1456 	/* Sets the Mode to 808x type bus */
1457 	ddi_put8(unitp->ctlr_handle,
1458 	    &unitp->bus_ctl_regs->s0, ENVCTRL_CHAR_ZERO);
1459 
1460 	/* SET UP SLAVE ADDR XXX Required..send 0x80 */
1461 
1462 	ddi_put8(unitp->ctlr_handle, &unitp->bus_ctl_regs->s1,
1463 	ENVCTRL_BUS_INIT0);
1464 	(void) ddi_put8(unitp->ctlr_handle, &unitp->bus_ctl_regs->s0,
1465 	ENVCTRL_BUS_INIT1);
1466 
1467 	/* Set the clock now */
1468 	ddi_put8(unitp->ctlr_handle,
1469 	    &unitp->bus_ctl_regs->s1, ENVCTRL_BUS_CLOCK0);
1470 
1471 	/* S0 is now S2  necause of the previous write to S1 */
1472 	/* clock= 12MHz, SCL=90KHz */
1473 	ddi_put8(unitp->ctlr_handle,
1474 	    &unitp->bus_ctl_regs->s0, ENVCTRL_BUS_CLOCK1);
1475 
1476 	/* Enable serial interface */
1477 	ddi_put8(unitp->ctlr_handle,
1478 	    &unitp->bus_ctl_regs->s1, ENVCTRL_BUS_ESI);
1479 
1480 	envctrl_stop_clock(unitp);
1481 
1482 	/*
1483 	 * This has been added here because the DAC is powered
1484 	 * on at "0". When the reset_dflop routine is called
1485 	 * this switched the  fans from blast to DAC control.
1486 	 * if the DAC is at "0", then the fans momentarily lose
1487 	 * power until the temp polling and fan set routine is
1488 	 * first called. If the fans lose power, then there is
1489 	 * a fan fault generated and the system will power off.
1490 	 * We only want to do this IF the bus is first being
1491 	 * initted. This will cause errors in Sunvts if we reset
1492 	 * the fan speed under normal operation. Sometimes we need
1493 	 * to be able to induce fan faults. Init bus is a common
1494 	 * routine to unwedge the i2c bus in some cases.
1495 	 */
1496 
1497 	if (unitp->initting == B_TRUE) {
1498 		fan.chip_num = ENVCTRL_TDA8444T_DEV7;
1499 		fan.val = INIT_FAN_VAL;
1500 
1501 		for (i = 0; i < sizeof (fans)/sizeof (int); i++) {
1502 			fan.fan_num = fans[i];
1503 			if ((fans[i] == ENVCTRL_AFB_FANS) &&
1504 				(unitp->AFB_present == B_FALSE))
1505 				continue;
1506 			(void) envctrl_xmit(unitp, (caddr_t *)(void *)&fan,
1507 				TDA8444T);
1508 		}
1509 	}
1510 
1511 	envctrl_reset_dflop(unitp);
1512 
1513 	envctrl_enable_devintrs(unitp);
1514 
1515 	unitp->current_mode = ENVCTRL_NORMAL_MODE;
1516 	envctrl_reset_watchdog(unitp, &noval);
1517 
1518 	mutex_exit(&unitp->umutex);
1519 }
1520 
1521 static int
1522 envctrl_xmit(struct envctrlunit *unitp, caddr_t *data, int chip_type)
1523 {
1524 
1525 	struct envctrl_tda8444t_chip *fanspeed;
1526 	struct envctrl_pcf8574_chip *ioport;
1527 	uint8_t slave_addr;
1528 	uint8_t buf[2];
1529 	int retrys = 0;
1530 	int status;
1531 
1532 	ASSERT(MUTEX_HELD(&unitp->umutex));
1533 
1534 	switch (chip_type) {
1535 	case TDA8444T:
1536 
1537 		fanspeed = (struct envctrl_tda8444t_chip *)data;
1538 
1539 		if (fanspeed->chip_num > ENVCTRL_FAN_ADDR_MAX) {
1540 			return (DDI_FAILURE);
1541 		}
1542 
1543 		if (fanspeed->fan_num > ENVCTRL_PORT7) {
1544 			return (DDI_FAILURE);
1545 		}
1546 
1547 		if (fanspeed->val > MAX_FAN_VAL) {
1548 			return (DDI_FAILURE);
1549 		}
1550 
1551 retry0:
1552 		slave_addr = (TDA8444T_BASE_ADDR | fanspeed->chip_num);
1553 		buf[0] = fanspeed->val;
1554 
1555 		status = eHc_write_tda8444((struct eHc_envcunit *)unitp,
1556 			TDA8444T_BASE_ADDR | fanspeed->chip_num, 0xF,
1557 			fanspeed->fan_num, buf, 1);
1558 		if (status != DDI_SUCCESS) {
1559 			drv_usecwait(1000);
1560 			if (retrys < envctrl_max_retries) {
1561 				retrys++;
1562 				goto retry0;
1563 			} else {
1564 				mutex_exit(&unitp->umutex);
1565 				envctrl_init_bus(unitp);
1566 				mutex_enter(&unitp->umutex);
1567 				if (envctrl_debug_flags)
1568 					cmn_err(CE_WARN,
1569 					    "envctrl_xmit: Write to TDA8444 " \
1570 					    "failed\n");
1571 				return (DDI_FAILURE);
1572 			}
1573 		}
1574 
1575 		/*
1576 		 * Update the kstats.
1577 		 */
1578 		switch (fanspeed->fan_num) {
1579 		case ENVCTRL_CPU_FANS:
1580 			unitp->fan_kstats[ENVCTRL_FAN_TYPE_CPU].fanspeed =
1581 			    fanspeed->val;
1582 			break;
1583 		case ENVCTRL_PS_FANS:
1584 			unitp->fan_kstats[ENVCTRL_FAN_TYPE_PS].fanspeed =
1585 			    fanspeed->val;
1586 			break;
1587 		case ENVCTRL_AFB_FANS:
1588 			unitp->fan_kstats[ENVCTRL_FAN_TYPE_AFB].fanspeed =
1589 			    fanspeed->val;
1590 			break;
1591 		default:
1592 			break;
1593 		}
1594 		break;
1595 	case PCF8574:
1596 		ioport = (struct envctrl_pcf8574_chip *)data;
1597 		buf[0] = ioport->val;
1598 		if (ioport->chip_num > ENVCTRL_PCF8574_DEV7)
1599 			return (DDI_FAILURE);
1600 
1601 retry:
1602 		if (ioport->type == PCF8574A) {
1603 			slave_addr = (PCF8574A_BASE_ADDR | ioport->chip_num);
1604 			status =
1605 				eHc_write_pcf8574a((struct eHc_envcunit *)unitp,
1606 				PCF8574A_BASE_ADDR | ioport->chip_num, buf, 1);
1607 		} else {
1608 			slave_addr = (PCF8574_BASE_ADDR | ioport->chip_num);
1609 			status = eHc_write_pcf8574((struct eHc_envcunit *)unitp,
1610 				PCF8574_BASE_ADDR | ioport->chip_num, buf, 1);
1611 		}
1612 
1613 		if (status != DDI_SUCCESS) {
1614 			drv_usecwait(1000);
1615 			if (retrys < envctrl_max_retries) {
1616 				retrys++;
1617 				goto retry;
1618 			} else {
1619 				mutex_exit(&unitp->umutex);
1620 				envctrl_init_bus(unitp);
1621 				mutex_enter(&unitp->umutex);
1622 				if (envctrl_debug_flags)
1623 					cmn_err(CE_WARN, "Write to PCF8574 " \
1624 					    "failed, addr = %X\n", slave_addr);
1625 				if (envctrl_debug_flags)
1626 					cmn_err(CE_WARN, "envctrl_xmit: PCF8574\
1627 						dev = %d, port = %d\n",
1628 						ioport->chip_num, ioport->type);
1629 				return (DDI_FAILURE);
1630 			}
1631 		}
1632 		break;
1633 
1634 	default:
1635 		return (DDI_FAILURE);
1636 	}
1637 
1638 	return (DDI_SUCCESS);
1639 }
1640 
1641 static void
1642 envctrl_recv(struct envctrlunit *unitp, caddr_t *data, int chip_type)
1643 {
1644 
1645 	struct envctrl_pcf8591_chip *temp;
1646 	struct envctrl_pcf8574_chip *ioport;
1647 	uint8_t slave_addr, recv_data;
1648 	int retrys = 0;
1649 	int status;
1650 	uint8_t buf[1];
1651 
1652 	ASSERT(MUTEX_HELD(&unitp->umutex));
1653 
1654 	switch (chip_type) {
1655 	case PCF8591:
1656 		temp = (struct envctrl_pcf8591_chip *)data;
1657 		slave_addr = (PCF8591_BASE_ADDR | temp->chip_num);
1658 
1659 retry:
1660 		status = eHc_read_pcf8591((struct eHc_envcunit *)unitp,
1661 			PCF8591_BASE_ADDR | temp->chip_num & 0xF,
1662 			temp->sensor_num, 0, 0, 1, &recv_data, 1);
1663 
1664 		/*
1665 		 * another place to catch the i2c bus hang on an 8591 read
1666 		 * In this instance we will just return the data that is read
1667 		 * after the max_retry because this could be a valid value.
1668 		 */
1669 		if (status != DDI_SUCCESS) {
1670 			drv_usecwait(1000);
1671 			if (retrys < envctrl_max_retries) {
1672 				retrys++;
1673 				goto retry;
1674 			} else {
1675 				mutex_exit(&unitp->umutex);
1676 				envctrl_init_bus(unitp);
1677 				mutex_enter(&unitp->umutex);
1678 				if (envctrl_debug_flags)
1679 					cmn_err(CE_WARN, "Read from PCF8591 " \
1680 					    "failed, slave_addr = %x\n",
1681 					    slave_addr);
1682 			}
1683 		}
1684 		temp->temp_val = recv_data;
1685 		break;
1686 	case TDA8444T:
1687 		printf("envctrl_recv: attempting to read TDA8444T\n");
1688 		return;
1689 	case PCF8574:
1690 		ioport = (struct envctrl_pcf8574_chip *)data;
1691 
1692 retry1:
1693 		if (ioport->chip_num > ENVCTRL_PCF8574_DEV7)
1694 			cmn_err(CE_WARN, "envctrl: dev out of range 0x%x\n",
1695 ioport->chip_num);
1696 
1697 		if (ioport->type == PCF8574A) {
1698 			slave_addr = (PCF8574_READ_BIT | PCF8574A_BASE_ADDR |
1699 			    ioport->chip_num);
1700 			status = eHc_read_pcf8574a((struct eHc_envcunit *)unitp,
1701 				PCF8574A_BASE_ADDR | ioport->chip_num, buf, 1);
1702 		} else {
1703 			slave_addr = (PCF8574_READ_BIT | PCF8574_BASE_ADDR |
1704 			    ioport->chip_num);
1705 			status = eHc_read_pcf8574((struct eHc_envcunit *)unitp,
1706 				PCF8574_BASE_ADDR | ioport->chip_num, buf, 1);
1707 		}
1708 
1709 		if (status != DDI_SUCCESS) {
1710 			drv_usecwait(1000);
1711 			if (retrys < envctrl_max_retries) {
1712 				retrys++;
1713 				goto retry1;
1714 			} else {
1715 				mutex_exit(&unitp->umutex);
1716 				envctrl_init_bus(unitp);
1717 				mutex_enter(&unitp->umutex);
1718 				if (envctrl_debug_flags)
1719 					cmn_err(CE_WARN, "Read from PCF8574 "\
1720 					    "failed, addr = %X\n", slave_addr);
1721 				if (envctrl_debug_flags)
1722 					cmn_err(CE_WARN, "envctrl_recv: PCF8574\
1723 						dev = %d, port = %d\n",
1724 						ioport->chip_num, ioport->type);
1725 			}
1726 		}
1727 		ioport->val = buf[0];
1728 		break;
1729 	default:
1730 		break;
1731 	}
1732 }
1733 
1734 static int
1735 envctrl_get_ps_temp(struct envctrlunit *unitp, uint8_t psaddr)
1736 {
1737 	uint8_t tempr;
1738 	int i, retrys;
1739 	int status;
1740 	uint8_t buf[4];
1741 
1742 	ASSERT(MUTEX_HELD(&unitp->umutex));
1743 
1744 	tempr = 0;
1745 	retrys = 0;
1746 
1747 retry:
1748 	status = eHc_read_pcf8591((struct eHc_envcunit *)unitp,
1749 			PCF8591_BASE_ADDR | psaddr & 0xF, 0, 1, 0, 1, buf, 4);
1750 
1751 	tempr = 0;
1752 	for (i = 0; i < PCF8591_MAX_PORTS; i++) {
1753 		/*
1754 		 * The pcf8591 will return 0xff if no port
1755 		 * is there.. this is bogus for setting temps.
1756 		 * so just ignore it!
1757 		 */
1758 		if (envctrl_debug_flags) {
1759 			cmn_err(CE_WARN, "PS addr 0x%x recvd 0x%x on port %d\n",
1760 			    psaddr, buf[i], i);
1761 		}
1762 		if (buf[i] > tempr && buf[i] < MAX_PS_ADVAL) {
1763 			tempr = buf[i];
1764 		}
1765 	}
1766 
1767 	/*
1768 	 * This routine is a safeguard to make sure that if the
1769 	 * powersupply temps cannot be read that we do something
1770 	 * to make sure that the system will notify the user and
1771 	 * it will stay running with the fans at 100%. The calling
1772 	 * routine should take care of that.
1773 	 */
1774 	if (status != DDI_SUCCESS) {
1775 		drv_usecwait(1000);
1776 		if (retrys < envctrl_max_retries) {
1777 			retrys++;
1778 			goto retry;
1779 		} else {
1780 			mutex_exit(&unitp->umutex);
1781 			envctrl_init_bus(unitp);
1782 			mutex_enter(&unitp->umutex);
1783 			if (envctrl_debug_flags)
1784 				cmn_err(CE_WARN,
1785 				    "Cannot read Power Supply Temps addr = %X",
1786 				    psaddr);
1787 			return (PS_DEFAULT_VAL);
1788 		}
1789 	}
1790 
1791 	return (ps_temps[tempr]);
1792 }
1793 
1794 static int
1795 envctrl_get_cpu_temp(struct envctrlunit *unitp, int cpunum)
1796 {
1797 	uint8_t recv_data;
1798 	int retrys;
1799 	int status;
1800 
1801 	ASSERT(MUTEX_HELD(&unitp->umutex));
1802 
1803 	/*
1804 	 * This routine takes in the number of the port that
1805 	 * we want to read in the 8591. This should be the
1806 	 * location of the COU thermistor for one of the 4
1807 	 * cpu's. It will return the temperature in degrees C
1808 	 * to the caller.
1809 	 */
1810 
1811 	retrys = 0;
1812 
1813 retry:
1814 	status = eHc_read_pcf8591((struct eHc_envcunit *)unitp,
1815 			PCF8591_BASE_ADDR | PCF8591_DEV7, cpunum, 0, 0, 0,
1816 			&recv_data, 1);
1817 
1818 	/*
1819 	 * We need to take a sledge hammer to the bus if we get back
1820 	 * value of the chip. This means that the i2c bus got wedged.
1821 	 * On the 1.4 systems this happens sometimes while running
1822 	 * sunvts. We will return the max cpu temp minus 10 to make
1823 	 * the fans run at full speed so that we don;t cook the
1824 	 * system.
1825 	 * At this point this is a workaround for hardware glitch.
1826 	 */
1827 	if (status == DDI_FAILURE) {
1828 		drv_usecwait(1000);
1829 		if (retrys < envctrl_max_retries) {
1830 			retrys++;
1831 			goto retry;
1832 		} else {
1833 			mutex_exit(&unitp->umutex);
1834 			envctrl_init_bus(unitp);
1835 			mutex_enter(&unitp->umutex);
1836 			if (envctrl_debug_flags)
1837 				cmn_err(CE_WARN, "envctrl CPU TEMP read " \
1838 				    "failed\n");
1839 			/* we don't want to power off the system */
1840 			return (MAX_CPU_TEMP - 10);
1841 		}
1842 	}
1843 
1844 	return (cpu_temps[recv_data]);
1845 }
1846 
1847 static int
1848 envctrl_get_lm75_temp(struct envctrlunit *unitp)
1849 {
1850 
1851 	int k;
1852 	ushort_t lmval;
1853 	uint8_t tmp1;
1854 	uint8_t tmp2;
1855 	int status;
1856 	uint8_t buf[2];
1857 
1858 
1859 	ASSERT(MUTEX_HELD(&unitp->umutex));
1860 
1861 	status = eHc_read_lm75((struct eHc_envcunit *)unitp,
1862 		LM75_BASE_ADDR | LM75_CONFIG_ADDRA, buf, 2);
1863 	if (status != DDI_SUCCESS)
1864 		cmn_err(CE_WARN, "read of LM75 failed\n");
1865 
1866 	tmp1 = buf[0];
1867 	tmp2 = buf[1];
1868 
1869 	/*
1870 	 * Store the forst 8 bits in the upper nibble of the
1871 	 * short, then store the lower 8 bits in the lower nibble
1872 	 * of the short, shift 7 to the right to get the 9 bit value
1873 	 * that the lm75 is really sending.
1874 	 */
1875 	lmval = tmp1 << 8;
1876 	lmval = (lmval | tmp2);
1877 	lmval = (lmval >> 7);
1878 	/*
1879 	 * Check the 9th bit to see if it is a negative
1880 	 * temperature. If so change into 2's compliment
1881 	 * and divide by 2 since each value is equal to a
1882 	 * half degree strp in degrees C
1883 	 */
1884 	if (lmval & LM75_COMP_MASK) {
1885 		tmp1 = (lmval & LM75_COMP_MASK_UPPER);
1886 		tmp1 = -tmp1;
1887 		tmp1 = tmp1/2;
1888 		k = 0 - tmp1;
1889 	} else {
1890 		k = lmval /2;
1891 	}
1892 		return (k);
1893 }
1894 
1895 
1896 static void
1897 envctrl_tempr_poll(void *arg)
1898 {
1899 	int diag_flag = 0;
1900 	struct envctrlunit *unitp = (struct envctrlunit *)arg;
1901 
1902 	mutex_enter(&unitp->umutex);
1903 
1904 	if (unitp->shutdown == B_TRUE) {
1905 		(void) power_down("Fatal System Environmental Control Error");
1906 	}
1907 
1908 	/*
1909 	 * if we are in diag mode and the temp poll thread goes off,
1910 	 * this means that the system is too heavily loaded and the 60 second
1911 	 * window to execute the test is failing. We will change the fanspeed
1912 	 * but will not check for a fanfault. This will cause a system shutdown
1913 	 * if the system has had a fanfault injected.
1914 	 */
1915 	if (unitp->current_mode == ENVCTRL_DIAG_MODE) {
1916 		diag_flag++;
1917 		if (envctrl_debug_flags) {
1918 			cmn_err(CE_WARN,
1919 			    "Tempr poll went off while in DIAG MODE");
1920 		}
1921 	}
1922 	unitp->current_mode = ENVCTRL_NORMAL_MODE;
1923 	envctrl_get_sys_temperatures(unitp, (uint8_t *)NULL);
1924 	if (diag_flag == 0) {
1925 		envctrl_fan_fail_service(unitp);
1926 	}
1927 	/* now have this thread sleep for a while */
1928 	unitp->timeout_id = (timeout(envctrl_tempr_poll,
1929 	    (caddr_t)unitp, overtemp_timeout_hz));
1930 
1931 	mutex_exit(&unitp->umutex);
1932 }
1933 
1934 static void
1935 envctrl_led_blink(void *arg)
1936 {
1937 	struct envctrl_pcf8574_chip fspchip;
1938 	struct envctrlunit *unitp = (struct envctrlunit *)arg;
1939 
1940 	mutex_enter(&unitp->umutex);
1941 
1942 	fspchip.type = PCF8574A;
1943 	fspchip.chip_num = ENVCTRL_PCF8574_DEV6; /* 0x01 port 1 */
1944 	envctrl_recv(unitp, (caddr_t *)(void *)&fspchip, PCF8574);
1945 
1946 	if (unitp->present_led_state == B_TRUE) {
1947 		/*
1948 		 * Now we need to "or" in fault bits of the FSP
1949 		 * module for the mass storage fault led.
1950 		 * and set it.
1951 		 */
1952 		fspchip.val = (fspchip.val & ~(ENVCTRL_PCF8574_PORT4) |
1953 				    0xC0);
1954 		unitp->present_led_state = B_FALSE;
1955 	} else {
1956 		fspchip.val = (fspchip.val | ENVCTRL_PCF8574_PORT4 | 0xC0);
1957 		unitp->present_led_state = B_TRUE;
1958 	}
1959 
1960 	(void) envctrl_xmit(unitp, (caddr_t *)(void *)&fspchip, PCF8574);
1961 
1962 	/* now have this thread sleep for a while */
1963 	unitp->blink_timeout_id = (timeout(envctrl_led_blink,
1964 	    (caddr_t)unitp, blink_timeout_hz));
1965 
1966 	mutex_exit(&unitp->umutex);
1967 }
1968 
1969 /* called with mutex held */
1970 static void
1971 envctrl_get_sys_temperatures(struct envctrlunit *unitp, uint8_t *diag_tempr)
1972 {
1973 	int temperature, tmptemp, cputemp, hicputemp, ambtemp;
1974 	int i;
1975 	struct envctrl_tda8444t_chip fan;
1976 	uint8_t psaddr[] = {PSTEMP3, PSTEMP2, PSTEMP1, PSTEMP0};
1977 	uint8_t noval = NULL;
1978 	uint8_t fspval;
1979 
1980 	ASSERT(MUTEX_HELD(&unitp->umutex));
1981 
1982 	fan.fan_num = ENVCTRL_CPU_FANS;
1983 	fan.chip_num = ENVCTRL_TDA8444T_DEV7;
1984 
1985 	tmptemp = 0;	/* Right init value ?? */
1986 
1987 	/*
1988 	 * THis routine is caled once every minute
1989 	 * we wil re-se the watchdog timer each time
1990 	 * we poll the temps. The watchdog timer is
1991 	 * set up for 3 minutes. Should the kernel thread
1992 	 * wedge, for some reason the watchdog will go off
1993 	 * and blast the fans.
1994 	 */
1995 
1996 	if (unitp->current_mode == ENVCTRL_DIAG_MODE) {
1997 		unitp->current_mode = ENVCTRL_NORMAL_MODE;
1998 		envctrl_reset_watchdog(unitp, &noval);
1999 		unitp->current_mode = ENVCTRL_DIAG_MODE;
2000 	} else {
2001 		envctrl_reset_watchdog(unitp, &noval);
2002 	}
2003 
2004 	/*
2005 	 * we need to reset the dflop to allow the fans to be
2006 	 * set if the watchdog goes of and the kernel resumes
2007 	 * resetting the dflop alos resets the device interrupts
2008 	 * we need to reenable them also.
2009 	 */
2010 	envctrl_reset_dflop(unitp);
2011 
2012 	envctrl_enable_devintrs(unitp);
2013 
2014 	/*
2015 	 * If we are in diag mode we allow the system to be
2016 	 * faked out as to what the temperature is
2017 	 * to see if the fans speed up.
2018 	 */
2019 	if (unitp->current_mode == ENVCTRL_DIAG_MODE && diag_tempr != NULL) {
2020 		if (unitp->timeout_id != 0) {
2021 		    (void) untimeout(unitp->timeout_id);
2022 		}
2023 
2024 		ambtemp = *diag_tempr;
2025 		unitp->timeout_id = (timeout(envctrl_tempr_poll,
2026 		    (caddr_t)unitp, overtemp_timeout_hz));
2027 	} else {
2028 		ambtemp = envctrl_get_lm75_temp(unitp);
2029 		/*
2030 		 * Sometimes when we read the temp it comes back bogus
2031 		 * to fix this we just need to reset the envctrl bus
2032 		 */
2033 		if (ambtemp == -100) {
2034 			mutex_exit(&unitp->umutex);
2035 			envctrl_init_bus(unitp);
2036 			mutex_enter(&unitp->umutex);
2037 			ambtemp = envctrl_get_lm75_temp(unitp);
2038 		}
2039 	}
2040 
2041 	envctrl_mod_encl_kstats(unitp, ENVCTRL_ENCL_AMBTEMPR, INSTANCE_0,
2042 	    ambtemp);
2043 
2044 	fspval = envctrl_get_fpm_status(unitp);
2045 
2046 	if (ambtemp > MAX_AMB_TEMP) {
2047 		fspval |= (ENVCTRL_FSP_TEMP_ERR | ENVCTRL_FSP_GEN_ERR);
2048 		if (!(envctrl_power_off_overide) &&
2049 		    unitp->current_mode == ENVCTRL_NORMAL_MODE) {
2050 			unitp->shutdown = B_TRUE;
2051 		}
2052 			if (unitp->current_mode == ENVCTRL_NORMAL_MODE) {
2053 				cmn_err(CE_WARN,
2054 			"Ambient Temperature is %d C, shutdown now\n",
2055 				    ambtemp);
2056 			}
2057 	} else {
2058 		if (envctrl_isother_fault_led(unitp, fspval,
2059 			ENVCTRL_FSP_TEMP_ERR)) {
2060 			fspval &= ~(ENVCTRL_FSP_TEMP_ERR);
2061 		} else {
2062 			fspval &= ~(ENVCTRL_FSP_TEMP_ERR | ENVCTRL_FSP_GEN_ERR);
2063 		}
2064 	}
2065 
2066 	envctrl_set_fsp(unitp, &fspval);
2067 
2068 	cputemp = hicputemp = 0;
2069 #ifndef TESTBED
2070 	for (i = 0; i < ENVCTRL_MAX_CPUS; i++) {
2071 		if (unitp->cpu_pr_location[i] == B_TRUE) {
2072 			cputemp = envctrl_get_cpu_temp(unitp, i);
2073 			envctrl_mod_encl_kstats(unitp, ENVCTRL_ENCL_CPUTEMPR,
2074 			    i, cputemp);
2075 			if (cputemp >= MAX_CPU_TEMP) {
2076 				if (!(envctrl_power_off_overide)) {
2077 					unitp->shutdown = B_TRUE;
2078 				}
2079 				cmn_err(CE_WARN,
2080 				    "CPU %d OVERHEATING!!!", i);
2081 			}
2082 
2083 			if (cputemp > hicputemp) {
2084 				hicputemp = cputemp;
2085 			}
2086 		}
2087 	}
2088 #else
2089 	cputemp = envctrl_get_cpu_temp(unitp, 0);
2090 	envctrl_mod_encl_kstats(unitp, ENVCTRL_ENCL_CPUTEMPR, 0, cputemp);
2091 #endif
2092 
2093 	fspval = envctrl_get_fpm_status(unitp);
2094 
2095 	/*
2096 	 * We first look at the ambient temp. If the system is at idle
2097 	 * the cpu temps will be approx 20 degrees above ambient.
2098 	 * If the cpu's rise above 20, then the CPU fans are set
2099 	 * according to the cpu temp minus 20 degrees C.
2100 	 */
2101 	if (unitp->current_mode == ENVCTRL_DIAG_MODE && diag_tempr != NULL) {
2102 		temperature = ambtemp;
2103 	} else {
2104 		temperature = hicputemp - CPU_AMB_RISE;
2105 	}
2106 
2107 	if (temperature < 0) {
2108 		fan.val = MAX_FAN_SPEED; 	/* blast it is out of range */
2109 	} else if (temperature > MAX_AMB_TEMP) {
2110 		fan.val = MAX_FAN_SPEED;
2111 		fspval |= (ENVCTRL_FSP_TEMP_ERR | ENVCTRL_FSP_GEN_ERR);
2112 
2113 			if (unitp->current_mode == ENVCTRL_NORMAL_MODE) {
2114 				cmn_err(CE_WARN,
2115 				    "CPU Fans set to MAX. CPU Temp is %d C\n",
2116 				    hicputemp);
2117 			}
2118 	} else if (ambtemp < MAX_AMB_TEMP) {
2119 		if (!envctrl_p0_enclosure) {
2120 			fan.val = acme_cpu_fanspd[temperature];
2121 		} else {
2122 			fan.val = fan_speed[temperature];
2123 		}
2124 		if (envctrl_isother_fault_led(unitp, fspval,
2125 			ENVCTRL_FSP_TEMP_ERR)) {
2126 			fspval &= ~(ENVCTRL_FSP_TEMP_ERR);
2127 		} else {
2128 			fspval &= ~(ENVCTRL_FSP_TEMP_ERR | ENVCTRL_FSP_GEN_ERR);
2129 		}
2130 	}
2131 
2132 	envctrl_set_fsp(unitp, &fspval);
2133 
2134 	/*
2135 	 * Update temperature kstats. FSP kstats are updated in the
2136 	 * set and get routine.
2137 	 */
2138 
2139 	unitp->fan_kstats[ENVCTRL_FAN_TYPE_CPU].fanspeed = fan.val;
2140 
2141 	/* CPU FANS */
2142 	(void) envctrl_xmit(unitp, (caddr_t *)(void *)&fan, TDA8444T);
2143 
2144 	/* The afb Fan is always at max */
2145 	if (unitp->AFB_present == B_TRUE) {
2146 		fan.val = AFB_MAX;
2147 		/* AFB FANS */
2148 		unitp->fan_kstats[ENVCTRL_FAN_TYPE_AFB].fanspeed = fan.val;
2149 		fan.fan_num = ENVCTRL_AFB_FANS;
2150 		(void) envctrl_xmit(unitp, (caddr_t *)(void *)&fan, TDA8444T);
2151 	}
2152 
2153 	/*
2154 	 * Now set the Powersupply fans
2155 	 */
2156 
2157 	tmptemp = temperature = 0;
2158 	for (i = 0; i <= MAXPS; i++) {
2159 		if (unitp->ps_present[i]) {
2160 			tmptemp = envctrl_get_ps_temp(unitp, psaddr[i]);
2161 			unitp->ps_kstats[i].ps_tempr = tmptemp & 0xFFFF;
2162 			if (tmptemp > temperature) {
2163 				temperature = tmptemp;
2164 			}
2165 			if (temperature >= MAX_PS_TEMP) {
2166 				if (!(envctrl_power_off_overide)) {
2167 					unitp->shutdown = B_TRUE;
2168 				}
2169 				cmn_err(CE_WARN,
2170 				    "Power Supply %d OVERHEATING!!!\
2171 				    Temp is %d C", i, temperature);
2172 			}
2173 		}
2174 	}
2175 
2176 
2177 	fan.fan_num = ENVCTRL_PS_FANS;
2178 	if (temperature > PS_TEMP_WARN) {
2179 		fspval = envctrl_get_fpm_status(unitp);
2180 		fspval |= (ENVCTRL_FSP_TEMP_ERR | ENVCTRL_FSP_GEN_ERR);
2181 		envctrl_set_fsp(unitp, &fspval);
2182 		fan.val = MAX_FAN_SPEED;
2183 		cmn_err(CE_WARN, "A Power Supply is close to  OVERHEATING!!!");
2184 	} else {
2185 		if (temperature - ambtemp > PS_AMB_RISE) {
2186 			ambtemp = temperature - PS_AMB_RISE;
2187 		}
2188 		if (!envctrl_p0_enclosure) {
2189 			fan.val = acme_ps_fanspd[ambtemp];
2190 		} else {
2191 			fan.val = ps_fans[ambtemp];
2192 		}
2193 	}
2194 
2195 	/*
2196 	 * XXX add in error condition for ps overtemp
2197 	 */
2198 
2199 	unitp->fan_kstats[ENVCTRL_FAN_TYPE_PS].fanspeed = fan.val;
2200 	(void) envctrl_xmit(unitp, (caddr_t *)(void *)&fan, TDA8444T);
2201 }
2202 
2203 /* called with mutex held */
2204 static void
2205 envctrl_fan_fail_service(struct envctrlunit *unitp)
2206 {
2207 	uint8_t recv_data, fpmstat;
2208 	int fantype;
2209 	int psfanflt, cpufanflt, afbfanflt;
2210 	int retries = 0, max_retry_count;
2211 	int status;
2212 
2213 	psfanflt = cpufanflt = afbfanflt = 0;
2214 	/*
2215 	 * The fan fail sensor is located at address 0x70
2216 	 * on the envctrl bus.
2217 	 */
2218 
2219 	ASSERT(MUTEX_HELD(&unitp->umutex));
2220 
2221 retry:
2222 	status = eHc_read_pcf8574a((struct eHc_envcunit *)unitp,
2223 		PCF8574A_BASE_ADDR | ENVCTRL_PCF8574_DEV4, &recv_data, 1);
2224 	if (status != DDI_SUCCESS)
2225 		cmn_err(CE_WARN, "fan_fail_service: status = %d, data = %x\n",
2226 			status, recv_data);
2227 
2228 	/*
2229 	 * If all fan ports are high (0xff) then we don't have any
2230 	 * fan faults. Reset the kstats
2231 	 */
2232 	if (recv_data == 0xff) {
2233 		unitp->fan_kstats[ENVCTRL_FAN_TYPE_PS].fans_ok = B_TRUE;
2234 		unitp->fan_kstats[ENVCTRL_FAN_TYPE_CPU].fans_ok = B_TRUE;
2235 		unitp->fan_kstats[ENVCTRL_FAN_TYPE_AFB].fans_ok = B_TRUE;
2236 		unitp->fan_kstats[ENVCTRL_FAN_TYPE_PS].fanflt_num = 0;
2237 		unitp->fan_kstats[ENVCTRL_FAN_TYPE_CPU].fanflt_num = 0;
2238 		unitp->fan_kstats[ENVCTRL_FAN_TYPE_AFB].fanflt_num = 0;
2239 		unitp->num_fans_failed = 0;
2240 		fpmstat = envctrl_get_fpm_status(unitp);
2241 		if (!(envctrl_isother_fault_led(unitp, fpmstat, 0))) {
2242 			fpmstat &= ~(ENVCTRL_FSP_GEN_ERR);
2243 		}
2244 		if (unitp->shutdown != B_TRUE) {
2245 			envctrl_set_fsp(unitp, &fpmstat);
2246 		}
2247 		return;
2248 	}
2249 
2250 	fantype = ENVCTRL_FAN_TYPE_PS;
2251 
2252 	if (!(recv_data & ENVCTRL_PCF8574_PORT0)) {
2253 		psfanflt = PS_FAN_3;
2254 	}
2255 	if (!(recv_data & ENVCTRL_PCF8574_PORT1)) {
2256 		psfanflt = PS_FAN_2;
2257 	}
2258 	if (!(recv_data & ENVCTRL_PCF8574_PORT2)) {
2259 		psfanflt = PS_FAN_1;
2260 	}
2261 
2262 	if (psfanflt != 0) {
2263 		unitp->fan_kstats[fantype].fans_ok = B_FALSE;
2264 		unitp->fan_kstats[fantype].fanflt_num = psfanflt - 1;
2265 		if (retries == MAX_FAN_FAIL_RETRY && status == DDI_SUCCESS &&
2266 		    unitp->current_mode == ENVCTRL_NORMAL_MODE) {
2267 			cmn_err(CE_WARN, "PS Fan Number %d Failed",
2268 			    psfanflt - 1);
2269 		}
2270 	} else {
2271 		unitp->fan_kstats[fantype].fans_ok = B_TRUE;
2272 		unitp->fan_kstats[fantype].fanflt_num = 0;
2273 	}
2274 
2275 	fantype = ENVCTRL_FAN_TYPE_CPU;
2276 
2277 	if (!(recv_data & ENVCTRL_PCF8574_PORT3)) {
2278 		cpufanflt = CPU_FAN_1;
2279 	}
2280 	if (!(recv_data & ENVCTRL_PCF8574_PORT4)) {
2281 		cpufanflt = CPU_FAN_2;
2282 	}
2283 	if (!(recv_data & ENVCTRL_PCF8574_PORT5)) {
2284 		cpufanflt = CPU_FAN_3;
2285 	}
2286 
2287 	if (cpufanflt != 0) {
2288 		unitp->fan_kstats[fantype].fans_ok = B_FALSE;
2289 		unitp->fan_kstats[fantype].fanflt_num = cpufanflt - 1;
2290 		if (retries == MAX_FAN_FAIL_RETRY && status == DDI_SUCCESS &&
2291 		    unitp->current_mode == ENVCTRL_NORMAL_MODE) {
2292 			cmn_err(CE_WARN, "CPU Fan Number %d Failed",
2293 			    cpufanflt - 1);
2294 		}
2295 	} else {
2296 		unitp->fan_kstats[fantype].fans_ok = B_TRUE;
2297 		unitp->fan_kstats[fantype].fanflt_num = 0;
2298 	}
2299 
2300 	if (!(recv_data & ENVCTRL_PCF8574_PORT6) &&
2301 		(unitp->AFB_present == B_TRUE)) {
2302 		/*
2303 		 * If the afb is present and the afb fan fails,
2304 		 * we need to power off or else it will melt!
2305 		 * If it isn't present just log the error.
2306 		 * We make the decision off of the afbfanflt
2307 		 * flag later on in an if statement.
2308 		 */
2309 		afbfanflt++;
2310 		unitp->fan_kstats[ENVCTRL_FAN_TYPE_AFB].fans_ok
2311 		    = B_FALSE;
2312 		unitp->fan_kstats[ENVCTRL_FAN_TYPE_AFB].fanflt_num =
2313 		    AFB_FAN_1;
2314 		if (unitp->current_mode == ENVCTRL_NORMAL_MODE) {
2315 			cmn_err(CE_WARN, "AFB Fan Failed");
2316 		}
2317 
2318 	}
2319 
2320 	/*
2321 	 * If we have no Fan Faults Clear the LED's
2322 	 * If we have fan faults set the Gen Fault LED.
2323 	 */
2324 	if (psfanflt == 0 && cpufanflt == 0 && afbfanflt == 0 &&
2325 	    unitp->num_fans_failed != 0) {
2326 		fpmstat = envctrl_get_fpm_status(unitp);
2327 		if (!(envctrl_isother_fault_led(unitp,
2328 		    fpmstat, 0))) {
2329 			fpmstat &= ~(ENVCTRL_FSP_GEN_ERR);
2330 		}
2331 		envctrl_set_fsp(unitp, &fpmstat);
2332 	} else if (psfanflt != 0 || cpufanflt != 0 || afbfanflt != 0) {
2333 		fpmstat = envctrl_get_fpm_status(unitp);
2334 		fpmstat |= ENVCTRL_FSP_GEN_ERR;
2335 		envctrl_set_fsp(unitp, &fpmstat);
2336 	}
2337 
2338 	if (unitp->AFB_present == B_FALSE) {
2339 		afbfanflt = 0;
2340 	}
2341 
2342 	if ((cpufanflt > 0 || psfanflt > 0 || afbfanflt > 0 ||
2343 		(status != DDI_SUCCESS)) && !unitp->initting &&
2344 		unitp->current_mode == ENVCTRL_NORMAL_MODE) {
2345 		if (status != DDI_SUCCESS)
2346 			max_retry_count = envctrl_max_retries;
2347 		else
2348 			max_retry_count = MAX_FAN_FAIL_RETRY;
2349 		if (retries <= max_retry_count) {
2350 			retries++;
2351 			drv_usecwait(1000);
2352 			if (retries == max_retry_count) {
2353 				cmn_err(CE_WARN,
2354 				    "Fan Fail is 0x%x, retries = %d\n",
2355 				    recv_data, retries);
2356 			}
2357 			envctrl_get_sys_temperatures(unitp,
2358 			    (uint8_t *)NULL);
2359 			goto retry;
2360 		}
2361 		if (!(envctrl_power_off_overide)) {
2362 			unitp->shutdown = B_TRUE;
2363 		}
2364 		cmn_err(CE_WARN, "Fan Failure(s), System Shutdown");
2365 	}
2366 
2367 	unitp->num_fans_failed = (psfanflt + cpufanflt + afbfanflt);
2368 
2369 }
2370 
2371 /*
2372  * Check for power supply insertion and failure.
2373  * This is a bit tricky, because a power supply insertion will
2374  * trigger a load share interrupt as well as PS present in the
2375  * new supply. if we detect an insertion clear
2376  * interrupts, disable interrupts, wait for a couple of seconds
2377  * come back and see if the PSOK bit is set, PS_PRESENT is set
2378  * and the share fail interrupts are gone. If not this is a
2379  * real load share fail event.
2380  * Called with mutex held
2381  */
2382 
2383 static void
2384 envctrl_PS_intr_service(struct envctrlunit *unitp, uint8_t psaddr)
2385 {
2386 	uint8_t recv_data;
2387 	int status, retrys = 0;
2388 
2389 	ASSERT(MUTEX_HELD(&unitp->umutex));
2390 
2391 	if (unitp->current_mode == ENVCTRL_DIAG_MODE) {
2392 		return;
2393 	}
2394 
2395 retry:
2396 	status = eHc_read_pcf8574a((struct eHc_envcunit *)unitp,
2397 			PCF8574A_BASE_ADDR | psaddr & 0xF, &recv_data, 1);
2398 	if (status != DDI_SUCCESS) {
2399 		drv_usecwait(1000);
2400 		if (retrys < envctrl_max_retries) {
2401 			retrys++;
2402 			goto retry;
2403 		} else {
2404 			mutex_exit(&unitp->umutex);
2405 			envctrl_init_bus(unitp);
2406 			mutex_enter(&unitp->umutex);
2407 			if (envctrl_debug_flags)
2408 				cmn_err(CE_WARN,
2409 					"PS_intr_service: Read from 8574A " \
2410 					    "failed\n");
2411 		}
2412 	}
2413 
2414 	/*
2415 	 * setup a timeout thread to poll the ps after a
2416 	 * couple of seconds. This allows for the PS to settle
2417 	 * and doesn't report false errors on a hotplug
2418 	 */
2419 
2420 	unitp->pshotplug_id = (timeout(envctrl_pshotplug_poll,
2421 	    (caddr_t)unitp, pshotplug_timeout_hz));
2422 
2423 }
2424 
2425 /* called with mutex held */
2426 static void
2427 envctrl_reset_dflop(struct envctrlunit *unitp)
2428 {
2429 	struct envctrl_pcf8574_chip initval;
2430 
2431 	ASSERT(MUTEX_HELD(&unitp->umutex));
2432 
2433 	/*
2434 	 * This initialization sequence allows a
2435 	 * to change state to stop the fans from
2436 	 * blastion upon poweron. If this isn't
2437 	 * done the writes to the 8444 will not complete
2438 	 * to the hardware because the dflop will
2439 	 * be closed
2440 	 */
2441 	initval.chip_num = ENVCTRL_PCF8574_DEV0; /* 0x01 port 1 */
2442 	initval.type = PCF8574A;
2443 
2444 	initval.val = ENVCTRL_DFLOP_INIT0;
2445 	(void) envctrl_xmit(unitp, (caddr_t *)(void *)&initval, PCF8574);
2446 
2447 	initval.val = ENVCTRL_DFLOP_INIT1;
2448 	(void) envctrl_xmit(unitp, (caddr_t *)(void *)&initval, PCF8574);
2449 }
2450 
2451 static void
2452 envctrl_add_encl_kstats(struct envctrlunit *unitp, int type,
2453     int instance, uint8_t val)
2454 {
2455 	int i = 0;
2456 	boolean_t inserted = B_FALSE;
2457 
2458 	ASSERT(MUTEX_HELD(&unitp->umutex));
2459 
2460 	while (i < MAX_DEVS && inserted == B_FALSE) {
2461 		if (unitp->encl_kstats[i].instance == I2C_NODEV) {
2462 			unitp->encl_kstats[i].instance = instance;
2463 			unitp->encl_kstats[i].type = type;
2464 			unitp->encl_kstats[i].value = val;
2465 			inserted = B_TRUE;
2466 		}
2467 		i++;
2468 	}
2469 	unitp->num_encl_present++;
2470 }
2471 
2472 /* called with mutex held */
2473 static void
2474 envctrl_enable_devintrs(struct envctrlunit *unitp)
2475 {
2476 	struct envctrl_pcf8574_chip initval;
2477 
2478 	ASSERT(MUTEX_HELD(&unitp->umutex));
2479 
2480 	/*
2481 	 * This initialization sequence allows a
2482 	 * to change state to stop the fans from
2483 	 * blastion upon poweron. If this isn't
2484 	 * done the writes to the 8444 will not complete
2485 	 * to the hardware because the dflop will
2486 	 * be closed
2487 	 */
2488 	initval.chip_num = ENVCTRL_PCF8574_DEV0; /* 0x01 port 1 */
2489 	initval.type = PCF8574A;
2490 
2491 	initval.val = ENVCTRL_DEVINTR_INTI0;
2492 	(void) envctrl_xmit(unitp, (caddr_t *)(void *)&initval, PCF8574);
2493 
2494 	/*
2495 	 * set lowerbits all high p0 = PS1, p1 = PS2
2496 	 * p2 = PS3 p4 = envctrl intr_ctrl
2497 	 */
2498 	initval.val = ENVCTRL_DEVINTR_INTI1;
2499 	(void) envctrl_xmit(unitp, (caddr_t *)(void *)&initval, PCF8574);
2500 }
2501 
2502 /* called with mutex held */
2503 static void
2504 envctrl_stop_clock(struct envctrlunit *unitp)
2505 {
2506 	int status;
2507 	uint8_t buf[2];
2508 
2509 	/*
2510 	 * This routine talks to the PCF8583 which
2511 	 * is a clock calendar chip on the envctrl bus.
2512 	 * We use this chip as a watchdog timer for the
2513 	 * fan control. At reset this chip pulses the interrupt
2514 	 * line every 1 second. We need to be able to shut
2515 	 * this off.
2516 	 */
2517 
2518 	ASSERT(MUTEX_HELD(&unitp->umutex));
2519 
2520 	buf[0] = CLOCK_CSR_REG;
2521 	buf[1] = CLOCK_DISABLE;
2522 
2523 	status = eHc_write_pcf8583((struct eHc_envcunit *)unitp,
2524 			PCF8583_BASE_ADDR | 0, buf, 2);
2525 	if (status != DDI_SUCCESS)
2526 		cmn_err(CE_WARN, "write to PCF8583 failed\n");
2527 }
2528 
2529 static void
2530 envctrl_reset_watchdog(struct envctrlunit *unitp, uint8_t *wdval)
2531 {
2532 
2533 	uint8_t w, r;
2534 	uint8_t res = 0;
2535 	int status;
2536 	uint8_t buf[3];
2537 
2538 	ASSERT(MUTEX_HELD(&unitp->umutex));
2539 
2540 	/* the clock MUST be stopped before we re-set it */
2541 	envctrl_stop_clock(unitp);
2542 
2543 	/*
2544 	 * Reset the minutes counter to 0.
2545 	 */
2546 	buf[0] = ALARM_CTR_REG_MINS;
2547 	buf[1] = 0x0;
2548 	status = eHc_write_pcf8583((struct eHc_envcunit *)unitp,
2549 			PCF8583_BASE_ADDR | 0, buf, 2);
2550 	if (status != DDI_SUCCESS)
2551 		cmn_err(CE_WARN, "write to PCF8583 failed\n");
2552 
2553 	/*
2554 	 * set up the alarm timer for 3 minutes
2555 	 * start by setting reg 8 ALARM_CTRL_REG
2556 	 * If we are in diag mode, we set the timer in
2557 	 * seconds. Valid values are 40-99. The timer
2558 	 * counts up to 99. 40 would be 59 seconds
2559 	 */
2560 	buf[0] = CLOCK_ALARM_REG_A;
2561 	if (unitp->current_mode == ENVCTRL_DIAG_MODE) {
2562 		if (unitp->timeout_id != 0) {
2563 			(void) untimeout(unitp->timeout_id);
2564 			unitp->timeout_id = 0;
2565 			unitp->timeout_id = (timeout(envctrl_tempr_poll,
2566 			    (caddr_t)unitp, overtemp_timeout_hz));
2567 		}
2568 		buf[1] = CLOCK_ENABLE_TIMER_S;
2569 	} else {
2570 		buf[1] = CLOCK_ENABLE_TIMER;
2571 	}
2572 
2573 	/* STEP 10: End Transmission */
2574 	status = eHc_write_pcf8583((struct eHc_envcunit *)unitp,
2575 			PCF8583_BASE_ADDR | 0, buf, 2);
2576 	if (status != DDI_SUCCESS)
2577 		cmn_err(CE_WARN, "Reset envctrl watchdog failed\n");
2578 
2579 	/*
2580 	 * Now set up the alarm timer register it
2581 	 * counts from 0-99 with an intr triggered
2582 	 * when it gets to overflow.. or 99. It will
2583 	 * also count from a pre-set value which is
2584 	 * where we are seting from. We want a 3 minute fail
2585 	 * safe so our value is 99-3 or 96.
2586 	 * we are programming register 7 in the 8583.
2587 	 */
2588 
2589 	buf[0] = ALARM_CTRL_REG;
2590 	/*
2591 	 * Allow the diagnostic to set the egg timer val.
2592 	 * never allow it to be set greater than the default.
2593 	 */
2594 	if (unitp->current_mode == ENVCTRL_DIAG_MODE) {
2595 		if (*wdval > MAX_CL_VAL) {
2596 			buf[1] = EGG_TIMER_VAL;
2597 		} else {
2598 
2599 			w = *wdval/10;
2600 			r = *wdval%10;
2601 
2602 			res = res | r;
2603 			res = (0x99 - (res | (w << 4)));
2604 			buf[1] = res;
2605 		}
2606 	} else {
2607 		buf[1] = EGG_TIMER_VAL;
2608 	}
2609 
2610 	status = eHc_write_pcf8583((struct eHc_envcunit *)unitp,
2611 			PCF8583_BASE_ADDR | 0, buf, 2);
2612 	if (status != DDI_SUCCESS)
2613 		cmn_err(CE_WARN, "Reset envctrl watchdog failed\n");
2614 
2615 
2616 	/*
2617 	 * Now that we have set up.. it is time
2618 	 * to re-start the clock in the CSR.
2619 	 */
2620 
2621 	buf[0] = CLOCK_CSR_REG;
2622 	buf[1] = CLOCK_ENABLE;
2623 	status = eHc_write_pcf8583((struct eHc_envcunit *)unitp,
2624 			PCF8583_BASE_ADDR | 0, buf, 2);
2625 	if (status != DDI_SUCCESS)
2626 		cmn_err(CE_WARN, "Reset envctrl watchdog failed\n");
2627 
2628 }
2629 
2630 /* Called with unip mutex held */
2631 static void
2632 envctrl_ps_probe(struct envctrlunit *unitp)
2633 {
2634 
2635 	uint8_t recv_data, fpmstat;
2636 	uint8_t psaddr[] = {PS1, PS2, PS3, PSTEMP0};
2637 	int i;
2638 	int ps_error = 0, retrys = 0;
2639 	int devaddr;
2640 	int status;
2641 	int twotimes = 0;
2642 
2643 	ASSERT(MUTEX_HELD(&unitp->umutex));
2644 
2645 	unitp->num_ps_present = 0;
2646 
2647 	for (i = 0; i <= MAXPS; i++) {
2648 		unitp->ps_present[i] = B_FALSE;
2649 		unitp->ps_kstats[i].ps_rating = 0;
2650 		unitp->ps_kstats[i].ps_tempr = 0;
2651 
2652 		switch (psaddr[i]) {
2653 		case PS1:
2654 			devaddr = ENVCTRL_PCF8574_DEV3;
2655 			break;
2656 		case PS2:
2657 			devaddr = ENVCTRL_PCF8574_DEV2;
2658 			break;
2659 		case PS3:
2660 			devaddr = ENVCTRL_PCF8574_DEV1;
2661 			break;
2662 		case PSTEMP0:
2663 			devaddr = 0;
2664 			break;
2665 		}
2666 		retrys = 0;
2667 retry:
2668 		status = eHc_read_pcf8574a((struct eHc_envcunit *)unitp,
2669 				PCF8574A_BASE_ADDR | devaddr, &recv_data, 1);
2670 		if (status != DDI_SUCCESS) {
2671 			drv_usecwait(1000);
2672 			if (retrys < envctrl_max_retries) {
2673 				retrys++;
2674 				goto retry;
2675 			} else {
2676 				mutex_exit(&unitp->umutex);
2677 				envctrl_init_bus(unitp);
2678 				mutex_enter(&unitp->umutex);
2679 				/*
2680 				 * If we just reset the bus we need to reread
2681 				 * the status.  If a second attempt still fails
2682 				 * then report the read failure.
2683 				 */
2684 				if (twotimes == 0) {
2685 					twotimes++;
2686 					retrys = 0;
2687 					goto retry;
2688 				} else {
2689 					cmn_err(CE_WARN,
2690 					"PS_probe: Read from 8574A failed\n");
2691 				}
2692 			}
2693 		}
2694 
2695 		/*
2696 		 * Port 0 = PS Present
2697 		 * Port 1 = PS Type
2698 		 * Port 2 = PS Type
2699 		 * Port 3 = PS TYpe
2700 		 * Port 4 = DC Status
2701 		 * Port 5 = Current Limit
2702 		 * Port 6 = Current Share
2703 		 * Port 7 = SPARE
2704 		 */
2705 
2706 		/*
2707 		 * Port 0 = PS Present
2708 		 * Port is pulled LOW "0" to indicate
2709 		 * present.
2710 		 */
2711 
2712 		if (!(recv_data & ENVCTRL_PCF8574_PORT0)) {
2713 			unitp->ps_present[i] = B_TRUE;
2714 			/* update unit kstat array */
2715 			unitp->ps_kstats[i].instance = i;
2716 			unitp->ps_kstats[i].ps_tempr = ENVCTRL_INIT_TEMPR;
2717 			++unitp->num_ps_present;
2718 
2719 			if (power_supply_previous_state[i] == 0) {
2720 				cmn_err(CE_NOTE,
2721 				    "Power Supply %d inserted\n", i);
2722 			}
2723 			power_supply_previous_state[i] = 1;
2724 
2725 			if (!(recv_data & ENVCTRL_PCF8574_PORT1)) {
2726 				unitp->ps_kstats[i].ps_rating = ENVCTRL_PS_550;
2727 			}
2728 			if (!(recv_data & ENVCTRL_PCF8574_PORT2)) {
2729 				unitp->ps_kstats[i].ps_rating = ENVCTRL_PS_650;
2730 			}
2731 			if (!(recv_data & ENVCTRL_PCF8574_PORT3)) {
2732 				cmn_err(CE_WARN,
2733 				    "Power Supply %d NOT okay\n", i);
2734 				unitp->ps_kstats[i].ps_ok = B_FALSE;
2735 				ps_error++;
2736 			} else {
2737 				unitp->ps_kstats[i].ps_ok = B_TRUE;
2738 			}
2739 			if (!(recv_data & ENVCTRL_PCF8574_PORT4)) {
2740 				cmn_err(CE_WARN,
2741 				    "Power Supply %d Overloaded\n", i);
2742 				unitp->ps_kstats[i].limit_ok = B_FALSE;
2743 				ps_error++;
2744 			} else {
2745 				unitp->ps_kstats[i].limit_ok = B_TRUE;
2746 			}
2747 			if (!(recv_data & ENVCTRL_PCF8574_PORT5)) {
2748 				cmn_err(CE_WARN,
2749 				    "Power Supply %d load share err\n", i);
2750 				unitp->ps_kstats[i].curr_share_ok = B_FALSE;
2751 				ps_error++;
2752 			} else {
2753 				unitp->ps_kstats[i].curr_share_ok = B_TRUE;
2754 			}
2755 
2756 			if (!(recv_data & ENVCTRL_PCF8574_PORT6)) {
2757 				cmn_err(CE_WARN,
2758 				    "PS %d Shouln't interrupt\n", i);
2759 				ps_error++;
2760 			}
2761 
2762 			if (!(recv_data & ENVCTRL_PCF8574_PORT7)) {
2763 				cmn_err(CE_WARN,
2764 				    "PS %d Shouln't interrupt\n", i);
2765 				ps_error++;
2766 			}
2767 		} else {
2768 			/* No power supply present */
2769 			if (power_supply_previous_state[i] == 1) {
2770 				cmn_err(CE_NOTE,
2771 				    "Power Supply %d removed\n", i);
2772 			}
2773 			power_supply_previous_state[i] = 0;
2774 		}
2775 	}
2776 
2777 	fpmstat = envctrl_get_fpm_status(unitp);
2778 	if (ps_error) {
2779 		fpmstat |= (ENVCTRL_FSP_PS_ERR | ENVCTRL_FSP_GEN_ERR);
2780 	} else {
2781 		if (envctrl_isother_fault_led(unitp, fpmstat,
2782 			ENVCTRL_FSP_PS_ERR)) {
2783 			fpmstat &= ~(ENVCTRL_FSP_PS_ERR);
2784 		} else {
2785 			fpmstat &= ~(ENVCTRL_FSP_PS_ERR |
2786 			    ENVCTRL_FSP_GEN_ERR);
2787 		}
2788 
2789 	}
2790 	envctrl_set_fsp(unitp, &fpmstat);
2791 
2792 	/*
2793 	 * We need to reset all of the fans etc when a supply is
2794 	 * interrupted and added, but we don't want to reset the
2795 	 * fans if we are in DIAG mode. This will mess up SUNVTS.
2796 	 */
2797 	if (unitp->current_mode == ENVCTRL_NORMAL_MODE) {
2798 		envctrl_get_sys_temperatures(unitp, (uint8_t *)NULL);
2799 	}
2800 }
2801 
2802 /*
2803  * consider key switch position when handling an abort sequence
2804  */
2805 static void
2806 envctrl_abort_seq_handler(char *msg)
2807 {
2808 	struct envctrlunit *unitp;
2809 	int i;
2810 	uint8_t secure = 0;
2811 
2812 	/*
2813 	 * Find the instance of the device available on this host.
2814 	 * Note that there may be only one, but the instance may
2815 	 * not be zero.
2816 	 */
2817 	for (i = 0; i < MAX_DEVS; i++) {
2818 		if (unitp = (struct envctrlunit *)
2819 				ddi_get_soft_state(envctrlsoft_statep, i))
2820 			break;
2821 	}
2822 
2823 	ASSERT(unitp);
2824 
2825 	for (i = 0; i < MAX_DEVS; i++) {
2826 		if ((unitp->encl_kstats[i].type == ENVCTRL_ENCL_FSP) &&
2827 			(unitp->encl_kstats[i].instance != I2C_NODEV)) {
2828 			secure = unitp->encl_kstats[i].value;
2829 			break;
2830 		}
2831 	}
2832 
2833 	/*
2834 	 * take the logical not because we are in hardware mode only
2835 	 */
2836 
2837 	if ((secure & ENVCTRL_FSP_KEYMASK) == ENVCTRL_FSP_KEYLOCKED) {
2838 			cmn_err(CE_CONT,
2839 			    "!envctrl: ignoring debug enter sequence\n");
2840 	} else {
2841 		if (envctrl_debug_flags) {
2842 			cmn_err(CE_CONT, "!envctrl: allowing debug enter\n");
2843 		}
2844 		debug_enter(msg);
2845 	}
2846 }
2847 
2848 /*
2849  * get the front Panel module LED and keyswitch status.
2850  * this part is addressed at 0x7C on the i2c bus.
2851  * called with mutex held
2852  */
2853 static uint8_t
2854 envctrl_get_fpm_status(struct envctrlunit *unitp)
2855 {
2856 	uint8_t recv_data;
2857 	int status, retrys = 0;
2858 
2859 	ASSERT(MUTEX_HELD(&unitp->umutex));
2860 
2861 retry:
2862 	status = eHc_read_pcf8574a((struct eHc_envcunit *)unitp,
2863 		PCF8574A_BASE_ADDR | ENVCTRL_PCF8574_DEV6, &recv_data, 1);
2864 
2865 	/*
2866 	 * yet another place where a read can cause the
2867 	 * the SDA line of the i2c bus to get stuck low.
2868 	 * this funky sequence frees the SDA line.
2869 	 */
2870 	if (status != DDI_SUCCESS) {
2871 		drv_usecwait(1000);
2872 		if (retrys < envctrl_max_retries) {
2873 			retrys++;
2874 			goto retry;
2875 		} else {
2876 			mutex_exit(&unitp->umutex);
2877 			envctrl_init_bus(unitp);
2878 			mutex_enter(&unitp->umutex);
2879 			if (envctrl_debug_flags)
2880 				cmn_err(CE_WARN, "Read from PCF8574 (FPM) "\
2881 				    "failed\n");
2882 		}
2883 	}
2884 	recv_data = ~recv_data;
2885 	envctrl_mod_encl_kstats(unitp, ENVCTRL_ENCL_FSP,
2886 	    INSTANCE_0, recv_data);
2887 
2888 	return (recv_data);
2889 }
2890 
2891 static void
2892 envctrl_set_fsp(struct envctrlunit *unitp, uint8_t *val)
2893 {
2894 	struct envctrl_pcf8574_chip chip;
2895 
2896 	ASSERT(MUTEX_HELD(&unitp->umutex));
2897 
2898 	chip.val = ENVCTRL_FSP_OFF; /* init all values to off */
2899 	chip.chip_num = ENVCTRL_PCF8574_DEV6; /* 0x01 port 1 */
2900 	chip.type = PCF8574A;
2901 
2902 	/*
2903 	 * strip off bits that are R/O
2904 	 */
2905 	chip.val = (~(ENVCTRL_FSP_KEYMASK | ENVCTRL_FSP_POMASK) & (*val));
2906 
2907 	chip.val = ~chip.val;
2908 	(void) envctrl_xmit(unitp, (caddr_t *)(void *)&chip, PCF8574);
2909 
2910 }
2911 
2912 static int
2913 envctrl_get_dskled(struct envctrlunit *unitp, struct envctrl_pcf8574_chip *chip)
2914 {
2915 	uint_t oldtype;
2916 
2917 	ASSERT(MUTEX_HELD(&unitp->umutex));
2918 
2919 	if (chip->chip_num > ENVCTRL_PCF8574_DEV2 ||
2920 		chip->type != ENVCTRL_ENCL_BACKPLANE4 &&
2921 		chip->type != ENVCTRL_ENCL_BACKPLANE8) {
2922 		return (DDI_FAILURE);
2923 	}
2924 	oldtype = chip->type;
2925 	chip->type = PCF8574;
2926 	envctrl_recv(unitp, (caddr_t *)(void *)chip, PCF8574);
2927 	chip->type = oldtype;
2928 	chip->val = ~chip->val;
2929 
2930 	return (DDI_SUCCESS);
2931 }
2932 static int
2933 envctrl_set_dskled(struct envctrlunit *unitp, struct envctrl_pcf8574_chip *chip)
2934 {
2935 
2936 	struct envctrl_pcf8574_chip fspchip;
2937 	struct envctrl_pcf8574_chip backchip;
2938 	int i, instance;
2939 	int diskfault = 0;
2940 	uint8_t controller_addr[] = {ENVCTRL_PCF8574_DEV0, ENVCTRL_PCF8574_DEV1,
2941 	    ENVCTRL_PCF8574_DEV2};
2942 
2943 	/*
2944 	 * We need to check the type of disk led being set. If it
2945 	 * is a 4 slot backplane then the upper 4 bits (7, 6, 5, 4) are
2946 	 * invalid.
2947 	 */
2948 	ASSERT(MUTEX_HELD(&unitp->umutex));
2949 
2950 
2951 	if (chip->chip_num > ENVCTRL_PCF8574_DEV2 ||
2952 		chip->val > ENVCTRL_DISK8LED_ALLOFF ||
2953 		chip->val < ENVCTRL_CHAR_ZERO) {
2954 		return (DDI_FAILURE);
2955 	}
2956 
2957 	if (chip->type != ENVCTRL_ENCL_BACKPLANE4 &&
2958 	    chip->type != ENVCTRL_ENCL_BACKPLANE8) {
2959 		return (DDI_FAILURE);
2960 	}
2961 
2962 	/*
2963 	 * Check all of the other controllwes LED states to make sure
2964 	 * that there are no disk faults. If so then if the user is
2965 	 * clearing the disk faults on this contoller, turn off
2966 	 * the mass storage fault led.
2967 	 */
2968 
2969 	backchip.type = PCF8574;
2970 	for (i = 0; i <= MAX_TAZ_CONTROLLERS; i++) {
2971 		if (controller_present[i] == -1)
2972 			continue;
2973 		backchip.chip_num = controller_addr[i];
2974 		envctrl_recv(unitp, (caddr_t *)(void *)&backchip, PCF8574);
2975 		if (chip->chip_num == controller_addr[i]) {
2976 			if (chip->val != ENVCTRL_CHAR_ZERO)
2977 				diskfault++;
2978 		} else if ((~backchip.val & 0xFF) != ENVCTRL_CHAR_ZERO) {
2979 			diskfault++;
2980 		}
2981 	}
2982 
2983 	fspchip.type = PCF8574A;
2984 	fspchip.chip_num = ENVCTRL_PCF8574_DEV6; /* 0x01 port 1 */
2985 	envctrl_recv(unitp, (caddr_t *)(void *)&fspchip, PCF8574);
2986 
2987 	if (diskfault) {
2988 		if (!(envctrl_isother_fault_led(unitp, fspchip.val & 0xFF,
2989 			ENVCTRL_FSP_DISK_ERR))) {
2990 			fspchip.val &= ~(ENVCTRL_FSP_DISK_ERR);
2991 		} else {
2992 			fspchip.val &= ~(ENVCTRL_FSP_DISK_ERR |
2993 			    ENVCTRL_FSP_GEN_ERR);
2994 		}
2995 		fspchip.val = (fspchip.val &
2996 		    ~(ENVCTRL_FSP_DISK_ERR | ENVCTRL_FSP_GEN_ERR));
2997 	} else {
2998 		fspchip.val = (fspchip.val |
2999 		    (ENVCTRL_FSP_DISK_ERR | ENVCTRL_FSP_GEN_ERR));
3000 	}
3001 	fspchip.type = PCF8574A;
3002 	fspchip.chip_num = ENVCTRL_PCF8574_DEV6; /* 0x01 port 1 */
3003 	(void) envctrl_xmit(unitp, (caddr_t *)(void *)&fspchip, PCF8574);
3004 
3005 	for (i = 0; i < (sizeof (backaddrs) / sizeof (uint8_t)); i++) {
3006 		if (chip->chip_num == backaddrs[i]) {
3007 			instance =  i;
3008 		}
3009 	}
3010 
3011 	switch (chip->type) {
3012 	case ENVCTRL_ENCL_BACKPLANE4:
3013 		envctrl_mod_encl_kstats(unitp, ENVCTRL_ENCL_BACKPLANE4,
3014 		    instance, chip->val);
3015 		break;
3016 	case ENVCTRL_ENCL_BACKPLANE8:
3017 		envctrl_mod_encl_kstats(unitp, ENVCTRL_ENCL_BACKPLANE8,
3018 		    instance, chip->val);
3019 		break;
3020 	default:
3021 		break;
3022 	}
3023 	chip->type = PCF8574;
3024 	/*
3025 	 * we take the ones compliment of the val passed in
3026 	 * because the hardware thinks that a "low" or "0"
3027 	 * is the way to indicate a fault. of course software
3028 	 * knows that a 1 is a TRUE state or fault. ;-)
3029 	 */
3030 	chip->val = ~(chip->val);
3031 	(void) envctrl_xmit(unitp, (caddr_t *)(void *)chip, PCF8574);
3032 	return (DDI_SUCCESS);
3033 }
3034 
3035 void
3036 envctrl_add_kstats(struct envctrlunit *unitp)
3037 {
3038 
3039 	ASSERT(MUTEX_HELD(&unitp->umutex));
3040 
3041 	if ((unitp->enclksp = kstat_create(ENVCTRL_MODULE_NAME, unitp->instance,
3042 	    ENVCTRL_KSTAT_ENCL, "misc", KSTAT_TYPE_RAW,
3043 	    sizeof (unitp->encl_kstats),
3044 	    KSTAT_FLAG_PERSISTENT)) == NULL) {
3045 		cmn_err(CE_WARN, "envctrl%d: encl raw kstat_create failed",
3046 			unitp->instance);
3047 		return;
3048 	}
3049 
3050 	unitp->enclksp->ks_update = envctrl_encl_kstat_update;
3051 	unitp->enclksp->ks_private = (void *)unitp;
3052 	kstat_install(unitp->enclksp);
3053 
3054 
3055 	if ((unitp->fanksp = kstat_create(ENVCTRL_MODULE_NAME, unitp->instance,
3056 	    ENVCTRL_KSTAT_FANSTAT, "misc", KSTAT_TYPE_RAW,
3057 	    sizeof (unitp->fan_kstats),
3058 	    KSTAT_FLAG_PERSISTENT)) == NULL) {
3059 		cmn_err(CE_WARN, "envctrl%d: fans kstat_create failed",
3060 			unitp->instance);
3061 		return;
3062 	}
3063 
3064 	unitp->fanksp->ks_update = envctrl_fanstat_kstat_update;
3065 	unitp->fanksp->ks_private = (void *)unitp;
3066 	kstat_install(unitp->fanksp);
3067 
3068 	if ((unitp->psksp = kstat_create(ENVCTRL_MODULE_NAME, unitp->instance,
3069 	    ENVCTRL_KSTAT_PSNAME, "misc", KSTAT_TYPE_RAW,
3070 	    sizeof (unitp->ps_kstats),
3071 	    KSTAT_FLAG_PERSISTENT)) == NULL) {
3072 		cmn_err(CE_WARN, "envctrl%d: ps name kstat_create failed",
3073 			unitp->instance);
3074 		return;
3075 	}
3076 
3077 	unitp->psksp->ks_update = envctrl_ps_kstat_update;
3078 	unitp->psksp->ks_private = (void *)unitp;
3079 	kstat_install(unitp->psksp);
3080 
3081 }
3082 
3083 int
3084 envctrl_ps_kstat_update(kstat_t *ksp, int rw)
3085 {
3086 	struct envctrlunit *unitp;
3087 	char *kstatp;
3088 
3089 
3090 
3091 	unitp = (struct envctrlunit *)ksp->ks_private;
3092 
3093 	mutex_enter(&unitp->umutex);
3094 	ASSERT(MUTEX_HELD(&unitp->umutex));
3095 
3096 	kstatp = (char *)ksp->ks_data;
3097 
3098 	if (rw == KSTAT_WRITE) {
3099 		return (EACCES);
3100 	} else {
3101 
3102 		unitp->psksp->ks_ndata = unitp->num_ps_present;
3103 		bcopy(&unitp->ps_kstats, kstatp, sizeof (unitp->ps_kstats));
3104 	}
3105 	mutex_exit(&unitp->umutex);
3106 	return (DDI_SUCCESS);
3107 }
3108 int
3109 envctrl_fanstat_kstat_update(kstat_t *ksp, int rw)
3110 {
3111 	struct envctrlunit *unitp;
3112 	char *kstatp;
3113 
3114 	kstatp = (char *)ksp->ks_data;
3115 	unitp = (struct envctrlunit *)ksp->ks_private;
3116 
3117 	mutex_enter(&unitp->umutex);
3118 	ASSERT(MUTEX_HELD(&unitp->umutex));
3119 
3120 	if (rw == KSTAT_WRITE) {
3121 		return (EACCES);
3122 	} else {
3123 		unitp->fanksp->ks_ndata = unitp->num_fans_present;
3124 		bcopy(unitp->fan_kstats, kstatp, sizeof (unitp->fan_kstats));
3125 	}
3126 	mutex_exit(&unitp->umutex);
3127 	return (DDI_SUCCESS);
3128 }
3129 
3130 int
3131 envctrl_encl_kstat_update(kstat_t *ksp, int rw)
3132 {
3133 	struct envctrlunit *unitp;
3134 	char *kstatp;
3135 
3136 
3137 	kstatp = (char *)ksp->ks_data;
3138 	unitp = (struct envctrlunit *)ksp->ks_private;
3139 
3140 	mutex_enter(&unitp->umutex);
3141 	ASSERT(MUTEX_HELD(&unitp->umutex));
3142 
3143 	if (rw == KSTAT_WRITE) {
3144 		return (EACCES);
3145 	} else {
3146 
3147 		unitp->enclksp->ks_ndata = unitp->num_encl_present;
3148 		(void) envctrl_get_fpm_status(unitp);
3149 		/* XXX Need to ad disk updates too ??? */
3150 		bcopy(unitp->encl_kstats, kstatp, sizeof (unitp->encl_kstats));
3151 	}
3152 	mutex_exit(&unitp->umutex);
3153 	return (DDI_SUCCESS);
3154 }
3155 
3156 /*
3157  * called with unitp lock held
3158  * type, fanspeed and fanflt will be set by the service routines
3159  */
3160 static void
3161 envctrl_init_fan_kstats(struct envctrlunit *unitp)
3162 {
3163 	int i;
3164 
3165 	ASSERT(MUTEX_HELD(&unitp->umutex));
3166 
3167 	for (i = 0; i < unitp->num_fans_present; i++) {
3168 		unitp->fan_kstats[i].instance = 0;
3169 		unitp->fan_kstats[i].type = 0;
3170 		unitp->fan_kstats[i].fans_ok = B_TRUE;
3171 		unitp->fan_kstats[i].fanflt_num = B_FALSE;
3172 		unitp->fan_kstats[i].fanspeed = B_FALSE;
3173 	}
3174 
3175 	unitp->fan_kstats[ENVCTRL_FAN_TYPE_PS].type = ENVCTRL_FAN_TYPE_PS;
3176 	unitp->fan_kstats[ENVCTRL_FAN_TYPE_CPU].type = ENVCTRL_FAN_TYPE_CPU;
3177 	if (unitp->AFB_present == B_TRUE)
3178 		unitp->fan_kstats[ENVCTRL_FAN_TYPE_AFB].type =
3179 			ENVCTRL_FAN_TYPE_AFB;
3180 }
3181 
3182 static void
3183 envctrl_init_encl_kstats(struct envctrlunit *unitp)
3184 {
3185 
3186 	int i;
3187 	uint8_t val;
3188 	struct envctrl_pcf8574_chip chip;
3189 	int *reg_prop;
3190 	uint_t len = 0;
3191 
3192 	ASSERT(MUTEX_HELD(&unitp->umutex));
3193 
3194 	for (i = 0; i < MAX_DEVS; i++) {
3195 		unitp->encl_kstats[i].instance = I2C_NODEV;
3196 	}
3197 
3198 	/*
3199 	 * add in kstats now
3200 	 * We ALWAYS HAVE THE FOLLOWING
3201 	 * 1. FSP
3202 	 * 2. AMB TEMPR
3203 	 * 3. (1) CPU TEMPR
3204 	 * 4. (1) 4 slot disk backplane
3205 	 * OPTIONAL
3206 	 * 8 slot backplane
3207 	 * more cpu's
3208 	 */
3209 
3210 	chip.type = PCF8574A;
3211 	chip.chip_num = ENVCTRL_PCF8574_DEV6; /* 0x01 port 1 */
3212 	envctrl_recv(unitp, (caddr_t *)(void *)&chip, PCF8574);
3213 
3214 	envctrl_add_encl_kstats(unitp, ENVCTRL_ENCL_FSP, INSTANCE_0,
3215 		chip.val & 0xFF);
3216 
3217 	val = envctrl_get_lm75_temp(unitp) & 0xFF;
3218 	envctrl_add_encl_kstats(unitp, ENVCTRL_ENCL_AMBTEMPR, INSTANCE_0, val);
3219 
3220 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, unitp->dip,
3221 			DDI_PROP_DONTPASS, ENVCTRL_DISK_LEDS_PR,
3222 			&reg_prop, &len) != DDI_PROP_SUCCESS) {
3223 		cmn_err(CE_WARN, "prop lookup of %s failed\n",
3224 			ENVCTRL_DISK_LEDS_PR);
3225 		return;
3226 	}
3227 
3228 	ASSERT(len != 0);
3229 
3230 	chip.type = PCF8574;
3231 
3232 	for (i = 0; i < len; i++) {
3233 		chip.chip_num = backaddrs[i];
3234 		if (reg_prop[i] == ENVCTRL_4SLOT_BACKPLANE) {
3235 			envctrl_recv(unitp, (caddr_t *)(void *)&chip, PCF8574);
3236 			envctrl_add_encl_kstats(unitp, ENVCTRL_ENCL_BACKPLANE4,
3237 			    i, ~chip.val);
3238 			controller_present[i] = 1;
3239 		}
3240 		if (reg_prop[i] == ENVCTRL_8SLOT_BACKPLANE) {
3241 			envctrl_recv(unitp, (caddr_t *)(void *)&chip, PCF8574);
3242 			envctrl_add_encl_kstats(unitp, ENVCTRL_ENCL_BACKPLANE8,
3243 			    i, ~chip.val);
3244 			controller_present[i] = 1;
3245 		}
3246 	}
3247 	ddi_prop_free((void *)reg_prop);
3248 
3249 }
3250 
3251 static void
3252 envctrl_mod_encl_kstats(struct envctrlunit *unitp, int type,
3253     int instance, uint8_t val)
3254 {
3255 	int i = 0;
3256 	boolean_t inserted = B_FALSE;
3257 
3258 	ASSERT(MUTEX_HELD(&unitp->umutex));
3259 
3260 	while (i < MAX_DEVS && inserted == B_FALSE) {
3261 		if (unitp->encl_kstats[i].instance == instance &&
3262 		    unitp->encl_kstats[i].type == type) {
3263 			unitp->encl_kstats[i].value = val;
3264 			inserted = B_TRUE;
3265 		}
3266 		i++;
3267 	}
3268 }
3269 
3270 static void
3271 envctrl_probe_cpus(struct envctrlunit *unitp)
3272 {
3273 	int instance;
3274 
3275 	/*
3276 	 * The cpu search is as follows:
3277 	 * If there is only 1 CPU module it is named as
3278 	 * SUNW,UltraSPARC. If this is a match we still don't
3279 	 * know what slot the cpu module is in therefore
3280 	 * we need to check the "upa-portid" property.
3281 	 * If we have more than 1 cpu, then they are appended by
3282 	 * instance numbers and slot locations. e.g.
3283 	 * SUNW,UltraSPARC@1,0 (slot 1). it would have been
3284 	 * nice to have the naming consistent for one CPU e.g.
3285 	 * SUNW,UltraSPARC@0,0...sigh
3286 	 */
3287 
3288 	for (instance = 0; instance < ENVCTRL_MAX_CPUS; instance++) {
3289 		unitp->cpu_pr_location[instance] = B_FALSE;
3290 	}
3291 
3292 	ddi_walk_devs(ddi_root_node(), envctrl_match_cpu, unitp);
3293 }
3294 
3295 static int
3296 envctrl_match_cpu(dev_info_t *dip, void *arg)
3297 {
3298 
3299 	int cpu_slot;
3300 	char name[32];
3301 	char name1[32];
3302 	struct envctrlunit *unitp = (struct envctrlunit *)arg;
3303 
3304 	(void) sprintf(name, "%s", ENVCTRL_TAZCPU_STRING);
3305 	(void) sprintf(name1, "%s", ENVCTRL_TAZBLKBRDCPU_STRING);
3306 
3307 	if ((strcmp(ddi_node_name(dip), name) == 0) ||
3308 		(strcmp(ddi_node_name(dip), name1) == 0)) {
3309 		if ((cpu_slot = (int)ddi_getprop(DDI_DEV_T_ANY, dip,
3310 			    DDI_PROP_DONTPASS, "upa-portid",
3311 				    -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
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
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
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 =
3461 			ddi_get8(ehcp->ctlr_handle, &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
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
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
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
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
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
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 =
3713 			ddi_get8(ehcp->ctlr_handle, &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
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
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 =
3815 			ddi_get8(ehcp->ctlr_handle, &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
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
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 =
3916 			ddi_get8(ehcp->ctlr_handle, &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
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
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