envctrl.c revision 1341:6d7c4f090a72
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29/* 30 * ENVCTRL_ Environment Monitoring driver for i2c 31 * 32 */ 33#include <sys/param.h> 34#include <sys/types.h> 35#include <sys/signal.h> 36#include <sys/errno.h> 37#include <sys/file.h> 38#include <sys/termio.h> 39#include <sys/termios.h> 40#include <sys/cmn_err.h> 41#include <sys/stream.h> 42#include <sys/strsun.h> 43#include <sys/stropts.h> 44#include <sys/strtty.h> 45#include <sys/debug.h> 46#include <sys/eucioctl.h> 47#include <sys/cred.h> 48#include <sys/uio.h> 49#include <sys/stat.h> 50#include <sys/kmem.h> 51 52#include <sys/ddi.h> 53#include <sys/sunddi.h> 54#include <sys/obpdefs.h> 55#include <sys/conf.h> /* req. by dev_ops flags MTSAFE etc. */ 56#include <sys/modctl.h> /* for modldrv */ 57#include <sys/stat.h> /* ddi_create_minor_node S_IFCHR */ 58#include <sys/open.h> /* for open params. */ 59#include <sys/uio.h> /* for read/write */ 60#include <sys/envctrl.h> /* Environment header */ 61 62/* driver entry point fn definitions */ 63static int envctrl_open(queue_t *, dev_t *, int, int, cred_t *); 64static int envctrl_close(queue_t *, int, cred_t *); 65static uint_t envctrl_bus_isr(caddr_t); 66static uint_t envctrl_dev_isr(caddr_t); 67 68/* configuration entry point fn definitions */ 69static int envctrl_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 70static int envctrl_attach(dev_info_t *, ddi_attach_cmd_t); 71static int envctrl_detach(dev_info_t *, ddi_detach_cmd_t); 72 73/* Driver private routines */ 74static void envctrl_init_bus(struct envctrlunit *); 75static int envctrl_xmit(struct envctrlunit *, caddr_t *, int); 76static void envctrl_recv(struct envctrlunit *, caddr_t *, int); 77static void envctrl_get_sys_temperatures(struct envctrlunit *, uint8_t *); 78static int envctrl_get_lm75_temp(struct envctrlunit *); 79static int envctrl_get_ps_temp(struct envctrlunit *, uint8_t); 80static int envctrl_get_cpu_temp(struct envctrlunit *, int); 81static void envctrl_fan_fail_service(struct envctrlunit *); 82static void envctrl_PS_intr_service(struct envctrlunit *, uint8_t); 83static void envctrl_ps_probe(struct envctrlunit *); 84static void envctrl_tempr_poll(void *); 85static void envctrl_pshotplug_poll(void *); 86static void envctrl_led_blink(void *); 87static void envctrl_reset_dflop(struct envctrlunit *); 88static void envctrl_enable_devintrs(struct envctrlunit *); 89static void envctrl_stop_clock(struct envctrlunit *); 90static void envctrl_reset_watchdog(struct envctrlunit *, uint8_t *); 91static void envctrl_abort_seq_handler(char *msg); 92static uint8_t envctrl_get_fpm_status(struct envctrlunit *); 93static void envctrl_set_fsp(struct envctrlunit *, uint8_t *); 94static int envctrl_set_dskled(struct envctrlunit *, 95 struct envctrl_pcf8574_chip *); 96static int envctrl_get_dskled(struct envctrlunit *, 97 struct envctrl_pcf8574_chip *); 98static void envctrl_probe_cpus(struct envctrlunit *); 99static int envctrl_match_cpu(dev_info_t *, void *); 100static int envctrl_isother_fault_led(struct envctrlunit *, 101 uint8_t, uint8_t); 102 103/* Kstat routines */ 104static void envctrl_add_kstats(struct envctrlunit *); 105static int envctrl_ps_kstat_update(kstat_t *, int); 106static int envctrl_fanstat_kstat_update(kstat_t *, int); 107static int envctrl_encl_kstat_update(kstat_t *, int); 108static void envctrl_init_fan_kstats(struct envctrlunit *); 109static void envctrl_init_encl_kstats(struct envctrlunit *); 110static void envctrl_add_encl_kstats(struct envctrlunit *, int, int, 111 uint8_t); 112static void envctrl_mod_encl_kstats(struct envctrlunit *, int, int, 113 uint8_t); 114 115 116/* Streams Routines */ 117static int envctrl_wput(queue_t *, mblk_t *); 118 119/* External routines */ 120extern void power_down(const char *); 121extern int prom_getprop(); 122extern int prom_getproplen(); 123extern void prom_printf(const char *fmt, ...); 124extern void (*abort_seq_handler)(); 125 126static void *envctrlsoft_statep; 127 128/* Local Variables */ 129/* Indicates whether or not the overtemp thread has been started */ 130static int envctrl_debug_flags = 0; 131static int envctrl_afb_present = 0; 132static int envctrl_power_off_overide = 0; 133static int envctrl_max_retries = 100; 134static int envctrl_allow_detach = 0; 135static int envctrl_numcpus = 1; 136static int envctrl_p0_enclosure = 0; /* set to 1 if it is a P0 */ 137static int envctrl_handler = 1; /* 1 is the default */ 138static clock_t overtemp_timeout_hz; 139static clock_t blink_timeout_hz; 140static clock_t pshotplug_timeout_hz; 141static int controller_present[] = {-1, -1, -1}; 142#ifdef MULTIFAN 143static int envctrl_fan_debug = 0; 144#endif 145static int eHc_debug = 0; 146static int power_supply_previous_state[] = {-1, -1, -1}; 147 148extern void pci_thermal_rem_intr(dev_info_t *, uint_t); 149 150#define LOOP_TIMEOUT 25 151#define INIT_FAN_VAL 35 152#define DCMNERR if (eHc_debug & 0x1) cmn_err 153#define DCMN2ERR if (eHc_debug & 0x2) cmn_err 154#define MAX_FAN_FAIL_RETRY 3 155 156uint8_t backaddrs[] = {ENVCTRL_PCF8574_DEV0, ENVCTRL_PCF8574_DEV1, 157 ENVCTRL_PCF8574_DEV2}; 158 159struct module_info envctrlinfo = { 160 /* id, name, min pkt siz, max pkt siz, hi water, low water */ 161 42, "envctrl", 0, 2048, (1024 * 20), (1024 * 1) 162}; 163 164static struct qinit envctrl_rinit = { 165 putq, NULL, envctrl_open, envctrl_close, NULL, &envctrlinfo, NULL 166}; 167 168static struct qinit envctrl_wint = { 169 envctrl_wput, NULL, envctrl_open, envctrl_close, 170 NULL, &envctrlinfo, NULL 171}; 172 173struct streamtab envctrl_str_info = { 174 &envctrl_rinit, &envctrl_wint, NULL, NULL 175}; 176 177static struct cb_ops envctrl_cb_ops = { 178 nodev, /* cb_open */ 179 nodev, /* cb_close */ 180 nodev, /* cb_strategy */ 181 nodev, /* cb_print */ 182 nodev, /* cb_dump */ 183 nodev, /* cb_read */ 184 nodev, /* cb_write */ 185 nodev, /* cb_ioctl */ 186 nodev, /* cb_devmap */ 187 nodev, /* cb_mmap */ 188 nodev, /* cb_segmap */ 189 nochpoll, /* cb_chpoll */ 190 ddi_prop_op, /* cb_prop_op */ 191 &envctrl_str_info, /* cb_stream */ 192 D_MP /* cb_flag */ 193}; 194 195/* 196 * Declare ops vectors for auto configuration. 197 */ 198struct dev_ops envctrl_ops = { 199 DEVO_REV, /* devo_rev */ 200 0, /* devo_refcnt */ 201 envctrl_getinfo, /* devo_getinfo */ 202 nulldev, /* devo_identify */ 203 nulldev, /* devo_probe */ 204 envctrl_attach, /* devo_attach */ 205 envctrl_detach, /* devo_detach */ 206 nodev, /* devo_reset */ 207 &envctrl_cb_ops, /* devo_cb_ops */ 208 (struct bus_ops *)NULL, /* devo_bus_ops */ 209 nulldev /* devo_power */ 210}; 211 212extern struct mod_ops mod_driverops; 213 214static struct modldrv envctrlmodldrv = { 215 &mod_driverops, /* type of module - driver */ 216 "I2C ENVCTRL_driver: %I% %E%", 217 &envctrl_ops, 218}; 219 220static 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 343struct 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 349struct 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 360static int eHc_write_tda8444(struct eHc_envcunit *, int, int, int, uint8_t *, 361 int); 362static int eHc_read_pcf8591(struct eHc_envcunit *, int, int, int, int, int, 363 uint8_t *, int); 364static int eHc_read_pcf8574a(struct eHc_envcunit *, int, uint8_t *, int); 365static int eHc_write_pcf8574a(struct eHc_envcunit *, int, uint8_t *, int); 366static int eHc_read_pcf8574(struct eHc_envcunit *, int, uint8_t *, int); 367static int eHc_write_pcf8574(struct eHc_envcunit *, int, uint8_t *, int); 368static int eHc_read_lm75(struct eHc_envcunit *, int, uint8_t *, int); 369static int eHc_write_pcf8583(struct eHc_envcunit *, int, uint8_t *, int); 370 371static int eHc_start_pcf8584(struct eHc_envcunit *, uint8_t); 372static void eHc_stop_pcf8584(struct eHc_envcunit *); 373static int eHc_read_pcf8584(struct eHc_envcunit *, uint8_t *); 374static int eHc_write_pcf8584(struct eHc_envcunit *, uint8_t); 375static int eHc_after_read_pcf8584(struct eHc_envcunit *, uint8_t *); 376 377/* 378 * End of i2c protocol definitions section 379 */ 380 381int 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 394int 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 405int 406_info(struct modinfo *modinfop) 407{ 408 return (mod_info(&envctrlmodlinkage, modinfop)); 409} 410 411static int 412envctrl_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 413{ 414 int instance; 415 char name[16]; 416 uint8_t fspval; 417 struct envctrlunit *unitp; 418 struct ddi_device_acc_attr attr; 419 int *reg_prop; 420 uchar_t *creg_prop; 421 uint_t len, tblsz; 422 int i, cputemp, status; 423 uint8_t buf[3]; 424 425 status = len = tblsz = 0; 426 427 attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 428 attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 429 430 attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; 431 432 instance = ddi_get_instance(dip); 433 434 switch (cmd) { 435 case DDI_ATTACH: 436 break; 437 case DDI_RESUME: 438 if (!(unitp = ddi_get_soft_state(envctrlsoft_statep, instance))) 439 return (DDI_FAILURE); 440 mutex_enter(&unitp->umutex); 441 if (!unitp->suspended) { 442 mutex_exit(&unitp->umutex); 443 return (DDI_FAILURE); 444 } 445 unitp->suspended = 0; 446 mutex_exit(&unitp->umutex); 447 unitp->initting = B_TRUE; 448 envctrl_init_bus(unitp); 449 unitp->initting = B_FALSE; 450 451 mutex_enter(&unitp->umutex); 452 envctrl_ps_probe(unitp); 453 envctrl_probe_cpus(unitp); 454 mutex_exit(&unitp->umutex); 455 456 return (DDI_SUCCESS); 457 458 default: 459 return (DDI_FAILURE); 460 } 461 462 /* Set up timer values */ 463 overtemp_timeout_hz = drv_usectohz(OVERTEMP_TIMEOUT_USEC); 464 blink_timeout_hz = drv_usectohz(BLINK_TIMEOUT_USEC); 465 pshotplug_timeout_hz = drv_usectohz(BLINK_TIMEOUT_USEC * 6); 466 467 if (ddi_soft_state_zalloc(envctrlsoft_statep, instance) != 0) { 468 cmn_err(CE_WARN, "envctrl failed to zalloc softstate\n"); 469 goto failed; 470 } 471 472 unitp = ddi_get_soft_state(envctrlsoft_statep, instance); 473 474 if (ddi_regs_map_setup(dip, 0, (caddr_t *)&unitp->bus_ctl_regs, 0, 475 sizeof (struct envctrl_pcd8584_regs), &attr, 476 &unitp->ctlr_handle) != DDI_SUCCESS) { 477 cmn_err(CE_WARN, "I2c failed to map in bus_control regs\n"); 478 return (DDI_FAILURE); 479 } 480 481 /* 482 * If the PCI nexus has added a thermal interrupt, we first need 483 * to remove that interrupt handler. 484 * 485 * WARNING: Removing another driver's interrupt handler is not 486 * allowed. The pci_thermal_rem_intr() call below is needed to retain 487 * the legacy behavior on Tazmo systems. 488 */ 489 490 pci_thermal_rem_intr(dip, (uint_t)0); 491 492 /* add interrupts */ 493 494 if (ddi_get_iblock_cookie(dip, 1, 495 &unitp->ic_trap_cookie) != DDI_SUCCESS) { 496 cmn_err(CE_WARN, "ddi_get_iblock_cookie FAILED \n"); 497 goto failed; 498 } 499 500 mutex_init(&unitp->umutex, NULL, MUTEX_DRIVER, 501 (void *)unitp->ic_trap_cookie); 502 503 504 if (ddi_add_intr(dip, 0, &unitp->ic_trap_cookie, NULL, envctrl_bus_isr, 505 (caddr_t)unitp) != DDI_SUCCESS) { 506 cmn_err(CE_WARN, "envctrl_attach failed to add hard intr %d\n", 507 instance); 508 goto remlock; 509 } 510 511 512 if (ddi_add_intr(dip, 1, &unitp->ic_trap_cookie, NULL, envctrl_dev_isr, 513 (caddr_t)unitp) != DDI_SUCCESS) { 514 cmn_err(CE_WARN, "envctrl_attach failed to add hard intr %d\n", 515 instance); 516 goto remhardintr; 517 } 518 519 520 (void) sprintf(name, "envctrl%d", instance); 521 522 if (ddi_create_minor_node(dip, name, S_IFCHR, instance, DDI_PSEUDO, 523 NULL) == DDI_FAILURE) { 524 ddi_remove_minor_node(dip, NULL); 525 goto remhardintr1; 526 } 527 528 mutex_enter(&unitp->umutex); 529 switch (ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 530 ENVCTRL_LED_BLINK, -1)) { 531 case 1: 532 unitp->activity_led_blink = B_TRUE; 533 break; 534 case 0: 535 default: 536 unitp->activity_led_blink = B_FALSE; 537 break; 538 } 539 unitp->shutdown = B_FALSE; 540 unitp->num_ps_present = unitp->num_encl_present = 0; 541 unitp->num_fans_present = MIN_FAN_BANKS; 542 unitp->num_fans_failed = ENVCTRL_CHAR_ZERO; 543 unitp->AFB_present = B_TRUE; 544 unitp->dip = dip; 545 546#ifdef DEBUG 547 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 548 DDI_PROP_DONTPASS, ENVCTRL_PANEL_LEDS_PR, 549 ®_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 728remhardintr1: 729 ddi_remove_intr(dip, (uint_t)1, unitp->ic_trap_cookie); 730remhardintr: 731 ddi_remove_intr(dip, (uint_t)0, unitp->ic_trap_cookie); 732 733remlock: 734 mutex_destroy(&unitp->umutex); 735 736failed: 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 746static int 747envctrl_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 */ 814int 815envctrl_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 */ 848static int 849envctrl_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 */ 894static int 895envctrl_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 */ 917static int 918envctrl_wput(queue_t *q, mblk_t *mp) 919{ 920 struct msgb *mp1; 921 struct envctrlunit *unitp; 922 struct iocblk *iocp; 923 struct copyresp *csp; 924 struct envctrl_tda8444t_chip *fanspeed; 925 struct envctrl_pcf8574_chip *ledchip; 926 struct envctrl_pcf8591_chip *temp, *a_fanspeed; 927 struct copyreq *cqp; 928 int cmd; 929 930 unitp = (struct envctrlunit *)q->q_ptr; 931 932 switch (DB_TYPE(mp)) { 933 934 case M_DATA: 935 936 while (mp) { 937 DB_TYPE(mp) = M_DATA; 938 mp1 = unlinkb(mp); 939 mp->b_cont = NULL; 940 if ((mp->b_wptr - mp->b_rptr) <= 0) { 941 freemsg(mp); 942 } else { 943 (void) putq(q, mp); 944 } 945 mp = mp1; 946 } 947 948 break; 949 950 case M_IOCTL: 951 { 952 iocp = (struct iocblk *)(void *)mp->b_rptr; 953 cmd = iocp->ioc_cmd; 954 955 switch (cmd) { 956 case ENVCTRL_IOC_SETMODE: 957 case ENVCTRL_IOC_GETMODE: 958 if (iocp->ioc_count == TRANSPARENT) { 959 mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr, 960 sizeof (uchar_t), NULL); 961 qreply(q, mp); 962 } else { 963 miocnak(q, mp, 0, EINVAL); 964 } 965 break; 966 case ENVCTRL_IOC_RESETTMPR: 967 /* 968 * For diags, cancel the current temp poll 969 * and reset it for a new one. 970 */ 971 if (unitp->current_mode == ENVCTRL_DIAG_MODE) { 972 if (unitp->timeout_id != 0) { 973 (void) untimeout(unitp->timeout_id); 974 unitp->timeout_id = 0; 975 } 976 envctrl_tempr_poll((void *)unitp); 977 miocack(q, mp, 0, 0); 978 } else { 979 miocnak(q, mp, 0, EINVAL); 980 } 981 break; 982 case ENVCTRL_IOC_GETTEMP: 983 if (iocp->ioc_count == TRANSPARENT) { 984 mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr, 985 sizeof (struct envctrl_pcf8591_chip), NULL); 986 qreply(q, mp); 987 } else { 988 miocnak(q, mp, 0, EINVAL); 989 } 990 break; 991 case ENVCTRL_IOC_SETTEMP: 992 if (unitp->current_mode == ENVCTRL_DIAG_MODE && 993 iocp->ioc_count == TRANSPARENT) { 994 mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr, 995 sizeof (uint8_t), NULL); 996 qreply(q, mp); 997 } else { 998 miocnak(q, mp, 0, EINVAL); 999 } 1000 break; 1001 case ENVCTRL_IOC_SETWDT: 1002 if (unitp->current_mode == ENVCTRL_DIAG_MODE && 1003 iocp->ioc_count == TRANSPARENT) { 1004 mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr, 1005 sizeof (uint8_t), NULL); 1006 qreply(q, mp); 1007 } else { 1008 miocnak(q, mp, 0, EINVAL); 1009 } 1010 break; 1011 case ENVCTRL_IOC_SETFAN: 1012 /* 1013 * we must be in diag mode before we can 1014 * set any fan speeds. 1015 */ 1016 if (unitp->current_mode == ENVCTRL_DIAG_MODE && 1017 iocp->ioc_count == TRANSPARENT) { 1018 mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr, 1019 sizeof (struct envctrl_tda8444t_chip), 1020 NULL); 1021 qreply(q, mp); 1022 } else { 1023 miocnak(q, mp, 0, EINVAL); 1024 } 1025 break; 1026 case ENVCTRL_IOC_GETFAN: 1027 if (iocp->ioc_count == TRANSPARENT) { 1028 mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr, 1029 sizeof (struct envctrl_pcf8591_chip), NULL); 1030 qreply(q, mp); 1031 } else { 1032 miocnak(q, mp, 0, EINVAL); 1033 } 1034 break; 1035 case ENVCTRL_IOC_SETFSP: 1036 if (iocp->ioc_count == TRANSPARENT) { 1037 mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr, 1038 sizeof (uint8_t), NULL); 1039 qreply(q, mp); 1040 } else { 1041 miocnak(q, mp, 0, EINVAL); 1042 } 1043 break; 1044 case ENVCTRL_IOC_SETDSKLED: 1045 case ENVCTRL_IOC_GETDSKLED: 1046 if (iocp->ioc_count == TRANSPARENT) { 1047 mcopyin(mp, *(caddr_t *)mp->b_cont->b_rptr, 1048 sizeof (struct envctrl_pcf8574_chip), NULL); 1049 qreply(q, mp); 1050 } else { 1051 miocnak(q, mp, 0, EINVAL); 1052 } 1053 break; 1054 default: 1055 miocnak(q, mp, 0, EINVAL); 1056 break; 1057 } 1058 1059 break; 1060 1061 } 1062 case M_IOCDATA: 1063 { 1064 uint8_t *tempr, *wdval; 1065 long state; 1066 1067 csp = (struct copyresp *)(void *)mp->b_rptr; 1068 1069 /* 1070 * If copy request failed, quit now 1071 */ 1072 if (csp->cp_rval != 0) { 1073 miocnak(q, mp, 0, EINVAL); 1074 return (0); 1075 } 1076 1077 cqp = (struct copyreq *)(void *)mp->b_rptr; 1078 1079 cmd = csp->cp_cmd; 1080 state = (long)cqp->cq_private; 1081 1082 switch (cmd) { 1083 case ENVCTRL_IOC_SETFAN: 1084 fanspeed = (struct envctrl_tda8444t_chip *) 1085 (void *)mp->b_cont->b_rptr; 1086 mutex_enter(&unitp->umutex); 1087 if (envctrl_xmit(unitp, (caddr_t *)(void *)fanspeed, 1088 fanspeed->type) == DDI_FAILURE) { 1089 /* 1090 * Fix for a ADF bug 1091 * move mutex to after fan fail call 1092 * bugid 4016121 1093 */ 1094 envctrl_fan_fail_service(unitp); 1095 mutex_exit(&unitp->umutex); 1096 miocnak(q, mp, 0, EINVAL); 1097 } else { 1098 mutex_exit(&unitp->umutex); 1099 miocack(q, mp, 0, 0); 1100 } 1101 break; 1102 case ENVCTRL_IOC_SETFSP: 1103 wdval = (uint8_t *)(void *)mp->b_cont->b_rptr; 1104 mutex_enter(&unitp->umutex); 1105 /* 1106 * If a user is in normal mode and they try 1107 * to set anything other than a disk fault or 1108 * a gen fault it is an invalid operation. 1109 * in diag mode we allow everything to be 1110 * twiddled. 1111 */ 1112 if (unitp->current_mode == ENVCTRL_NORMAL_MODE) { 1113 if (*wdval & ~ENVCTRL_FSP_USRMASK) { 1114 mutex_exit(&unitp->umutex); 1115 miocnak(q, mp, 0, EINVAL); 1116 break; 1117 } 1118 } 1119 envctrl_set_fsp(unitp, wdval); 1120 mutex_exit(&unitp->umutex); 1121 miocack(q, mp, 0, 0); 1122 break; 1123 case ENVCTRL_IOC_SETDSKLED: 1124 ledchip = (struct envctrl_pcf8574_chip *) 1125 (void *)mp->b_cont->b_rptr; 1126 mutex_enter(&unitp->umutex); 1127 if (envctrl_set_dskled(unitp, ledchip)) { 1128 miocnak(q, mp, 0, EINVAL); 1129 } else { 1130 miocack(q, mp, 0, 0); 1131 } 1132 mutex_exit(&unitp->umutex); 1133 break; 1134 case ENVCTRL_IOC_GETDSKLED: 1135 if (state == -1) { 1136 miocack(q, mp, 0, 0); 1137 break; 1138 } 1139 ledchip = (struct envctrl_pcf8574_chip *) 1140 (void *)mp->b_cont->b_rptr; 1141 mutex_enter(&unitp->umutex); 1142 if (envctrl_get_dskled(unitp, ledchip)) { 1143 miocnak(q, mp, 0, EINVAL); 1144 } else { 1145 mcopyout(mp, (void *)-1, 1146 sizeof (struct envctrl_pcf8574_chip), 1147 csp->cp_private, NULL); 1148 qreply(q, mp); 1149 } 1150 mutex_exit(&unitp->umutex); 1151 break; 1152 case ENVCTRL_IOC_GETTEMP: 1153 /* Get the user buffer address */ 1154 1155 if (state == -1) { 1156 miocack(q, mp, 0, 0); 1157 break; 1158 } 1159 temp = (struct envctrl_pcf8591_chip *) 1160 (void *)mp->b_cont->b_rptr; 1161 mutex_enter(&unitp->umutex); 1162 envctrl_recv(unitp, (caddr_t *)(void *)temp, PCF8591); 1163 mutex_exit(&unitp->umutex); 1164 mcopyout(mp, (void *)-1, 1165 sizeof (struct envctrl_pcf8591_chip), 1166 csp->cp_private, NULL); 1167 qreply(q, mp); 1168 break; 1169 case ENVCTRL_IOC_GETFAN: 1170 /* Get the user buffer address */ 1171 1172 if (state == -1) { 1173 miocack(q, mp, 0, 0); 1174 break; 1175 } 1176 a_fanspeed = (struct envctrl_pcf8591_chip *) 1177 (void *)mp->b_cont->b_rptr; 1178 mutex_enter(&unitp->umutex); 1179 envctrl_recv(unitp, (caddr_t *)(void *)a_fanspeed, 1180 PCF8591); 1181 mutex_exit(&unitp->umutex); 1182 mcopyout(mp, (void *)-1, 1183 sizeof (struct envctrl_pcf8591_chip), 1184 csp->cp_private, NULL); 1185 qreply(q, mp); 1186 break; 1187 case ENVCTRL_IOC_SETTEMP: 1188 tempr = (uint8_t *)(void *)mp->b_cont->b_rptr; 1189 if (*tempr > MAX_DIAG_TEMPR) { 1190 miocnak(q, mp, 0, EINVAL); 1191 } else { 1192 mutex_enter(&unitp->umutex); 1193 envctrl_get_sys_temperatures(unitp, tempr); 1194 mutex_exit(&unitp->umutex); 1195 miocack(q, mp, 0, 0); 1196 } 1197 break; 1198 case ENVCTRL_IOC_SETWDT: 1199 /* reset watchdog timeout period */ 1200 wdval = (uint8_t *)(void *)mp->b_cont->b_rptr; 1201 if (*wdval > MAX_CL_VAL) { 1202 miocnak(q, mp, 0, EINVAL); 1203 } else { 1204 mutex_enter(&unitp->umutex); 1205 envctrl_reset_watchdog(unitp, wdval); 1206 mutex_exit(&unitp->umutex); 1207 miocack(q, mp, 0, 0); 1208 } 1209 break; 1210 case ENVCTRL_IOC_GETMODE: 1211 /* Get the user buffer address */ 1212 1213 if (state == -1) { 1214 miocack(q, mp, 0, 0); 1215 break; 1216 } 1217 tempr = (uchar_t *)(void *)mp->b_cont->b_rptr; 1218 *tempr = unitp->current_mode; 1219 mcopyout(mp, (void *)-1, sizeof (uchar_t), 1220 csp->cp_private, NULL); 1221 qreply(q, mp); 1222 break; 1223 case ENVCTRL_IOC_SETMODE: 1224 /* Set mode */ 1225 wdval = (uint8_t *)(void *)mp->b_cont->b_rptr; 1226 if (*wdval == ENVCTRL_DIAG_MODE || *wdval == 1227 ENVCTRL_NORMAL_MODE) { 1228 mutex_enter(&unitp->umutex); 1229 unitp->current_mode = *wdval; 1230 if (unitp->timeout_id != 0 && 1231 *wdval == ENVCTRL_DIAG_MODE) { 1232 (void) untimeout(unitp->timeout_id); 1233 unitp->timeout_id = 1234 (timeout(envctrl_tempr_poll, 1235 (caddr_t)unitp, overtemp_timeout_hz)); 1236 1237 } 1238 if (*wdval == ENVCTRL_NORMAL_MODE) { 1239 envctrl_get_sys_temperatures(unitp, 1240 (uint8_t *)NULL); 1241 /* 1242 * going to normal mode we 1243 * need to go to diag mode 1244 * just in case we have 1245 * injected a fan fault. It 1246 * may not be cleared and if 1247 * we call fan_failsrvc it will 1248 * power off the ystem if we are 1249 * in NORMAL_MODE. Also we need 1250 * to delay 1 bit of time here 1251 * to allow the fans to rotate 1252 * back up and clear the intr 1253 * after we get the sys temps. 1254 */ 1255 unitp->current_mode = 1256 ENVCTRL_DIAG_MODE; 1257 envctrl_fan_fail_service(unitp); 1258 unitp->current_mode = 1259 ENVCTRL_NORMAL_MODE; 1260 } 1261 mutex_exit(&unitp->umutex); 1262 miocack(q, mp, 0, 0); 1263 } else { 1264 miocnak(q, mp, 0, EINVAL); 1265 } 1266 break; 1267 default: 1268 freemsg(mp); 1269 break; 1270 } 1271 1272 break; 1273 } 1274 1275 case M_FLUSH: 1276 if (*mp->b_rptr & FLUSHR) { 1277 *mp->b_rptr &= ~FLUSHW; 1278 qreply(q, mp); 1279 } else { 1280 freemsg(mp); 1281 } 1282 break; 1283 1284 default: 1285 freemsg(mp); 1286 break; 1287 } 1288 1289 return (0); 1290} 1291 1292uint_t 1293envctrl_bus_isr(caddr_t arg) 1294{ 1295 struct envctrlunit *unitp = (struct envctrlunit *)(void *)arg; 1296 int ic = DDI_INTR_UNCLAIMED; 1297 1298 mutex_enter(&unitp->umutex); 1299 1300 /* 1301 * NOT USED 1302 */ 1303 1304 mutex_exit(&unitp->umutex); 1305 return (ic); 1306} 1307 1308uint_t 1309envctrl_dev_isr(caddr_t arg) 1310{ 1311 struct envctrlunit *unitp = (struct envctrlunit *)(void *)arg; 1312 uint8_t recv_data; 1313 int ic; 1314 int retrys = 0; 1315 int status; 1316 1317 ic = DDI_INTR_UNCLAIMED; 1318 1319 mutex_enter(&unitp->umutex); 1320 1321 /* 1322 * First check to see if it is an interrupt for us by 1323 * looking at the "ganged" interrrupt and vector 1324 * according to the major type 1325 * 0x70 is the addr of the ganged interrupt controller. 1326 * Address map for the port byte read is as follows 1327 * MSB 1328 * ------------------------- 1329 * | | | | | | | | | 1330 * ------------------------- 1331 * P7 P6 P5 P4 P3 P2 P1 P0 1332 * P0 = Power Supply 1 intr 1333 * P1 = Power Supply 2 intr 1334 * P2 = Power Supply 3 intr 1335 * P3 = Dlfop enable for fan sped set 1336 * P4 = ENVCTRL_ Fan Fail intr 1337 * P5 = Front Panel Interrupt 1338 * P6 = Power Fail Detect Low. 1339 * P7 = Enable Interrupts to system 1340 */ 1341 1342retry: 1343 1344 status = eHc_read_pcf8574a((struct eHc_envcunit *)unitp, 1345 PCF8574A_BASE_ADDR | ENVCTRL_PCF8574_DEV0, &recv_data, 1); 1346 1347 /* 1348 * This extra read is needed since the first read is discarded 1349 * and the second read seems to return 0xFF. 1350 */ 1351 if (recv_data == 0xFF) { 1352 status = eHc_read_pcf8574a((struct eHc_envcunit *)unitp, 1353 PCF8574A_BASE_ADDR | ENVCTRL_PCF8574_DEV0, &recv_data, 1); 1354 } 1355 if (envctrl_debug_flags) 1356 cmn_err(CE_WARN, "envctrl_dev_isr: status= %d, data = %x\n", 1357 status, recv_data); 1358 1359 /* 1360 * if the i2c bus is hung it is imperative that this 1361 * be cleared on an interrupt or else it will 1362 * hang the system with continuous interrupts 1363 */ 1364 1365 if (status == DDI_FAILURE) { 1366 drv_usecwait(1000); 1367 if (retrys < envctrl_max_retries) { 1368 retrys++; 1369 goto retry; 1370 } else { 1371 if (envctrl_debug_flags) 1372 cmn_err(CE_WARN, 1373 "DEVISR FAILED received 0x%x\n", recv_data); 1374 mutex_exit(&unitp->umutex); 1375 envctrl_init_bus(unitp); 1376 mutex_enter(&unitp->umutex); 1377 envctrl_ps_probe(unitp); 1378 mutex_exit(&unitp->umutex); 1379 ic = DDI_INTR_CLAIMED; 1380 return (ic); 1381 } 1382 } 1383 1384 /* 1385 * Port 0 = PS1 interrupt 1386 * Port 1 = PS2 Interrupt 1387 * Port 2 = PS3 Interrupt 1388 * Port 3 = SPARE 1389 * Port 4 = Fan Fail Intr 1390 * Port 5 = Front Panle Module intr 1391 * Port 6 = Keyswitch Intr 1392 * Port 7 = ESINTR ENABLE ??? 1393 */ 1394 1395 if (!(recv_data & ENVCTRL_PCF8574_PORT0)) { 1396 envctrl_PS_intr_service(unitp, PS1); 1397 ic = DDI_INTR_CLAIMED; 1398 } 1399 1400 if (!(recv_data & ENVCTRL_PCF8574_PORT1)) { 1401 envctrl_PS_intr_service(unitp, PS2); 1402 ic = DDI_INTR_CLAIMED; 1403 } 1404 1405 if (!(recv_data & ENVCTRL_PCF8574_PORT2)) { 1406 envctrl_PS_intr_service(unitp, PS3); 1407 ic = DDI_INTR_CLAIMED; 1408 } 1409 1410 if (!(recv_data & ENVCTRL_PCF8574_PORT3)) { 1411 ic = DDI_INTR_CLAIMED; 1412 } 1413 1414 if (!(recv_data & ENVCTRL_PCF8574_PORT4)) { 1415 /* 1416 * Check for a fan fail 1417 * Single fan fail 1418 * shutdown system 1419 */ 1420 envctrl_fan_fail_service(unitp); 1421 ic = DDI_INTR_CLAIMED; 1422 } 1423 1424 if (!(recv_data & ENVCTRL_PCF8574_PORT5)) { 1425 (void) envctrl_get_fpm_status(unitp); 1426 ic = DDI_INTR_CLAIMED; 1427 } 1428 1429 if (!(recv_data & ENVCTRL_PCF8574_PORT6)) { 1430 ic = DDI_INTR_CLAIMED; 1431 } 1432 1433 if (!(recv_data & ENVCTRL_PCF8574_PORT7)) { 1434 ic = DDI_INTR_CLAIMED; 1435 } 1436 1437 if ((recv_data == 0xFF)) { 1438 ic = DDI_INTR_CLAIMED; 1439 } 1440 1441 mutex_exit(&unitp->umutex); 1442 return (ic); 1443 1444} 1445 1446static void 1447envctrl_init_bus(struct envctrlunit *unitp) 1448{ 1449 1450 int i; 1451 uint8_t noval = NULL; 1452 struct envctrl_tda8444t_chip fan; 1453 int fans[] = {ENVCTRL_CPU_FANS, ENVCTRL_PS_FANS, ENVCTRL_AFB_FANS}; 1454 1455 mutex_enter(&unitp->umutex); 1456 /* Sets the Mode to 808x type bus */ 1457 ddi_put8(unitp->ctlr_handle, 1458 &unitp->bus_ctl_regs->s0, ENVCTRL_CHAR_ZERO); 1459 1460 /* SET UP SLAVE ADDR XXX Required..send 0x80 */ 1461 1462 ddi_put8(unitp->ctlr_handle, &unitp->bus_ctl_regs->s1, 1463 ENVCTRL_BUS_INIT0); 1464 (void) ddi_put8(unitp->ctlr_handle, &unitp->bus_ctl_regs->s0, 1465 ENVCTRL_BUS_INIT1); 1466 1467 /* Set the clock now */ 1468 ddi_put8(unitp->ctlr_handle, 1469 &unitp->bus_ctl_regs->s1, ENVCTRL_BUS_CLOCK0); 1470 1471 /* S0 is now S2 necause of the previous write to S1 */ 1472 /* clock= 12MHz, SCL=90KHz */ 1473 ddi_put8(unitp->ctlr_handle, 1474 &unitp->bus_ctl_regs->s0, ENVCTRL_BUS_CLOCK1); 1475 1476 /* Enable serial interface */ 1477 ddi_put8(unitp->ctlr_handle, 1478 &unitp->bus_ctl_regs->s1, ENVCTRL_BUS_ESI); 1479 1480 envctrl_stop_clock(unitp); 1481 1482 /* 1483 * This has been added here because the DAC is powered 1484 * on at "0". When the reset_dflop routine is called 1485 * this switched the fans from blast to DAC control. 1486 * if the DAC is at "0", then the fans momentarily lose 1487 * power until the temp polling and fan set routine is 1488 * first called. If the fans lose power, then there is 1489 * a fan fault generated and the system will power off. 1490 * We only want to do this IF the bus is first being 1491 * initted. This will cause errors in Sunvts if we reset 1492 * the fan speed under normal operation. Sometimes we need 1493 * to be able to induce fan faults. Init bus is a common 1494 * routine to unwedge the i2c bus in some cases. 1495 */ 1496 1497 if (unitp->initting == B_TRUE) { 1498 fan.chip_num = ENVCTRL_TDA8444T_DEV7; 1499 fan.val = INIT_FAN_VAL; 1500 1501 for (i = 0; i < sizeof (fans)/sizeof (int); i++) { 1502 fan.fan_num = fans[i]; 1503 if ((fans[i] == ENVCTRL_AFB_FANS) && 1504 (unitp->AFB_present == B_FALSE)) 1505 continue; 1506 (void) envctrl_xmit(unitp, (caddr_t *)(void *)&fan, 1507 TDA8444T); 1508 } 1509 } 1510 1511 envctrl_reset_dflop(unitp); 1512 1513 envctrl_enable_devintrs(unitp); 1514 1515 unitp->current_mode = ENVCTRL_NORMAL_MODE; 1516 envctrl_reset_watchdog(unitp, &noval); 1517 1518 mutex_exit(&unitp->umutex); 1519} 1520 1521static int 1522envctrl_xmit(struct envctrlunit *unitp, caddr_t *data, int chip_type) 1523{ 1524 1525 struct envctrl_tda8444t_chip *fanspeed; 1526 struct envctrl_pcf8574_chip *ioport; 1527 uint8_t slave_addr; 1528 uint8_t buf[2]; 1529 int retrys = 0; 1530 int status; 1531 1532 ASSERT(MUTEX_HELD(&unitp->umutex)); 1533 1534 switch (chip_type) { 1535 case TDA8444T: 1536 1537 fanspeed = (struct envctrl_tda8444t_chip *)data; 1538 1539 if (fanspeed->chip_num > ENVCTRL_FAN_ADDR_MAX) { 1540 return (DDI_FAILURE); 1541 } 1542 1543 if (fanspeed->fan_num > ENVCTRL_PORT7) { 1544 return (DDI_FAILURE); 1545 } 1546 1547 if (fanspeed->val > MAX_FAN_VAL) { 1548 return (DDI_FAILURE); 1549 } 1550 1551retry0: 1552 slave_addr = (TDA8444T_BASE_ADDR | fanspeed->chip_num); 1553 buf[0] = fanspeed->val; 1554 1555 status = eHc_write_tda8444((struct eHc_envcunit *)unitp, 1556 TDA8444T_BASE_ADDR | fanspeed->chip_num, 0xF, 1557 fanspeed->fan_num, buf, 1); 1558 if (status != DDI_SUCCESS) { 1559 drv_usecwait(1000); 1560 if (retrys < envctrl_max_retries) { 1561 retrys++; 1562 goto retry0; 1563 } else { 1564 mutex_exit(&unitp->umutex); 1565 envctrl_init_bus(unitp); 1566 mutex_enter(&unitp->umutex); 1567 if (envctrl_debug_flags) 1568 cmn_err(CE_WARN, 1569 "envctrl_xmit: Write to TDA8444 " \ 1570 "failed\n"); 1571 return (DDI_FAILURE); 1572 } 1573 } 1574 1575 /* 1576 * Update the kstats. 1577 */ 1578 switch (fanspeed->fan_num) { 1579 case ENVCTRL_CPU_FANS: 1580 unitp->fan_kstats[ENVCTRL_FAN_TYPE_CPU].fanspeed = 1581 fanspeed->val; 1582 break; 1583 case ENVCTRL_PS_FANS: 1584 unitp->fan_kstats[ENVCTRL_FAN_TYPE_PS].fanspeed = 1585 fanspeed->val; 1586 break; 1587 case ENVCTRL_AFB_FANS: 1588 unitp->fan_kstats[ENVCTRL_FAN_TYPE_AFB].fanspeed = 1589 fanspeed->val; 1590 break; 1591 default: 1592 break; 1593 } 1594 break; 1595 case PCF8574: 1596 ioport = (struct envctrl_pcf8574_chip *)data; 1597 buf[0] = ioport->val; 1598 if (ioport->chip_num > ENVCTRL_PCF8574_DEV7) 1599 return (DDI_FAILURE); 1600 1601retry: 1602 if (ioport->type == PCF8574A) { 1603 slave_addr = (PCF8574A_BASE_ADDR | ioport->chip_num); 1604 status = 1605 eHc_write_pcf8574a((struct eHc_envcunit *)unitp, 1606 PCF8574A_BASE_ADDR | ioport->chip_num, buf, 1); 1607 } else { 1608 slave_addr = (PCF8574_BASE_ADDR | ioport->chip_num); 1609 status = eHc_write_pcf8574((struct eHc_envcunit *)unitp, 1610 PCF8574_BASE_ADDR | ioport->chip_num, buf, 1); 1611 } 1612 1613 if (status != DDI_SUCCESS) { 1614 drv_usecwait(1000); 1615 if (retrys < envctrl_max_retries) { 1616 retrys++; 1617 goto retry; 1618 } else { 1619 mutex_exit(&unitp->umutex); 1620 envctrl_init_bus(unitp); 1621 mutex_enter(&unitp->umutex); 1622 if (envctrl_debug_flags) 1623 cmn_err(CE_WARN, "Write to PCF8574 " \ 1624 "failed, addr = %X\n", slave_addr); 1625 if (envctrl_debug_flags) 1626 cmn_err(CE_WARN, "envctrl_xmit: PCF8574\ 1627 dev = %d, port = %d\n", 1628 ioport->chip_num, ioport->type); 1629 return (DDI_FAILURE); 1630 } 1631 } 1632 break; 1633 1634 default: 1635 return (DDI_FAILURE); 1636 } 1637 1638 return (DDI_SUCCESS); 1639} 1640 1641static void 1642envctrl_recv(struct envctrlunit *unitp, caddr_t *data, int chip_type) 1643{ 1644 1645 struct envctrl_pcf8591_chip *temp; 1646 struct envctrl_pcf8574_chip *ioport; 1647 uint8_t slave_addr, recv_data; 1648 int retrys = 0; 1649 int status; 1650 uint8_t buf[1]; 1651 1652 ASSERT(MUTEX_HELD(&unitp->umutex)); 1653 1654 switch (chip_type) { 1655 case PCF8591: 1656 temp = (struct envctrl_pcf8591_chip *)data; 1657 slave_addr = (PCF8591_BASE_ADDR | temp->chip_num); 1658 1659retry: 1660 status = eHc_read_pcf8591((struct eHc_envcunit *)unitp, 1661 PCF8591_BASE_ADDR | temp->chip_num & 0xF, 1662 temp->sensor_num, 0, 0, 1, &recv_data, 1); 1663 1664 /* 1665 * another place to catch the i2c bus hang on an 8591 read 1666 * In this instance we will just return the data that is read 1667 * after the max_retry because this could be a valid value. 1668 */ 1669 if (status != DDI_SUCCESS) { 1670 drv_usecwait(1000); 1671 if (retrys < envctrl_max_retries) { 1672 retrys++; 1673 goto retry; 1674 } else { 1675 mutex_exit(&unitp->umutex); 1676 envctrl_init_bus(unitp); 1677 mutex_enter(&unitp->umutex); 1678 if (envctrl_debug_flags) 1679 cmn_err(CE_WARN, "Read from PCF8591 " \ 1680 "failed, slave_addr = %x\n", 1681 slave_addr); 1682 } 1683 } 1684 temp->temp_val = recv_data; 1685 break; 1686 case TDA8444T: 1687 printf("envctrl_recv: attempting to read TDA8444T\n"); 1688 return; 1689 case PCF8574: 1690 ioport = (struct envctrl_pcf8574_chip *)data; 1691 1692retry1: 1693 if (ioport->chip_num > ENVCTRL_PCF8574_DEV7) 1694 cmn_err(CE_WARN, "envctrl: dev out of range 0x%x\n", 1695ioport->chip_num); 1696 1697 if (ioport->type == PCF8574A) { 1698 slave_addr = (PCF8574_READ_BIT | PCF8574A_BASE_ADDR | 1699 ioport->chip_num); 1700 status = eHc_read_pcf8574a((struct eHc_envcunit *)unitp, 1701 PCF8574A_BASE_ADDR | ioport->chip_num, buf, 1); 1702 } else { 1703 slave_addr = (PCF8574_READ_BIT | PCF8574_BASE_ADDR | 1704 ioport->chip_num); 1705 status = eHc_read_pcf8574((struct eHc_envcunit *)unitp, 1706 PCF8574_BASE_ADDR | ioport->chip_num, buf, 1); 1707 } 1708 1709 if (status != DDI_SUCCESS) { 1710 drv_usecwait(1000); 1711 if (retrys < envctrl_max_retries) { 1712 retrys++; 1713 goto retry1; 1714 } else { 1715 mutex_exit(&unitp->umutex); 1716 envctrl_init_bus(unitp); 1717 mutex_enter(&unitp->umutex); 1718 if (envctrl_debug_flags) 1719 cmn_err(CE_WARN, "Read from PCF8574 "\ 1720 "failed, addr = %X\n", slave_addr); 1721 if (envctrl_debug_flags) 1722 cmn_err(CE_WARN, "envctrl_recv: PCF8574\ 1723 dev = %d, port = %d\n", 1724 ioport->chip_num, ioport->type); 1725 } 1726 } 1727 ioport->val = buf[0]; 1728 break; 1729 default: 1730 break; 1731 } 1732} 1733 1734static int 1735envctrl_get_ps_temp(struct envctrlunit *unitp, uint8_t psaddr) 1736{ 1737 uint8_t tempr; 1738 int i, retrys; 1739 int status; 1740 uint8_t buf[4]; 1741 1742 ASSERT(MUTEX_HELD(&unitp->umutex)); 1743 1744 tempr = 0; 1745 retrys = 0; 1746 1747retry: 1748 status = eHc_read_pcf8591((struct eHc_envcunit *)unitp, 1749 PCF8591_BASE_ADDR | psaddr & 0xF, 0, 1, 0, 1, buf, 4); 1750 1751 tempr = 0; 1752 for (i = 0; i < PCF8591_MAX_PORTS; i++) { 1753 /* 1754 * The pcf8591 will return 0xff if no port 1755 * is there.. this is bogus for setting temps. 1756 * so just ignore it! 1757 */ 1758 if (envctrl_debug_flags) { 1759 cmn_err(CE_WARN, "PS addr 0x%x recvd 0x%x on port %d\n", 1760 psaddr, buf[i], i); 1761 } 1762 if (buf[i] > tempr && buf[i] < MAX_PS_ADVAL) { 1763 tempr = buf[i]; 1764 } 1765 } 1766 1767 /* 1768 * This routine is a safeguard to make sure that if the 1769 * powersupply temps cannot be read that we do something 1770 * to make sure that the system will notify the user and 1771 * it will stay running with the fans at 100%. The calling 1772 * routine should take care of that. 1773 */ 1774 if (status != DDI_SUCCESS) { 1775 drv_usecwait(1000); 1776 if (retrys < envctrl_max_retries) { 1777 retrys++; 1778 goto retry; 1779 } else { 1780 mutex_exit(&unitp->umutex); 1781 envctrl_init_bus(unitp); 1782 mutex_enter(&unitp->umutex); 1783 if (envctrl_debug_flags) 1784 cmn_err(CE_WARN, 1785 "Cannot read Power Supply Temps addr = %X", 1786 psaddr); 1787 return (PS_DEFAULT_VAL); 1788 } 1789 } 1790 1791 return (ps_temps[tempr]); 1792} 1793 1794static int 1795envctrl_get_cpu_temp(struct envctrlunit *unitp, int cpunum) 1796{ 1797 uint8_t recv_data; 1798 int retrys; 1799 int status; 1800 1801 ASSERT(MUTEX_HELD(&unitp->umutex)); 1802 1803 /* 1804 * This routine takes in the number of the port that 1805 * we want to read in the 8591. This should be the 1806 * location of the COU thermistor for one of the 4 1807 * cpu's. It will return the temperature in degrees C 1808 * to the caller. 1809 */ 1810 1811 retrys = 0; 1812 1813retry: 1814 status = eHc_read_pcf8591((struct eHc_envcunit *)unitp, 1815 PCF8591_BASE_ADDR | PCF8591_DEV7, cpunum, 0, 0, 0, 1816 &recv_data, 1); 1817 1818 /* 1819 * We need to take a sledge hammer to the bus if we get back 1820 * value of the chip. This means that the i2c bus got wedged. 1821 * On the 1.4 systems this happens sometimes while running 1822 * sunvts. We will return the max cpu temp minus 10 to make 1823 * the fans run at full speed so that we don;t cook the 1824 * system. 1825 * At this point this is a workaround for hardware glitch. 1826 */ 1827 if (status == DDI_FAILURE) { 1828 drv_usecwait(1000); 1829 if (retrys < envctrl_max_retries) { 1830 retrys++; 1831 goto retry; 1832 } else { 1833 mutex_exit(&unitp->umutex); 1834 envctrl_init_bus(unitp); 1835 mutex_enter(&unitp->umutex); 1836 if (envctrl_debug_flags) 1837 cmn_err(CE_WARN, "envctrl CPU TEMP read " \ 1838 "failed\n"); 1839 /* we don't want to power off the system */ 1840 return (MAX_CPU_TEMP - 10); 1841 } 1842 } 1843 1844 return (cpu_temps[recv_data]); 1845} 1846 1847static int 1848envctrl_get_lm75_temp(struct envctrlunit *unitp) 1849{ 1850 1851 int k; 1852 ushort_t lmval; 1853 uint8_t tmp1; 1854 uint8_t tmp2; 1855 int status; 1856 uint8_t buf[2]; 1857 1858 1859 ASSERT(MUTEX_HELD(&unitp->umutex)); 1860 1861 status = eHc_read_lm75((struct eHc_envcunit *)unitp, 1862 LM75_BASE_ADDR | LM75_CONFIG_ADDRA, buf, 2); 1863 if (status != DDI_SUCCESS) 1864 cmn_err(CE_WARN, "read of LM75 failed\n"); 1865 1866 tmp1 = buf[0]; 1867 tmp2 = buf[1]; 1868 1869 /* 1870 * Store the forst 8 bits in the upper nibble of the 1871 * short, then store the lower 8 bits in the lower nibble 1872 * of the short, shift 7 to the right to get the 9 bit value 1873 * that the lm75 is really sending. 1874 */ 1875 lmval = tmp1 << 8; 1876 lmval = (lmval | tmp2); 1877 lmval = (lmval >> 7); 1878 /* 1879 * Check the 9th bit to see if it is a negative 1880 * temperature. If so change into 2's compliment 1881 * and divide by 2 since each value is equal to a 1882 * half degree strp in degrees C 1883 */ 1884 if (lmval & LM75_COMP_MASK) { 1885 tmp1 = (lmval & LM75_COMP_MASK_UPPER); 1886 tmp1 = -tmp1; 1887 tmp1 = tmp1/2; 1888 k = 0 - tmp1; 1889 } else { 1890 k = lmval /2; 1891 } 1892 return (k); 1893} 1894 1895 1896static void 1897envctrl_tempr_poll(void *arg) 1898{ 1899 int diag_flag = 0; 1900 struct envctrlunit *unitp = (struct envctrlunit *)arg; 1901 1902 mutex_enter(&unitp->umutex); 1903 1904 if (unitp->shutdown == B_TRUE) { 1905 (void) power_down("Fatal System Environmental Control Error"); 1906 } 1907 1908 /* 1909 * if we are in diag mode and the temp poll thread goes off, 1910 * this means that the system is too heavily loaded and the 60 second 1911 * window to execute the test is failing. We will change the fanspeed 1912 * but will not check for a fanfault. This will cause a system shutdown 1913 * if the system has had a fanfault injected. 1914 */ 1915 if (unitp->current_mode == ENVCTRL_DIAG_MODE) { 1916 diag_flag++; 1917 if (envctrl_debug_flags) { 1918 cmn_err(CE_WARN, 1919 "Tempr poll went off while in DIAG MODE"); 1920 } 1921 } 1922 unitp->current_mode = ENVCTRL_NORMAL_MODE; 1923 envctrl_get_sys_temperatures(unitp, (uint8_t *)NULL); 1924 if (diag_flag == 0) { 1925 envctrl_fan_fail_service(unitp); 1926 } 1927 /* now have this thread sleep for a while */ 1928 unitp->timeout_id = (timeout(envctrl_tempr_poll, 1929 (caddr_t)unitp, overtemp_timeout_hz)); 1930 1931 mutex_exit(&unitp->umutex); 1932} 1933 1934static void 1935envctrl_led_blink(void *arg) 1936{ 1937 struct envctrl_pcf8574_chip fspchip; 1938 struct envctrlunit *unitp = (struct envctrlunit *)arg; 1939 1940 mutex_enter(&unitp->umutex); 1941 1942 fspchip.type = PCF8574A; 1943 fspchip.chip_num = ENVCTRL_PCF8574_DEV6; /* 0x01 port 1 */ 1944 envctrl_recv(unitp, (caddr_t *)(void *)&fspchip, PCF8574); 1945 1946 if (unitp->present_led_state == B_TRUE) { 1947 /* 1948 * Now we need to "or" in fault bits of the FSP 1949 * module for the mass storage fault led. 1950 * and set it. 1951 */ 1952 fspchip.val = (fspchip.val & ~(ENVCTRL_PCF8574_PORT4) | 1953 0xC0); 1954 unitp->present_led_state = B_FALSE; 1955 } else { 1956 fspchip.val = (fspchip.val | ENVCTRL_PCF8574_PORT4 | 0xC0); 1957 unitp->present_led_state = B_TRUE; 1958 } 1959 1960 (void) envctrl_xmit(unitp, (caddr_t *)(void *)&fspchip, PCF8574); 1961 1962 /* now have this thread sleep for a while */ 1963 unitp->blink_timeout_id = (timeout(envctrl_led_blink, 1964 (caddr_t)unitp, blink_timeout_hz)); 1965 1966 mutex_exit(&unitp->umutex); 1967} 1968 1969/* called with mutex held */ 1970static void 1971envctrl_get_sys_temperatures(struct envctrlunit *unitp, uint8_t *diag_tempr) 1972{ 1973 int temperature, tmptemp, cputemp, hicputemp, ambtemp; 1974 int i; 1975 struct envctrl_tda8444t_chip fan; 1976 uint8_t psaddr[] = {PSTEMP3, PSTEMP2, PSTEMP1, PSTEMP0}; 1977 uint8_t noval = NULL; 1978 uint8_t fspval; 1979 1980 ASSERT(MUTEX_HELD(&unitp->umutex)); 1981 1982 fan.fan_num = ENVCTRL_CPU_FANS; 1983 fan.chip_num = ENVCTRL_TDA8444T_DEV7; 1984 1985 tmptemp = 0; /* Right init value ?? */ 1986 1987 /* 1988 * THis routine is caled once every minute 1989 * we wil re-se the watchdog timer each time 1990 * we poll the temps. The watchdog timer is 1991 * set up for 3 minutes. Should the kernel thread 1992 * wedge, for some reason the watchdog will go off 1993 * and blast the fans. 1994 */ 1995 1996 if (unitp->current_mode == ENVCTRL_DIAG_MODE) { 1997 unitp->current_mode = ENVCTRL_NORMAL_MODE; 1998 envctrl_reset_watchdog(unitp, &noval); 1999 unitp->current_mode = ENVCTRL_DIAG_MODE; 2000 } else { 2001 envctrl_reset_watchdog(unitp, &noval); 2002 } 2003 2004 /* 2005 * we need to reset the dflop to allow the fans to be 2006 * set if the watchdog goes of and the kernel resumes 2007 * resetting the dflop alos resets the device interrupts 2008 * we need to reenable them also. 2009 */ 2010 envctrl_reset_dflop(unitp); 2011 2012 envctrl_enable_devintrs(unitp); 2013 2014 /* 2015 * If we are in diag mode we allow the system to be 2016 * faked out as to what the temperature is 2017 * to see if the fans speed up. 2018 */ 2019 if (unitp->current_mode == ENVCTRL_DIAG_MODE && diag_tempr != NULL) { 2020 if (unitp->timeout_id != 0) { 2021 (void) untimeout(unitp->timeout_id); 2022 } 2023 2024 ambtemp = *diag_tempr; 2025 unitp->timeout_id = (timeout(envctrl_tempr_poll, 2026 (caddr_t)unitp, overtemp_timeout_hz)); 2027 } else { 2028 ambtemp = envctrl_get_lm75_temp(unitp); 2029 /* 2030 * Sometimes when we read the temp it comes back bogus 2031 * to fix this we just need to reset the envctrl bus 2032 */ 2033 if (ambtemp == -100) { 2034 mutex_exit(&unitp->umutex); 2035 envctrl_init_bus(unitp); 2036 mutex_enter(&unitp->umutex); 2037 ambtemp = envctrl_get_lm75_temp(unitp); 2038 } 2039 } 2040 2041 envctrl_mod_encl_kstats(unitp, ENVCTRL_ENCL_AMBTEMPR, INSTANCE_0, 2042 ambtemp); 2043 2044 fspval = envctrl_get_fpm_status(unitp); 2045 2046 if (ambtemp > MAX_AMB_TEMP) { 2047 fspval |= (ENVCTRL_FSP_TEMP_ERR | ENVCTRL_FSP_GEN_ERR); 2048 if (!(envctrl_power_off_overide) && 2049 unitp->current_mode == ENVCTRL_NORMAL_MODE) { 2050 unitp->shutdown = B_TRUE; 2051 } 2052 if (unitp->current_mode == ENVCTRL_NORMAL_MODE) { 2053 cmn_err(CE_WARN, 2054 "Ambient Temperature is %d C, shutdown now\n", 2055 ambtemp); 2056 } 2057 } else { 2058 if (envctrl_isother_fault_led(unitp, fspval, 2059 ENVCTRL_FSP_TEMP_ERR)) { 2060 fspval &= ~(ENVCTRL_FSP_TEMP_ERR); 2061 } else { 2062 fspval &= ~(ENVCTRL_FSP_TEMP_ERR | ENVCTRL_FSP_GEN_ERR); 2063 } 2064 } 2065 2066 envctrl_set_fsp(unitp, &fspval); 2067 2068 cputemp = hicputemp = 0; 2069#ifndef TESTBED 2070 for (i = 0; i < ENVCTRL_MAX_CPUS; i++) { 2071 if (unitp->cpu_pr_location[i] == B_TRUE) { 2072 cputemp = envctrl_get_cpu_temp(unitp, i); 2073 envctrl_mod_encl_kstats(unitp, ENVCTRL_ENCL_CPUTEMPR, 2074 i, cputemp); 2075 if (cputemp >= MAX_CPU_TEMP) { 2076 if (!(envctrl_power_off_overide)) { 2077 unitp->shutdown = B_TRUE; 2078 } 2079 cmn_err(CE_WARN, 2080 "CPU %d OVERHEATING!!!", i); 2081 } 2082 2083 if (cputemp > hicputemp) { 2084 hicputemp = cputemp; 2085 } 2086 } 2087 } 2088#else 2089 cputemp = envctrl_get_cpu_temp(unitp, 0); 2090 envctrl_mod_encl_kstats(unitp, ENVCTRL_ENCL_CPUTEMPR, 0, cputemp); 2091#endif 2092 2093 fspval = envctrl_get_fpm_status(unitp); 2094 2095 /* 2096 * We first look at the ambient temp. If the system is at idle 2097 * the cpu temps will be approx 20 degrees above ambient. 2098 * If the cpu's rise above 20, then the CPU fans are set 2099 * according to the cpu temp minus 20 degrees C. 2100 */ 2101 if (unitp->current_mode == ENVCTRL_DIAG_MODE && diag_tempr != NULL) { 2102 temperature = ambtemp; 2103 } else { 2104 temperature = hicputemp - CPU_AMB_RISE; 2105 } 2106 2107 if (temperature < 0) { 2108 fan.val = MAX_FAN_SPEED; /* blast it is out of range */ 2109 } else if (temperature > MAX_AMB_TEMP) { 2110 fan.val = MAX_FAN_SPEED; 2111 fspval |= (ENVCTRL_FSP_TEMP_ERR | ENVCTRL_FSP_GEN_ERR); 2112 2113 if (unitp->current_mode == ENVCTRL_NORMAL_MODE) { 2114 cmn_err(CE_WARN, 2115 "CPU Fans set to MAX. CPU Temp is %d C\n", 2116 hicputemp); 2117 } 2118 } else if (ambtemp < MAX_AMB_TEMP) { 2119 if (!envctrl_p0_enclosure) { 2120 fan.val = acme_cpu_fanspd[temperature]; 2121 } else { 2122 fan.val = fan_speed[temperature]; 2123 } 2124 if (envctrl_isother_fault_led(unitp, fspval, 2125 ENVCTRL_FSP_TEMP_ERR)) { 2126 fspval &= ~(ENVCTRL_FSP_TEMP_ERR); 2127 } else { 2128 fspval &= ~(ENVCTRL_FSP_TEMP_ERR | ENVCTRL_FSP_GEN_ERR); 2129 } 2130 } 2131 2132 envctrl_set_fsp(unitp, &fspval); 2133 2134 /* 2135 * Update temperature kstats. FSP kstats are updated in the 2136 * set and get routine. 2137 */ 2138 2139 unitp->fan_kstats[ENVCTRL_FAN_TYPE_CPU].fanspeed = fan.val; 2140 2141 /* CPU FANS */ 2142 (void) envctrl_xmit(unitp, (caddr_t *)(void *)&fan, TDA8444T); 2143 2144 /* The afb Fan is always at max */ 2145 if (unitp->AFB_present == B_TRUE) { 2146 fan.val = AFB_MAX; 2147 /* AFB FANS */ 2148 unitp->fan_kstats[ENVCTRL_FAN_TYPE_AFB].fanspeed = fan.val; 2149 fan.fan_num = ENVCTRL_AFB_FANS; 2150 (void) envctrl_xmit(unitp, (caddr_t *)(void *)&fan, TDA8444T); 2151 } 2152 2153 /* 2154 * Now set the Powersupply fans 2155 */ 2156 2157 tmptemp = temperature = 0; 2158 for (i = 0; i <= MAXPS; i++) { 2159 if (unitp->ps_present[i]) { 2160 tmptemp = envctrl_get_ps_temp(unitp, psaddr[i]); 2161 unitp->ps_kstats[i].ps_tempr = tmptemp & 0xFFFF; 2162 if (tmptemp > temperature) { 2163 temperature = tmptemp; 2164 } 2165 if (temperature >= MAX_PS_TEMP) { 2166 if (!(envctrl_power_off_overide)) { 2167 unitp->shutdown = B_TRUE; 2168 } 2169 cmn_err(CE_WARN, 2170 "Power Supply %d OVERHEATING!!!\ 2171 Temp is %d C", i, temperature); 2172 } 2173 } 2174 } 2175 2176 2177 fan.fan_num = ENVCTRL_PS_FANS; 2178 if (temperature > PS_TEMP_WARN) { 2179 fspval = envctrl_get_fpm_status(unitp); 2180 fspval |= (ENVCTRL_FSP_TEMP_ERR | ENVCTRL_FSP_GEN_ERR); 2181 envctrl_set_fsp(unitp, &fspval); 2182 fan.val = MAX_FAN_SPEED; 2183 cmn_err(CE_WARN, "A Power Supply is close to OVERHEATING!!!"); 2184 } else { 2185 if (temperature - ambtemp > PS_AMB_RISE) { 2186 ambtemp = temperature - PS_AMB_RISE; 2187 } 2188 if (!envctrl_p0_enclosure) { 2189 fan.val = acme_ps_fanspd[ambtemp]; 2190 } else { 2191 fan.val = ps_fans[ambtemp]; 2192 } 2193 } 2194 2195 /* 2196 * XXX add in error condition for ps overtemp 2197 */ 2198 2199 unitp->fan_kstats[ENVCTRL_FAN_TYPE_PS].fanspeed = fan.val; 2200 (void) envctrl_xmit(unitp, (caddr_t *)(void *)&fan, TDA8444T); 2201} 2202 2203/* called with mutex held */ 2204static void 2205envctrl_fan_fail_service(struct envctrlunit *unitp) 2206{ 2207 uint8_t recv_data, fpmstat; 2208 int fantype; 2209 int psfanflt, cpufanflt, afbfanflt; 2210 int retries = 0, max_retry_count; 2211 int status; 2212 2213 psfanflt = cpufanflt = afbfanflt = 0; 2214 /* 2215 * The fan fail sensor is located at address 0x70 2216 * on the envctrl bus. 2217 */ 2218 2219 ASSERT(MUTEX_HELD(&unitp->umutex)); 2220 2221retry: 2222 status = eHc_read_pcf8574a((struct eHc_envcunit *)unitp, 2223 PCF8574A_BASE_ADDR | ENVCTRL_PCF8574_DEV4, &recv_data, 1); 2224 if (status != DDI_SUCCESS) 2225 cmn_err(CE_WARN, "fan_fail_service: status = %d, data = %x\n", 2226 status, recv_data); 2227 2228 /* 2229 * If all fan ports are high (0xff) then we don't have any 2230 * fan faults. Reset the kstats 2231 */ 2232 if (recv_data == 0xff) { 2233 unitp->fan_kstats[ENVCTRL_FAN_TYPE_PS].fans_ok = B_TRUE; 2234 unitp->fan_kstats[ENVCTRL_FAN_TYPE_CPU].fans_ok = B_TRUE; 2235 unitp->fan_kstats[ENVCTRL_FAN_TYPE_AFB].fans_ok = B_TRUE; 2236 unitp->fan_kstats[ENVCTRL_FAN_TYPE_PS].fanflt_num = 0; 2237 unitp->fan_kstats[ENVCTRL_FAN_TYPE_CPU].fanflt_num = 0; 2238 unitp->fan_kstats[ENVCTRL_FAN_TYPE_AFB].fanflt_num = 0; 2239 unitp->num_fans_failed = 0; 2240 fpmstat = envctrl_get_fpm_status(unitp); 2241 if (!(envctrl_isother_fault_led(unitp, fpmstat, 0))) { 2242 fpmstat &= ~(ENVCTRL_FSP_GEN_ERR); 2243 } 2244 if (unitp->shutdown != B_TRUE) { 2245 envctrl_set_fsp(unitp, &fpmstat); 2246 } 2247 return; 2248 } 2249 2250 fantype = ENVCTRL_FAN_TYPE_PS; 2251 2252 if (!(recv_data & ENVCTRL_PCF8574_PORT0)) { 2253 psfanflt = PS_FAN_3; 2254 } 2255 if (!(recv_data & ENVCTRL_PCF8574_PORT1)) { 2256 psfanflt = PS_FAN_2; 2257 } 2258 if (!(recv_data & ENVCTRL_PCF8574_PORT2)) { 2259 psfanflt = PS_FAN_1; 2260 } 2261 2262 if (psfanflt != 0) { 2263 unitp->fan_kstats[fantype].fans_ok = B_FALSE; 2264 unitp->fan_kstats[fantype].fanflt_num = psfanflt - 1; 2265 if (retries == MAX_FAN_FAIL_RETRY && status == DDI_SUCCESS && 2266 unitp->current_mode == ENVCTRL_NORMAL_MODE) { 2267 cmn_err(CE_WARN, "PS Fan Number %d Failed", 2268 psfanflt - 1); 2269 } 2270 } else { 2271 unitp->fan_kstats[fantype].fans_ok = B_TRUE; 2272 unitp->fan_kstats[fantype].fanflt_num = 0; 2273 } 2274 2275 fantype = ENVCTRL_FAN_TYPE_CPU; 2276 2277 if (!(recv_data & ENVCTRL_PCF8574_PORT3)) { 2278 cpufanflt = CPU_FAN_1; 2279 } 2280 if (!(recv_data & ENVCTRL_PCF8574_PORT4)) { 2281 cpufanflt = CPU_FAN_2; 2282 } 2283 if (!(recv_data & ENVCTRL_PCF8574_PORT5)) { 2284 cpufanflt = CPU_FAN_3; 2285 } 2286 2287 if (cpufanflt != 0) { 2288 unitp->fan_kstats[fantype].fans_ok = B_FALSE; 2289 unitp->fan_kstats[fantype].fanflt_num = cpufanflt - 1; 2290 if (retries == MAX_FAN_FAIL_RETRY && status == DDI_SUCCESS && 2291 unitp->current_mode == ENVCTRL_NORMAL_MODE) { 2292 cmn_err(CE_WARN, "CPU Fan Number %d Failed", 2293 cpufanflt - 1); 2294 } 2295 } else { 2296 unitp->fan_kstats[fantype].fans_ok = B_TRUE; 2297 unitp->fan_kstats[fantype].fanflt_num = 0; 2298 } 2299 2300 if (!(recv_data & ENVCTRL_PCF8574_PORT6) && 2301 (unitp->AFB_present == B_TRUE)) { 2302 /* 2303 * If the afb is present and the afb fan fails, 2304 * we need to power off or else it will melt! 2305 * If it isn't present just log the error. 2306 * We make the decision off of the afbfanflt 2307 * flag later on in an if statement. 2308 */ 2309 afbfanflt++; 2310 unitp->fan_kstats[ENVCTRL_FAN_TYPE_AFB].fans_ok 2311 = B_FALSE; 2312 unitp->fan_kstats[ENVCTRL_FAN_TYPE_AFB].fanflt_num = 2313 AFB_FAN_1; 2314 if (unitp->current_mode == ENVCTRL_NORMAL_MODE) { 2315 cmn_err(CE_WARN, "AFB Fan Failed"); 2316 } 2317 2318 } 2319 2320 /* 2321 * If we have no Fan Faults Clear the LED's 2322 * If we have fan faults set the Gen Fault LED. 2323 */ 2324 if (psfanflt == 0 && cpufanflt == 0 && afbfanflt == 0 && 2325 unitp->num_fans_failed != 0) { 2326 fpmstat = envctrl_get_fpm_status(unitp); 2327 if (!(envctrl_isother_fault_led(unitp, 2328 fpmstat, 0))) { 2329 fpmstat &= ~(ENVCTRL_FSP_GEN_ERR); 2330 } 2331 envctrl_set_fsp(unitp, &fpmstat); 2332 } else if (psfanflt != 0 || cpufanflt != 0 || afbfanflt != 0) { 2333 fpmstat = envctrl_get_fpm_status(unitp); 2334 fpmstat |= ENVCTRL_FSP_GEN_ERR; 2335 envctrl_set_fsp(unitp, &fpmstat); 2336 } 2337 2338 if (unitp->AFB_present == B_FALSE) { 2339 afbfanflt = 0; 2340 } 2341 2342 if ((cpufanflt > 0 || psfanflt > 0 || afbfanflt > 0 || 2343 (status != DDI_SUCCESS)) && !unitp->initting && 2344 unitp->current_mode == ENVCTRL_NORMAL_MODE) { 2345 if (status != DDI_SUCCESS) 2346 max_retry_count = envctrl_max_retries; 2347 else 2348 max_retry_count = MAX_FAN_FAIL_RETRY; 2349 if (retries <= max_retry_count) { 2350 retries++; 2351 drv_usecwait(1000); 2352 if (retries == max_retry_count) { 2353 cmn_err(CE_WARN, 2354 "Fan Fail is 0x%x, retries = %d\n", 2355 recv_data, retries); 2356 } 2357 envctrl_get_sys_temperatures(unitp, 2358 (uint8_t *)NULL); 2359 goto retry; 2360 } 2361 if (!(envctrl_power_off_overide)) { 2362 unitp->shutdown = B_TRUE; 2363 } 2364 cmn_err(CE_WARN, "Fan Failure(s), System Shutdown"); 2365 } 2366 2367 unitp->num_fans_failed = (psfanflt + cpufanflt + afbfanflt); 2368 2369} 2370 2371/* 2372 * Check for power supply insertion and failure. 2373 * This is a bit tricky, because a power supply insertion will 2374 * trigger a load share interrupt as well as PS present in the 2375 * new supply. if we detect an insertion clear 2376 * interrupts, disable interrupts, wait for a couple of seconds 2377 * come back and see if the PSOK bit is set, PS_PRESENT is set 2378 * and the share fail interrupts are gone. If not this is a 2379 * real load share fail event. 2380 * Called with mutex held 2381 */ 2382 2383static void 2384envctrl_PS_intr_service(struct envctrlunit *unitp, uint8_t psaddr) 2385{ 2386 uint8_t recv_data; 2387 int status, retrys = 0; 2388 2389 ASSERT(MUTEX_HELD(&unitp->umutex)); 2390 2391 if (unitp->current_mode == ENVCTRL_DIAG_MODE) { 2392 return; 2393 } 2394 2395retry: 2396 status = eHc_read_pcf8574a((struct eHc_envcunit *)unitp, 2397 PCF8574A_BASE_ADDR | psaddr & 0xF, &recv_data, 1); 2398 if (status != DDI_SUCCESS) { 2399 drv_usecwait(1000); 2400 if (retrys < envctrl_max_retries) { 2401 retrys++; 2402 goto retry; 2403 } else { 2404 mutex_exit(&unitp->umutex); 2405 envctrl_init_bus(unitp); 2406 mutex_enter(&unitp->umutex); 2407 if (envctrl_debug_flags) 2408 cmn_err(CE_WARN, 2409 "PS_intr_service: Read from 8574A " \ 2410 "failed\n"); 2411 } 2412 } 2413 2414 /* 2415 * setup a timeout thread to poll the ps after a 2416 * couple of seconds. This allows for the PS to settle 2417 * and doesn't report false errors on a hotplug 2418 */ 2419 2420 unitp->pshotplug_id = (timeout(envctrl_pshotplug_poll, 2421 (caddr_t)unitp, pshotplug_timeout_hz)); 2422 2423} 2424 2425/* called with mutex held */ 2426static void 2427envctrl_reset_dflop(struct envctrlunit *unitp) 2428{ 2429 struct envctrl_pcf8574_chip initval; 2430 2431 ASSERT(MUTEX_HELD(&unitp->umutex)); 2432 2433 /* 2434 * This initialization sequence allows a 2435 * to change state to stop the fans from 2436 * blastion upon poweron. If this isn't 2437 * done the writes to the 8444 will not complete 2438 * to the hardware because the dflop will 2439 * be closed 2440 */ 2441 initval.chip_num = ENVCTRL_PCF8574_DEV0; /* 0x01 port 1 */ 2442 initval.type = PCF8574A; 2443 2444 initval.val = ENVCTRL_DFLOP_INIT0; 2445 (void) envctrl_xmit(unitp, (caddr_t *)(void *)&initval, PCF8574); 2446 2447 initval.val = ENVCTRL_DFLOP_INIT1; 2448 (void) envctrl_xmit(unitp, (caddr_t *)(void *)&initval, PCF8574); 2449} 2450 2451static void 2452envctrl_add_encl_kstats(struct envctrlunit *unitp, int type, 2453 int instance, uint8_t val) 2454{ 2455 int i = 0; 2456 boolean_t inserted = B_FALSE; 2457 2458 ASSERT(MUTEX_HELD(&unitp->umutex)); 2459 2460 while (i < MAX_DEVS && inserted == B_FALSE) { 2461 if (unitp->encl_kstats[i].instance == I2C_NODEV) { 2462 unitp->encl_kstats[i].instance = instance; 2463 unitp->encl_kstats[i].type = type; 2464 unitp->encl_kstats[i].value = val; 2465 inserted = B_TRUE; 2466 } 2467 i++; 2468 } 2469 unitp->num_encl_present++; 2470} 2471 2472/* called with mutex held */ 2473static void 2474envctrl_enable_devintrs(struct envctrlunit *unitp) 2475{ 2476 struct envctrl_pcf8574_chip initval; 2477 2478 ASSERT(MUTEX_HELD(&unitp->umutex)); 2479 2480 /* 2481 * This initialization sequence allows a 2482 * to change state to stop the fans from 2483 * blastion upon poweron. If this isn't 2484 * done the writes to the 8444 will not complete 2485 * to the hardware because the dflop will 2486 * be closed 2487 */ 2488 initval.chip_num = ENVCTRL_PCF8574_DEV0; /* 0x01 port 1 */ 2489 initval.type = PCF8574A; 2490 2491 initval.val = ENVCTRL_DEVINTR_INTI0; 2492 (void) envctrl_xmit(unitp, (caddr_t *)(void *)&initval, PCF8574); 2493 2494 /* 2495 * set lowerbits all high p0 = PS1, p1 = PS2 2496 * p2 = PS3 p4 = envctrl intr_ctrl 2497 */ 2498 initval.val = ENVCTRL_DEVINTR_INTI1; 2499 (void) envctrl_xmit(unitp, (caddr_t *)(void *)&initval, PCF8574); 2500} 2501 2502/* called with mutex held */ 2503static void 2504envctrl_stop_clock(struct envctrlunit *unitp) 2505{ 2506 int status; 2507 uint8_t buf[2]; 2508 2509 /* 2510 * This routine talks to the PCF8583 which 2511 * is a clock calendar chip on the envctrl bus. 2512 * We use this chip as a watchdog timer for the 2513 * fan control. At reset this chip pulses the interrupt 2514 * line every 1 second. We need to be able to shut 2515 * this off. 2516 */ 2517 2518 ASSERT(MUTEX_HELD(&unitp->umutex)); 2519 2520 buf[0] = CLOCK_CSR_REG; 2521 buf[1] = CLOCK_DISABLE; 2522 2523 status = eHc_write_pcf8583((struct eHc_envcunit *)unitp, 2524 PCF8583_BASE_ADDR | 0, buf, 2); 2525 if (status != DDI_SUCCESS) 2526 cmn_err(CE_WARN, "write to PCF8583 failed\n"); 2527} 2528 2529static void 2530envctrl_reset_watchdog(struct envctrlunit *unitp, uint8_t *wdval) 2531{ 2532 2533 uint8_t w, r; 2534 uint8_t res = 0; 2535 int status; 2536 uint8_t buf[3]; 2537 2538 ASSERT(MUTEX_HELD(&unitp->umutex)); 2539 2540 /* the clock MUST be stopped before we re-set it */ 2541 envctrl_stop_clock(unitp); 2542 2543 /* 2544 * Reset the minutes counter to 0. 2545 */ 2546 buf[0] = ALARM_CTR_REG_MINS; 2547 buf[1] = 0x0; 2548 status = eHc_write_pcf8583((struct eHc_envcunit *)unitp, 2549 PCF8583_BASE_ADDR | 0, buf, 2); 2550 if (status != DDI_SUCCESS) 2551 cmn_err(CE_WARN, "write to PCF8583 failed\n"); 2552 2553 /* 2554 * set up the alarm timer for 3 minutes 2555 * start by setting reg 8 ALARM_CTRL_REG 2556 * If we are in diag mode, we set the timer in 2557 * seconds. Valid values are 40-99. The timer 2558 * counts up to 99. 40 would be 59 seconds 2559 */ 2560 buf[0] = CLOCK_ALARM_REG_A; 2561 if (unitp->current_mode == ENVCTRL_DIAG_MODE) { 2562 if (unitp->timeout_id != 0) { 2563 (void) untimeout(unitp->timeout_id); 2564 unitp->timeout_id = 0; 2565 unitp->timeout_id = (timeout(envctrl_tempr_poll, 2566 (caddr_t)unitp, overtemp_timeout_hz)); 2567 } 2568 buf[1] = CLOCK_ENABLE_TIMER_S; 2569 } else { 2570 buf[1] = CLOCK_ENABLE_TIMER; 2571 } 2572 2573 /* STEP 10: End Transmission */ 2574 status = eHc_write_pcf8583((struct eHc_envcunit *)unitp, 2575 PCF8583_BASE_ADDR | 0, buf, 2); 2576 if (status != DDI_SUCCESS) 2577 cmn_err(CE_WARN, "Reset envctrl watchdog failed\n"); 2578 2579 /* 2580 * Now set up the alarm timer register it 2581 * counts from 0-99 with an intr triggered 2582 * when it gets to overflow.. or 99. It will 2583 * also count from a pre-set value which is 2584 * where we are seting from. We want a 3 minute fail 2585 * safe so our value is 99-3 or 96. 2586 * we are programming register 7 in the 8583. 2587 */ 2588 2589 buf[0] = ALARM_CTRL_REG; 2590 /* 2591 * Allow the diagnostic to set the egg timer val. 2592 * never allow it to be set greater than the default. 2593 */ 2594 if (unitp->current_mode == ENVCTRL_DIAG_MODE) { 2595 if (*wdval > MAX_CL_VAL) { 2596 buf[1] = EGG_TIMER_VAL; 2597 } else { 2598 2599 w = *wdval/10; 2600 r = *wdval%10; 2601 2602 res = res | r; 2603 res = (0x99 - (res | (w << 4))); 2604 buf[1] = res; 2605 } 2606 } else { 2607 buf[1] = EGG_TIMER_VAL; 2608 } 2609 2610 status = eHc_write_pcf8583((struct eHc_envcunit *)unitp, 2611 PCF8583_BASE_ADDR | 0, buf, 2); 2612 if (status != DDI_SUCCESS) 2613 cmn_err(CE_WARN, "Reset envctrl watchdog failed\n"); 2614 2615 2616 /* 2617 * Now that we have set up.. it is time 2618 * to re-start the clock in the CSR. 2619 */ 2620 2621 buf[0] = CLOCK_CSR_REG; 2622 buf[1] = CLOCK_ENABLE; 2623 status = eHc_write_pcf8583((struct eHc_envcunit *)unitp, 2624 PCF8583_BASE_ADDR | 0, buf, 2); 2625 if (status != DDI_SUCCESS) 2626 cmn_err(CE_WARN, "Reset envctrl watchdog failed\n"); 2627 2628} 2629 2630/* Called with unip mutex held */ 2631static void 2632envctrl_ps_probe(struct envctrlunit *unitp) 2633{ 2634 2635 uint8_t recv_data, fpmstat; 2636 uint8_t psaddr[] = {PS1, PS2, PS3, PSTEMP0}; 2637 int i; 2638 int ps_error = 0, retrys = 0; 2639 int devaddr; 2640 int status; 2641 int twotimes = 0; 2642 2643 ASSERT(MUTEX_HELD(&unitp->umutex)); 2644 2645 unitp->num_ps_present = 0; 2646 2647 for (i = 0; i <= MAXPS; i++) { 2648 unitp->ps_present[i] = B_FALSE; 2649 unitp->ps_kstats[i].ps_rating = 0; 2650 unitp->ps_kstats[i].ps_tempr = 0; 2651 2652 switch (psaddr[i]) { 2653 case PS1: 2654 devaddr = ENVCTRL_PCF8574_DEV3; 2655 break; 2656 case PS2: 2657 devaddr = ENVCTRL_PCF8574_DEV2; 2658 break; 2659 case PS3: 2660 devaddr = ENVCTRL_PCF8574_DEV1; 2661 break; 2662 case PSTEMP0: 2663 devaddr = 0; 2664 break; 2665 } 2666 retrys = 0; 2667retry: 2668 status = eHc_read_pcf8574a((struct eHc_envcunit *)unitp, 2669 PCF8574A_BASE_ADDR | devaddr, &recv_data, 1); 2670 if (status != DDI_SUCCESS) { 2671 drv_usecwait(1000); 2672 if (retrys < envctrl_max_retries) { 2673 retrys++; 2674 goto retry; 2675 } else { 2676 mutex_exit(&unitp->umutex); 2677 envctrl_init_bus(unitp); 2678 mutex_enter(&unitp->umutex); 2679 /* 2680 * If we just reset the bus we need to reread 2681 * the status. If a second attempt still fails 2682 * then report the read failure. 2683 */ 2684 if (twotimes == 0) { 2685 twotimes++; 2686 retrys = 0; 2687 goto retry; 2688 } else { 2689 cmn_err(CE_WARN, 2690 "PS_probe: Read from 8574A failed\n"); 2691 } 2692 } 2693 } 2694 2695 /* 2696 * Port 0 = PS Present 2697 * Port 1 = PS Type 2698 * Port 2 = PS Type 2699 * Port 3 = PS TYpe 2700 * Port 4 = DC Status 2701 * Port 5 = Current Limit 2702 * Port 6 = Current Share 2703 * Port 7 = SPARE 2704 */ 2705 2706 /* 2707 * Port 0 = PS Present 2708 * Port is pulled LOW "0" to indicate 2709 * present. 2710 */ 2711 2712 if (!(recv_data & ENVCTRL_PCF8574_PORT0)) { 2713 unitp->ps_present[i] = B_TRUE; 2714 /* update unit kstat array */ 2715 unitp->ps_kstats[i].instance = i; 2716 unitp->ps_kstats[i].ps_tempr = ENVCTRL_INIT_TEMPR; 2717 ++unitp->num_ps_present; 2718 2719 if (power_supply_previous_state[i] == 0) { 2720 cmn_err(CE_NOTE, 2721 "Power Supply %d inserted\n", i); 2722 } 2723 power_supply_previous_state[i] = 1; 2724 2725 if (!(recv_data & ENVCTRL_PCF8574_PORT1)) { 2726 unitp->ps_kstats[i].ps_rating = ENVCTRL_PS_550; 2727 } 2728 if (!(recv_data & ENVCTRL_PCF8574_PORT2)) { 2729 unitp->ps_kstats[i].ps_rating = ENVCTRL_PS_650; 2730 } 2731 if (!(recv_data & ENVCTRL_PCF8574_PORT3)) { 2732 cmn_err(CE_WARN, 2733 "Power Supply %d NOT okay\n", i); 2734 unitp->ps_kstats[i].ps_ok = B_FALSE; 2735 ps_error++; 2736 } else { 2737 unitp->ps_kstats[i].ps_ok = B_TRUE; 2738 } 2739 if (!(recv_data & ENVCTRL_PCF8574_PORT4)) { 2740 cmn_err(CE_WARN, 2741 "Power Supply %d Overloaded\n", i); 2742 unitp->ps_kstats[i].limit_ok = B_FALSE; 2743 ps_error++; 2744 } else { 2745 unitp->ps_kstats[i].limit_ok = B_TRUE; 2746 } 2747 if (!(recv_data & ENVCTRL_PCF8574_PORT5)) { 2748 cmn_err(CE_WARN, 2749 "Power Supply %d load share err\n", i); 2750 unitp->ps_kstats[i].curr_share_ok = B_FALSE; 2751 ps_error++; 2752 } else { 2753 unitp->ps_kstats[i].curr_share_ok = B_TRUE; 2754 } 2755 2756 if (!(recv_data & ENVCTRL_PCF8574_PORT6)) { 2757 cmn_err(CE_WARN, 2758 "PS %d Shouln't interrupt\n", i); 2759 ps_error++; 2760 } 2761 2762 if (!(recv_data & ENVCTRL_PCF8574_PORT7)) { 2763 cmn_err(CE_WARN, 2764 "PS %d Shouln't interrupt\n", i); 2765 ps_error++; 2766 } 2767 } else { 2768 /* No power supply present */ 2769 if (power_supply_previous_state[i] == 1) { 2770 cmn_err(CE_NOTE, 2771 "Power Supply %d removed\n", i); 2772 } 2773 power_supply_previous_state[i] = 0; 2774 } 2775 } 2776 2777 fpmstat = envctrl_get_fpm_status(unitp); 2778 if (ps_error) { 2779 fpmstat |= (ENVCTRL_FSP_PS_ERR | ENVCTRL_FSP_GEN_ERR); 2780 } else { 2781 if (envctrl_isother_fault_led(unitp, fpmstat, 2782 ENVCTRL_FSP_PS_ERR)) { 2783 fpmstat &= ~(ENVCTRL_FSP_PS_ERR); 2784 } else { 2785 fpmstat &= ~(ENVCTRL_FSP_PS_ERR | 2786 ENVCTRL_FSP_GEN_ERR); 2787 } 2788 2789 } 2790 envctrl_set_fsp(unitp, &fpmstat); 2791 2792 /* 2793 * We need to reset all of the fans etc when a supply is 2794 * interrupted and added, but we don't want to reset the 2795 * fans if we are in DIAG mode. This will mess up SUNVTS. 2796 */ 2797 if (unitp->current_mode == ENVCTRL_NORMAL_MODE) { 2798 envctrl_get_sys_temperatures(unitp, (uint8_t *)NULL); 2799 } 2800} 2801 2802/* 2803 * consider key switch position when handling an abort sequence 2804 */ 2805static void 2806envctrl_abort_seq_handler(char *msg) 2807{ 2808 struct envctrlunit *unitp; 2809 int i; 2810 uint8_t secure = 0; 2811 2812 /* 2813 * Find the instance of the device available on this host. 2814 * Note that there may be only one, but the instance may 2815 * not be zero. 2816 */ 2817 for (i = 0; i < MAX_DEVS; i++) { 2818 if (unitp = (struct envctrlunit *) 2819 ddi_get_soft_state(envctrlsoft_statep, i)) 2820 break; 2821 } 2822 2823 ASSERT(unitp); 2824 2825 for (i = 0; i < MAX_DEVS; i++) { 2826 if ((unitp->encl_kstats[i].type == ENVCTRL_ENCL_FSP) && 2827 (unitp->encl_kstats[i].instance != I2C_NODEV)) { 2828 secure = unitp->encl_kstats[i].value; 2829 break; 2830 } 2831 } 2832 2833 /* 2834 * take the logical not because we are in hardware mode only 2835 */ 2836 2837 if ((secure & ENVCTRL_FSP_KEYMASK) == ENVCTRL_FSP_KEYLOCKED) { 2838 cmn_err(CE_CONT, 2839 "!envctrl: ignoring debug enter sequence\n"); 2840 } else { 2841 if (envctrl_debug_flags) { 2842 cmn_err(CE_CONT, "!envctrl: allowing debug enter\n"); 2843 } 2844 debug_enter(msg); 2845 } 2846} 2847 2848/* 2849 * get the front Panel module LED and keyswitch status. 2850 * this part is addressed at 0x7C on the i2c bus. 2851 * called with mutex held 2852 */ 2853static uint8_t 2854envctrl_get_fpm_status(struct envctrlunit *unitp) 2855{ 2856 uint8_t recv_data; 2857 int status, retrys = 0; 2858 2859 ASSERT(MUTEX_HELD(&unitp->umutex)); 2860 2861retry: 2862 status = eHc_read_pcf8574a((struct eHc_envcunit *)unitp, 2863 PCF8574A_BASE_ADDR | ENVCTRL_PCF8574_DEV6, &recv_data, 1); 2864 2865 /* 2866 * yet another place where a read can cause the 2867 * the SDA line of the i2c bus to get stuck low. 2868 * this funky sequence frees the SDA line. 2869 */ 2870 if (status != DDI_SUCCESS) { 2871 drv_usecwait(1000); 2872 if (retrys < envctrl_max_retries) { 2873 retrys++; 2874 goto retry; 2875 } else { 2876 mutex_exit(&unitp->umutex); 2877 envctrl_init_bus(unitp); 2878 mutex_enter(&unitp->umutex); 2879 if (envctrl_debug_flags) 2880 cmn_err(CE_WARN, "Read from PCF8574 (FPM) "\ 2881 "failed\n"); 2882 } 2883 } 2884 recv_data = ~recv_data; 2885 envctrl_mod_encl_kstats(unitp, ENVCTRL_ENCL_FSP, 2886 INSTANCE_0, recv_data); 2887 2888 return (recv_data); 2889} 2890 2891static void 2892envctrl_set_fsp(struct envctrlunit *unitp, uint8_t *val) 2893{ 2894 struct envctrl_pcf8574_chip chip; 2895 2896 ASSERT(MUTEX_HELD(&unitp->umutex)); 2897 2898 chip.val = ENVCTRL_FSP_OFF; /* init all values to off */ 2899 chip.chip_num = ENVCTRL_PCF8574_DEV6; /* 0x01 port 1 */ 2900 chip.type = PCF8574A; 2901 2902 /* 2903 * strip off bits that are R/O 2904 */ 2905 chip.val = (~(ENVCTRL_FSP_KEYMASK | ENVCTRL_FSP_POMASK) & (*val)); 2906 2907 chip.val = ~chip.val; 2908 (void) envctrl_xmit(unitp, (caddr_t *)(void *)&chip, PCF8574); 2909 2910} 2911 2912static int 2913envctrl_get_dskled(struct envctrlunit *unitp, struct envctrl_pcf8574_chip *chip) 2914{ 2915 uint_t oldtype; 2916 2917 ASSERT(MUTEX_HELD(&unitp->umutex)); 2918 2919 if (chip->chip_num > ENVCTRL_PCF8574_DEV2 || 2920 chip->type != ENVCTRL_ENCL_BACKPLANE4 && 2921 chip->type != ENVCTRL_ENCL_BACKPLANE8) { 2922 return (DDI_FAILURE); 2923 } 2924 oldtype = chip->type; 2925 chip->type = PCF8574; 2926 envctrl_recv(unitp, (caddr_t *)(void *)chip, PCF8574); 2927 chip->type = oldtype; 2928 chip->val = ~chip->val; 2929 2930 return (DDI_SUCCESS); 2931} 2932static int 2933envctrl_set_dskled(struct envctrlunit *unitp, struct envctrl_pcf8574_chip *chip) 2934{ 2935 2936 struct envctrl_pcf8574_chip fspchip; 2937 struct envctrl_pcf8574_chip backchip; 2938 int i, instance; 2939 int diskfault = 0; 2940 uint8_t controller_addr[] = {ENVCTRL_PCF8574_DEV0, ENVCTRL_PCF8574_DEV1, 2941 ENVCTRL_PCF8574_DEV2}; 2942 2943 /* 2944 * We need to check the type of disk led being set. If it 2945 * is a 4 slot backplane then the upper 4 bits (7, 6, 5, 4) are 2946 * invalid. 2947 */ 2948 ASSERT(MUTEX_HELD(&unitp->umutex)); 2949 2950 2951 if (chip->chip_num > ENVCTRL_PCF8574_DEV2 || 2952 chip->val > ENVCTRL_DISK8LED_ALLOFF || 2953 chip->val < ENVCTRL_CHAR_ZERO) { 2954 return (DDI_FAILURE); 2955 } 2956 2957 if (chip->type != ENVCTRL_ENCL_BACKPLANE4 && 2958 chip->type != ENVCTRL_ENCL_BACKPLANE8) { 2959 return (DDI_FAILURE); 2960 } 2961 2962 /* 2963 * Check all of the other controllwes LED states to make sure 2964 * that there are no disk faults. If so then if the user is 2965 * clearing the disk faults on this contoller, turn off 2966 * the mass storage fault led. 2967 */ 2968 2969 backchip.type = PCF8574; 2970 for (i = 0; i <= MAX_TAZ_CONTROLLERS; i++) { 2971 if (controller_present[i] == -1) 2972 continue; 2973 backchip.chip_num = controller_addr[i]; 2974 envctrl_recv(unitp, (caddr_t *)(void *)&backchip, PCF8574); 2975 if (chip->chip_num == controller_addr[i]) { 2976 if (chip->val != ENVCTRL_CHAR_ZERO) 2977 diskfault++; 2978 } else if ((~backchip.val & 0xFF) != ENVCTRL_CHAR_ZERO) { 2979 diskfault++; 2980 } 2981 } 2982 2983 fspchip.type = PCF8574A; 2984 fspchip.chip_num = ENVCTRL_PCF8574_DEV6; /* 0x01 port 1 */ 2985 envctrl_recv(unitp, (caddr_t *)(void *)&fspchip, PCF8574); 2986 2987 if (diskfault) { 2988 if (!(envctrl_isother_fault_led(unitp, fspchip.val & 0xFF, 2989 ENVCTRL_FSP_DISK_ERR))) { 2990 fspchip.val &= ~(ENVCTRL_FSP_DISK_ERR); 2991 } else { 2992 fspchip.val &= ~(ENVCTRL_FSP_DISK_ERR | 2993 ENVCTRL_FSP_GEN_ERR); 2994 } 2995 fspchip.val = (fspchip.val & 2996 ~(ENVCTRL_FSP_DISK_ERR | ENVCTRL_FSP_GEN_ERR)); 2997 } else { 2998 fspchip.val = (fspchip.val | 2999 (ENVCTRL_FSP_DISK_ERR | ENVCTRL_FSP_GEN_ERR)); 3000 } 3001 fspchip.type = PCF8574A; 3002 fspchip.chip_num = ENVCTRL_PCF8574_DEV6; /* 0x01 port 1 */ 3003 (void) envctrl_xmit(unitp, (caddr_t *)(void *)&fspchip, PCF8574); 3004 3005 for (i = 0; i < (sizeof (backaddrs) / sizeof (uint8_t)); i++) { 3006 if (chip->chip_num == backaddrs[i]) { 3007 instance = i; 3008 } 3009 } 3010 3011 switch (chip->type) { 3012 case ENVCTRL_ENCL_BACKPLANE4: 3013 envctrl_mod_encl_kstats(unitp, ENVCTRL_ENCL_BACKPLANE4, 3014 instance, chip->val); 3015 break; 3016 case ENVCTRL_ENCL_BACKPLANE8: 3017 envctrl_mod_encl_kstats(unitp, ENVCTRL_ENCL_BACKPLANE8, 3018 instance, chip->val); 3019 break; 3020 default: 3021 break; 3022 } 3023 chip->type = PCF8574; 3024 /* 3025 * we take the ones compliment of the val passed in 3026 * because the hardware thinks that a "low" or "0" 3027 * is the way to indicate a fault. of course software 3028 * knows that a 1 is a TRUE state or fault. ;-) 3029 */ 3030 chip->val = ~(chip->val); 3031 (void) envctrl_xmit(unitp, (caddr_t *)(void *)chip, PCF8574); 3032 return (DDI_SUCCESS); 3033} 3034 3035void 3036envctrl_add_kstats(struct envctrlunit *unitp) 3037{ 3038 3039 ASSERT(MUTEX_HELD(&unitp->umutex)); 3040 3041 if ((unitp->enclksp = kstat_create(ENVCTRL_MODULE_NAME, unitp->instance, 3042 ENVCTRL_KSTAT_ENCL, "misc", KSTAT_TYPE_RAW, 3043 sizeof (unitp->encl_kstats), 3044 KSTAT_FLAG_PERSISTENT)) == NULL) { 3045 cmn_err(CE_WARN, "envctrl%d: encl raw kstat_create failed", 3046 unitp->instance); 3047 return; 3048 } 3049 3050 unitp->enclksp->ks_update = envctrl_encl_kstat_update; 3051 unitp->enclksp->ks_private = (void *)unitp; 3052 kstat_install(unitp->enclksp); 3053 3054 3055 if ((unitp->fanksp = kstat_create(ENVCTRL_MODULE_NAME, unitp->instance, 3056 ENVCTRL_KSTAT_FANSTAT, "misc", KSTAT_TYPE_RAW, 3057 sizeof (unitp->fan_kstats), 3058 KSTAT_FLAG_PERSISTENT)) == NULL) { 3059 cmn_err(CE_WARN, "envctrl%d: fans kstat_create failed", 3060 unitp->instance); 3061 return; 3062 } 3063 3064 unitp->fanksp->ks_update = envctrl_fanstat_kstat_update; 3065 unitp->fanksp->ks_private = (void *)unitp; 3066 kstat_install(unitp->fanksp); 3067 3068 if ((unitp->psksp = kstat_create(ENVCTRL_MODULE_NAME, unitp->instance, 3069 ENVCTRL_KSTAT_PSNAME, "misc", KSTAT_TYPE_RAW, 3070 sizeof (unitp->ps_kstats), 3071 KSTAT_FLAG_PERSISTENT)) == NULL) { 3072 cmn_err(CE_WARN, "envctrl%d: ps name kstat_create failed", 3073 unitp->instance); 3074 return; 3075 } 3076 3077 unitp->psksp->ks_update = envctrl_ps_kstat_update; 3078 unitp->psksp->ks_private = (void *)unitp; 3079 kstat_install(unitp->psksp); 3080 3081} 3082 3083int 3084envctrl_ps_kstat_update(kstat_t *ksp, int rw) 3085{ 3086 struct envctrlunit *unitp; 3087 char *kstatp; 3088 3089 3090 3091 unitp = (struct envctrlunit *)ksp->ks_private; 3092 3093 mutex_enter(&unitp->umutex); 3094 ASSERT(MUTEX_HELD(&unitp->umutex)); 3095 3096 kstatp = (char *)ksp->ks_data; 3097 3098 if (rw == KSTAT_WRITE) { 3099 return (EACCES); 3100 } else { 3101 3102 unitp->psksp->ks_ndata = unitp->num_ps_present; 3103 bcopy(&unitp->ps_kstats, kstatp, sizeof (unitp->ps_kstats)); 3104 } 3105 mutex_exit(&unitp->umutex); 3106 return (DDI_SUCCESS); 3107} 3108int 3109envctrl_fanstat_kstat_update(kstat_t *ksp, int rw) 3110{ 3111 struct envctrlunit *unitp; 3112 char *kstatp; 3113 3114 kstatp = (char *)ksp->ks_data; 3115 unitp = (struct envctrlunit *)ksp->ks_private; 3116 3117 mutex_enter(&unitp->umutex); 3118 ASSERT(MUTEX_HELD(&unitp->umutex)); 3119 3120 if (rw == KSTAT_WRITE) { 3121 return (EACCES); 3122 } else { 3123 unitp->fanksp->ks_ndata = unitp->num_fans_present; 3124 bcopy(unitp->fan_kstats, kstatp, sizeof (unitp->fan_kstats)); 3125 } 3126 mutex_exit(&unitp->umutex); 3127 return (DDI_SUCCESS); 3128} 3129 3130int 3131envctrl_encl_kstat_update(kstat_t *ksp, int rw) 3132{ 3133 struct envctrlunit *unitp; 3134 char *kstatp; 3135 3136 3137 kstatp = (char *)ksp->ks_data; 3138 unitp = (struct envctrlunit *)ksp->ks_private; 3139 3140 mutex_enter(&unitp->umutex); 3141 ASSERT(MUTEX_HELD(&unitp->umutex)); 3142 3143 if (rw == KSTAT_WRITE) { 3144 return (EACCES); 3145 } else { 3146 3147 unitp->enclksp->ks_ndata = unitp->num_encl_present; 3148 (void) envctrl_get_fpm_status(unitp); 3149 /* XXX Need to ad disk updates too ??? */ 3150 bcopy(unitp->encl_kstats, kstatp, sizeof (unitp->encl_kstats)); 3151 } 3152 mutex_exit(&unitp->umutex); 3153 return (DDI_SUCCESS); 3154} 3155 3156/* 3157 * called with unitp lock held 3158 * type, fanspeed and fanflt will be set by the service routines 3159 */ 3160static void 3161envctrl_init_fan_kstats(struct envctrlunit *unitp) 3162{ 3163 int i; 3164 3165 ASSERT(MUTEX_HELD(&unitp->umutex)); 3166 3167 for (i = 0; i < unitp->num_fans_present; i++) { 3168 unitp->fan_kstats[i].instance = 0; 3169 unitp->fan_kstats[i].type = 0; 3170 unitp->fan_kstats[i].fans_ok = B_TRUE; 3171 unitp->fan_kstats[i].fanflt_num = B_FALSE; 3172 unitp->fan_kstats[i].fanspeed = B_FALSE; 3173 } 3174 3175 unitp->fan_kstats[ENVCTRL_FAN_TYPE_PS].type = ENVCTRL_FAN_TYPE_PS; 3176 unitp->fan_kstats[ENVCTRL_FAN_TYPE_CPU].type = ENVCTRL_FAN_TYPE_CPU; 3177 if (unitp->AFB_present == B_TRUE) 3178 unitp->fan_kstats[ENVCTRL_FAN_TYPE_AFB].type = 3179 ENVCTRL_FAN_TYPE_AFB; 3180} 3181 3182static void 3183envctrl_init_encl_kstats(struct envctrlunit *unitp) 3184{ 3185 3186 int i; 3187 uint8_t val; 3188 struct envctrl_pcf8574_chip chip; 3189 int *reg_prop; 3190 uint_t len = 0; 3191 3192 ASSERT(MUTEX_HELD(&unitp->umutex)); 3193 3194 for (i = 0; i < MAX_DEVS; i++) { 3195 unitp->encl_kstats[i].instance = I2C_NODEV; 3196 } 3197 3198 /* 3199 * add in kstats now 3200 * We ALWAYS HAVE THE FOLLOWING 3201 * 1. FSP 3202 * 2. AMB TEMPR 3203 * 3. (1) CPU TEMPR 3204 * 4. (1) 4 slot disk backplane 3205 * OPTIONAL 3206 * 8 slot backplane 3207 * more cpu's 3208 */ 3209 3210 chip.type = PCF8574A; 3211 chip.chip_num = ENVCTRL_PCF8574_DEV6; /* 0x01 port 1 */ 3212 envctrl_recv(unitp, (caddr_t *)(void *)&chip, PCF8574); 3213 3214 envctrl_add_encl_kstats(unitp, ENVCTRL_ENCL_FSP, INSTANCE_0, 3215 chip.val & 0xFF); 3216 3217 val = envctrl_get_lm75_temp(unitp) & 0xFF; 3218 envctrl_add_encl_kstats(unitp, ENVCTRL_ENCL_AMBTEMPR, INSTANCE_0, val); 3219 3220 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, unitp->dip, 3221 DDI_PROP_DONTPASS, ENVCTRL_DISK_LEDS_PR, 3222 ®_prop, &len) != DDI_PROP_SUCCESS) { 3223 cmn_err(CE_WARN, "prop lookup of %s failed\n", 3224 ENVCTRL_DISK_LEDS_PR); 3225 return; 3226 } 3227 3228 ASSERT(len != 0); 3229 3230 chip.type = PCF8574; 3231 3232 for (i = 0; i < len; i++) { 3233 chip.chip_num = backaddrs[i]; 3234 if (reg_prop[i] == ENVCTRL_4SLOT_BACKPLANE) { 3235 envctrl_recv(unitp, (caddr_t *)(void *)&chip, PCF8574); 3236 envctrl_add_encl_kstats(unitp, ENVCTRL_ENCL_BACKPLANE4, 3237 i, ~chip.val); 3238 controller_present[i] = 1; 3239 } 3240 if (reg_prop[i] == ENVCTRL_8SLOT_BACKPLANE) { 3241 envctrl_recv(unitp, (caddr_t *)(void *)&chip, PCF8574); 3242 envctrl_add_encl_kstats(unitp, ENVCTRL_ENCL_BACKPLANE8, 3243 i, ~chip.val); 3244 controller_present[i] = 1; 3245 } 3246 } 3247 ddi_prop_free((void *)reg_prop); 3248 3249} 3250 3251static void 3252envctrl_mod_encl_kstats(struct envctrlunit *unitp, int type, 3253 int instance, uint8_t val) 3254{ 3255 int i = 0; 3256 boolean_t inserted = B_FALSE; 3257 3258 ASSERT(MUTEX_HELD(&unitp->umutex)); 3259 3260 while (i < MAX_DEVS && inserted == B_FALSE) { 3261 if (unitp->encl_kstats[i].instance == instance && 3262 unitp->encl_kstats[i].type == type) { 3263 unitp->encl_kstats[i].value = val; 3264 inserted = B_TRUE; 3265 } 3266 i++; 3267 } 3268} 3269 3270static void 3271envctrl_probe_cpus(struct envctrlunit *unitp) 3272{ 3273 int instance; 3274 3275 /* 3276 * The cpu search is as follows: 3277 * If there is only 1 CPU module it is named as 3278 * SUNW,UltraSPARC. If this is a match we still don't 3279 * know what slot the cpu module is in therefore 3280 * we need to check the "upa-portid" property. 3281 * If we have more than 1 cpu, then they are appended by 3282 * instance numbers and slot locations. e.g. 3283 * SUNW,UltraSPARC@1,0 (slot 1). it would have been 3284 * nice to have the naming consistent for one CPU e.g. 3285 * SUNW,UltraSPARC@0,0...sigh 3286 */ 3287 3288 for (instance = 0; instance < ENVCTRL_MAX_CPUS; instance++) { 3289 unitp->cpu_pr_location[instance] = B_FALSE; 3290 } 3291 3292 ddi_walk_devs(ddi_root_node(), envctrl_match_cpu, unitp); 3293} 3294 3295static int 3296envctrl_match_cpu(dev_info_t *dip, void *arg) 3297{ 3298 3299 int cpu_slot; 3300 char name[32]; 3301 char name1[32]; 3302 struct envctrlunit *unitp = (struct envctrlunit *)arg; 3303 3304 (void) sprintf(name, "%s", ENVCTRL_TAZCPU_STRING); 3305 (void) sprintf(name1, "%s", ENVCTRL_TAZBLKBRDCPU_STRING); 3306 3307 if ((strcmp(ddi_node_name(dip), name) == 0) || 3308 (strcmp(ddi_node_name(dip), name1) == 0)) { 3309 if ((cpu_slot = (int)ddi_getprop(DDI_DEV_T_ANY, dip, 3310 DDI_PROP_DONTPASS, "upa-portid", 3311 -1)) == -1) { 3312 cmn_err(CE_WARN, "envctrl no cpu upa-portid"); 3313 } else { 3314 unitp->cpu_pr_location[cpu_slot] = B_TRUE; 3315 unitp->num_cpus_present++; 3316 } 3317 } 3318 3319 return (DDI_WALK_CONTINUE); 3320} 3321 3322/* 3323 * This routine returns TRUE if some other error condition 3324 * has set the GEN_ERR FAULT LED. Tp further complicate this 3325 * LED panel we have overloaded the GEN_ERR LED to indicate 3326 * that a fan fault has occurred without having a fan fault 3327 * LED as does all other error conditions. So we just take the 3328 * software state and return true. The whole purpose of this functon 3329 * is to tell us wehther or not we can shut off the GEN_FAULT LED. 3330 * NOTE: this ledval is usually one of the following FSP vals 3331 * EXCEPT in the case of the fan fail.. we pass in a "0". 3332 */ 3333 3334static int 3335envctrl_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 3355static void 3356envctrl_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 */ 3375static int 3376eHc_start_pcf8584(struct eHc_envcunit *ehcp, uint8_t byteaddress) 3377{ 3378 uint8_t poll_status; 3379 uint8_t discard; 3380 int i; 3381 3382 /* wait if bus is busy */ 3383 3384 i = 0; 3385 do { 3386 drv_usecwait(1000); 3387 poll_status = 3388 ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1); 3389 i++; 3390 } while (((poll_status & EHC_S1_NBB) == 0) && i < EHC_MAX_WAIT); 3391 3392 if (i == EHC_MAX_WAIT) { 3393 DCMNERR(CE_WARN, "eHc_start_pcf8584: I2C bus busy"); 3394 return (EHC_FAILURE); 3395 } 3396 3397 if (poll_status & EHC_S1_BER) { 3398 DCMN2ERR(CE_WARN, "eHc_start_pcf8584: I2C bus error"); 3399 return (EHC_FAILURE); 3400 } 3401 3402 if (poll_status & EHC_S1_LAB) { 3403 DCMN2ERR(CE_WARN, "eHc_start_pcf8584: Lost arbitration"); 3404 return (EHC_FAILURE); 3405 } 3406 3407 /* load the slave address */ 3408 ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0, byteaddress); 3409 3410 /* generate the "start condition" and clock out the slave address */ 3411 ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1, 3412 EHC_S1_PIN | EHC_S1_ES0 | EHC_S1_STA | EHC_S1_ACK); 3413 3414 /* wait for completion of transmission */ 3415 i = 0; 3416 do { 3417 drv_usecwait(1000); 3418 poll_status = 3419 ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1); 3420 i++; 3421 } while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT); 3422 3423 if (i == EHC_MAX_WAIT) { 3424 DCMNERR(CE_WARN, "eHc_start_pcf8584: I2C bus busy"); 3425 return (EHC_FAILURE); 3426 } 3427 3428 if (poll_status & EHC_S1_BER) { 3429 DCMN2ERR(CE_WARN, "eHc_start_pcf8584: I2C bus error"); 3430 return (EHC_FAILURE); 3431 } 3432 3433 if (poll_status & EHC_S1_LAB) { 3434 DCMN2ERR(CE_WARN, "eHc_start_pcf8584: Lost arbitration"); 3435 return (EHC_FAILURE); 3436 } 3437 3438 if (poll_status & EHC_S1_LRB) { 3439 DCMNERR(CE_WARN, "eHc_start_pcf8584: No slave ACK"); 3440 return (EHC_NO_SLAVE_ACK); 3441 } 3442 3443 /* 3444 * If this is a read we are setting up for (as indicated by 3445 * the least significant byte being set), read 3446 * and discard the first byte off the bus - this 3447 * is the slave address. 3448 */ 3449 3450 i = 0; 3451 if (byteaddress & EHC_BYTE_READ) { 3452 discard = ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0); 3453#ifdef lint 3454 discard = discard; 3455#endif 3456 3457 /* wait for completion of transmission */ 3458 do { 3459 drv_usecwait(1000); 3460 poll_status = 3461 ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1); 3462 i++; 3463 } while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT); 3464 3465 if (i == EHC_MAX_WAIT) { 3466 DCMNERR(CE_WARN, "eHc_start_pcf8584: I2C bus busy"); 3467 return (EHC_FAILURE); 3468 } 3469 3470 if (poll_status & EHC_S1_BER) { 3471 DCMN2ERR(CE_WARN, 3472 "eHc_start_pcf8584: I2C bus error"); 3473 return (EHC_FAILURE); 3474 } 3475 3476 if (poll_status & EHC_S1_LAB) { 3477 DCMN2ERR(CE_WARN, 3478 "eHc_start_pcf8584: Lost arbitration"); 3479 return (EHC_FAILURE); 3480 } 3481 } 3482 3483 return (EHC_SUCCESS); 3484} 3485 3486/* 3487 * put host interface into slave/receiver mode 3488 */ 3489static void 3490eHc_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 3496static int 3497eHc_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 3536static int 3537eHc_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 3576static int 3577eHc_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 */ 3636static int 3637eHc_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 */ 3688static int 3689eHc_read_pcf8574a(struct eHc_envcunit *ehcp, int byteaddress, uint8_t *buf, 3690 int size) 3691{ 3692 int i; 3693 int status; 3694 uint8_t discard; 3695 3696 ASSERT((byteaddress & 0x1) == 0); 3697 ASSERT(MUTEX_HELD(&ehcp->umutex)); 3698 3699 /* 3700 * Put the bus into the start condition 3701 */ 3702 if ((status = eHc_start_pcf8584(ehcp, EHC_BYTE_READ | byteaddress)) != 3703 EHC_SUCCESS) { 3704 if (status == EHC_NO_SLAVE_ACK) { 3705 /* 3706 * Send the "stop" condition. 3707 */ 3708 eHc_stop_pcf8584(ehcp); 3709 /* 3710 * Read the last byte - discard it. 3711 */ 3712 discard = 3713 ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0); 3714#ifdef lint 3715 discard = discard; 3716#endif 3717 } 3718 return (EHC_FAILURE); 3719 } 3720 3721 for (i = 0; i < size - 1; i++) { 3722 if ((status = eHc_read_pcf8584(ehcp, &buf[i])) != EHC_SUCCESS) { 3723 return (EHC_FAILURE); 3724 } 3725 } 3726 3727 /* 3728 * Handle the part of the bus protocol which comes 3729 * after a read, including reading the last byte. 3730 */ 3731 3732 if (eHc_after_read_pcf8584(ehcp, &buf[i]) != EHC_SUCCESS) { 3733 return (EHC_FAILURE); 3734 } 3735 3736 return (EHC_SUCCESS); 3737} 3738 3739/* 3740 * Write to the PCF8574A chip. 3741 * byteaddress = chip type base address | chip offset address. 3742 */ 3743static int 3744eHc_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 */ 3790static int 3791eHc_read_pcf8574(struct eHc_envcunit *ehcp, int byteaddress, uint8_t *buf, 3792 int size) 3793{ 3794 int i; 3795 int status; 3796 uint8_t discard; 3797 3798 ASSERT((byteaddress & 0x1) == 0); 3799 ASSERT(MUTEX_HELD(&ehcp->umutex)); 3800 3801 /* 3802 * Put the bus into the start condition 3803 */ 3804 if ((status = eHc_start_pcf8584(ehcp, EHC_BYTE_READ | byteaddress)) != 3805 EHC_SUCCESS) { 3806 if (status == EHC_NO_SLAVE_ACK) { 3807 /* 3808 * Send the "stop" condition. 3809 */ 3810 eHc_stop_pcf8584(ehcp); 3811 /* 3812 * Read the last byte - discard it. 3813 */ 3814 discard = 3815 ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0); 3816#ifdef lint 3817 discard = discard; 3818#endif 3819 } 3820 return (EHC_FAILURE); 3821 } 3822 3823 for (i = 0; i < size - 1; i++) { 3824 if ((status = eHc_read_pcf8584(ehcp, &buf[i])) != EHC_SUCCESS) { 3825 return (EHC_FAILURE); 3826 } 3827 } 3828 3829 /* 3830 * Handle the part of the bus protocol which comes 3831 * after a read. 3832 */ 3833 3834 if (eHc_after_read_pcf8584(ehcp, &buf[i]) != EHC_SUCCESS) { 3835 return (EHC_FAILURE); 3836 } 3837 3838 return (EHC_SUCCESS); 3839} 3840 3841/* 3842 * Write to the PCF8574 chip. 3843 * byteaddress = chip type base address | chip offset address. 3844 */ 3845static int 3846eHc_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 */ 3891static int 3892eHc_read_lm75(struct eHc_envcunit *ehcp, int byteaddress, uint8_t *buf, 3893 int size) 3894{ 3895 int i; 3896 int status; 3897 uint8_t discard; 3898 3899 ASSERT((byteaddress & 0x1) == 0); 3900 ASSERT(MUTEX_HELD(&ehcp->umutex)); 3901 3902 /* 3903 * Put the bus into the start condition 3904 */ 3905 if ((status = eHc_start_pcf8584(ehcp, EHC_BYTE_READ | byteaddress)) != 3906 EHC_SUCCESS) { 3907 if (status == EHC_NO_SLAVE_ACK) { 3908 /* 3909 * Send the stop condition. 3910 */ 3911 eHc_stop_pcf8584(ehcp); 3912 /* 3913 * Read the last byte - discard it. 3914 */ 3915 discard = 3916 ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0); 3917#ifdef lint 3918 discard = discard; 3919#endif 3920 } 3921 return (EHC_FAILURE); 3922 } 3923 3924 for (i = 0; i < size - 1; i++) { 3925 if ((status = eHc_read_pcf8584(ehcp, &buf[i])) != EHC_SUCCESS) { 3926 return (EHC_FAILURE); 3927 } 3928 } 3929 3930 /* 3931 * Handle the part of the bus protocol which comes 3932 * after a read. 3933 */ 3934 if (eHc_after_read_pcf8584(ehcp, &buf[i]) != EHC_SUCCESS) { 3935 return (EHC_FAILURE); 3936 } 3937 3938 return (EHC_SUCCESS); 3939} 3940 3941/* 3942 * Write to the PCF8583 chip. 3943 * byteaddress = chip type base address | chip offset address. 3944 */ 3945static int 3946eHc_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 */ 3989static int 3990eHc_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