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