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 382 _init(void) 383 { 384 int error; 385 386 if ((error = mod_install(&envctrlmodlinkage)) == 0) { 387 (void) ddi_soft_state_init(&envctrlsoft_statep, 388 sizeof (struct envctrlunit), 1); 389 } 390 391 return (error); 392 } 393 394 int 395 _fini(void) 396 { 397 int error; 398 399 if ((error = mod_remove(&envctrlmodlinkage)) == 0) 400 ddi_soft_state_fini(&envctrlsoft_statep); 401 402 return (error); 403 } 404 405 int 406 _info(struct modinfo *modinfop) 407 { 408 return (mod_info(&envctrlmodlinkage, modinfop)); 409 } 410 411 static int 412 envctrl_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 413 { 414 int instance; 415 char name[16]; 416 uint8_t fspval; 417 struct envctrlunit *unitp; 418 struct ddi_device_acc_attr attr; 419 int *reg_prop; 420 uchar_t *creg_prop; 421 uint_t len, tblsz; 422 int i, cputemp, status; 423 uint8_t buf[3]; 424 425 status = len = tblsz = 0; 426 427 attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 428 attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 429 430 attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; 431 432 instance = ddi_get_instance(dip); 433 434 switch (cmd) { 435 case DDI_ATTACH: 436 break; 437 case DDI_RESUME: 438 if (!(unitp = ddi_get_soft_state(envctrlsoft_statep, instance))) 439 return (DDI_FAILURE); 440 mutex_enter(&unitp->umutex); 441 if (!unitp->suspended) { 442 mutex_exit(&unitp->umutex); 443 return (DDI_FAILURE); 444 } 445 unitp->suspended = 0; 446 mutex_exit(&unitp->umutex); 447 unitp->initting = B_TRUE; 448 envctrl_init_bus(unitp); 449 unitp->initting = B_FALSE; 450 451 mutex_enter(&unitp->umutex); 452 envctrl_ps_probe(unitp); 453 envctrl_probe_cpus(unitp); 454 mutex_exit(&unitp->umutex); 455 456 return (DDI_SUCCESS); 457 458 default: 459 return (DDI_FAILURE); 460 } 461 462 /* Set up timer values */ 463 overtemp_timeout_hz = drv_usectohz(OVERTEMP_TIMEOUT_USEC); 464 blink_timeout_hz = drv_usectohz(BLINK_TIMEOUT_USEC); 465 pshotplug_timeout_hz = drv_usectohz(BLINK_TIMEOUT_USEC * 6); 466 467 if (ddi_soft_state_zalloc(envctrlsoft_statep, instance) != 0) { 468 cmn_err(CE_WARN, "envctrl failed to zalloc softstate\n"); 469 goto failed; 470 } 471 472 unitp = ddi_get_soft_state(envctrlsoft_statep, instance); 473 474 if (ddi_regs_map_setup(dip, 0, (caddr_t *)&unitp->bus_ctl_regs, 0, 475 sizeof (struct envctrl_pcd8584_regs), &attr, 476 &unitp->ctlr_handle) != DDI_SUCCESS) { 477 cmn_err(CE_WARN, "I2c failed to map in bus_control regs\n"); 478 return (DDI_FAILURE); 479 } 480 481 /* 482 * If the PCI nexus has added a thermal interrupt, we first need 483 * to remove that interrupt handler. 484 * 485 * WARNING: Removing another driver's interrupt handler is not 486 * allowed. The pci_thermal_rem_intr() call below is needed to retain 487 * the legacy behavior on Tazmo systems. 488 */ 489 490 pci_thermal_rem_intr(dip, (uint_t)0); 491 492 /* add interrupts */ 493 494 if (ddi_get_iblock_cookie(dip, 1, 495 &unitp->ic_trap_cookie) != DDI_SUCCESS) { 496 cmn_err(CE_WARN, "ddi_get_iblock_cookie FAILED \n"); 497 goto failed; 498 } 499 500 mutex_init(&unitp->umutex, NULL, MUTEX_DRIVER, 501 (void *)unitp->ic_trap_cookie); 502 503 504 if (ddi_add_intr(dip, 0, &unitp->ic_trap_cookie, NULL, envctrl_bus_isr, 505 (caddr_t)unitp) != DDI_SUCCESS) { 506 cmn_err(CE_WARN, "envctrl_attach failed to add hard intr %d\n", 507 instance); 508 goto remlock; 509 } 510 511 512 if (ddi_add_intr(dip, 1, &unitp->ic_trap_cookie, NULL, envctrl_dev_isr, 513 (caddr_t)unitp) != DDI_SUCCESS) { 514 cmn_err(CE_WARN, "envctrl_attach failed to add hard intr %d\n", 515 instance); 516 goto remhardintr; 517 } 518 519 520 (void) sprintf(name, "envctrl%d", instance); 521 522 if (ddi_create_minor_node(dip, name, S_IFCHR, instance, DDI_PSEUDO, 523 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 747 envctrl_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 748 { 749 int instance; 750 struct envctrlunit *unitp; 751 752 instance = ddi_get_instance(dip); 753 unitp = ddi_get_soft_state(envctrlsoft_statep, instance); 754 755 switch (cmd) { 756 case DDI_DETACH: 757 if (envctrl_allow_detach) { 758 759 if (unitp->psksp != NULL) { 760 kstat_delete(unitp->psksp); 761 } 762 if (unitp->fanksp != NULL) { 763 kstat_delete(unitp->fanksp); 764 } 765 if (unitp->enclksp != NULL) { 766 kstat_delete(unitp->enclksp); 767 } 768 769 if (unitp->timeout_id != 0) { 770 (void) untimeout(unitp->timeout_id); 771 unitp->timeout_id = 0; 772 } 773 if (unitp->blink_timeout_id != 0) { 774 (void) untimeout(unitp->blink_timeout_id); 775 unitp->blink_timeout_id = 0; 776 } 777 778 ddi_remove_minor_node(dip, NULL); 779 780 ddi_remove_intr(dip, (uint_t)0, unitp->ic_trap_cookie); 781 ddi_remove_intr(dip, (uint_t)1, unitp->ic_trap_cookie); 782 783 ddi_regs_map_free(&unitp->ctlr_handle); 784 785 mutex_destroy(&unitp->umutex); 786 787 return (DDI_SUCCESS); 788 } else { 789 return (DDI_FAILURE); 790 } 791 792 case DDI_SUSPEND: 793 if (!(unitp = ddi_get_soft_state(envctrlsoft_statep, instance))) 794 return (DDI_FAILURE); 795 mutex_enter(&unitp->umutex); 796 if (unitp->suspended) { 797 cmn_err(CE_WARN, "envctrl already suspended\n"); 798 mutex_exit(&unitp->umutex); 799 return (DDI_FAILURE); 800 } 801 unitp->suspended = 1; 802 mutex_exit(&unitp->umutex); 803 return (DDI_SUCCESS); 804 805 default: 806 cmn_err(CE_WARN, "envctrl suspend general fault\n"); 807 return (DDI_FAILURE); 808 } 809 810 811 } 812 813 /* ARGSUSED */ 814 int 815 envctrl_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, 816 void **result) 817 { 818 dev_t dev = (dev_t)arg; 819 struct envctrlunit *unitp; 820 int ret; 821 minor_t instance = getminor(dev); 822 823 switch (infocmd) { 824 case DDI_INFO_DEVT2DEVINFO: 825 if ((unitp = (struct envctrlunit *) 826 ddi_get_soft_state(envctrlsoft_statep, 827 instance)) != NULL) { 828 *result = unitp->dip; 829 ret = DDI_SUCCESS; 830 } else { 831 *result = NULL; 832 ret = DDI_FAILURE; 833 } 834 break; 835 case DDI_INFO_DEVT2INSTANCE: 836 *result = (void *)(uintptr_t)instance; 837 ret = DDI_SUCCESS; 838 break; 839 default: 840 ret = DDI_FAILURE; 841 break; 842 } 843 844 return (ret); 845 } 846 847 /* ARGSUSED */ 848 static int 849 envctrl_open(queue_t *q, dev_t *dev, int flag, int sflag, cred_t *credp) 850 { 851 struct envctrlunit *unitp; 852 int status = 0; 853 int instance; 854 855 instance = getminor(*dev); 856 if (instance < 0) 857 return (ENXIO); 858 unitp = (struct envctrlunit *) 859 ddi_get_soft_state(envctrlsoft_statep, instance); 860 861 if (unitp == NULL) 862 return (ENXIO); 863 864 mutex_enter(&unitp->umutex); 865 866 if (flag & FWRITE) { 867 if ((unitp->oflag & FWRITE)) { 868 mutex_exit(&unitp->umutex); 869 return (EBUSY); 870 } else { 871 unitp->oflag |= FWRITE; 872 } 873 } 874 875 q->q_ptr = WR(q)->q_ptr = (caddr_t)unitp; 876 877 /* 878 * if device is open with O_NONBLOCK flag set, let read(2) return 0 879 * if no data waiting to be read. Writes will block on flow control. 880 */ 881 882 /* enable the stream */ 883 qprocson(q); 884 885 unitp->readq = RD(q); 886 unitp->writeq = WR(q); 887 unitp->msg = (mblk_t *)NULL; 888 889 mutex_exit(&unitp->umutex); 890 return (status); 891 } 892 893 /* ARGSUSED */ 894 static int 895 envctrl_close(queue_t *q, int flag, cred_t *cred_p) 896 { 897 struct envctrlunit *unitp; 898 899 unitp = (struct envctrlunit *)q->q_ptr; 900 901 mutex_enter(&unitp->umutex); 902 903 unitp->oflag = B_FALSE; 904 unitp->current_mode = ENVCTRL_NORMAL_MODE; 905 906 /* disable the stream */ 907 q->q_ptr = WR(q)->q_ptr = NULL; 908 qprocsoff(q); 909 910 mutex_exit(&unitp->umutex); 911 return (DDI_SUCCESS); 912 } 913 914 /* 915 * standard put procedure for envctrl 916 */ 917 static int 918 envctrl_wput(queue_t *q, mblk_t *mp) 919 { 920 struct msgb *mp1; 921 struct envctrlunit *unitp; 922 struct iocblk *iocp; 923 struct copyresp *csp; 924 struct envctrl_tda8444t_chip *fanspeed; 925 struct envctrl_pcf8574_chip *ledchip; 926 struct envctrl_pcf8591_chip *temp, *a_fanspeed; 927 struct copyreq *cqp; 928 int cmd; 929 930 unitp = (struct envctrlunit *)q->q_ptr; 931 932 switch (DB_TYPE(mp)) { 933 934 case M_DATA: 935 936 while (mp) { 937 DB_TYPE(mp) = M_DATA; 938 mp1 = unlinkb(mp); 939 mp->b_cont = NULL; 940 if ((mp->b_wptr - mp->b_rptr) <= 0) { 941 freemsg(mp); 942 } else { 943 (void) putq(q, mp); 944 } 945 mp = mp1; 946 } 947 948 break; 949 950 case M_IOCTL: 951 { 952 iocp = (struct iocblk *)(void *)mp->b_rptr; 953 cmd = iocp->ioc_cmd; 954 955 switch (cmd) { 956 case ENVCTRL_IOC_SETMODE: 957 case ENVCTRL_IOC_GETMODE: 958 if (iocp->ioc_count == TRANSPARENT) { 959 mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr, 960 sizeof (uchar_t), NULL); 961 qreply(q, mp); 962 } else { 963 miocnak(q, mp, 0, EINVAL); 964 } 965 break; 966 case ENVCTRL_IOC_RESETTMPR: 967 /* 968 * For diags, cancel the current temp poll 969 * and reset it for a new one. 970 */ 971 if (unitp->current_mode == ENVCTRL_DIAG_MODE) { 972 if (unitp->timeout_id != 0) { 973 (void) untimeout(unitp->timeout_id); 974 unitp->timeout_id = 0; 975 } 976 envctrl_tempr_poll((void *)unitp); 977 miocack(q, mp, 0, 0); 978 } else { 979 miocnak(q, mp, 0, EINVAL); 980 } 981 break; 982 case ENVCTRL_IOC_GETTEMP: 983 if (iocp->ioc_count == TRANSPARENT) { 984 mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr, 985 sizeof (struct envctrl_pcf8591_chip), NULL); 986 qreply(q, mp); 987 } else { 988 miocnak(q, mp, 0, EINVAL); 989 } 990 break; 991 case ENVCTRL_IOC_SETTEMP: 992 if (unitp->current_mode == ENVCTRL_DIAG_MODE && 993 iocp->ioc_count == TRANSPARENT) { 994 mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr, 995 sizeof (uint8_t), NULL); 996 qreply(q, mp); 997 } else { 998 miocnak(q, mp, 0, EINVAL); 999 } 1000 break; 1001 case ENVCTRL_IOC_SETWDT: 1002 if (unitp->current_mode == ENVCTRL_DIAG_MODE && 1003 iocp->ioc_count == TRANSPARENT) { 1004 mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr, 1005 sizeof (uint8_t), NULL); 1006 qreply(q, mp); 1007 } else { 1008 miocnak(q, mp, 0, EINVAL); 1009 } 1010 break; 1011 case ENVCTRL_IOC_SETFAN: 1012 /* 1013 * we must be in diag mode before we can 1014 * set any fan speeds. 1015 */ 1016 if (unitp->current_mode == ENVCTRL_DIAG_MODE && 1017 iocp->ioc_count == TRANSPARENT) { 1018 mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr, 1019 sizeof (struct envctrl_tda8444t_chip), 1020 NULL); 1021 qreply(q, mp); 1022 } else { 1023 miocnak(q, mp, 0, EINVAL); 1024 } 1025 break; 1026 case ENVCTRL_IOC_GETFAN: 1027 if (iocp->ioc_count == TRANSPARENT) { 1028 mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr, 1029 sizeof (struct envctrl_pcf8591_chip), NULL); 1030 qreply(q, mp); 1031 } else { 1032 miocnak(q, mp, 0, EINVAL); 1033 } 1034 break; 1035 case ENVCTRL_IOC_SETFSP: 1036 if (iocp->ioc_count == TRANSPARENT) { 1037 mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr, 1038 sizeof (uint8_t), NULL); 1039 qreply(q, mp); 1040 } else { 1041 miocnak(q, mp, 0, EINVAL); 1042 } 1043 break; 1044 case ENVCTRL_IOC_SETDSKLED: 1045 case ENVCTRL_IOC_GETDSKLED: 1046 if (iocp->ioc_count == TRANSPARENT) { 1047 mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr, 1048 sizeof (struct envctrl_pcf8574_chip), NULL); 1049 qreply(q, mp); 1050 } else { 1051 miocnak(q, mp, 0, EINVAL); 1052 } 1053 break; 1054 default: 1055 miocnak(q, mp, 0, EINVAL); 1056 break; 1057 } 1058 1059 break; 1060 1061 } 1062 case M_IOCDATA: 1063 { 1064 uint8_t *tempr, *wdval; 1065 long state; 1066 1067 csp = (struct copyresp *)(void *)mp->b_rptr; 1068 1069 /* 1070 * If copy request failed, quit now 1071 */ 1072 if (csp->cp_rval != 0) { 1073 miocnak(q, mp, 0, EINVAL); 1074 return (0); 1075 } 1076 1077 cqp = (struct copyreq *)(void *)mp->b_rptr; 1078 1079 cmd = csp->cp_cmd; 1080 state = (long)cqp->cq_private; 1081 1082 switch (cmd) { 1083 case ENVCTRL_IOC_SETFAN: 1084 fanspeed = (struct envctrl_tda8444t_chip *) 1085 (void *)mp->b_cont->b_rptr; 1086 mutex_enter(&unitp->umutex); 1087 if (envctrl_xmit(unitp, (caddr_t *)(void *)fanspeed, 1088 fanspeed->type) == DDI_FAILURE) { 1089 /* 1090 * Fix for a ADF bug 1091 * move mutex to after fan fail call 1092 * bugid 4016121 1093 */ 1094 envctrl_fan_fail_service(unitp); 1095 mutex_exit(&unitp->umutex); 1096 miocnak(q, mp, 0, EINVAL); 1097 } else { 1098 mutex_exit(&unitp->umutex); 1099 miocack(q, mp, 0, 0); 1100 } 1101 break; 1102 case ENVCTRL_IOC_SETFSP: 1103 wdval = (uint8_t *)(void *)mp->b_cont->b_rptr; 1104 mutex_enter(&unitp->umutex); 1105 /* 1106 * If a user is in normal mode and they try 1107 * to set anything other than a disk fault or 1108 * a gen fault it is an invalid operation. 1109 * in diag mode we allow everything to be 1110 * twiddled. 1111 */ 1112 if (unitp->current_mode == ENVCTRL_NORMAL_MODE) { 1113 if (*wdval & ~ENVCTRL_FSP_USRMASK) { 1114 mutex_exit(&unitp->umutex); 1115 miocnak(q, mp, 0, EINVAL); 1116 break; 1117 } 1118 } 1119 envctrl_set_fsp(unitp, wdval); 1120 mutex_exit(&unitp->umutex); 1121 miocack(q, mp, 0, 0); 1122 break; 1123 case ENVCTRL_IOC_SETDSKLED: 1124 ledchip = (struct envctrl_pcf8574_chip *) 1125 (void *)mp->b_cont->b_rptr; 1126 mutex_enter(&unitp->umutex); 1127 if (envctrl_set_dskled(unitp, ledchip)) { 1128 miocnak(q, mp, 0, EINVAL); 1129 } else { 1130 miocack(q, mp, 0, 0); 1131 } 1132 mutex_exit(&unitp->umutex); 1133 break; 1134 case ENVCTRL_IOC_GETDSKLED: 1135 if (state == -1) { 1136 miocack(q, mp, 0, 0); 1137 break; 1138 } 1139 ledchip = (struct envctrl_pcf8574_chip *) 1140 (void *)mp->b_cont->b_rptr; 1141 mutex_enter(&unitp->umutex); 1142 if (envctrl_get_dskled(unitp, ledchip)) { 1143 miocnak(q, mp, 0, EINVAL); 1144 } else { 1145 mcopyout(mp, (void *)-1, 1146 sizeof (struct envctrl_pcf8574_chip), 1147 csp->cp_private, NULL); 1148 qreply(q, mp); 1149 } 1150 mutex_exit(&unitp->umutex); 1151 break; 1152 case ENVCTRL_IOC_GETTEMP: 1153 /* Get the user buffer address */ 1154 1155 if (state == -1) { 1156 miocack(q, mp, 0, 0); 1157 break; 1158 } 1159 temp = (struct envctrl_pcf8591_chip *) 1160 (void *)mp->b_cont->b_rptr; 1161 mutex_enter(&unitp->umutex); 1162 envctrl_recv(unitp, (caddr_t *)(void *)temp, PCF8591); 1163 mutex_exit(&unitp->umutex); 1164 mcopyout(mp, (void *)-1, 1165 sizeof (struct envctrl_pcf8591_chip), 1166 csp->cp_private, NULL); 1167 qreply(q, mp); 1168 break; 1169 case ENVCTRL_IOC_GETFAN: 1170 /* Get the user buffer address */ 1171 1172 if (state == -1) { 1173 miocack(q, mp, 0, 0); 1174 break; 1175 } 1176 a_fanspeed = (struct envctrl_pcf8591_chip *) 1177 (void *)mp->b_cont->b_rptr; 1178 mutex_enter(&unitp->umutex); 1179 envctrl_recv(unitp, (caddr_t *)(void *)a_fanspeed, 1180 PCF8591); 1181 mutex_exit(&unitp->umutex); 1182 mcopyout(mp, (void *)-1, 1183 sizeof (struct envctrl_pcf8591_chip), 1184 csp->cp_private, NULL); 1185 qreply(q, mp); 1186 break; 1187 case ENVCTRL_IOC_SETTEMP: 1188 tempr = (uint8_t *)(void *)mp->b_cont->b_rptr; 1189 if (*tempr > MAX_DIAG_TEMPR) { 1190 miocnak(q, mp, 0, EINVAL); 1191 } else { 1192 mutex_enter(&unitp->umutex); 1193 envctrl_get_sys_temperatures(unitp, tempr); 1194 mutex_exit(&unitp->umutex); 1195 miocack(q, mp, 0, 0); 1196 } 1197 break; 1198 case ENVCTRL_IOC_SETWDT: 1199 /* reset watchdog timeout period */ 1200 wdval = (uint8_t *)(void *)mp->b_cont->b_rptr; 1201 if (*wdval > MAX_CL_VAL) { 1202 miocnak(q, mp, 0, EINVAL); 1203 } else { 1204 mutex_enter(&unitp->umutex); 1205 envctrl_reset_watchdog(unitp, wdval); 1206 mutex_exit(&unitp->umutex); 1207 miocack(q, mp, 0, 0); 1208 } 1209 break; 1210 case ENVCTRL_IOC_GETMODE: 1211 /* Get the user buffer address */ 1212 1213 if (state == -1) { 1214 miocack(q, mp, 0, 0); 1215 break; 1216 } 1217 tempr = (uchar_t *)(void *)mp->b_cont->b_rptr; 1218 *tempr = unitp->current_mode; 1219 mcopyout(mp, (void *)-1, sizeof (uchar_t), 1220 csp->cp_private, NULL); 1221 qreply(q, mp); 1222 break; 1223 case ENVCTRL_IOC_SETMODE: 1224 /* Set mode */ 1225 wdval = (uint8_t *)(void *)mp->b_cont->b_rptr; 1226 if (*wdval == ENVCTRL_DIAG_MODE || *wdval == 1227 ENVCTRL_NORMAL_MODE) { 1228 mutex_enter(&unitp->umutex); 1229 unitp->current_mode = *wdval; 1230 if (unitp->timeout_id != 0 && 1231 *wdval == ENVCTRL_DIAG_MODE) { 1232 (void) untimeout(unitp->timeout_id); 1233 unitp->timeout_id = 1234 (timeout(envctrl_tempr_poll, 1235 (caddr_t)unitp, 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 3335 envctrl_isother_fault_led(struct envctrlunit *unitp, uint8_t fspval, 3336 uint8_t thisled) 3337 { 3338 int status = B_FALSE; 3339 3340 if (fspval != 0) { 3341 fspval = (fspval & ~(thisled)); 3342 } 3343 if (unitp->num_fans_failed > 0 && thisled != 0) { 3344 status = B_TRUE; 3345 } else if (fspval & ENVCTRL_FSP_DISK_ERR) { 3346 status = B_TRUE; 3347 } else if (fspval & ENVCTRL_FSP_PS_ERR) { 3348 status = B_TRUE; 3349 } else if (fspval & ENVCTRL_FSP_TEMP_ERR) { 3350 status = B_TRUE; 3351 } 3352 return (status); 3353 } 3354 3355 static void 3356 envctrl_pshotplug_poll(void *arg) 3357 { 3358 struct envctrlunit *unitp = (struct envctrlunit *)arg; 3359 3360 mutex_enter(&unitp->umutex); 3361 3362 envctrl_ps_probe(unitp); 3363 3364 mutex_exit(&unitp->umutex); 3365 } 3366 3367 /* 3368 * The following routines implement the i2c protocol. 3369 * They should be removed once the envctrl_targets.c file is included. 3370 */ 3371 3372 /* 3373 * put host interface into master mode 3374 */ 3375 static int 3376 eHc_start_pcf8584(struct eHc_envcunit *ehcp, uint8_t byteaddress) 3377 { 3378 uint8_t poll_status; 3379 uint8_t discard; 3380 int i; 3381 3382 /* wait if bus is busy */ 3383 3384 i = 0; 3385 do { 3386 drv_usecwait(1000); 3387 poll_status = 3388 ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1); 3389 i++; 3390 } while (((poll_status & EHC_S1_NBB) == 0) && i < EHC_MAX_WAIT); 3391 3392 if (i == EHC_MAX_WAIT) { 3393 DCMNERR(CE_WARN, "eHc_start_pcf8584: I2C bus busy"); 3394 return (EHC_FAILURE); 3395 } 3396 3397 if (poll_status & EHC_S1_BER) { 3398 DCMN2ERR(CE_WARN, "eHc_start_pcf8584: I2C bus error"); 3399 return (EHC_FAILURE); 3400 } 3401 3402 if (poll_status & EHC_S1_LAB) { 3403 DCMN2ERR(CE_WARN, "eHc_start_pcf8584: Lost arbitration"); 3404 return (EHC_FAILURE); 3405 } 3406 3407 /* load the slave address */ 3408 ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0, byteaddress); 3409 3410 /* generate the "start condition" and clock out the slave address */ 3411 ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1, 3412 EHC_S1_PIN | EHC_S1_ES0 | EHC_S1_STA | EHC_S1_ACK); 3413 3414 /* wait for completion of transmission */ 3415 i = 0; 3416 do { 3417 drv_usecwait(1000); 3418 poll_status = 3419 ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1); 3420 i++; 3421 } while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT); 3422 3423 if (i == EHC_MAX_WAIT) { 3424 DCMNERR(CE_WARN, "eHc_start_pcf8584: I2C bus busy"); 3425 return (EHC_FAILURE); 3426 } 3427 3428 if (poll_status & EHC_S1_BER) { 3429 DCMN2ERR(CE_WARN, "eHc_start_pcf8584: I2C bus error"); 3430 return (EHC_FAILURE); 3431 } 3432 3433 if (poll_status & EHC_S1_LAB) { 3434 DCMN2ERR(CE_WARN, "eHc_start_pcf8584: Lost arbitration"); 3435 return (EHC_FAILURE); 3436 } 3437 3438 if (poll_status & EHC_S1_LRB) { 3439 DCMNERR(CE_WARN, "eHc_start_pcf8584: No slave ACK"); 3440 return (EHC_NO_SLAVE_ACK); 3441 } 3442 3443 /* 3444 * If this is a read we are setting up for (as indicated by 3445 * the least significant byte being set), read 3446 * and discard the first byte off the bus - this 3447 * is the slave address. 3448 */ 3449 3450 i = 0; 3451 if (byteaddress & EHC_BYTE_READ) { 3452 discard = ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0); 3453 #ifdef lint 3454 discard = discard; 3455 #endif 3456 3457 /* wait for completion of transmission */ 3458 do { 3459 drv_usecwait(1000); 3460 poll_status = 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 3490 eHc_stop_pcf8584(struct eHc_envcunit *ehcp) 3491 { 3492 ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1, 3493 EHC_S1_PIN | EHC_S1_ES0 | EHC_S1_STO | EHC_S1_ACK); 3494 } 3495 3496 static int 3497 eHc_read_pcf8584(struct eHc_envcunit *ehcp, uint8_t *data) 3498 { 3499 uint8_t poll_status; 3500 int i = 0; 3501 3502 /* Read the byte of interest */ 3503 *data = ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0); 3504 3505 /* wait for completion of transmission */ 3506 do { 3507 drv_usecwait(1000); 3508 poll_status = 3509 ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1); 3510 i++; 3511 } while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT); 3512 3513 if (i == EHC_MAX_WAIT) { 3514 DCMNERR(CE_WARN, "eHc_read_pcf8584: I2C bus busy"); 3515 return (EHC_FAILURE); 3516 } 3517 3518 if (poll_status & EHC_S1_BER) { 3519 DCMN2ERR(CE_WARN, "eHc_read_pcf8584: I2C bus error"); 3520 return (EHC_FAILURE); 3521 } 3522 3523 if (poll_status & EHC_S1_LAB) { 3524 DCMN2ERR(CE_WARN, "eHc_read_pcf8584: Lost arbitration"); 3525 return (EHC_FAILURE); 3526 } 3527 3528 return (EHC_SUCCESS); 3529 } 3530 3531 /* 3532 * host interface is in transmitter state, thus mode is master/transmitter 3533 * NOTE to Bill: this check the LRB bit (only done in transmit mode). 3534 */ 3535 3536 static int 3537 eHc_write_pcf8584(struct eHc_envcunit *ehcp, uint8_t data) 3538 { 3539 uint8_t poll_status; 3540 int i = 0; 3541 3542 /* send the data, EHC_S1_PIN should go to "1" immediately */ 3543 ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0, data); 3544 3545 /* wait for completion of transmission */ 3546 do { 3547 drv_usecwait(1000); 3548 poll_status = 3549 ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1); 3550 i++; 3551 } while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT); 3552 3553 if (i == EHC_MAX_WAIT) { 3554 DCMNERR(CE_WARN, "eHc_write_pcf8584: I2C bus busy"); 3555 return (EHC_FAILURE); 3556 } 3557 3558 if (poll_status & EHC_S1_BER) { 3559 DCMN2ERR(CE_WARN, "eHc_write_pcf8584: I2C bus error"); 3560 return (EHC_FAILURE); 3561 } 3562 3563 if (poll_status & EHC_S1_LAB) { 3564 DCMN2ERR(CE_WARN, "eHc_write_pcf8584: Lost arbitration"); 3565 return (EHC_FAILURE); 3566 } 3567 3568 if (poll_status & EHC_S1_LRB) { 3569 DCMNERR(CE_WARN, "eHc_write_pcf8584: No slave ACK"); 3570 return (EHC_NO_SLAVE_ACK); 3571 } 3572 3573 return (EHC_SUCCESS); 3574 } 3575 3576 static int 3577 eHc_after_read_pcf8584(struct eHc_envcunit *ehcp, uint8_t *data) 3578 { 3579 uint8_t discard; 3580 uint8_t poll_status; 3581 int i = 0; 3582 3583 /* set ACK in register S1 to 0 */ 3584 ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1, EHC_S1_ES0); 3585 3586 /* 3587 * Read the "byte-before-the-last-byte" - sets PIN bit to '1' 3588 */ 3589 3590 *data = ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0); 3591 3592 /* wait for completion of transmission */ 3593 do { 3594 drv_usecwait(1000); 3595 poll_status = 3596 ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1); 3597 i++; 3598 } while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT); 3599 3600 if (i == EHC_MAX_WAIT) { 3601 DCMNERR(CE_WARN, "eHc_after_read_pcf8584: I2C bus busy"); 3602 return (EHC_FAILURE); 3603 } 3604 3605 if (poll_status & EHC_S1_BER) { 3606 DCMN2ERR(CE_WARN, 3607 "eHc_after_read_pcf8584: I2C bus error"); 3608 return (EHC_FAILURE); 3609 } 3610 3611 if (poll_status & EHC_S1_LAB) { 3612 DCMN2ERR(CE_WARN, "eHc_after_read_pcf8584: Lost arbitration"); 3613 return (EHC_FAILURE); 3614 } 3615 3616 /* 3617 * Generate the "stop" condition. 3618 */ 3619 eHc_stop_pcf8584(ehcp); 3620 3621 /* 3622 * Read the "last" byte. 3623 */ 3624 discard = ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0); 3625 #ifdef lint 3626 discard = discard; 3627 #endif 3628 3629 return (EHC_SUCCESS); 3630 } 3631 3632 /* 3633 * Write to the TDA8444 chip. 3634 * byteaddress = chip type base address | chip offset address. 3635 */ 3636 static int 3637 eHc_write_tda8444(struct eHc_envcunit *ehcp, int byteaddress, int instruction, 3638 int subaddress, uint8_t *buf, int size) 3639 { 3640 uint8_t control; 3641 int i, status; 3642 3643 ASSERT((byteaddress & 0x1) == 0); 3644 ASSERT(subaddress < 8); 3645 ASSERT(instruction == 0xf || instruction == 0x0); 3646 ASSERT(MUTEX_HELD(&ehcp->umutex)); 3647 3648 control = (instruction << 4) | subaddress; 3649 3650 if ((status = eHc_start_pcf8584(ehcp, byteaddress)) != EHC_SUCCESS) { 3651 if (status == EHC_NO_SLAVE_ACK) { 3652 /* 3653 * Send the "stop" condition. 3654 */ 3655 eHc_stop_pcf8584(ehcp); 3656 } 3657 return (EHC_FAILURE); 3658 } 3659 3660 if ((status = eHc_write_pcf8584(ehcp, control)) != EHC_SUCCESS) { 3661 if (status == EHC_NO_SLAVE_ACK) { 3662 /* 3663 * Send the "stop" condition. 3664 */ 3665 eHc_stop_pcf8584(ehcp); 3666 } 3667 return (EHC_FAILURE); 3668 } 3669 3670 for (i = 0; i < size; i++) { 3671 if ((status = eHc_write_pcf8584(ehcp, (buf[i] & 0x3f))) != 3672 EHC_SUCCESS) { 3673 if (status == EHC_NO_SLAVE_ACK) 3674 eHc_stop_pcf8584(ehcp); 3675 return (EHC_FAILURE); 3676 } 3677 } 3678 3679 eHc_stop_pcf8584(ehcp); 3680 3681 return (EHC_SUCCESS); 3682 } 3683 3684 /* 3685 * Read from PCF8574A chip. 3686 * byteaddress = chip type base address | chip offset address. 3687 */ 3688 static int 3689 eHc_read_pcf8574a(struct eHc_envcunit *ehcp, int byteaddress, uint8_t *buf, 3690 int size) 3691 { 3692 int i; 3693 int status; 3694 uint8_t discard; 3695 3696 ASSERT((byteaddress & 0x1) == 0); 3697 ASSERT(MUTEX_HELD(&ehcp->umutex)); 3698 3699 /* 3700 * Put the bus into the start condition 3701 */ 3702 if ((status = eHc_start_pcf8584(ehcp, EHC_BYTE_READ | byteaddress)) != 3703 EHC_SUCCESS) { 3704 if (status == EHC_NO_SLAVE_ACK) { 3705 /* 3706 * Send the "stop" condition. 3707 */ 3708 eHc_stop_pcf8584(ehcp); 3709 /* 3710 * Read the last byte - discard it. 3711 */ 3712 discard = 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 3744 eHc_write_pcf8574a(struct eHc_envcunit *ehcp, int byteaddress, uint8_t *buf, 3745 int size) 3746 { 3747 int i; 3748 int status; 3749 3750 ASSERT((byteaddress & 0x1) == 0); 3751 ASSERT(MUTEX_HELD(&ehcp->umutex)); 3752 3753 /* 3754 * Put the bus into the start condition (write) 3755 */ 3756 if ((status = eHc_start_pcf8584(ehcp, byteaddress)) != EHC_SUCCESS) { 3757 if (status == EHC_NO_SLAVE_ACK) { 3758 /* 3759 * Send the "stop" condition. 3760 */ 3761 eHc_stop_pcf8584(ehcp); 3762 } 3763 return (EHC_FAILURE); 3764 } 3765 3766 /* 3767 * Send the data - poll as needed. 3768 */ 3769 for (i = 0; i < size; i++) { 3770 if ((status = eHc_write_pcf8584(ehcp, buf[i])) != EHC_SUCCESS) { 3771 if (status == EHC_NO_SLAVE_ACK) 3772 eHc_stop_pcf8584(ehcp); 3773 return (EHC_FAILURE); 3774 } 3775 } 3776 3777 /* 3778 * Transmission complete - generate stop condition and 3779 * put device back into slave receiver mode. 3780 */ 3781 eHc_stop_pcf8584(ehcp); 3782 3783 return (EHC_SUCCESS); 3784 } 3785 3786 /* 3787 * Read from the PCF8574 chip. 3788 * byteaddress = chip type base address | chip offset address. 3789 */ 3790 static int 3791 eHc_read_pcf8574(struct eHc_envcunit *ehcp, int byteaddress, uint8_t *buf, 3792 int size) 3793 { 3794 int i; 3795 int status; 3796 uint8_t discard; 3797 3798 ASSERT((byteaddress & 0x1) == 0); 3799 ASSERT(MUTEX_HELD(&ehcp->umutex)); 3800 3801 /* 3802 * Put the bus into the start condition 3803 */ 3804 if ((status = eHc_start_pcf8584(ehcp, EHC_BYTE_READ | byteaddress)) != 3805 EHC_SUCCESS) { 3806 if (status == EHC_NO_SLAVE_ACK) { 3807 /* 3808 * Send the "stop" condition. 3809 */ 3810 eHc_stop_pcf8584(ehcp); 3811 /* 3812 * Read the last byte - discard it. 3813 */ 3814 discard = 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 3846 eHc_write_pcf8574(struct eHc_envcunit *ehcp, int byteaddress, uint8_t *buf, 3847 int size) 3848 { 3849 int i; 3850 int status; 3851 3852 ASSERT((byteaddress & 0x1) == 0); 3853 ASSERT(MUTEX_HELD(&ehcp->umutex)); 3854 3855 /* 3856 * Put the bus into the start condition (write) 3857 */ 3858 if ((status = eHc_start_pcf8584(ehcp, byteaddress)) != EHC_SUCCESS) { 3859 if (status == EHC_NO_SLAVE_ACK) { 3860 /* 3861 * Send the "stop" condition. 3862 */ 3863 eHc_stop_pcf8584(ehcp); 3864 } 3865 return (EHC_FAILURE); 3866 } 3867 3868 /* 3869 * Send the data - poll as needed. 3870 */ 3871 for (i = 0; i < size; i++) { 3872 if ((status = eHc_write_pcf8584(ehcp, buf[i])) != EHC_SUCCESS) { 3873 if (status == EHC_NO_SLAVE_ACK) 3874 eHc_stop_pcf8584(ehcp); 3875 return (EHC_FAILURE); 3876 } 3877 } 3878 /* 3879 * Transmission complete - generate stop condition and 3880 * put device back into slave receiver mode. 3881 */ 3882 eHc_stop_pcf8584(ehcp); 3883 3884 return (EHC_SUCCESS); 3885 } 3886 3887 /* 3888 * Read from the LM75 3889 * byteaddress = chip type base address | chip offset address. 3890 */ 3891 static int 3892 eHc_read_lm75(struct eHc_envcunit *ehcp, int byteaddress, uint8_t *buf, 3893 int size) 3894 { 3895 int i; 3896 int status; 3897 uint8_t discard; 3898 3899 ASSERT((byteaddress & 0x1) == 0); 3900 ASSERT(MUTEX_HELD(&ehcp->umutex)); 3901 3902 /* 3903 * Put the bus into the start condition 3904 */ 3905 if ((status = eHc_start_pcf8584(ehcp, EHC_BYTE_READ | byteaddress)) != 3906 EHC_SUCCESS) { 3907 if (status == EHC_NO_SLAVE_ACK) { 3908 /* 3909 * Send the stop condition. 3910 */ 3911 eHc_stop_pcf8584(ehcp); 3912 /* 3913 * Read the last byte - discard it. 3914 */ 3915 discard = 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 3946 eHc_write_pcf8583(struct eHc_envcunit *ehcp, int byteaddress, uint8_t *buf, 3947 int size) 3948 { 3949 int i; 3950 int status; 3951 3952 ASSERT((byteaddress & 0x1) == 0); 3953 ASSERT(MUTEX_HELD(&ehcp->umutex)); 3954 3955 if ((status = eHc_start_pcf8584(ehcp, byteaddress)) != EHC_SUCCESS) { 3956 if (status == EHC_NO_SLAVE_ACK) { 3957 /* 3958 * Send the "stop" condition. 3959 */ 3960 eHc_stop_pcf8584(ehcp); 3961 } 3962 return (EHC_FAILURE); 3963 } 3964 3965 /* 3966 * Send the data - poll as needed. 3967 */ 3968 for (i = 0; i < size; i++) { 3969 if ((status = eHc_write_pcf8584(ehcp, buf[i])) != EHC_SUCCESS) { 3970 if (status == EHC_NO_SLAVE_ACK) 3971 eHc_stop_pcf8584(ehcp); 3972 return (EHC_FAILURE); 3973 } 3974 } 3975 3976 /* 3977 * Transmission complete - generate stop condition and 3978 * put device back into slave receiver mode. 3979 */ 3980 eHc_stop_pcf8584(ehcp); 3981 3982 return (EHC_SUCCESS); 3983 } 3984 3985 /* 3986 * Read from the PCF8581 chip. 3987 * byteaddress = chip type base address | chip offset address. 3988 */ 3989 static int 3990 eHc_read_pcf8591(struct eHc_envcunit *ehcp, int byteaddress, int channel, 3991 int autoinc, int amode, int aenable, uint8_t *buf, int size) 3992 { 3993 int i; 3994 int status; 3995 uint8_t control; 3996 uint8_t discard; 3997 3998 ASSERT((byteaddress & 0x1) == 0); 3999 ASSERT(channel < 4); 4000 ASSERT(amode < 4); 4001 ASSERT(MUTEX_HELD(&ehcp->umutex)); 4002 4003 /* 4004 * Write the control word to the PCF8591. 4005 * Follow the control word with a repeated START byte 4006 * rather than a STOP so that reads can follow without giving 4007 * up the bus. 4008 */ 4009 4010 control = ((aenable << 6) | (amode << 4) | (autoinc << 2) | channel); 4011 4012 if ((status = eHc_start_pcf8584(ehcp, byteaddress)) != EHC_SUCCESS) { 4013 if (status == EHC_NO_SLAVE_ACK) { 4014 eHc_stop_pcf8584(ehcp); 4015 } 4016 return (EHC_FAILURE); 4017 } 4018 4019 if ((status = eHc_write_pcf8584(ehcp, control)) != EHC_SUCCESS) { 4020 if (status == EHC_NO_SLAVE_ACK) 4021 eHc_stop_pcf8584(ehcp); 4022 return (EHC_FAILURE); 4023 } 4024 4025 /* 4026 * The following two operations, 0x45 to S1, and the byteaddress 4027 * to S0, will result in a repeated START being sent out on the bus. 4028 * Refer to Fig.8 of Philips Semiconductors PCF8584 product spec. 4029 */ 4030 4031 ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1, 4032 EHC_S1_ES0 | EHC_S1_STA | EHC_S1_ACK); 4033 4034 ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0, 4035 EHC_BYTE_READ | byteaddress); 4036 4037 i = 0; 4038 4039 do { 4040 drv_usecwait(1000); 4041 status = 4042 ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1); 4043 i++; 4044 } while ((status & EHC_S1_PIN) && i < EHC_MAX_WAIT); 4045 4046 if (i == EHC_MAX_WAIT) { 4047 DCMNERR(CE_WARN, "eHc_read_pcf8591(): read of S1 failed"); 4048 return (EHC_FAILURE); 4049 } 4050 4051 if (status & EHC_S1_LRB) { 4052 DCMNERR(CE_WARN, "eHc_read_pcf8591(): No slave ACK"); 4053 /* 4054 * Send the stop condition. 4055 */ 4056 eHc_stop_pcf8584(ehcp); 4057 /* 4058 * Read the last byte - discard it. 4059 */ 4060 discard = ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0); 4061 #ifdef lint 4062 discard = discard; 4063 #endif 4064 return (EHC_FAILURE); 4065 } 4066 4067 if (status & EHC_S1_BER) { 4068 DCMN2ERR(CE_WARN, "eHc_read_pcf8591(): Bus error"); 4069 return (EHC_FAILURE); 4070 } 4071 4072 if (status & EHC_S1_LAB) { 4073 DCMN2ERR(CE_WARN, "eHc_read_pcf8591(): Lost Arbitration"); 4074 return (EHC_FAILURE); 4075 } 4076 4077 /* 4078 * Discard first read as per PCF8584 master receiver protocol. 4079 * This is normally done in the eHc_start_pcf8584() routine. 4080 */ 4081 if ((status = eHc_read_pcf8584(ehcp, &discard)) != EHC_SUCCESS) { 4082 return (EHC_FAILURE); 4083 } 4084 4085 /* Discard second read as per PCF8591 protocol */ 4086 if ((status = eHc_read_pcf8584(ehcp, &discard)) != EHC_SUCCESS) { 4087 return (EHC_FAILURE); 4088 } 4089 4090 for (i = 0; i < size - 1; i++) { 4091 if ((status = eHc_read_pcf8584(ehcp, &buf[i])) != EHC_SUCCESS) { 4092 return (EHC_FAILURE); 4093 } 4094 } 4095 4096 if (eHc_after_read_pcf8584(ehcp, &buf[i]) != EHC_SUCCESS) { 4097 return (EHC_FAILURE); 4098 } 4099 4100 return (EHC_SUCCESS); 4101 } 4102