03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER START
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The contents of this file are subject to the terms of the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Common Development and Distribution License (the "License").
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You may not use this file except in compliance with the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
03831d35f7499c87d51205817c93e9a8d42c4baestevel * or http://www.opensolaris.org/os/licensing.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * See the License for the specific language governing permissions
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and limitations under the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * When distributing Covered Code, include this CDDL HEADER in each
03831d35f7499c87d51205817c93e9a8d42c4baestevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If applicable, add the following below this CDDL HEADER, with the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * fields enclosed by brackets "[]" replaced with your own identifying
03831d35f7499c87d51205817c93e9a8d42c4baestevel * information: Portions Copyright [yyyy] [name of copyright owner]
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER END
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Use is subject to license terms.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/time.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/errno.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/kmem.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/stat.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/cmn_err.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/conf.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/modctl.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/devops.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/ddi.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sunddi.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/callb.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/disp.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/strlog.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sgevents.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/serengeti.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sgsbbc.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sgsbbc_iosram.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sgsbbc_mailbox.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/uadmin.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/machsystm.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sysevent.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sysevent/dr.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sysevent/eventdefs.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/file.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/lw8.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/lw8_impl.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/plat_ecc_unum.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Global Variables - can be patched from Solaris
03831d35f7499c87d51205817c93e9a8d42c4baestevel * ==============================================
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Module Variables
03831d35f7499c87d51205817c93e9a8d42c4baestevel * ================
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * functions local to this driver.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int lw8_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int lw8_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int lw8_add_intr_handlers(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int lw8_remove_intr_handlers(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void lw8_wakeup_sleepers(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uint_t lw8_fast_shutdown(char *arg);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uint_t lw8_slow_shutdown(char *arg);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uint_t lw8_event_data_handler(char *);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uint_t lw8_dr_data_handler(char *);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uint_t lw8_env_data_handler(char *);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uint_t lw8_cap_ecc_msg_handler(char *);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int lw8_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int lw8_close(dev_t dev, int flag, int otyp, cred_t *cred_p);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int lw8_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
03831d35f7499c87d51205817c93e9a8d42c4baestevel cred_t *cred_p, int *rval_p);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void lw8_logger_start(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void lw8_logger_destroy(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void lw8_logger_wakeup(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Driver entry points
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct cb_ops lw8_cb_ops = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_open, /* open */
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_close, /* close */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* strategy() */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* print() */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* dump() */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* read() */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* write() */
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_ioctl, /* ioctl() */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* devmap() */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* mmap() */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_segmap, /* segmap() */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nochpoll, /* poll() */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_prop_op, /* prop_op() */
03831d35f7499c87d51205817c93e9a8d42c4baestevel NULL, /* cb_str */
03831d35f7499c87d51205817c93e9a8d42c4baestevel D_NEW | D_MP /* cb_flag */
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct dev_ops lw8_ops = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel DEVO_REV,
03831d35f7499c87d51205817c93e9a8d42c4baestevel 0, /* ref count */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_getinfo_1to1, /* getinfo() */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* identify() */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* probe() */
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_attach, /* attach() */
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_detach, /* detach */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* reset */
03831d35f7499c87d51205817c93e9a8d42c4baestevel &lw8_cb_ops, /* pointer to cb_ops structure */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (struct bus_ops *)NULL,
193974072f41a843678abf5f61979c748687e66bSherry Moore nulldev, /* power() */
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_quiesce_not_needed, /* quiesce() */
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Loadable module support.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelextern struct mod_ops mod_driverops;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct modldrv modldrv = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel &mod_driverops, /* Type of module. This is a driver */
193974072f41a843678abf5f61979c748687e66bSherry Moore "Netra-T12 control driver", /* Name of the module */
03831d35f7499c87d51205817c93e9a8d42c4baestevel &lw8_ops /* pointer to the dev_ops structure */
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct modlinkage modlinkage = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel MODREV_1,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &modldrv,
03831d35f7499c87d51205817c93e9a8d42c4baestevel NULL
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * messages
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SHUTDOWN_EVENT_MSG "lw8: system shutdown due to " \
03831d35f7499c87d51205817c93e9a8d42c4baestevel "SC request.\n"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define VOLTAGE_EVENT_MSG "lw8: system shutdown due to " \
03831d35f7499c87d51205817c93e9a8d42c4baestevel "voltage out of range.\n"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define TEMPERATURE_EVENT_MSG "lw8: system shutdown due to " \
03831d35f7499c87d51205817c93e9a8d42c4baestevel "temperature exceeding limits.\n"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define FANFAIL_EVENT_MSG "lw8: system shutdown due to " \
03831d35f7499c87d51205817c93e9a8d42c4baestevel "too many fan failures.\n"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define NO_SCC_EVENT_MSG "lw8: system shutdown due to " \
03831d35f7499c87d51205817c93e9a8d42c4baestevel "no system configuration card.\n"
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * led table - the following provides a cache of the led state - needed
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to avoid the overhead of readoing from the SC each time
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstruct led_info {
03831d35f7499c87d51205817c93e9a8d42c4baestevel char id[MAX_ID_LEN];
03831d35f7499c87d51205817c93e9a8d42c4baestevel int position;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int status;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char color[MAX_COLOR_LEN];
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct fru_led_info {
03831d35f7499c87d51205817c93e9a8d42c4baestevel char location[MAX_LOCATION_LEN];
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct led_info led_info[MAX_LEDS_PER_FRU];
03831d35f7499c87d51205817c93e9a8d42c4baestevel} fru_led_table[MAX_FRUS] = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel "SB0", {"fault", LOM_LED_POSITION_FRU, 0, "amber",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "power", LOM_LED_POSITION_FRU, 0, "green",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "ok_to_remove", LOM_LED_POSITION_FRU, 0, "amber"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "PS0", {"fault", LOM_LED_POSITION_FRU, 0, "amber",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "power", LOM_LED_POSITION_FRU, 0, "green",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "predicted_fault", LOM_LED_POSITION_FRU, 0, "amber"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "SB2", {"fault", LOM_LED_POSITION_FRU, 0, "amber",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "power", LOM_LED_POSITION_FRU, 0, "green",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "ok_to_remove", LOM_LED_POSITION_FRU, 0, "amber"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "PS1", {"fault", LOM_LED_POSITION_FRU, 0, "amber",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "power", LOM_LED_POSITION_FRU, 0, "green",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "predicted_fault", LOM_LED_POSITION_FRU, 0, "amber"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "SB4", {"fault", LOM_LED_POSITION_FRU, 0, "amber",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "power", LOM_LED_POSITION_FRU, 0, "green",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "ok_to_remove", LOM_LED_POSITION_FRU, 0, "amber"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "PS2", {"fault", LOM_LED_POSITION_FRU, 0, "amber",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "power", LOM_LED_POSITION_FRU, 0, "green",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "predicted_fault", LOM_LED_POSITION_FRU, 0, "amber"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "IB6", {"fault", LOM_LED_POSITION_FRU, 0, "amber",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "power", LOM_LED_POSITION_FRU, 0, "green",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "ok_to_remove", LOM_LED_POSITION_FRU, 0, "amber"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "PS3", {"fault", LOM_LED_POSITION_FRU, 0, "amber",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "power", LOM_LED_POSITION_FRU, 0, "green",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "predicted_fault", LOM_LED_POSITION_FRU, 0, "amber"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "FT0", {"fault", LOM_LED_POSITION_FRU, 0, "amber",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "power", LOM_LED_POSITION_FRU, 0, "green",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "ok_to_remove", LOM_LED_POSITION_FRU, 0, "amber"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "FAN0", {"fault", LOM_LED_POSITION_LOCATION, 0, "amber"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "FAN1", {"fault", LOM_LED_POSITION_LOCATION, 0, "amber"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "FAN2", {"fault", LOM_LED_POSITION_LOCATION, 0, "amber"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "FAN3", {"fault", LOM_LED_POSITION_LOCATION, 0, "amber"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "FAN4", {"fault", LOM_LED_POSITION_LOCATION, 0, "amber"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "FAN5", {"fault", LOM_LED_POSITION_LOCATION, 0, "amber"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "FAN6", {"fault", LOM_LED_POSITION_LOCATION, 0, "amber"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "FAN7", {"fault", LOM_LED_POSITION_LOCATION, 0, "amber"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "FAN8", {"fault", LOM_LED_POSITION_LOCATION, 0, "amber"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "FAN9", {"fault", LOM_LED_POSITION_LOCATION, 0, "amber"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "DISK0", {"fault", LOM_LED_POSITION_LOCATION, 0, "amber",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "power", LOM_LED_POSITION_LOCATION, 0, "green",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "ok_to_remove", LOM_LED_POSITION_LOCATION, 0, "blue"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "DISK1", {"fault", LOM_LED_POSITION_LOCATION, 0, "amber",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "power", LOM_LED_POSITION_LOCATION, 0, "green",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "ok_to_remove", LOM_LED_POSITION_LOCATION, 0, "blue"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "RP0", {"fault", LOM_LED_POSITION_FRU, 0, "amber",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "power", LOM_LED_POSITION_FRU, 0, "green",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "ok_to_remove", LOM_LED_POSITION_FRU, 0, "amber"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "RP2", {"fault", LOM_LED_POSITION_FRU, 0, "amber",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "power", LOM_LED_POSITION_FRU, 0, "green",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "ok_to_remove", LOM_LED_POSITION_FRU, 0, "amber"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel "chassis", {"fault", LOM_LED_POSITION_FRU, 0, "amber",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "power", LOM_LED_POSITION_FRU, 0, "green",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "locator", LOM_LED_POSITION_FRU, 0, "white",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "top_access", LOM_LED_POSITION_FRU, 0, "amber",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "alarm1", LOM_LED_POSITION_FRU, 0, "amber",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "alarm2", LOM_LED_POSITION_FRU, 0, "amber",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "system", LOM_LED_POSITION_FRU, 0, "green",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "supplyA", LOM_LED_POSITION_FRU, 0, "green",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "supplyB", LOM_LED_POSITION_FRU, 0, "green"},
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelchar *fru_locn[MAX_LOCATION_LEN] = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel "SB0",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "PS0",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "SB2",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "PS1",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "SB4",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "PS2",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "IB6",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "PS3",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "SCC",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "SSC1",
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * mutexes which protect the interrupt handlers.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic kmutex_t lw8_shutdown_hdlr_lock;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic kmutex_t lw8_dr_hdlr_lock;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic kmutex_t lw8_env_hdlr_lock;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic kmutex_t lw8_event_mutex;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic kmutex_t lw8_logger_lock;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic kmutex_t lw8_cap_msg_hdlr_lock;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic kcondvar_t lw8_event_cv;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic kcondvar_t lw8_logger_sig_cv;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * state booleans
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic boolean_t lw8_event_pending = B_FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic boolean_t led_state_cached = B_FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Payloads of the event handlers.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic lw8_event_t lw8_shutdown_payload;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic sbbc_msg_t lw8_shutdown_payload_msg;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic sg_system_fru_descriptor_t lw8_dr_payload;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic sbbc_msg_t lw8_dr_payload_msg;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic sg_event_fan_status_t lw8_env_payload;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic sbbc_msg_t lw8_env_payload_msg;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic plat_capability_data_t lw8_cap_payload;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic sbbc_msg_t lw8_cap_payload_msg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The IDs of the soft interrupts
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic ddi_softintr_t lw8_slow_shutdown_softint_id;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic ddi_softintr_t lw8_fast_shutdown_softint_id;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Logger commands..
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define LW8_LOGGER_EXITNOW -1
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define LW8_LOGGER_WAIT 0
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define LW8_LOGGER_PROCESSNOW 1
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Logger thread state
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int lw8_logger_sig = LW8_LOGGER_WAIT;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic kt_did_t lw8_logger_tid = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelextern pri_t maxclsyspri;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevel_init(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int error = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_init(&lw8_shutdown_hdlr_lock, NULL, MUTEX_DEFAULT, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_init(&lw8_dr_hdlr_lock, NULL, MUTEX_DEFAULT, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_init(&lw8_env_hdlr_lock, NULL, MUTEX_DEFAULT, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_init(&lw8_cap_msg_hdlr_lock, NULL, MUTEX_DEFAULT, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_init(&lw8_event_mutex, NULL, MUTEX_DRIVER, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_init(&lw8_logger_lock, NULL, MUTEX_DRIVER, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cv_init(&lw8_event_cv, NULL, CV_DRIVER, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cv_init(&lw8_logger_sig_cv, NULL, CV_DRIVER, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel error = mod_install(&modlinkage);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (error) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cv_destroy(&lw8_logger_sig_cv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cv_destroy(&lw8_event_cv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_destroy(&lw8_logger_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_destroy(&lw8_event_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_destroy(&lw8_env_hdlr_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_destroy(&lw8_cap_msg_hdlr_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_destroy(&lw8_dr_hdlr_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_destroy(&lw8_shutdown_hdlr_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (error);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevel_info(struct modinfo *modinfop)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (mod_info(&modlinkage, modinfop));
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevel_fini(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int error = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel error = mod_remove(&modlinkage);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (error)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (error);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cv_destroy(&lw8_logger_sig_cv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cv_destroy(&lw8_event_cv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_destroy(&lw8_logger_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_destroy(&lw8_event_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_destroy(&lw8_env_hdlr_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_destroy(&lw8_cap_msg_hdlr_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_destroy(&lw8_dr_hdlr_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_destroy(&lw8_shutdown_hdlr_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (error);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevellw8_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int instance;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (cmd) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_ATTACH:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * only allow one instance
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel instance = ddi_get_instance(dip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (instance != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ddi_create_minor_node(dip, "lw8", S_IFCHR,
193974072f41a843678abf5f61979c748687e66bSherry Moore instance, DDI_PSEUDO, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != DDI_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ddi_add_softintr(dip, DDI_SOFTINT_LOW,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &lw8_slow_shutdown_softint_id, NULL, NULL,
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_slow_shutdown, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "Failed to add polling softint"
03831d35f7499c87d51205817c93e9a8d42c4baestevel "handler for lw8. Err=%d", err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_remove_minor_node(dip, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ddi_add_softintr(dip, DDI_SOFTINT_LOW,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &lw8_fast_shutdown_softint_id, NULL, NULL,
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_fast_shutdown, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "Failed to add polling softint"
03831d35f7499c87d51205817c93e9a8d42c4baestevel "handler for lw8. Err=%d", err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_remove_softintr(lw8_slow_shutdown_softint_id);
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_remove_minor_node(dip, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_logger_start();
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Add the handlers which watch for unsolicited messages
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and post event to Sysevent Framework.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = lw8_add_intr_handlers();
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != DDI_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "Failed to add event handlers");
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_logger_destroy();
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_remove_softintr(lw8_fast_shutdown_softint_id);
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_remove_softintr(lw8_slow_shutdown_softint_id);
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_remove_minor_node(dip, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_report_dev(dip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_RESUME:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevellw8_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int instance;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (cmd) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_DETACH:
03831d35f7499c87d51205817c93e9a8d42c4baestevel instance = ddi_get_instance(dip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (instance != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Remove the handlers which watch for unsolicited messages
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and post event to Sysevent Framework.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = lw8_remove_intr_handlers();
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != DDI_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "Failed to remove event handlers");
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_logger_destroy();
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_remove_softintr(lw8_slow_shutdown_softint_id);
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_remove_softintr(lw8_fast_shutdown_softint_id);
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_remove_minor_node(dip, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_SUSPEND:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevellw8_add_intr_handlers()
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_shutdown_payload_msg.msg_buf = (caddr_t)&lw8_shutdown_payload;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_shutdown_payload_msg.msg_len = sizeof (lw8_shutdown_payload);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = sbbc_mbox_reg_intr(MBOX_EVENT_LW8, lw8_event_data_handler,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &lw8_shutdown_payload_msg, NULL, &lw8_shutdown_hdlr_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "Failed to register MBOX_EVENT_LW8 "
193974072f41a843678abf5f61979c748687e66bSherry Moore " handler. Err=%d", err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_dr_payload_msg.msg_buf = (caddr_t)&lw8_dr_payload;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_dr_payload_msg.msg_len = sizeof (lw8_dr_payload);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = sbbc_mbox_reg_intr(MBOX_EVENT_GENERIC, lw8_dr_data_handler,
193974072f41a843678abf5f61979c748687e66bSherry Moore &lw8_dr_payload_msg, NULL, &lw8_dr_hdlr_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "Failed to register MBOX_EVENT_GENERIC "
193974072f41a843678abf5f61979c748687e66bSherry Moore " handler. Err=%d", err);
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) sbbc_mbox_unreg_intr(MBOX_EVENT_LW8,
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki lw8_event_data_handler);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_env_payload_msg.msg_buf = (caddr_t)&lw8_env_payload;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_env_payload_msg.msg_len = sizeof (lw8_env_payload);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = sbbc_mbox_reg_intr(MBOX_EVENT_ENV, lw8_env_data_handler,
193974072f41a843678abf5f61979c748687e66bSherry Moore &lw8_env_payload_msg, NULL, &lw8_env_hdlr_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "Failed to register MBOX_EVENT_ENV "
193974072f41a843678abf5f61979c748687e66bSherry Moore " handler. Err=%d", err);
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) sbbc_mbox_unreg_intr(MBOX_EVENT_GENERIC,
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki lw8_dr_data_handler);
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) sbbc_mbox_unreg_intr(MBOX_EVENT_LW8,
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki lw8_event_data_handler);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_cap_payload_msg.msg_buf = (caddr_t)&lw8_cap_payload;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_cap_payload_msg.msg_len = sizeof (lw8_cap_payload);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = sbbc_mbox_reg_intr(INFO_MBOX, lw8_cap_ecc_msg_handler,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &lw8_cap_payload_msg, NULL, &lw8_cap_msg_hdlr_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "Failed to register INFO_MBOX "
03831d35f7499c87d51205817c93e9a8d42c4baestevel " handler. Err=%d", err);
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) sbbc_mbox_unreg_intr(MBOX_EVENT_GENERIC,
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki lw8_dr_data_handler);
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) sbbc_mbox_unreg_intr(MBOX_EVENT_LW8,
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki lw8_event_data_handler);
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) sbbc_mbox_unreg_intr(INFO_MBOX,
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki lw8_cap_ecc_msg_handler);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevellw8_remove_intr_handlers(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rv = DDI_SUCCESS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = sbbc_mbox_unreg_intr(MBOX_EVENT_LW8, lw8_event_data_handler);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "Failed to unregister MBOX_EVENT_LW8 "
193974072f41a843678abf5f61979c748687e66bSherry Moore "handler. Err=%d", err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = DDI_FAILURE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = sbbc_mbox_unreg_intr(MBOX_EVENT_GENERIC, lw8_dr_data_handler);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "Failed to unregister MBOX_EVENT_GENERIC "
193974072f41a843678abf5f61979c748687e66bSherry Moore "handler. Err=%d", err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = DDI_FAILURE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = sbbc_mbox_unreg_intr(MBOX_EVENT_ENV, lw8_env_data_handler);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "Failed to unregister MBOX_EVENT_ENV "
193974072f41a843678abf5f61979c748687e66bSherry Moore "handler. Err=%d", err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = DDI_FAILURE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = sbbc_mbox_unreg_intr(INFO_MBOX, lw8_cap_ecc_msg_handler);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "Failed to unregister INFO_MBOX "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "handler. Err=%d", err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = DDI_FAILURE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uint_t
03831d35f7499c87d51205817c93e9a8d42c4baestevellw8_dr_data_handler(char *arg)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel sg_system_fru_descriptor_t *payload;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t *msg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int hint;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sysevent_t *ev;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sysevent_id_t eid;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rv = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sysevent_value_t evnt_val;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sysevent_attr_list_t *evnt_attr_list = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char attach_pnt[MAXPATHLEN];
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel msg = (sbbc_msg_t *)arg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (msg == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_INTR_CLAIMED);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel payload = (sg_system_fru_descriptor_t *)msg->msg_buf;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (payload == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_INTR_CLAIMED);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (payload->slot < 0 || payload->slot >= sizeof (fru_locn) /
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (char *)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_INTR_CLAIMED);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * if not SB send sysevent (SBs send sysevent from ssm driver)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strncmp(fru_locn[payload->slot], "SB", 2) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (payload->event_details) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_EVT_BOARD_ABSENT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel hint = SE_HINT_REMOVE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_EVT_BOARD_PRESENT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel hint = SE_HINT_INSERT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel hint = SE_NO_HINT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(attach_pnt, sizeof (attach_pnt), "ssm0:N0.%s",
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_locn[payload->slot]);
03831d35f7499c87d51205817c93e9a8d42c4baestevel ev = sysevent_alloc(EC_DR, ESC_DR_AP_STATE_CHANGE, EP_DDI,
03831d35f7499c87d51205817c93e9a8d42c4baestevel KM_NOSLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ev == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "Failed to allocate %s event", EC_DR);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_INTR_CLAIMED);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel evnt_val.value_type = SE_DATA_TYPE_STRING;
03831d35f7499c87d51205817c93e9a8d42c4baestevel evnt_val.value.sv_string = attach_pnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = sysevent_add_attr(&evnt_attr_list, DR_AP_ID, &evnt_val,
03831d35f7499c87d51205817c93e9a8d42c4baestevel KM_NOSLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rv != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "Failed to add attr [%s] for %s event",
03831d35f7499c87d51205817c93e9a8d42c4baestevel DR_AP_ID, EC_DR);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sysevent_free(ev);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_INTR_CLAIMED);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Add the hint
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel evnt_val.value_type = SE_DATA_TYPE_STRING;
03831d35f7499c87d51205817c93e9a8d42c4baestevel evnt_val.value.sv_string = SE_HINT2STR(hint);
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = sysevent_add_attr(&evnt_attr_list, DR_HINT, &evnt_val,
03831d35f7499c87d51205817c93e9a8d42c4baestevel KM_NOSLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rv != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "Failed to add attr [%s] for %s event",
03831d35f7499c87d51205817c93e9a8d42c4baestevel DR_HINT, EC_DR);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sysevent_free_attr(evnt_attr_list);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sysevent_free(ev);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_INTR_CLAIMED);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sysevent_attach_attributes(ev, evnt_attr_list) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "Failed to attach attr list for %s "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "event", EC_DR);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sysevent_free_attr(evnt_attr_list);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sysevent_free(ev);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_INTR_CLAIMED);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = log_sysevent(ev, KM_NOSLEEP, &eid);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rv != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "lw8_dr_event_handler: failed to log event");
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel sysevent_free(ev);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_wakeup_sleepers();
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_INTR_CLAIMED);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uint_t
03831d35f7499c87d51205817c93e9a8d42c4baestevellw8_cap_ecc_msg_handler(char *addr)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t *msg = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel plat_capability_data_t *cap = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel msg = (sbbc_msg_t *)addr;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (msg == NULL || msg->msg_buf == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_INTR_CLAIMED);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel cap = (plat_capability_data_t *)msg->msg_buf;
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (cap->capd_msg_type) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case PLAT_ECC_CAPABILITY_MESSAGE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel plat_ecc_capability_sc_set(cap->capd_capability);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_INTR_CLAIMED);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uint_t
03831d35f7499c87d51205817c93e9a8d42c4baestevellw8_env_data_handler(char *arg)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_wakeup_sleepers();
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_INTR_CLAIMED);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * wakeup sleepers + mark led cache for this fru as invalid
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevellw8_wakeup_sleepers()
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&lw8_event_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_event_pending = B_TRUE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel cv_broadcast(&lw8_event_cv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel led_state_cached = B_FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&lw8_event_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This function is triggered by a soft interrupt and it's purpose is to call
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to kadmin() to shutdown the system.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uint_t
03831d35f7499c87d51205817c93e9a8d42c4baestevellw8_fast_shutdown(char *arg)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) kadmin(A_SHUTDOWN, AD_POWEROFF, NULL, kcred);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If kadmin fails for some reason then we bring the system down
03831d35f7499c87d51205817c93e9a8d42c4baestevel * via power_down(), or failing that using halt().
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel power_down("kadmin() failed, trying power_down()");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel halt("power_down() failed, trying halt()");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We should never make it this far, so something must have gone
03831d35f7499c87d51205817c93e9a8d42c4baestevel * horribly, horribly wrong.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*NOTREACHED*/
055d7c804dc8f1263f0b3166ba459c65996b8697carlsonj return (DDI_INTR_UNCLAIMED);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This function is triggered by a soft interrupt and it's purpose is to call
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to do_shutdown() to shutdown the system.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uint_t
03831d35f7499c87d51205817c93e9a8d42c4baestevellw8_slow_shutdown(char *arg)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel do_shutdown();
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uint_t
03831d35f7499c87d51205817c93e9a8d42c4baestevellw8_event_data_handler(char *arg)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_event_t *payload;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t *msg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (arg == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_INTR_CLAIMED);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel msg = (sbbc_msg_t *)arg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (msg->msg_buf == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_INTR_CLAIMED);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel payload = (lw8_event_t *)msg->msg_buf;
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (payload->event_type) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LW8_EVENT_REQUESTED_SHUTDOWN:
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Let the user know why the domain is going down.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "%s", SHUTDOWN_EVENT_MSG);
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_trigger_softintr(lw8_slow_shutdown_softint_id);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*NOTREACHED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LW8_EVENT_VOLTAGE_SHUTDOWN:
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Let the user know why the domain is going down.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "%s", VOLTAGE_EVENT_MSG);
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_trigger_softintr(lw8_fast_shutdown_softint_id);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*NOTREACHED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LW8_EVENT_TEMPERATURE_SHUTDOWN:
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Let the user know why the domain is going down.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "%s", TEMPERATURE_EVENT_MSG);
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_trigger_softintr(lw8_fast_shutdown_softint_id);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*NOTREACHED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LW8_EVENT_FANFAIL_SHUTDOWN:
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Let the user know why the domain is going down.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "%s", FANFAIL_EVENT_MSG);
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_trigger_softintr(lw8_fast_shutdown_softint_id);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*NOTREACHED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LW8_EVENT_NO_SCC_SHUTDOWN:
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Let the user know why the domain is going down.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "%s", NO_SCC_EVENT_MSG);
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_trigger_softintr(lw8_fast_shutdown_softint_id);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*NOTREACHED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LW8_EVENT_NEW_LOG_MSG:
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Wake up the log retrieval thread.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_logger_wakeup();
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_INTR_CLAIMED);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_INTR_CLAIMED);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevellw8_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int error = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int instance = getminor(*dev_p);
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "lw8_open";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (instance != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENXIO);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((error = drv_priv(cred_p)) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "lw8:%s: inst %d drv_priv failed",
03831d35f7499c87d51205817c93e9a8d42c4baestevel f, instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (error);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (error);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevellw8_close(dev_t dev, int flag, int otyp, cred_t *cred_p)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevellw8_lomcmd(int cmd, intptr_t arg)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t request, *reqp = &request;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t response, *resp = &response;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rv = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom_eventreq_t *eventreqp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((caddr_t)&request, sizeof (request));
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_type.type = LW8_MBOX;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_type.sub_type = cmd;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((caddr_t)&response, sizeof (response));
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_type.type = LW8_MBOX;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_type.sub_type = cmd;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (cmd) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LW8_MBOX_GET_INFO:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = (caddr_t)NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = sizeof (lom2_info_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = (caddr_t)arg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LW8_MBOX_SET_CTL:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = sizeof (lom_ctl2_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = (caddr_t)arg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = (caddr_t)NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LW8_MBOX_UPDATE_FW:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = sizeof (lom_prog_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = (caddr_t)arg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = (caddr_t)NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LW8_MBOX_GET_LED:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = sizeof (lw8_get_led_payload_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = (caddr_t)arg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = sizeof (lw8_get_led_payload_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = (caddr_t)arg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LW8_MBOX_SET_LED:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = sizeof (lw8_set_led_payload_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = (caddr_t)arg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = (caddr_t)NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LW8_MBOX_GET_EVENTS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * cast as lom_eventreq_t to minimise data traffic
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel eventreqp = (lom_eventreq_t *)arg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = sizeof (lom_eventreq_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = (caddr_t)arg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = sizeof (lom_eventreq_t) +
03831d35f7499c87d51205817c93e9a8d42c4baestevel (eventreqp->num * MAX_EVENT_STR);
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = (caddr_t)arg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LW8_MBOX_GET_NEXT_MSG:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = (caddr_t)NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = sizeof (lw8_logmsg_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = (caddr_t)arg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = sbbc_mbox_request_response(reqp, resp,
03831d35f7499c87d51205817c93e9a8d42c4baestevel LW8_DEFAULT_MAX_MBOX_WAIT_TIME);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((rv) || (resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* errors from sgsbbc */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (resp->msg_status > 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (resp->msg_status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* errors from SCAPP */
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (resp->msg_status) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_COMMAND_FAILURE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* internal SCAPP error */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINTR);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_HARDWARE_FAILURE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* seprom read/write errors */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EIO);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_ILLEGAL_PARAMETER:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* illegal ioctl parameter */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_BOARD_ACCESS_DENIED:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* board access denied */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EACCES);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_STALE_CONTENTS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* stale contents */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ESTALE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_STALE_OBJECT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* stale handle */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENOENT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_NO_SEPROM_SPACE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* seprom lacks space */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENOSPC);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_NO_MEMORY:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* user prog. lacks space */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENOMEM);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_NOT_SUPPORTED:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* unsupported operation */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENOTSUP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EIO);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * set the requested led, and mark cache as empty
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevellw8_setled(lom_set_led_t *set_ledp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int retval;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int i, j;
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct led_info *lip;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_set_led_payload_t lw8_set_led;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < MAX_FRUS; i++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strncmp(set_ledp->location, fru_led_table[i].location,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_LOCATION_LEN) != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (j = 0; j < MAX_LEDS_PER_FRU; j++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel lip = &fru_led_table[i].led_info[j];
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (lip->id == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strncmp(set_ledp->id, lip->id, MAX_ID_LEN) != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_set_led.value = set_ledp->status;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to minimise data transfer, the SC maintains
03831d35f7499c87d51205817c93e9a8d42c4baestevel * just 3 values per fru - except for
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the chassis itself at the end which has
03831d35f7499c87d51205817c93e9a8d42c4baestevel * MAX_LEDS_PER_FRU
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_set_led.offset = (i * 3) + j;
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = lw8_lomcmd(LW8_MBOX_SET_LED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel (intptr_t)&lw8_set_led);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (retval != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (retval);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&lw8_event_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel led_state_cached = B_FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&lw8_event_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * read led value from cache if possible, otherwise read from sc and
03831d35f7499c87d51205817c93e9a8d42c4baestevel * update the cache
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevellw8_getled(lom_get_led_t *get_ledp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int retval;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int i, j, k;
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct led_info *lip;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_get_led_payload_t lw8_get_led;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < MAX_FRUS; i++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strncmp(get_ledp->location, fru_led_table[i].location,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_LOCATION_LEN) != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (get_ledp->id[0] == '\0') {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strncpy(get_ledp->next_id,
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_led_table[i].led_info[0].id, MAX_ID_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (j = 0; j < MAX_LEDS_PER_FRU; j++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel lip = &fru_led_table[i].led_info[j];
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (lip->id == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strncmp(get_ledp->id, lip->id, MAX_ID_LEN) != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&lw8_event_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!led_state_cached) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&lw8_event_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = lw8_lomcmd(LW8_MBOX_GET_LED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel (intptr_t)&lw8_get_led);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (retval != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (retval);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&lw8_event_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to minimise data transfer, the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * lw8_get_led_payload_t structure just has 3
03831d35f7499c87d51205817c93e9a8d42c4baestevel * values per fru - except for the chassis
03831d35f7499c87d51205817c93e9a8d42c4baestevel * itself at the end which has MAX_LEDS_PER_FRU
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (k = 0; k < (MAX_FRUS - 1) * 3; k++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_led_table[k / 3].led_info[k % 3].
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = lw8_get_led.value[k];
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (k = 0; k < MAX_LEDS_PER_FRU; k++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_led_table[MAX_FRUS - 1].led_info[k].
03831d35f7499c87d51205817c93e9a8d42c4baestevel status = lw8_get_led.value[k +
03831d35f7499c87d51205817c93e9a8d42c4baestevel ((MAX_FRUS - 1) * 3)];
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel led_state_cached = B_TRUE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel get_ledp->status = lip->status;
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&lw8_event_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel get_ledp->position = lip->position;
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strncpy(get_ledp->color, lip->color,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_COLOR_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (j == MAX_LEDS_PER_FRU - 1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel get_ledp->next_id[0] = '\0';
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strncpy(get_ledp->next_id,
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_led_table[i].led_info[j + 1].id, MAX_ID_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (get_ledp->id[0] == '\0') {
03831d35f7499c87d51205817c93e9a8d42c4baestevel get_ledp->next_id[0] = '\0';
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevellw8_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred_p,
03831d35f7499c87d51205817c93e9a8d42c4baestevel int *rval_p)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int instance = getminor(dev);
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom2_info_t lw8_info2;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom_ctl_t lw8_ctl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom_ctl2_t lw8_ctl2;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom_mprog_t lw8_mprog;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom_fled_info_t lw8_fled_info;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom_info_t lw8_info;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom_aldata_t lw8_aldata;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom_get_led_t lw8_get_led;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom_set_led_t lw8_set_led;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom_prog_t *lw8_progp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom_eventlog2_t *lw8_eventlogp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom_eventresp_t *lw8_eventresp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int retval = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int i, j;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (instance != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENXIO);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (cmd) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LOMIOCWTMON:
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&lw8_event_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!lw8_event_pending) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (cv_wait_sig(&lw8_event_cv, &lw8_event_mutex) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&lw8_event_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = EINTR;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_event_pending = B_FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&lw8_event_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LOMIOCMREAD:
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((caddr_t)&lw8_mprog, sizeof (lw8_mprog));
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_mprog.config = 4;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyout((caddr_t)&lw8_mprog, (caddr_t)arg,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (lw8_mprog), mode) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = EFAULT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LOMIOCCTL2:
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyin((caddr_t)arg, (caddr_t)&lw8_ctl2,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (lw8_ctl2), mode) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = EFAULT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = lw8_lomcmd(LW8_MBOX_SET_CTL, (intptr_t)&lw8_ctl2);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LOMIOCPROG:
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_progp = kmem_alloc(sizeof (*lw8_progp), KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyin((caddr_t)arg, (caddr_t)lw8_progp,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (*lw8_progp), mode) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(lw8_progp, sizeof (*lw8_progp));
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = EFAULT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = lw8_lomcmd(LW8_MBOX_UPDATE_FW, (intptr_t)lw8_progp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(lw8_progp, sizeof (*lw8_progp));
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LOMIOCINFO2:
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((caddr_t)&lw8_info2, sizeof (lw8_info2));
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = lw8_lomcmd(LW8_MBOX_GET_INFO, (intptr_t)&lw8_info2);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (retval != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyout((caddr_t)&lw8_info2, (caddr_t)arg,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (lw8_info2), mode) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = EFAULT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LOMIOCINFO:
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((caddr_t)&lw8_info2, sizeof (lw8_info2));
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = lw8_lomcmd(LW8_MBOX_GET_INFO, (intptr_t)&lw8_info2);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (retval != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((caddr_t)&lw8_info, sizeof (lw8_info));
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_info.ser_char = lw8_info2.escape_chars[0];
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_info.fver = lw8_info2.fver;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_info.fchksum = lw8_info2.fchksum;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_info.prod_rev = lw8_info2.prod_rev;
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) strncpy(lw8_info.prod_id, lw8_info2.prod_id, MAX_ID_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyout((caddr_t)&lw8_info, (caddr_t)arg,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (lw8_info), mode) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = EFAULT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LOMIOCFLEDSTATE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((caddr_t)&lw8_get_led, sizeof (lw8_get_led));
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strncpy(lw8_get_led.location, "chassis",
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_LOCATION_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strncpy(lw8_get_led.id, "fault", MAX_ID_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = lw8_getled(&lw8_get_led);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (retval != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_fled_info.on = lw8_get_led.status;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyout((caddr_t)&lw8_fled_info, (caddr_t)arg,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (lw8_fled_info), mode) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = EFAULT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LOMIOCALSTATE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyin((caddr_t)arg, (caddr_t)&lw8_aldata,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (lw8_aldata), mode) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = EFAULT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((caddr_t)&lw8_get_led, sizeof (lw8_get_led));
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strncpy(lw8_get_led.location, "chassis",
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_LOCATION_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (lw8_aldata.alarm_no == 3)
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(lw8_get_led.id, MAX_ID_LEN, "system");
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(lw8_get_led.id, MAX_ID_LEN, "alarm%d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_aldata.alarm_no);
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = lw8_getled(&lw8_get_led);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (retval != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_aldata.state = lw8_get_led.status;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyout((caddr_t)&lw8_aldata, (caddr_t)arg,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (lw8_aldata), mode) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = EFAULT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LOMIOCGETLED:
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyin((caddr_t)arg, (caddr_t)&lw8_get_led,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (lw8_get_led), mode) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = EFAULT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = lw8_getled(&lw8_get_led);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (retval != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyout((caddr_t)&lw8_get_led, (caddr_t)arg,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (lw8_get_led), mode) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = EFAULT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LOMIOCEVENTLOG2:
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_eventlogp = kmem_alloc(sizeof (*lw8_eventlogp), KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_eventresp = kmem_zalloc(sizeof (*lw8_eventresp), KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyin((caddr_t)arg, (caddr_t)lw8_eventlogp,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (*lw8_eventlogp), mode) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(lw8_eventlogp, sizeof (*lw8_eventlogp));
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(lw8_eventresp, sizeof (*lw8_eventresp));
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = EFAULT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_eventresp->num = lw8_eventlogp->num;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_eventresp->level = lw8_eventlogp->level;
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = lw8_lomcmd(LW8_MBOX_GET_EVENTS,
03831d35f7499c87d51205817c93e9a8d42c4baestevel (intptr_t)lw8_eventresp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (retval == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_eventlogp->num = lw8_eventresp->num;
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < lw8_eventresp->num; i++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (j = 0; j < MAX_EVENT_STR; j++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_eventlogp->string[i][j] =
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_eventresp->string[i][j];
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyout((caddr_t)lw8_eventlogp, (caddr_t)arg,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (*lw8_eventlogp), mode) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = EFAULT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(lw8_eventlogp, sizeof (*lw8_eventlogp));
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(lw8_eventresp, sizeof (*lw8_eventresp));
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LOMIOCALCTL:
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyin((caddr_t)arg, (caddr_t)&lw8_aldata,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (lw8_aldata), mode) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = EFAULT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((caddr_t)&lw8_set_led, sizeof (lw8_set_led));
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strncpy(lw8_set_led.location, "chassis",
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_LOCATION_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (lw8_aldata.alarm_no == 3)
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(lw8_set_led.id, MAX_ID_LEN, "system");
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(lw8_set_led.id, MAX_ID_LEN, "alarm%d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_aldata.alarm_no);
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_set_led.status = lw8_aldata.state;
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = lw8_setled(&lw8_set_led);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LOMIOCSETLED:
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyin((caddr_t)arg, (caddr_t)&lw8_set_led,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (lw8_set_led), mode) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = EFAULT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = lw8_setled(&lw8_set_led);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LOMIOCCTL:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * for this ioctl, as well as setting the fault led in the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * LOMIOCCTL case in lw8_lomcmd(), we also need to set the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * escape character. To do this we must use LW8_MBOX_SET_CTL,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * but this also needs the serial_event value which we have
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to get via LW8_MBOX_GET_INFO
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyin((caddr_t)arg, (caddr_t)&lw8_ctl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (lw8_ctl), mode) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = EFAULT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((caddr_t)&lw8_info2, sizeof (lw8_info2));
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = lw8_lomcmd(LW8_MBOX_GET_INFO, (intptr_t)&lw8_info2);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (retval != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((caddr_t)&lw8_ctl2, sizeof (lw8_ctl2));
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_ctl2.escape_chars[0] = lw8_ctl.ser_char;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_ctl2.serial_events = lw8_info2.serial_events;
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = lw8_lomcmd(LW8_MBOX_SET_CTL, (intptr_t)&lw8_ctl2);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (retval != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * if fault_led != 0, then set the led
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (lw8_ctl.fault_led == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((caddr_t)&lw8_set_led, sizeof (lw8_set_led));
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strncpy(lw8_set_led.location, "chassis",
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_LOCATION_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strncpy(lw8_set_led.id, "fault", MAX_ID_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_set_led.status = lw8_ctl.fault_led - 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = lw8_setled(&lw8_set_led);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = ENOTSUP;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (retval);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* ARGSUSED */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevellw8_logger(caddr_t arg)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel callb_cpr_t cprinfo;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_logmsg_t *lw8_logmsgp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel boolean_t more_waiting;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char level;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int retval;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel CALLB_CPR_INIT(&cprinfo, &lw8_logger_lock, callb_generic_cpr,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "lw8_logger");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_logmsgp = kmem_zalloc(sizeof (*lw8_logmsgp), KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&lw8_logger_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (;;) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Wait for someone to tell me to continue.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (lw8_logger_sig == LW8_LOGGER_WAIT) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel CALLB_CPR_SAFE_BEGIN(&cprinfo);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cv_wait(&lw8_logger_sig_cv, &lw8_logger_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel CALLB_CPR_SAFE_END(&cprinfo, &lw8_logger_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* LW8_LOGGER_EXITNOW implies signal by _detach(). */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (lw8_logger_sig == LW8_LOGGER_EXITNOW) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_logger_sig = LW8_LOGGER_WAIT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(lw8_logmsgp, sizeof (*lw8_logmsgp));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* lw8_logger_lock is held at this point! */
03831d35f7499c87d51205817c93e9a8d42c4baestevel CALLB_CPR_EXIT(&cprinfo);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel thread_exit();
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* NOTREACHED */
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel ASSERT(lw8_logger_sig == LW8_LOGGER_PROCESSNOW);
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_logger_sig = LW8_LOGGER_WAIT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&lw8_logger_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Do lw8_event logging */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Get one message per iteration. We do not sleep if
03831d35f7499c87d51205817c93e9a8d42c4baestevel * there are more to process. This makes exit from the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * routine much more reliable.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel more_waiting = B_FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel retval = lw8_lomcmd(LW8_MBOX_GET_NEXT_MSG,
03831d35f7499c87d51205817c93e9a8d42c4baestevel (intptr_t)lw8_logmsgp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (retval == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (lw8_logmsgp->msg_valid) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (lw8_logmsgp->level) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case 0: /* LOG_EMERG */
03831d35f7499c87d51205817c93e9a8d42c4baestevel level = SL_FATAL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case 1: /* LOG_ALERT */
03831d35f7499c87d51205817c93e9a8d42c4baestevel level = SL_FATAL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case 2: /* LOG_CRIT */
03831d35f7499c87d51205817c93e9a8d42c4baestevel level = SL_FATAL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case 3: /* LOG_ERR */
03831d35f7499c87d51205817c93e9a8d42c4baestevel level = SL_ERROR;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case 4: /* LOG_WARNING */
03831d35f7499c87d51205817c93e9a8d42c4baestevel level = SL_WARN;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case 5: /* LOG_NOTICE */
03831d35f7499c87d51205817c93e9a8d42c4baestevel level = SL_NOTE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case 6: /* LOG_INFO */
03831d35f7499c87d51205817c93e9a8d42c4baestevel level = SL_NOTE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case 7: /* LOG_DEBUG */
03831d35f7499c87d51205817c93e9a8d42c4baestevel level = SL_TRACE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel default: /* unknown */
03831d35f7499c87d51205817c93e9a8d42c4baestevel level = SL_NOTE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Ensure NUL termination */
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_logmsgp->msg[
193974072f41a843678abf5f61979c748687e66bSherry Moore sizeof (lw8_logmsgp->msg) - 1] = '\0';
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) strlog(0, 0, 0, SL_CONSOLE | level,
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_logmsgp->msg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (lw8_logmsgp->num_remaining > 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel more_waiting = B_TRUE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Re-enter the lock to prepare for another iteration.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We must have the lock here to protect lw8_logger_sig.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&lw8_logger_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((lw8_logger_sig == LW8_LOGGER_WAIT) && more_waiting)
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* We need to get more events */
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_logger_sig = LW8_LOGGER_PROCESSNOW;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevellw8_logger_start(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel kthread_t *tp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&lw8_logger_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (lw8_logger_tid == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Force retrieval of any pending messages */
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_logger_sig = LW8_LOGGER_PROCESSNOW;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel tp = thread_create(NULL, 0, lw8_logger, NULL, 0,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &p0, TS_RUN, maxclsyspri);
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_logger_tid = tp->t_did;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&lw8_logger_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevellw8_logger_destroy(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel kt_did_t tid;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&lw8_logger_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tid = lw8_logger_tid;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (tid != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_logger_sig = LW8_LOGGER_EXITNOW;
03831d35f7499c87d51205817c93e9a8d42c4baestevel cv_signal(&lw8_logger_sig_cv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_logger_tid = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&lw8_logger_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Wait for lw8_logger() to finish.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (tid != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel thread_join(tid);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevellw8_logger_wakeup(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&lw8_logger_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (lw8_logger_sig != LW8_LOGGER_EXITNOW)
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_logger_sig = LW8_LOGGER_PROCESSNOW;
03831d35f7499c87d51205817c93e9a8d42c4baestevel cv_signal(&lw8_logger_sig_cv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&lw8_logger_lock);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}