3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * CDDL HEADER START
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The contents of this file are subject to the terms of the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Common Development and Distribution License (the "License").
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * You may not use this file except in compliance with the License.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * or http://www.opensolaris.org/os/licensing.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * See the License for the specific language governing permissions
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and limitations under the License.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * When distributing Covered Code, include this CDDL HEADER in each
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If applicable, add the following below this CDDL HEADER, with the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * fields enclosed by brackets "[]" replaced with your own identifying
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * information: Portions Copyright [yyyy] [name of copyright owner]
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * CDDL HEADER END
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
193974072f41a843678abf5f61979c748687e66bSherry Moore * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Use is subject to license terms.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * ENVCTRLTWO_ Environment Monitoring driver for i2c on Javelin
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/param.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/types.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/signal.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/errno.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/file.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/termio.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/termios.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/cmn_err.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/stream.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/strsun.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/stropts.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/strtty.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/debug.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/eucioctl.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/cred.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/uio.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/stat.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/kmem.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/ddi.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/sunddi.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/obpdefs.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/conf.h> /* req. by dev_ops flags MTSAFE etc. */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/modctl.h> /* for modldrv */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/stat.h> /* ddi_create_minor_node S_IFCHR */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/open.h> /* for open params. */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/uio.h> /* for read/write */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/envctrl_gen.h> /* user level generic visible definitions */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/envctrl_ue250.h> /* user level UE250 visible definitions */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <javelin/sys/envctrltwo.h> /* definitions for Javelin */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <io/envctrl_targets.c>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/priv_names.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/* driver entry point fn definitions */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_open(dev_t *, int, int, cred_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_close(dev_t, int, int, cred_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uint_t envctrl_bus_isr(caddr_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uint_t envctrl_dev_isr(caddr_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/* configuration entry point fn definitions */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_attach(dev_info_t *, ddi_attach_cmd_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_detach(dev_info_t *, ddi_detach_cmd_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/* Driver private routines */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef GET_CPU_TEMP
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_get_cpu_temp(struct envctrlunit *, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void envctrl_fan_fail_service(struct envctrlunit *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void envctrl_PS_intr_service(struct envctrlunit *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void envctrl_ps_probe(struct envctrlunit *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void envctrl_tempr_poll(void *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void envctrl_pshotplug_poll(void *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void envctrl_led_blink(void *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void envctrl_init_bus(struct envctrlunit *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void envctrl_reset_dflop(struct envctrlunit *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void envctrl_enable_devintrs(struct envctrlunit *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void envctrl_intr_latch_clr(struct envctrlunit *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void envctrl_abort_seq_handler(char *msg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_get_fpm_status(struct envctrlunit *, uint8_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_set_fsp(struct envctrlunit *, uint8_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_set_dskled(struct envctrlunit *,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrl_chip *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_get_dskled(struct envctrlunit *,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrl_chip *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_set_fanspeed(struct envctrlunit *,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrl_chip *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void envctrl_probe_cpus(struct envctrlunit *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_match_cpu(dev_info_t *, void *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_isother_fault_led(struct envctrlunit *,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t, uint8_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_check_sys_temperatures(struct envctrlunit *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void envctrl_check_disk_kstats(struct envctrlunit *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void envctrl_update_disk_kstats(struct envctrlunit *,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t, uint8_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_read_chip(struct envctrlunit *, int, int, int,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t *, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_write_chip(struct envctrlunit *, int, int, int,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t *, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_check_tempr_levels(struct envctrlunit *,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int, uint8_t *, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void envctrl_update_fanspeed(struct envctrlunit *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/* Kstat routines */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void envctrl_add_kstats(struct envctrlunit *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_ps_kstat_update(kstat_t *, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_fanstat_kstat_update(kstat_t *, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_encl_kstat_update(kstat_t *, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_temp_kstat_update(kstat_t *, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_disk_kstat_update(kstat_t *, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void envctrl_init_encl_kstats(struct envctrlunit *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelextern void power_down(const char *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelextern int prom_getprop();
3db86aab554edbb4244c8d1a1c90f152eee768afstevelextern int prom_getproplen();
3db86aab554edbb4244c8d1a1c90f152eee768afstevelextern void prom_printf(const char *fmt, ...);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelextern void (*abort_seq_handler)();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void *envctrlsoft_statep;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic char driver_name[] = "envctrltwo";
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uchar_t _cpu_temps[256];
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uchar_t _cpu_fan_speeds[256];
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int psok[2] = {-1, -1};
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pspr[2] = {-1, -1};
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uint8_t idle_fanspeed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int power_flt_led_lit = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelextern void pci_thermal_rem_intr(dev_info_t *, uint_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/* Local Variables */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/* Indicates whether or not the overtemp thread has been started */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_debug_flags = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_power_off_overide = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_max_retries = 200;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_allow_detach = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_numcpus = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int envctrl_handler = 1; /* 1 is the default */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic clock_t overtemp_timeout_hz;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic clock_t blink_timeout_hz;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic clock_t pshotplug_timeout_hz;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic clock_t warning_timeout_hz;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Temperature levels :
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * green = OK - no action needed
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * yellow = warning - display warning message and poll faster
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * red = critical - shutdown system
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenum levels {green, yellow, red};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define DPRINTF1 if (envctrl_debug_flags && (envctrl_debug_flags & 0x1)) printf
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define DPRINTF2 if (envctrl_debug_flags && (envctrl_debug_flags & 0x2)) printf
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define DPRINTF3 if (envctrl_debug_flags && (envctrl_debug_flags & 0x4)) printf
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define JAV_FAN_SPEED_SF_NUM 107
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define JAV_FAN_SPEED_SF_DEN 100
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define JAV_MAX_TEMP_SENSORS 6
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define JAV_FSP_MASK 0xC0
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define FAN_DRIFT 25
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define MAX_FAN_SPEED 255
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define MAX_DEVS 16
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define ENVCTRL_UE250_INTR_LATCH_INIT0 0xFE
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define ENVCTRL_UE250_INTR_LATCH_INIT1 0xFF
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int t_scale_num[8];
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int t_scale_den[8];
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uint8_t t_addr[8];
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uint8_t t_port[8];
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int sensor_types[] = { ENVCTRL_UE250_CPU0_SENSOR,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ENVCTRL_UE250_CPU1_SENSOR, ENVCTRL_UE250_MB0_SENSOR,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ENVCTRL_UE250_MB1_SENSOR, ENVCTRL_UE250_PDB_SENSOR,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ENVCTRL_UE250_SCSI_SENSOR };
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic struct cb_ops envctrl_cb_ops = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_open, /* cb_open */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_close, /* cb_close */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nodev, /* cb_strategy */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nodev, /* cb_print */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nodev, /* cb_dump */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nodev, /* cb_read */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nodev, /* cb_write */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_ioctl, /* cb_ioctl */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nodev, /* cb_devmap */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nodev, /* cb_mmap */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nodev, /* cb_segmap */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nochpoll, /* cb_chpoll */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_prop_op, /* cb_prop_op */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL, /* cb_stream */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (int)(D_NEW | D_MP) /* cb_flag */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Declare ops vectors for auto configuration.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstruct dev_ops envctrltwo_ops = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DEVO_REV, /* devo_rev */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 0, /* devo_refcnt */
193974072f41a843678abf5f61979c748687e66bSherry Moore envctrl_getinfo, /* devo_getinfo */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nulldev, /* devo_identify */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nulldev, /* devo_probe */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_attach, /* devo_attach */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_detach, /* devo_detach */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nodev, /* devo_reset */
193974072f41a843678abf5f61979c748687e66bSherry Moore &envctrl_cb_ops, /* devo_cb_ops */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (struct bus_ops *)NULL, /* devo_bus_ops */
193974072f41a843678abf5f61979c748687e66bSherry Moore nulldev, /* devo_power */
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_quiesce_not_supported, /* devo_quiesce */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelextern struct mod_ops mod_driverops;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic struct modldrv envctrlmodldrv = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel &mod_driverops, /* type of module - driver */
193974072f41a843678abf5f61979c748687e66bSherry Moore "I2C ENVCTRLTWO_driver",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel &envctrltwo_ops,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic struct modlinkage envctrlmodlinkage = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel MODREV_1,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel &envctrlmodldrv,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 0
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint
3db86aab554edbb4244c8d1a1c90f152eee768afstevel_init(void)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel register int error;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((error = mod_install(&envctrlmodlinkage)) == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_soft_state_init(&envctrlsoft_statep,
193974072f41a843678abf5f61979c748687e66bSherry Moore sizeof (struct envctrlunit), 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (error);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint
3db86aab554edbb4244c8d1a1c90f152eee768afstevel_fini(void)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel register int error;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((error = mod_remove(&envctrlmodlinkage)) == 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_soft_state_fini(&envctrlsoft_statep);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (error);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint
3db86aab554edbb4244c8d1a1c90f152eee768afstevel_info(struct modinfo *modinfop)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (mod_info(&envctrlmodlinkage, modinfop));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel register int instance;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char name[16];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t fspval;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel register struct envctrlunit *unitp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct ddi_device_acc_attr attr;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uchar_t *creg_prop;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint_t len, tblsz;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int i, j, k, status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t fanspeed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = len = tblsz = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel instance = ddi_get_instance(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (cmd) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_ATTACH:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_RESUME:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(unitp = ddi_get_soft_state(envctrlsoft_statep, instance)))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!unitp->suspended) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->suspended = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->initting = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_init_bus(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->initting = B_FALSE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_ps_probe(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_probe_cpus(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Set up timer values */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel overtemp_timeout_hz = drv_usectohz(ENVCTRL_UE250_OVERTEMP_TIMEOUT_USEC);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel blink_timeout_hz = drv_usectohz(ENVCTRL_UE250_BLINK_TIMEOUT_USEC);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pshotplug_timeout_hz =
193974072f41a843678abf5f61979c748687e66bSherry Moore drv_usectohz(ENVCTRL_UE250_BLINK_TIMEOUT_USEC * 2);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * On a cooling failure, either a fan failure or temperature
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * exceeding a WARNING level, the temperature poll thread
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * will run every 6 seconds.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel warning_timeout_hz =
193974072f41a843678abf5f61979c748687e66bSherry Moore drv_usectohz(ENVCTRL_UE250_OVERTEMP_TIMEOUT_USEC / 6);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_soft_state_zalloc(envctrlsoft_statep, instance) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: failed to zalloc softstate\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_name(dip), instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto failed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp = ddi_get_soft_state(envctrlsoft_statep, instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_regs_map_setup(dip, 0, (caddr_t *)&unitp->bus_ctl_regs, 0,
193974072f41a843678abf5f61979c748687e66bSherry Moore sizeof (struct ehc_pcd8584_regs), &attr,
193974072f41a843678abf5f61979c748687e66bSherry Moore &unitp->ctlr_handle) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: failed to map in bus_control regs\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_name(dip), instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If the PCI nexus has added a thermal interrupt, we first need
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * to remove that interrupt handler.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * WARNING: Removing another driver's interrupt handler is not
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * allowed. The pci_thermal_rem_intr() call below is needed to retain
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the legacy behavior on Javelin systems.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_thermal_rem_intr(dip, (uint_t)0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* add interrupts */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_get_iblock_cookie(dip, 1,
193974072f41a843678abf5f61979c748687e66bSherry Moore &unitp->ic_trap_cookie) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: ddi_get_iblock_cookie FAILED \n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_name(dip), instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto failed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_init(&unitp->umutex, NULL, MUTEX_DRIVER,
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)unitp->ic_trap_cookie);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_add_intr(dip, 0, &unitp->ic_trap_cookie, NULL, envctrl_bus_isr,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t)unitp) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: failed to add hard intr \n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_name(dip), instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto remlock;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_add_intr(dip, 1, &unitp->ic_trap_cookie, NULL, envctrl_dev_isr,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t)unitp) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: failed to add hard intr \n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_name(dip), instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto remhardintr;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) sprintf(name, "envctrltwo%d", instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_create_priv_minor_node(dip, name, S_IFCHR, instance,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_PSEUDO, 0, PRIV_SYS_CONFIG, PRIV_SYS_CONFIG, 0666) ==
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto remhardintr1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Javelin will not have a workstation configuration so activity
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * LED will always blink.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->activity_led_blink = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->shutdown = B_FALSE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->num_ps_present = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->num_encl_present = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->current_mode = ENVCTRL_NORMAL_MODE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (envctrl_numcpus > 1) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->num_cpus_present = envctrl_numcpus;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_probe_cpus(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((unitp->cpu_pr_location[ENVCTRL_CPU0] == B_FALSE) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (unitp->cpu_pr_location[ENVCTRL_CPU1] == B_FALSE))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Only one CPU in the system */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->num_temps_present = 5;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->num_temps_present = 6;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->num_fans_present = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->dip = dip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cpu-temp-factors", &creg_prop, &len) != DDI_PROP_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: Unable to read cpu-temp-factors property",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_name(dip), instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_NOT_WELL_FORMED);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel tblsz = (sizeof (_cpu_temps) / sizeof (uchar_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (len <= tblsz && status == DDI_PROP_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < len; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel _cpu_temps[i+2] = creg_prop[i];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel _cpu_temps[0] = _cpu_temps[1] = _cpu_temps[2];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_prop_free((void *)creg_prop);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cpu-fan-speeds", &creg_prop, &len) != DDI_PROP_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: Unable to read cpu-fan-speeds property",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_name(dip), instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_NOT_WELL_FORMED);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel tblsz = (sizeof (_cpu_fan_speeds) / sizeof (uchar_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (len <= tblsz && status == DDI_PROP_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < len; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel _cpu_fan_speeds[i+2] = creg_prop[i];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel _cpu_fan_speeds[0] = _cpu_fan_speeds[1] = _cpu_fan_speeds[2];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_prop_free((void *)creg_prop);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "thermisters", &creg_prop, &len) != DDI_PROP_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: Unable to read thermisters property",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_name(dip), instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_NOT_WELL_FORMED);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel j = 0; k = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < JAV_MAX_TEMP_SENSORS; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Type */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->temp_kstats[k].type = sensor_types[i];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Address */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel t_addr[k] = creg_prop[j] << 24 | creg_prop[j+1] << 16 |
193974072f41a843678abf5f61979c748687e66bSherry Moore creg_prop[j+2] << 8 | creg_prop[j+3];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel j += 4;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Port */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel t_port[k] = creg_prop[j] << 24 | creg_prop[j+1] << 16 |
193974072f41a843678abf5f61979c748687e66bSherry Moore creg_prop[j+2] << 8 | creg_prop[j+3];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel j += 4;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Min */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->temp_kstats[k].min =
193974072f41a843678abf5f61979c748687e66bSherry Moore creg_prop[j] << 24 | creg_prop[j+1] << 16 |
193974072f41a843678abf5f61979c748687e66bSherry Moore creg_prop[j+2] << 8 | creg_prop[j+3];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel j += 4;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Warning threshold */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->temp_kstats[k].warning_threshold =
193974072f41a843678abf5f61979c748687e66bSherry Moore creg_prop[j] << 24 | creg_prop[j+1] << 16 |
193974072f41a843678abf5f61979c748687e66bSherry Moore creg_prop[j+2] << 8 | creg_prop[j+3];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel j += 4;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Shutdown threshold */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->temp_kstats[k].shutdown_threshold =
193974072f41a843678abf5f61979c748687e66bSherry Moore creg_prop[j] << 24 | creg_prop[j+1] << 16 |
193974072f41a843678abf5f61979c748687e66bSherry Moore creg_prop[j+2] << 8 | creg_prop[j+3];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel j += 4;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Numerator of scale factor */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel t_scale_num[k] = creg_prop[j] << 24 | creg_prop[j+1] << 16 |
193974072f41a843678abf5f61979c748687e66bSherry Moore creg_prop[j+2] << 8 | creg_prop[j+3];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel j += 4;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Denominator of scale factor */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel t_scale_den[k] = creg_prop[j] << 24 | creg_prop[j+1] << 16 |
193974072f41a843678abf5f61979c748687e66bSherry Moore creg_prop[j+2] << 8 | creg_prop[j+3];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel j += 4;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bcopy((caddr_t)&creg_prop[j], unitp->temp_kstats[k].label,
193974072f41a843678abf5f61979c748687e66bSherry Moore (size_t)sizeof (&creg_prop[j]));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while (creg_prop[j] != '\0') j++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel j++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (t_addr[k] == ENVCTRL_UE250_CPU_TEMP_DEV) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (((t_port[k] == ENVCTRL_UE250_CPU0_PORT) &&
193974072f41a843678abf5f61979c748687e66bSherry Moore (unitp->cpu_pr_location[ENVCTRL_CPU0] ==
193974072f41a843678abf5f61979c748687e66bSherry Moore B_FALSE)) ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ((t_port[k] == ENVCTRL_UE250_CPU1_PORT) &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (unitp->cpu_pr_location[ENVCTRL_CPU1] == B_FALSE)))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Don't increment the kstat line count */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef lint
3db86aab554edbb4244c8d1a1c90f152eee768afstevel k = k;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel k++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel k++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_prop_free((void *)creg_prop);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* initialize the envctrl bus controller */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->initting = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_init_bus(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DPRINTF1("envctrl_attach(): Completed initialization of PCF8584");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->initting = B_FALSE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel drv_usecwait(1000);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->timeout_id = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->blink_timeout_id = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->fan_failed = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->fan_kstats.fans_ok = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->tempr_warning = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_ps_probe(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->initting = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_fan_fail_service(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->initting = B_FALSE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Fans could be blasting, turn them down.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fanspeed = 0x0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_write_chip(unitp, ENVCTRL_PCF8591, EHC_DEV2, 0,
193974072f41a843678abf5f61979c748687e66bSherry Moore &fanspeed, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Write to PCF8591 (SETFAN) failed\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_name(dip), instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we need to init the fan kstats before the tempr_poll
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_add_kstats(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_init_encl_kstats(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_check_disk_kstats(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_update_fanspeed(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel idle_fanspeed = unitp->fan_kstats.fanspeed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->activity_led_blink == B_TRUE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->present_led_state = B_FALSE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_led_blink((void *)unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fspval = ENVCTRL_UE250_FSP_ACTIVE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) envctrl_set_fsp(unitp, &fspval);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_tempr_poll((void *)unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * interpose envctrl's abort sequence handler
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (envctrl_handler) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel abort_seq_handler = envctrl_abort_seq_handler;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_report_dev(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelremhardintr1:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_remove_intr(dip, (uint_t)1, unitp->ic_trap_cookie);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelremhardintr:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_remove_intr(dip, (uint_t)0, unitp->ic_trap_cookie);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelremlock:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_destroy(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelfailed:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->ctlr_handle)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&unitp->ctlr_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: attach failed\n", ddi_get_name(dip), instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int instance;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel register struct envctrlunit *unitp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel instance = ddi_get_instance(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp = ddi_get_soft_state(envctrlsoft_statep, instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (cmd) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_DETACH:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (envctrl_allow_detach) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->psksp != NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kstat_delete(unitp->psksp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->fanksp != NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kstat_delete(unitp->fanksp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->enclksp != NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kstat_delete(unitp->enclksp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->tempksp != NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kstat_delete(unitp->tempksp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->diskksp != NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kstat_delete(unitp->diskksp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->timeout_id != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) untimeout(unitp->timeout_id);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->timeout_id = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->blink_timeout_id != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) untimeout(unitp->blink_timeout_id);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->blink_timeout_id = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_remove_minor_node(dip, NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_remove_intr(dip, (uint_t)0, unitp->ic_trap_cookie);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_remove_intr(dip, (uint_t)1, unitp->ic_trap_cookie);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&unitp->ctlr_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_destroy(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_SUSPEND:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(unitp = ddi_get_soft_state(envctrlsoft_statep, instance)))
193974072f41a843678abf5f61979c748687e66bSherry Moore return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->suspended) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: envctrltwo already suspended\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_name(dip), instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->suspended = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: suspend general fault\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_name(dip), instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel void **result)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_t dev = (dev_t)arg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrlunit *unitp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int instance, ret;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel instance = getminor(dev);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef lint
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dip = dip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (infocmd) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_INFO_DEVT2DEVINFO:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((unitp = (struct envctrlunit *)
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_soft_state(envctrlsoft_statep,
193974072f41a843678abf5f61979c748687e66bSherry Moore instance)) != NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *result = unitp->dip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ret = DDI_SUCCESS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *result = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ret = DDI_FAILURE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_INFO_DEVT2INSTANCE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *result = (void *)(uintptr_t)instance;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ret = DDI_SUCCESS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ret = DDI_FAILURE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ret);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/* ARGSUSED1 */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_open(dev_t *dev, int flag, int otyp, cred_t *cred_p)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrlunit *unitp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel register int instance;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel instance = getminor(*dev);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (instance < 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ENXIO);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp = (struct envctrlunit *)
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_soft_state(envctrlsoft_statep, instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp == NULL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ENXIO);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (otyp != OTYP_CHR)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (EINVAL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (flag & FWRITE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((unitp->oflag & FWRITE)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (EBUSY);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->oflag |= FWRITE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (status);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*ARGSUSED1*/
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_close(dev_t dev, int flag, int otyp, cred_t *cred_p)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrlunit *unitp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel register int instance;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel instance = getminor(dev);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (instance < 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ENXIO);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp = (struct envctrlunit *)
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_soft_state(envctrlsoft_statep, instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp == NULL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ENXIO);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->oflag = B_FALSE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->current_mode = ENVCTRL_NORMAL_MODE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * standard put procedure for envctrl
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cred_p,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int *rvalp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrlunit *unitp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel register int instance;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t wdval, tempr;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrl_chip fanspeed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrl_chip ledchip, envcchip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrl_chip temp, a_fanspeed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int rval = 0, status, tfanspeed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef lint
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cred_p = cred_p;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rvalp = rvalp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel instance = getminor(dev);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp = (struct envctrlunit *)
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_soft_state(envctrlsoft_statep, instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((cmd == ENVCTRL_IOC_SETFAN2) ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (cmd == ENVCTRL_IOC_GETFAN2) ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (cmd == ENVCTRL_IOC_SETMODE) ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (cmd == ENVCTRL_IOC_GETMODE) ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (cmd == ENVCTRL_IOC_GETTEMP2) ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (cmd == ENVCTRL_IOC_SETFSP2) ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (cmd == ENVCTRL_IOC_GETFSP2) ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (cmd == ENVCTRL_IOC_RESETTMPR) ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (cmd == ENVCTRL_IOC_SETDSKLED2) ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (cmd == ENVCTRL_IOC_GETDSKLED2))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((caddr_t)arg == NULL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (EFAULT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (cmd) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case ENVCTRL_IOC_SETMODE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Set mode */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_copyin((caddr_t)arg, (caddr_t)&wdval, sizeof (uint8_t),
193974072f41a843678abf5f61979c748687e66bSherry Moore flag)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EFAULT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (wdval == ENVCTRL_DIAG_MODE ||
193974072f41a843678abf5f61979c748687e66bSherry Moore wdval == ENVCTRL_NORMAL_MODE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->current_mode = wdval;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->timeout_id != 0 &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel wdval == ENVCTRL_DIAG_MODE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) untimeout(unitp->timeout_id);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->timeout_id =
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (timeout(envctrl_tempr_poll,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (caddr_t)unitp, overtemp_timeout_hz));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (wdval == ENVCTRL_NORMAL_MODE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Fans could be blasting, turn them down.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel tempr = 0x0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_write_chip(unitp,
193974072f41a843678abf5f61979c748687e66bSherry Moore ENVCTRL_PCF8591, EHC_DEV2, 0,
193974072f41a843678abf5f61979c748687e66bSherry Moore &tempr, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE)
193974072f41a843678abf5f61979c748687e66bSherry Moore cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: Write to PCF8591 "
193974072f41a843678abf5f61979c748687e66bSherry Moore "(SETMODE) failed\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * This delay allows the fans to time to
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * change speed
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel drv_usecwait(100000);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) envctrl_check_sys_temperatures(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->current_mode = ENVCTRL_DIAG_MODE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_fan_fail_service(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->current_mode = ENVCTRL_NORMAL_MODE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case ENVCTRL_IOC_GETMODE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel wdval = unitp->current_mode;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_copyout((caddr_t)&wdval, (caddr_t)arg,
193974072f41a843678abf5f61979c748687e66bSherry Moore sizeof (uint8_t), flag)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EFAULT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case ENVCTRL_IOC_RESETTMPR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * For diags, cancel the curent temp poll
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and reset it for a new one.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->current_mode == ENVCTRL_DIAG_MODE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->timeout_id != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) untimeout(unitp->timeout_id);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->timeout_id = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_tempr_poll((void *)unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case ENVCTRL_IOC_GETTEMP2:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Get the user buffer address */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_copyin((caddr_t)arg, (caddr_t)&temp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (struct envctrl_chip), flag)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EFAULT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (((temp.chip_num != ENVCTRL_DEV2) &&
193974072f41a843678abf5f61979c748687e66bSherry Moore (temp.chip_num != ENVCTRL_DEV7)) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (temp.index > EHC_PCF8591_CH_3)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_read_chip(unitp, ENVCTRL_PCF8591,
193974072f41a843678abf5f61979c748687e66bSherry Moore temp.chip_num, temp.index, &temp.val, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: Read from PCF8591 (IOC_GETTEMP) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_copyout((caddr_t)&temp, (caddr_t)arg,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (struct envctrl_chip), flag)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EFAULT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case ENVCTRL_IOC_SETTEMP:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case ENVCTRL_IOC_SETWDT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case ENVCTRL_IOC_SETFAN2:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* NOTE: need to sanity check values coming from userland */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->current_mode == ENVCTRL_DIAG_MODE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_copyin((caddr_t)arg, (caddr_t)&fanspeed,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (struct envctrl_chip), flag)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EFAULT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((fanspeed.type != ENVCTRL_PCF8591) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (fanspeed.chip_num != ENVCTRL_DEV2) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (fanspeed.index > EHC_PCF8591_CH_3)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_set_fanspeed(unitp, &fanspeed);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: Write to PCF8591 "
193974072f41a843678abf5f61979c748687e66bSherry Moore "(IOC_SETFAN) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case ENVCTRL_IOC_GETFAN2:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_copyin((caddr_t)arg, (caddr_t)&a_fanspeed,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (struct envctrl_chip), flag)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EFAULT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((a_fanspeed.type != ENVCTRL_PCF8591) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (a_fanspeed.chip_num != ENVCTRL_DEV2) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (a_fanspeed.index != EHC_PCF8591_CH_1)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_read_chip(unitp, ENVCTRL_PCF8591,
193974072f41a843678abf5f61979c748687e66bSherry Moore a_fanspeed.chip_num, a_fanspeed.index,
193974072f41a843678abf5f61979c748687e66bSherry Moore &a_fanspeed.val, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: Read of PCF8591 (IOC_GETFAN) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Due to hardware limitation, the actual fan speed
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * is always a little less than what it was set to by
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * software. Hence, we scale up the read fan speed value
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * to more closely match the set value.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((tfanspeed = ((int)a_fanspeed.val * JAV_FAN_SPEED_SF_NUM) /
193974072f41a843678abf5f61979c748687e66bSherry Moore JAV_FAN_SPEED_SF_DEN) > 255)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel a_fanspeed.val = 255;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel a_fanspeed.val = tfanspeed & 0xFF;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->fan_kstats.fanspeed = a_fanspeed.val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_copyout((caddr_t)&a_fanspeed, (caddr_t)arg,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (struct envctrl_chip), flag)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EFAULT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case ENVCTRL_IOC_SETFSP2:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_copyin((caddr_t)arg, (caddr_t)&envcchip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (struct envctrl_chip), flag)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EFAULT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((envcchip.type != ENVCTRL_PCF8574A) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (envcchip.chip_num != ENVCTRL_DEV6)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel wdval = envcchip.val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If a user is in normal mode and they try
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * to set anything other than a disk fault or
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * a gen fault it is an invalid operation.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * in diag mode we allow everything to be
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * twiddled.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->current_mode == ENVCTRL_NORMAL_MODE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (wdval & ~ENVCTRL_UE250_FSP_USRMASK) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (wdval & ENVCTRL_UE250_FSP_PS_ERR)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel power_flt_led_lit = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_set_fsp(unitp, &wdval);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: Read of PCF8574A (IOC_SETFSP) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case ENVCTRL_IOC_GETFSP2:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_copyin((caddr_t)arg, (caddr_t)&envcchip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (struct envctrl_chip), flag)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EFAULT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((envcchip.type != ENVCTRL_PCF8574A) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (envcchip.chip_num != ENVCTRL_DEV6)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_get_fpm_status(unitp, &wdval);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: Read of PCF8574A (IOC_GETFSP) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envcchip.val = wdval;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_copyout((caddr_t)&envcchip, (caddr_t)arg,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (struct envctrl_chip), flag)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EFAULT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case ENVCTRL_IOC_SETDSKLED2:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_copyin((caddr_t)arg, (caddr_t)&ledchip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (struct envctrl_chip), flag)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EFAULT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((ledchip.type != ENVCTRL_PCF8574A) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (ledchip.chip_num != ENVCTRL_DEV7)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (envctrl_set_dskled(unitp, &ledchip)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case ENVCTRL_IOC_GETDSKLED2:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_copyin((caddr_t)arg, (caddr_t)&ledchip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (struct envctrl_chip), flag)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EFAULT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((ledchip.type != ENVCTRL_PCF8574A) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (ledchip.chip_num != ENVCTRL_DEV7)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (envctrl_get_dskled(unitp, &ledchip)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_copyout((caddr_t)&ledchip, (caddr_t)arg,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (struct envctrl_chip), flag)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EFAULT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case ENVCTRL_IOC_SETRAW:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->current_mode != ENVCTRL_DIAG_MODE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_copyin((caddr_t)arg, (caddr_t)&temp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (struct envctrl_chip), flag)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EFAULT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_write_chip(unitp, temp.type, temp.chip_num,
193974072f41a843678abf5f61979c748687e66bSherry Moore temp.index, &temp.val, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: Write to chip (IOC_SETRAW) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case ENVCTRL_IOC_GETRAW:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_copyin((caddr_t)arg, (caddr_t)&temp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (struct envctrl_chip), flag)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EFAULT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_read_chip(unitp, temp.type, temp.chip_num,
193974072f41a843678abf5f61979c748687e66bSherry Moore temp.index, &temp.val, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: Read of chip (IOC_GETRAW) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_copyout((caddr_t)&temp, (caddr_t)arg,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (struct envctrl_chip), flag)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EFAULT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (rval);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afsteveluint_t
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_bus_isr(caddr_t arg)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrlunit *unitp = (struct envctrlunit *)(void *)arg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int ic = DDI_INTR_UNCLAIMED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * NOT USED
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ic);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afsteveluint_t
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_dev_isr(caddr_t arg)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrlunit *unitp = (struct envctrlunit *)(void *)arg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t recv_data;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int ic;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int retrys = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel static int spurious_intr_count = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ic = DDI_INTR_UNCLAIMED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * First check to see if it is an interrupt for us by
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * looking at the "ganged" interrupt and vector
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * according to the major type
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * 0x70 is the addr of the ganged interrupt controller.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Address map for the port byte read is as follows
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * MSB
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * -------------------------
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * | | | | | | | | |
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * -------------------------
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * P7 P6 P5 P4 P3 P2 P1 P0
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * P0 = Spare
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * P1 = Thermal Interrupt
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * P2 = Disk Interrupt
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * P3 = Interrupt clock enable
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * P4 = Fan Fail Interrupt
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * P5 = Front Panel Interrupt
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * P6 = Power Supply Interrupt
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * P7 = Enable Interrupts
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel do {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = ehc_read_pcf8574a((struct ehc_envcunit *)unitp,
193974072f41a843678abf5f61979c748687e66bSherry Moore ENVCTRL_UE250_PCF8574A_BASE_ADDR | EHC_DEV0,
193974072f41a843678abf5f61979c748687e66bSherry Moore &recv_data, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * This extra read is needed since the first read is discarded
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and the second read seems to return 0xFF.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (recv_data == 0xFF) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = ehc_read_pcf8574a((struct ehc_envcunit *)unitp,
193974072f41a843678abf5f61979c748687e66bSherry Moore ENVCTRL_UE250_PCF8574A_BASE_ADDR | EHC_DEV0,
193974072f41a843678abf5f61979c748687e66bSherry Moore &recv_data, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * if the i2c bus is hung it is imperative that this
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * be cleared on an interrupt or else it will
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * hang the system with continuous interrupts
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel drv_usecwait(1000);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (retrys < envctrl_max_retries) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel retrys++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: Read of PCF8574A (INT) failed\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ehc_init_pcf8584((struct ehc_envcunit *)unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ic = DDI_INTR_CLAIMED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ic);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } while (status != DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DPRINTF1("Interrupt routine called, interrupt = %X\n", recv_data);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(recv_data & EHC_PCF8574_PORT0)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ic = DDI_INTR_CLAIMED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(recv_data & EHC_PCF8574_PORT1)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DPRINTF1("Temperature interrupt detected\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) envctrl_check_sys_temperatures(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Clear the interrupt latches
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_intr_latch_clr(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ic = DDI_INTR_CLAIMED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(recv_data & EHC_PCF8574_PORT2)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DPRINTF1("Disk interrupt detected\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_check_disk_kstats(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ic = DDI_INTR_CLAIMED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(recv_data & EHC_PCF8574_PORT3)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ic = DDI_INTR_CLAIMED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(recv_data & EHC_PCF8574_PORT4)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Check for a fan fail
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DPRINTF1("Fan interrupt detected\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_fan_fail_service(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Clear the interrupt latches
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_intr_latch_clr(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ic = DDI_INTR_CLAIMED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(recv_data & EHC_PCF8574_PORT5)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DPRINTF1("Keyswitch interrupt detected\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) envctrl_get_fpm_status(unitp, (uint8_t *)NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ic = DDI_INTR_CLAIMED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(recv_data & EHC_PCF8574_PORT6)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DPRINTF1("Power supply interrupt detected\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_PS_intr_service(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ic = DDI_INTR_CLAIMED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(recv_data & EHC_PCF8574_PORT7)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ic = DDI_INTR_CLAIMED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The interrupt routine got called but the interrupt chip
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * shows no interrupt present. If this happens more than 256
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * times in a row, there is probably some hardware problem so
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * send a warning message to the console.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((recv_data == 0xFF)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (spurious_intr_count == 255)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: Received 256 spurious interrupts\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel spurious_intr_count++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ic = DDI_INTR_CLAIMED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel spurious_intr_count = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ic);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_read_chip(struct envctrlunit *unitp, int type, int chip_num, int port,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t *data, int num)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int retrys = 0, autoincr = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If more than one read is requested, set auto-increment bit
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (num > 1)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel autoincr = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel do {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (type == ENVCTRL_PCF8574A) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = ehc_read_pcf8574a((struct ehc_envcunit *)unitp,
193974072f41a843678abf5f61979c748687e66bSherry Moore ENVCTRL_UE250_PCF8574A_BASE_ADDR | chip_num,
193974072f41a843678abf5f61979c748687e66bSherry Moore data, num);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (type == ENVCTRL_PCF8574) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = ehc_read_pcf8574((struct ehc_envcunit *)unitp,
193974072f41a843678abf5f61979c748687e66bSherry Moore ENVCTRL_UE250_PCF8574_BASE_ADDR | chip_num,
193974072f41a843678abf5f61979c748687e66bSherry Moore data, num);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (type == ENVCTRL_PCF8591) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = ehc_read_pcf8591((struct ehc_envcunit *)unitp,
193974072f41a843678abf5f61979c748687e66bSherry Moore ENVCTRL_UE250_PCF8591_BASE_ADDR | chip_num,
193974072f41a843678abf5f61979c748687e66bSherry Moore port, autoincr, 0, 1, data, num);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If the bus hangs, attempt a recovery
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel drv_usecwait(1000);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (retrys < envctrl_max_retries) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel retrys++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ehc_init_pcf8584((struct ehc_envcunit *)unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } while (status != DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (status);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_write_chip(struct envctrlunit *unitp, int type, int chip_num, int port,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t *data, int num)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int retrys = 0, autoincr = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Incase some applications mistakenly include the chips base addr
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel chip_num = chip_num & 0xF;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If more than one write is requested, set auto-increment bit
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (num > 1)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel autoincr = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel do {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (type == ENVCTRL_PCF8574A) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = ehc_write_pcf8574a(
193974072f41a843678abf5f61979c748687e66bSherry Moore (struct ehc_envcunit *)unitp,
193974072f41a843678abf5f61979c748687e66bSherry Moore ENVCTRL_UE250_PCF8574A_BASE_ADDR | chip_num,
193974072f41a843678abf5f61979c748687e66bSherry Moore data, num);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (type == ENVCTRL_PCF8574) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = ehc_write_pcf8574((struct ehc_envcunit *)unitp,
193974072f41a843678abf5f61979c748687e66bSherry Moore ENVCTRL_UE250_PCF8574_BASE_ADDR | chip_num,
193974072f41a843678abf5f61979c748687e66bSherry Moore data, num);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (type == ENVCTRL_PCF8591) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = ehc_write_pcf8591((struct ehc_envcunit *)unitp,
193974072f41a843678abf5f61979c748687e66bSherry Moore ENVCTRL_UE250_PCF8591_BASE_ADDR | chip_num,
193974072f41a843678abf5f61979c748687e66bSherry Moore port, autoincr, 0, 1, data, num);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If the bus hangs, attempt a recovery
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel drv_usecwait(1000);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (retrys < envctrl_max_retries) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel retrys++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ehc_init_pcf8584((struct ehc_envcunit *)unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } while (status != DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (status);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef GET_CPU_TEMP
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_get_cpu_temp(struct envctrlunit *unitp, int cpunum)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t recv_data;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(MUTEX_HELD(&unitp->umutex));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * This routine takes in the number of the port that
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we want to read in the 8591. This should be the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * location of the CPU thermistor for one of the 2
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * cpu's. It will return a normalized value
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * to the caller.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_read_chip(unitp, ENVCTRL_PCF8591, EHC_DEV7, cpunum,
193974072f41a843678abf5f61979c748687e66bSherry Moore &recv_data, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: CPU TEMP read failed\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ENVCTRL_UE250_MAX_CPU_TEMP - 10);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (_cpu_temps[recv_data]);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_tempr_poll(void *arg)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int diag_flag = 0, status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrlunit *unitp = (struct envctrlunit *)arg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->shutdown == B_TRUE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) power_down("Fatal System Environmental Control Error");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Clear the interrupt latches
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_intr_latch_clr(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_reset_dflop(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_enable_devintrs(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * if we are in diag mode and the temp poll thread goes off,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * this means that the system is too heavily loaded and the 60 second
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * window to execute the test is failing.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->current_mode == ENVCTRL_DIAG_MODE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel diag_flag++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (envctrl_debug_flags) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "Tempr poll went off while in DIAG MODE\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->current_mode = ENVCTRL_NORMAL_MODE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DPRINTF1("envctrl_tempr_poll(): Checking system temps\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_check_sys_temperatures(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: Failure detected during temperature poll",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (diag_flag == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_fan_fail_service(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Turn of the power fault LED if ps_ok is asserted */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_ps_probe(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* now have this thread sleep for a while */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((unitp->fan_failed == B_TRUE) || (unitp->tempr_warning == B_TRUE)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * A thermal warning or fan failure condition exists.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Temperature poll thread will run every 10 seconds.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->timeout_id != 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) untimeout(unitp->timeout_id);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->timeout_id = (timeout(envctrl_tempr_poll,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t)unitp, warning_timeout_hz));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * No thermal warning or fan failure condition exists.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * This thread is set to run every 60 seconds.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->timeout_id = (timeout(envctrl_tempr_poll,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t)unitp, overtemp_timeout_hz));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_led_blink(void *arg)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t val, tmpval;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrlunit *unitp = (struct envctrlunit *)arg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_read_chip(unitp, ENVCTRL_PCF8574A, EHC_DEV6,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, &val, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Failed to read FSP LEDs",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* now have this thread sleep for a while */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->blink_timeout_id = (timeout(envctrl_led_blink,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t)unitp, blink_timeout_hz));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->present_led_state == B_TRUE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Now we need to "or" in fault bits of the FSP
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * module for the mass storage fault led.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and set it.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val = (val & ~(EHC_PCF8574_PORT4) | JAV_FSP_MASK);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->present_led_state = B_FALSE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val = (val | EHC_PCF8574_PORT4 | JAV_FSP_MASK);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->present_led_state = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * A static global variable, power_flt_led_lit, is used to keep
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * track of periods when the software has lit the power fault LED.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Whenever the power fault LED is lit and this variable is not set,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * then the power fault LED has been lit by hardware. In this case
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * mask out the power fault LED in the byte. This is a fix for
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * bug 4144872.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel tmpval = ~val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (tmpval & ENVCTRL_UE250_FSP_PS_ERR) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (power_flt_led_lit == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Turn off power fault bit in the FSP byte.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel tmpval &= ~(ENVCTRL_UE250_FSP_PS_ERR);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val = ~tmpval;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_write_chip(unitp, ENVCTRL_PCF8574A, EHC_DEV6,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, &val, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Failed to blink activity LED",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* now have this thread sleep for a while */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->blink_timeout_id = (timeout(envctrl_led_blink,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t)unitp, blink_timeout_hz));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* now have this thread sleep for a while */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->blink_timeout_id = (timeout(envctrl_led_blink,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (caddr_t)unitp, blink_timeout_hz));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_check_sys_temperatures(struct envctrlunit *unitp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t buf[8];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel enum levels warning_level, level;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t fspval;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status, warning_count = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelretrytemp1:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_read_chip(unitp, ENVCTRL_PCF8591, EHC_DEV2,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, buf, 4);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Temperature read failed (PDB)",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (status);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel warning_level = envctrl_check_tempr_levels(unitp, EHC_DEV2,
193974072f41a843678abf5f61979c748687e66bSherry Moore buf, warning_count);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel level = warning_level;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (warning_level != green) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (warning_count == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel warning_count++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel drv_usecwait(1000);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto retrytemp1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (warning_level == yellow)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->tempr_warning = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else if (warning_level == red) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->tempr_warning = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!envctrl_power_off_overide)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->shutdown = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel warning_count = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelretrytemp2:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_read_chip(unitp, ENVCTRL_PCF8591, EHC_DEV7,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, buf+4, 4);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Temperature read failed (MBD)",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (status);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel warning_level = envctrl_check_tempr_levels(unitp, EHC_DEV7,
193974072f41a843678abf5f61979c748687e66bSherry Moore buf+4, warning_count);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (warning_level != green) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (warning_count == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel warning_count++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel drv_usecwait(1000);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto retrytemp2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((warning_level == yellow) && (unitp->shutdown == B_FALSE))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->tempr_warning = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else if (warning_level == red) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->tempr_warning = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!envctrl_power_off_overide)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->shutdown = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if ((level == green) && (unitp->tempr_warning == B_TRUE)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Current tempr. poll shows all levels normal.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If the previous poll showed warning levels, we need
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * to clear that status
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_NOTE,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "TEMPERATURE NORMAL: all sensors back to normal readings");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->tempr_warning = B_FALSE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_get_fpm_status(unitp, &fspval);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: Read of Front Status Panel LEDs failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((unitp->tempr_warning == B_TRUE) || (unitp->shutdown == B_TRUE))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fspval |= (ENVCTRL_UE250_FSP_TEMP_ERR |
193974072f41a843678abf5f61979c748687e66bSherry Moore ENVCTRL_UE250_FSP_GEN_ERR);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (envctrl_isother_fault_led(unitp, fspval,
193974072f41a843678abf5f61979c748687e66bSherry Moore ENVCTRL_UE250_FSP_TEMP_ERR)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fspval &= ~(ENVCTRL_UE250_FSP_TEMP_ERR);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fspval &= ~(ENVCTRL_UE250_FSP_TEMP_ERR |
193974072f41a843678abf5f61979c748687e66bSherry Moore ENVCTRL_UE250_FSP_GEN_ERR);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_set_fsp(unitp, &fspval);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: Setting of Front Status Panel LEDs failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Have this thread run again in about 10 seconds
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->tempr_warning == B_TRUE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->timeout_id != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) untimeout(unitp->timeout_id);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->timeout_id = (timeout(envctrl_tempr_poll,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t)unitp, warning_timeout_hz));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (status);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_check_tempr_levels(struct envctrlunit *unitp, int chip_num,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t *data, int count)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint_t temp_degree_c;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t buf[8];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel enum levels warning_level = green;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int i, j;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t fanspeed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int tval;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < 4; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (chip_num == EHC_DEV2) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (i == 1) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel tval = ((int)data[i] * JAV_FAN_SPEED_SF_NUM) /
193974072f41a843678abf5f61979c748687e66bSherry Moore JAV_FAN_SPEED_SF_DEN;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (tval > 255)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->fan_kstats.fanspeed = 255;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->fan_kstats.fanspeed = tval;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DPRINTF1("device %X, fan = %d %d\n", chip_num,
193974072f41a843678abf5f61979c748687e66bSherry Moore unitp->fan_kstats.fanspeed, data[i]);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel continue;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (i == 2)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel continue;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((chip_num == EHC_DEV7) && ((i == ENVCTRL_UE250_CPU0_PORT) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (i == ENVCTRL_UE250_CPU1_PORT)))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->cpu_pr_location[i] == B_FALSE)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel continue;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel j = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while ((((t_addr[j] & 0xF) != chip_num) || (t_port[j] != i)) &&
193974072f41a843678abf5f61979c748687e66bSherry Moore (j < unitp->num_temps_present))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel j++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((chip_num == EHC_DEV7) && ((i == ENVCTRL_UE250_CPU0_PORT) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (i == ENVCTRL_UE250_CPU1_PORT)))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel temp_degree_c = _cpu_temps[data[i]];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel temp_degree_c = ((int)data[i] * t_scale_num[j]) /
193974072f41a843678abf5f61979c748687e66bSherry Moore t_scale_den[j];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Javelin hardware will not control fan speeds based on
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * cpu temperature values because the voltages corresponding
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * to the cpu temperatures are based on an inverted scale
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * compared to the ambient temperatures and thus can be
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * fed to the same fan control circuit. As a result, it
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * has been decided that software will control fan speed
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * if cpu temperatures rise.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((chip_num == EHC_DEV7) && ((i == ENVCTRL_UE250_CPU0_PORT) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (i == ENVCTRL_UE250_CPU1_PORT)) &&
193974072f41a843678abf5f61979c748687e66bSherry Moore (unitp->current_mode == ENVCTRL_NORMAL_MODE)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (_cpu_fan_speeds[data[ENVCTRL_UE250_CPU0_PORT]] >
193974072f41a843678abf5f61979c748687e66bSherry Moore _cpu_fan_speeds[data[ENVCTRL_UE250_CPU1_PORT]])
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fanspeed =
193974072f41a843678abf5f61979c748687e66bSherry Moore _cpu_fan_speeds[
193974072f41a843678abf5f61979c748687e66bSherry Moore data[ENVCTRL_UE250_CPU0_PORT]];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fanspeed =
193974072f41a843678abf5f61979c748687e66bSherry Moore _cpu_fan_speeds[
193974072f41a843678abf5f61979c748687e66bSherry Moore data[ENVCTRL_UE250_CPU1_PORT]];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_write_chip(unitp, ENVCTRL_PCF8591,
193974072f41a843678abf5f61979c748687e66bSherry Moore EHC_DEV2, 0, &fanspeed, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: Write to PCF8591 (SETFAN) failed\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_read_chip(unitp, ENVCTRL_PCF8591,
193974072f41a843678abf5f61979c748687e66bSherry Moore EHC_DEV2, 0, buf, 4);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: Fan speed read failed (PDB)",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel tval = ((int)buf[1] * JAV_FAN_SPEED_SF_NUM) /
193974072f41a843678abf5f61979c748687e66bSherry Moore JAV_FAN_SPEED_SF_DEN;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (tval > 255)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->fan_kstats.fanspeed = 255;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->fan_kstats.fanspeed = tval;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DPRINTF1("device %X, temp = %d %d loc = %s\n", chip_num,
193974072f41a843678abf5f61979c748687e66bSherry Moore temp_degree_c, data[i], unitp->temp_kstats[j].label);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->temp_kstats[j].value = temp_degree_c;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((temp_degree_c >=
193974072f41a843678abf5f61979c748687e66bSherry Moore unitp->temp_kstats[j].warning_threshold) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (temp_degree_c < unitp->temp_kstats[j].min)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (warning_level < yellow)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel warning_level = yellow;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (count != 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "TEMPERATURE WARNING: %d degrees "
193974072f41a843678abf5f61979c748687e66bSherry Moore "celsius at location %s",
193974072f41a843678abf5f61979c748687e66bSherry Moore temp_degree_c, unitp->temp_kstats[j].label);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (temp_degree_c >=
193974072f41a843678abf5f61979c748687e66bSherry Moore unitp->temp_kstats[j].shutdown_threshold) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (warning_level < red)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel warning_level = red;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (count != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "TEMPERATURE CRITICAL: %d "
193974072f41a843678abf5f61979c748687e66bSherry Moore "degrees celsius at location %s",
193974072f41a843678abf5f61979c748687e66bSherry Moore temp_degree_c, unitp->temp_kstats[j].label);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!envctrl_power_off_overide)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "System shutdown in "
193974072f41a843678abf5f61979c748687e66bSherry Moore "10 seconds ...");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (warning_level);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_update_fanspeed(struct envctrlunit *unitp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t buf[8];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int tval;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_read_chip(unitp, ENVCTRL_PCF8591, EHC_DEV2,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, buf, 4);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Fan speed read failed ",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel tval = ((int)buf[ENVCTRL_PORT1] * JAV_FAN_SPEED_SF_NUM) /
193974072f41a843678abf5f61979c748687e66bSherry Moore JAV_FAN_SPEED_SF_DEN;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (tval > 255)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->fan_kstats.fanspeed = 255;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->fan_kstats.fanspeed = tval;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/* called with mutex held */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_fan_fail_service(struct envctrlunit *unitp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t recv_data, fpmstat;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int retrys = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The fan fail interrupt is read from address 0x70
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * on the envctrl bus.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(MUTEX_HELD(&unitp->umutex));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Clear the interrupt latches to handle spurious interrupts
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_intr_latch_clr(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel do {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = ehc_read_pcf8574a((struct ehc_envcunit *)unitp,
193974072f41a843678abf5f61979c748687e66bSherry Moore ENVCTRL_UE250_PCF8574A_BASE_ADDR | EHC_DEV0,
193974072f41a843678abf5f61979c748687e66bSherry Moore &recv_data, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * This extra read is needed since the first read is discarded
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and the second read seems to return 0xFF.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (recv_data == 0xFF) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = ehc_read_pcf8574a((struct ehc_envcunit *)unitp,
193974072f41a843678abf5f61979c748687e66bSherry Moore ENVCTRL_UE250_PCF8574A_BASE_ADDR | EHC_DEV0,
193974072f41a843678abf5f61979c748687e66bSherry Moore &recv_data, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel drv_usecwait(1000);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (retrys < envctrl_max_retries) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel retrys++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "%s%d: Read of PCF8574A (INTFAN) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ehc_init_pcf8584((struct ehc_envcunit *)unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } while (status != DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* If the fan fail interrupt is now absent */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (recv_data & EHC_PCF8574_PORT4) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->fan_failed == B_TRUE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->current_mode == ENVCTRL_NORMAL_MODE)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "Fan failure has been cleared\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->fan_kstats.fans_ok = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Clear general fault LED if no other faults
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_get_fpm_status(unitp, &fpmstat);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: Read of Front Status "
193974072f41a843678abf5f61979c748687e66bSherry Moore "Panel LEDs failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(envctrl_isother_fault_led(unitp, fpmstat, 0))) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fpmstat &= ~(ENVCTRL_UE250_FSP_GEN_ERR);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->shutdown != B_TRUE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_set_fsp(unitp, &fpmstat);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: "
193974072f41a843678abf5f61979c748687e66bSherry Moore "Setting of Front Status "
193974072f41a843678abf5f61979c748687e66bSherry Moore "Panel LEDs failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * This should be set after envctrl_isother_fault_led()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * is called
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->fan_failed = B_FALSE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->fan_failed == B_FALSE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->current_mode == ENVCTRL_NORMAL_MODE)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "Fan failure has been detected");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->fan_failed = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->fan_kstats.fans_ok = B_FALSE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Set general fault LED
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_get_fpm_status(unitp, &fpmstat);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: Read of Front Status "
193974072f41a843678abf5f61979c748687e66bSherry Moore "Panel LEDs failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fpmstat |= ENVCTRL_UE250_FSP_GEN_ERR;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_set_fsp(unitp, &fpmstat);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: "
193974072f41a843678abf5f61979c748687e66bSherry Moore "Setting of Front Status Panel LEDs failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * A fan failure condition exists.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Temperature poll thread should run every 10 seconds.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->timeout_id != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) untimeout(unitp->timeout_id);
193974072f41a843678abf5f61979c748687e66bSherry Moore unitp->timeout_id =
193974072f41a843678abf5f61979c748687e66bSherry Moore (timeout(envctrl_tempr_poll,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t)unitp, warning_timeout_hz));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Check for power supply insertion and failure.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * This is a bit tricky, because a power supply insertion will
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * cause the ps_ok line to go active as well as PS present in the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * new supply. If we detect an insertion clear
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * interrupts, disable interrupts, wait for a couple of seconds
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * come back and see if the PSOK bit is set, PS_PRESENT is set
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and the share fail interrupts are gone. If not this is a
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * real load share fail event.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Called with mutex held
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_PS_intr_service(struct envctrlunit *unitp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(MUTEX_HELD(&unitp->umutex));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp->current_mode == ENVCTRL_DIAG_MODE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * setup a timeout thread to poll the ps after a
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * couple of seconds. This allows for the PS to settle
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and doesn't report false errors on a hotplug
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->pshotplug_id = (timeout(envctrl_pshotplug_poll,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (caddr_t)unitp, pshotplug_timeout_hz));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_init_bus(struct envctrlunit *unitp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ehc_init_pcf8584((struct ehc_envcunit *)unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Clear the interrupt latches
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_intr_latch_clr(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_reset_dflop(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_enable_devintrs(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/* called with mutex held */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_reset_dflop(struct envctrlunit *unitp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t value;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(MUTEX_HELD(&unitp->umutex));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = ENVCTRL_UE250_DFLOP_INIT0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_write_chip(unitp, ENVCTRL_PCF8574A, EHC_DEV0,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, &value, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Write to PCF8574A (DFLOP_INIT0) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = ENVCTRL_UE250_DFLOP_INIT1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_write_chip(unitp, ENVCTRL_PCF8574A, EHC_DEV0,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, &value, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Write to PCF8574A (DFLOP_INIT1) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/* called with mutex held */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_enable_devintrs(struct envctrlunit *unitp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t value;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(MUTEX_HELD(&unitp->umutex));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = ENVCTRL_UE250_DEVINTR_INIT0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_write_chip(unitp, ENVCTRL_PCF8574A, EHC_DEV0,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, &value, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Write to PCF8574A (INTR_INIT0) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = ENVCTRL_UE250_DEVINTR_INIT1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_write_chip(unitp, ENVCTRL_PCF8574A, EHC_DEV0,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, &value, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Write to PCF8574A (INTR_INIT1) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_intr_latch_clr(struct envctrlunit *unitp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t value;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(MUTEX_HELD(&unitp->umutex));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = ENVCTRL_UE250_INTR_LATCH_INIT0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_write_chip(unitp, ENVCTRL_PCF8574A, EHC_DEV0,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, &value, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Write to PCF8574A (INTR_LATCH0) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = ENVCTRL_UE250_INTR_LATCH_INIT1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_write_chip(unitp, ENVCTRL_PCF8574A, EHC_DEV0,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, &value, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Write to PCF8574A (INTR_LATCH1) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/* Called with unitp mutex held */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_ps_probe(struct envctrlunit *unitp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t recv_data, fpmstat;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int i, j;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int ps_error = 0, ps_present_port, power_ok_port;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(MUTEX_HELD(&unitp->umutex));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->num_ps_present = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_read_chip(unitp, ENVCTRL_PCF8574A, EHC_DEV1,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, &recv_data, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Read of PCF8574 (PS) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0, j = 0; i < ENVCTRL_UE250_MAXPS; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->ps_kstats[i].slot = -1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Port 0 = PS0 Present
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Port 1 = PS1 Present
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Port 2 = SPARE
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Port 3 = SPARE
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Port 4 = PS0 OK
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Port 5 = PS1 OK
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Port 6 = SPARE
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Port 7 = SPARE
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Port 0 = PS Present
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Port is pulled LOW "0" to indicate
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * present.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (i) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case 0:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ps_present_port = EHC_PCF8574_PORT0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel power_ok_port = EHC_PCF8574_PORT4;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case 1:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ps_present_port = EHC_PCF8574_PORT1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel power_ok_port = EHC_PCF8574_PORT5;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(recv_data & ps_present_port)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* update unit kstat array */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->ps_kstats[j].slot = i;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ++unitp->num_ps_present;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pspr[i] == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_NOTE,
193974072f41a843678abf5f61979c748687e66bSherry Moore "Power Supply %d inserted\n", i);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pspr[i] = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(recv_data & power_ok_port)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "Power Supply %d NOT okay\n", i);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->ps_kstats[j].ps_ok = B_FALSE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ps_error++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel psok[i] = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->ps_kstats[j].ps_ok = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (psok[i] == 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_NOTE,
193974072f41a843678abf5f61979c748687e66bSherry Moore "Power Supply %d okay\n", i);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel psok[i] = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(recv_data & EHC_PCF8574_PORT2)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "PS %d Shouln't interrupt\n", i);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ps_error++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(recv_data & EHC_PCF8574_PORT3)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "PS %d Shouln't interrupt\n", i);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ps_error++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(recv_data & EHC_PCF8574_PORT6)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "PS %d Shouln't interrupt\n", i);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ps_error++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(recv_data & EHC_PCF8574_PORT7)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "PS %d Shouln't interrupt\n", i);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ps_error++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel j++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pspr[i] == 1) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_NOTE,
193974072f41a843678abf5f61979c748687e66bSherry Moore "Power Supply %d removed\n", i);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pspr[i] = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_get_fpm_status(unitp, &fpmstat);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Read of Front Status Panel LEDs failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ps_error) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fpmstat |= (ENVCTRL_UE250_FSP_PS_ERR |
193974072f41a843678abf5f61979c748687e66bSherry Moore ENVCTRL_UE250_FSP_GEN_ERR);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (envctrl_isother_fault_led(unitp, fpmstat,
193974072f41a843678abf5f61979c748687e66bSherry Moore ENVCTRL_UE250_FSP_PS_ERR)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fpmstat &= ~(ENVCTRL_UE250_FSP_PS_ERR);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fpmstat &= ~(ENVCTRL_UE250_FSP_PS_ERR |
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ENVCTRL_UE250_FSP_GEN_ERR);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_set_fsp(unitp, &fpmstat);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: Setting of Front Status Panel LEDs failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ps_error) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel power_flt_led_lit = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel power_flt_led_lit = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * consider key switch position when handling an abort sequence
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_abort_seq_handler(char *msg)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrlunit *unitp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int i;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t secure = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Find the instance of the device available on this host.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Note that there may be only one, but the instance may
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * not be zero.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < MAX_DEVS; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (unitp = (struct envctrlunit *)
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_soft_state(envctrlsoft_statep, i))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel secure = unitp->encl_kstats.value;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((secure & ENVCTRL_UE250_FSP_KEYMASK) ==
193974072f41a843678abf5f61979c748687e66bSherry Moore ENVCTRL_UE250_FSP_KEYLOCKED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "%s%d: ignoring debug enter sequence\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (envctrl_debug_flags) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "%s%d: allowing debug enter\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel debug_enter(msg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * get the front Panel module LED and keyswitch status.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * this part is addressed at 0x7C on the i2c bus.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * called with mutex held
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_get_fpm_status(struct envctrlunit *unitp, uint8_t *val)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t recv_data;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(MUTEX_HELD(&unitp->umutex));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_read_chip(unitp, ENVCTRL_PCF8574A, EHC_DEV6,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, &recv_data, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Read from PCF8574A (FSP) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (status);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel recv_data = ~recv_data;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (val != (uint8_t *)NULL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *val = recv_data;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Update kstats */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->encl_kstats.value = recv_data;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (status);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_set_fsp(struct envctrlunit *unitp, uint8_t *val)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t value;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status = DDI_SUCCESS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t confirm_val = 0, confirm_val_hold;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int confirm_count = 0, confirm_max = 20;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(MUTEX_HELD(&unitp->umutex));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = ENVCTRL_UE250_FSP_OFF; /* init all values to off */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * strip off bits that are R/O
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = (~(ENVCTRL_UE250_FSP_KEYMASK | ENVCTRL_UE250_FSP_POMASK) &
193974072f41a843678abf5f61979c748687e66bSherry Moore (*val));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel confirm_val_hold = value;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = ~value;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while (confirm_count < confirm_max) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_write_chip(unitp, ENVCTRL_PCF8574A, EHC_DEV6,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, &value, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Write to PCF8574A (FSP) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Sometimes the i2c hardware status is not
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * completely dependable as far as reporting
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * a condition where the set does not take
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * place. So we read back the set value to
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * confirm what we set.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_get_fpm_status(unitp, &confirm_val);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel confirm_val = ~(ENVCTRL_UE250_FSP_KEYMASK |
193974072f41a843678abf5f61979c748687e66bSherry Moore ENVCTRL_UE250_FSP_POMASK) & confirm_val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "%s%d: Read of PCF8574A (FSP) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (confirm_val != confirm_val_hold) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel confirm_count++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel drv_usecwait(1000);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel continue;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Set was confirmed.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (confirm_count == confirm_max)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = DDI_FAILURE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (status);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_get_dskled(struct envctrlunit *unitp, struct envctrl_chip *chip)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(MUTEX_HELD(&unitp->umutex));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (chip->chip_num != EHC_DEV7 ||
193974072f41a843678abf5f61979c748687e66bSherry Moore chip->type != ENVCTRL_PCF8574A) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_read_chip(unitp, ENVCTRL_PCF8574A, EHC_DEV7,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, &chip->val, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Read of PCF8574A (DISKFL) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel chip->val = ~chip->val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (status);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_set_dskled(struct envctrlunit *unitp, struct envctrl_chip *chip)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrl_chip confirm_chip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t confirm_val_hold;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int confirm_count = 0, confirm_max = 20;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * We need to check the type of disk led being set. If it
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * is a 4 slot backplane then the upper 4 bits (7, 6, 5, 4) are
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * invalid.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(MUTEX_HELD(&unitp->umutex));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (chip->chip_num != EHC_DEV7)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (chip->type != ENVCTRL_PCF8574A)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_read_chip(unitp, ENVCTRL_PCF8574A, EHC_DEV6,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, &val, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Read of PCF8574A (FSP) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (status);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val = ~val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((chip->val & 0x3F) == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(envctrl_isother_fault_led(unitp, val,
193974072f41a843678abf5f61979c748687e66bSherry Moore ENVCTRL_UE250_FSP_DISK_ERR))) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val &= ~(ENVCTRL_UE250_FSP_DISK_ERR);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val &= ~(ENVCTRL_UE250_FSP_DISK_ERR |
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ENVCTRL_UE250_FSP_GEN_ERR);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val = (val & ~(ENVCTRL_UE250_FSP_DISK_ERR |
193974072f41a843678abf5f61979c748687e66bSherry Moore ENVCTRL_UE250_FSP_GEN_ERR));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val = (val | (ENVCTRL_UE250_FSP_DISK_ERR |
193974072f41a843678abf5f61979c748687e66bSherry Moore ENVCTRL_UE250_FSP_GEN_ERR));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_set_fsp(unitp, &val);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Write to PCF8574A (FSP) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (status);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_read_chip(unitp, ENVCTRL_PCF8574A, EHC_DEV5,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, &val, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Read of PCF8574A (DISKFL) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (status);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_update_disk_kstats(unitp, val, ~(chip->val));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we take the ones compliment of the val passed in
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * because the hardware thinks that a "low" or "0"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * is the way to indicate a fault. of course software
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * knows that a 1 is a TRUE state or fault. ;-)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel confirm_val_hold = chip->val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel chip->val = ~(chip->val);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while (confirm_count < confirm_max) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_write_chip(unitp, ENVCTRL_PCF8574A, EHC_DEV7,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, &chip->val, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Write PCF8574A (DISKFL) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (status);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Sometimes the i2c hardware status is not
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * completely dependable as far as reporting
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * a condition where the set does not take
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * place. So we read back the set value to
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * confirm what we set.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel confirm_chip.type = chip->type;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel confirm_chip.chip_num = chip->chip_num;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel confirm_chip.index = chip->index;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_get_dskled(unitp, &confirm_chip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (status);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (confirm_chip.val != confirm_val_hold) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel confirm_count++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel drv_usecwait(1000);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel continue;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Set was confirmed.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (confirm_count == confirm_max)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * After setting the fan speed, we read back the fan speed to confirm
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * that the new value is within an acceptable range, else we retry.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * We do not confirm the fan speed if the set value is below the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * hardware determined speed (based on system temeratures).
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_set_fanspeed(struct envctrlunit *unitp, struct envctrl_chip *fanspeed)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int readback_speed, max_speed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int confirm_count = 0, confirm_max = 20;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t fanspeed_hold;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fanspeed_hold = fanspeed->val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while (confirm_count < confirm_max) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_write_chip(unitp, ENVCTRL_PCF8591,
193974072f41a843678abf5f61979c748687e66bSherry Moore EHC_DEV2, 0, &fanspeed->val, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_fan_fail_service(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "%s%d: Set fanspeed failed", driver_name,
193974072f41a843678abf5f61979c748687e66bSherry Moore unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (status);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel drv_usecwait(100000);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_update_fanspeed(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel readback_speed = unitp->fan_kstats.fanspeed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (fanspeed_hold > idle_fanspeed) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel max_speed =
193974072f41a843678abf5f61979c748687e66bSherry Moore (fanspeed->val + FAN_DRIFT >
193974072f41a843678abf5f61979c748687e66bSherry Moore MAX_FAN_SPEED) ? MAX_FAN_SPEED :
193974072f41a843678abf5f61979c748687e66bSherry Moore (fanspeed->val + FAN_DRIFT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((readback_speed < fanspeed->val -
193974072f41a843678abf5f61979c748687e66bSherry Moore FAN_DRIFT) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (readback_speed > max_speed)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel confirm_count++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel drv_usecwait(1000);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel continue;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (confirm_count == confirm_max)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_add_kstats(struct envctrlunit *unitp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(MUTEX_HELD(&unitp->umutex));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((unitp->enclksp = kstat_create(ENVCTRL_MODULE_NAME, unitp->instance,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ENVCTRL_KSTAT_ENCL, "misc", KSTAT_TYPE_RAW,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (unitp->encl_kstats),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel KSTAT_FLAG_PERSISTENT)) == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: encl raw kstat_create failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->enclksp->ks_update = envctrl_encl_kstat_update;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->enclksp->ks_private = (void *)unitp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kstat_install(unitp->enclksp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((unitp->fanksp = kstat_create(ENVCTRL_MODULE_NAME, unitp->instance,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ENVCTRL_KSTAT_FANSTAT, "misc", KSTAT_TYPE_RAW,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (unitp->fan_kstats),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel KSTAT_FLAG_PERSISTENT | KSTAT_FLAG_WRITABLE)) == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: fans kstat_create failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->fanksp->ks_update = envctrl_fanstat_kstat_update;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->fanksp->ks_private = (void *)unitp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kstat_install(unitp->fanksp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((unitp->psksp = kstat_create(ENVCTRL_MODULE_NAME, unitp->instance,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ENVCTRL_KSTAT_PSNAME2, "misc", KSTAT_TYPE_RAW,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (unitp->ps_kstats),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel KSTAT_FLAG_PERSISTENT)) == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: ps name kstat_create failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->psksp->ks_update = envctrl_ps_kstat_update;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->psksp->ks_private = (void *)unitp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kstat_install(unitp->psksp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((unitp->tempksp = kstat_create(ENVCTRL_MODULE_NAME,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->instance, ENVCTRL_KSTAT_TEMPERATURE, "misc", KSTAT_TYPE_RAW,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (unitp->temp_kstats),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel KSTAT_FLAG_PERSISTENT)) == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: temp name kstat_create failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->tempksp->ks_update = envctrl_temp_kstat_update;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->tempksp->ks_private = (void *)unitp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kstat_install(unitp->tempksp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((unitp->diskksp = kstat_create(ENVCTRL_MODULE_NAME,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->instance, ENVCTRL_KSTAT_DISK, "misc", KSTAT_TYPE_RAW,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (unitp->disk_kstats),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel KSTAT_FLAG_PERSISTENT)) == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: disk name kstat_create failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->diskksp->ks_update = envctrl_disk_kstat_update;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->diskksp->ks_private = (void *)unitp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kstat_install(unitp->diskksp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_ps_kstat_update(kstat_t *ksp, int rw)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrlunit *unitp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *kstatp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp = (struct envctrlunit *)ksp->ks_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(MUTEX_HELD(&unitp->umutex));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kstatp = (char *)ksp->ks_data;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (rw == KSTAT_WRITE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (EACCES);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->psksp->ks_ndata = unitp->num_ps_present;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bcopy((caddr_t)&unitp->ps_kstats, kstatp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (unitp->ps_kstats));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_fanstat_kstat_update(kstat_t *ksp, int rw)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrlunit *unitp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *kstatp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kstatp = (char *)ksp->ks_data;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp = (struct envctrlunit *)ksp->ks_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(MUTEX_HELD(&unitp->umutex));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (rw == KSTAT_WRITE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (EACCES);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->fanksp->ks_ndata = unitp->num_fans_present;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bcopy((caddr_t)&unitp->fan_kstats, kstatp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (unitp->fan_kstats));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_encl_kstat_update(kstat_t *ksp, int rw)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrlunit *unitp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *kstatp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kstatp = (char *)ksp->ks_data;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp = (struct envctrlunit *)ksp->ks_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(MUTEX_HELD(&unitp->umutex));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (rw == KSTAT_WRITE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (EACCES);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->enclksp->ks_ndata = unitp->num_encl_present;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_get_fpm_status(unitp, (uint8_t *)NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bcopy((caddr_t)&unitp->encl_kstats, kstatp,
193974072f41a843678abf5f61979c748687e66bSherry Moore sizeof (unitp->encl_kstats));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_temp_kstat_update(kstat_t *ksp, int rw)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrlunit *unitp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *kstatp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kstatp = (char *)ksp->ks_data;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp = (struct envctrlunit *)ksp->ks_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(MUTEX_HELD(&unitp->umutex));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (rw == KSTAT_WRITE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (EACCES);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->tempksp->ks_ndata = unitp->num_temps_present;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bcopy((caddr_t)unitp->temp_kstats, kstatp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (unitp->temp_kstats));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_disk_kstat_update(kstat_t *ksp, int rw)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrlunit *unitp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *kstatp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kstatp = (char *)ksp->ks_data;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp = (struct envctrlunit *)ksp->ks_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(MUTEX_HELD(&unitp->umutex));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (rw == KSTAT_WRITE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (EACCES);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->diskksp->ks_ndata = unitp->num_disks_present;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bcopy((caddr_t)unitp->disk_kstats, kstatp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (unitp->disk_kstats));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_init_encl_kstats(struct envctrlunit *unitp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(MUTEX_HELD(&unitp->umutex));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_read_chip(unitp, ENVCTRL_PCF8574A, EHC_DEV6,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, &val, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Read of PCF8574A (FSP) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->encl_kstats.value = val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_check_disk_kstats(struct envctrlunit *unitp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t diskpr, diskfl;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(MUTEX_HELD(&unitp->umutex));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_read_chip(unitp, ENVCTRL_PCF8574A, EHC_DEV5,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, &diskpr, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Read of PCF8574A (DISKPR) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = envctrl_read_chip(unitp, ENVCTRL_PCF8574A, EHC_DEV7,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0, &diskfl, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: Read of PCF8574A (DISKFL) failed",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_update_disk_kstats(unitp, diskpr, diskfl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_update_disk_kstats(struct envctrlunit *unitp, uint8_t diskpr,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t diskfl)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int i, j, count = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DPRINTF1("diskpr = %X, diskfl = %X\n", diskpr, diskfl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0, j = 1; i < ENVCTRL_UE250_MAX_DISKS; i++, j = j << 1) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(diskpr & j)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(diskfl & j))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->disk_kstats[count].disk_ok = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->disk_kstats[count].disk_ok = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->disk_kstats[count].slot = i;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel count++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->num_disks_present = count;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_probe_cpus(struct envctrlunit *unitp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int instance;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The cpu search is as follows:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If there is only 1 CPU module it is named as
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * SUNW,UltraSPARC. If this is a match we still don't
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * know what slot the cpu module is in therefore
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we need to check the "upa-portid" property.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If we have more than 1 cpu, then they are appended by
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * instance numbers and slot locations. e.g.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * SUNW,UltraSPARC@1,0 (slot 1). it would have been
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * nice to have the naming consistent for one CPU e.g.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * SUNW,UltraSPARC@0,0...sigh
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (instance = 0; instance < ENVCTRL_MAX_CPUS; instance++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->cpu_pr_location[instance] = B_FALSE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_walk_devs(ddi_root_node(), envctrl_match_cpu, unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_match_cpu(dev_info_t *dip, void *arg)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int cpu_slot;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char name[32];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char name1[32];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrlunit *unitp = (struct envctrlunit *)arg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) sprintf(name, "%s", ENVCTRL_ULTRA1CPU_STRING);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) sprintf(name1, "%s", ENVCTRL_ULTRA2CPU_STRING);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((strcmp(ddi_node_name(dip), name) == 0) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (strcmp(ddi_node_name(dip), name1) == 0)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((cpu_slot = (int)ddi_getprop(DDI_DEV_T_ANY, dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_PROP_DONTPASS, "upa-portid",
193974072f41a843678abf5f61979c748687e66bSherry Moore -1)) == -1) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: no cpu upa-portid",
193974072f41a843678abf5f61979c748687e66bSherry Moore driver_name, unitp->instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->cpu_pr_location[cpu_slot] = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unitp->num_cpus_present++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_WALK_CONTINUE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * This routine returns TRUE if some other error condition
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * has set the GEN_ERR FAULT LED. Tp further complicate this
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * LED panel we have overloaded the GEN_ERR LED to indicate
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * that a fan fault has occurred without having a fan fault
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * LED as does all other error conditions. So we just take the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * software state and return true. The whole purpose of this functon
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * is to tell us wehther or not we can shut off the GEN_FAULT LED.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * NOTE: this ledval is usually one of the following FSP vals
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * EXCEPT in the case of the fan fail.. we pass in a "0".
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_isother_fault_led(struct envctrlunit *unitp, uint8_t fspval,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t thisled)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int status = B_FALSE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (fspval != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fspval = (fspval & ~(thisled));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((unitp->fan_failed == B_TRUE) && thisled != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (fspval & ENVCTRL_UE250_FSP_DISK_ERR) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (fspval & ENVCTRL_UE250_FSP_PS_ERR) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (fspval & ENVCTRL_UE250_FSP_TEMP_ERR) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (status);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelenvctrl_pshotplug_poll(void *arg)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct envctrlunit *unitp = (struct envctrlunit *)arg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel envctrl_ps_probe(unitp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&unitp->umutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}