927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy/*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * CDDL HEADER START
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy *
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * The contents of this file are subject to the terms of the
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * Common Development and Distribution License (the "License").
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * You may not use this file except in compliance with the License.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy *
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * or http://www.opensolaris.org/os/licensing.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * See the License for the specific language governing permissions
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * and limitations under the License.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy *
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * When distributing Covered Code, include this CDDL HEADER in each
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * If applicable, add the following below this CDDL HEADER, with the
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * fields enclosed by brackets "[]" replaced with your own identifying
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * information: Portions Copyright [yyyy] [name of copyright owner]
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy *
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * CDDL HEADER END
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy/*
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * Use is subject to license terms.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy/*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * sun4v application watchdog driver
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#include <sys/types.h>
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#include <sys/file.h>
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#include <sys/errno.h>
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#include <sys/open.h>
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#include <sys/callb.h>
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#include <sys/cred.h>
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#include <sys/cyclic.h>
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#include <sys/uio.h>
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#include <sys/stat.h>
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#include <sys/ksynch.h>
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#include <sys/modctl.h>
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#include <sys/conf.h>
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#include <sys/devops.h>
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#include <sys/debug.h>
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#include <sys/cmn_err.h>
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#include <sys/ddi.h>
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#include <sys/reboot.h>
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#include <sys/sunddi.h>
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#include <sys/signal.h>
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#include <sys/ntwdt.h>
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#include <sys/note.h>
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy/*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * tunables
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyint ntwdt_disable_timeout_action = 0;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#ifdef DEBUG
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyint ntwdt_debug = 0; /* ntwdt debug flag, dbg all for now. */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy/*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * Flags to set in ntwdt_debug.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#define NTWDT_DBG_ENTRY 0x00000001 /* drv entry points */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#define NTWDT_DBG_IOCTL 0x00000002 /* ioctl's */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#define NTWDT_DBG_NTWDT 0x00000004 /* other ntwdt debug */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#define NTWDT_DBG(flag, msg) \
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy { if ((ntwdt_debug) & (flag)) (void) printf msg; }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#else /* DEBUG */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#define NTWDT_DBG(flag, msg)
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#endif /* DEBUG */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#define NTWDT_MINOR_NODE "awdt"
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#define getstate(minor) \
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ((ntwdt_state_t *)ddi_get_soft_state(ntwdt_statep, (minor)))
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy/*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * The ntwdt cyclic interval in nanosecond unit as cyclic subsystem supports
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * nanosecond resolution.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#define NTWDT_CYCLIC_INTERVAL NANOSEC /* 1 seconds */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy/*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * The ntwdt decrement interval in 1 second resolution.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#define NTWDT_DECREMENT_INTERVAL 1 /* 1 second */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy/*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * ntwdt_watchdog_flags and macros to set/clear one bit in it.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#define NTWDT_FLAG_SKIP_CYCLIC 0x1 /* skip next cyclic */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#define NTWDT_MAX_TIMEOUT (3 * 60 * 60) /* 3 hours */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#define WDT_MIN_COREAPI_MAJOR 1
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy#define WDT_MIN_COREAPI_MINOR 1
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy/*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * Application watchdog state.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoytypedef struct ntwdt_runstate {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy kmutex_t ntwdt_runstate_mutex;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ddi_iblock_cookie_t ntwdt_runstate_mtx_cookie;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy int ntwdt_watchdog_enabled; /* wdog enabled ? */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy int ntwdt_reset_enabled; /* reset enabled ? */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy int ntwdt_timer_running; /* wdog running ? */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy int ntwdt_watchdog_expired; /* wdog expired ? */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy uint32_t ntwdt_time_remaining; /* expiration timer */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy uint32_t ntwdt_watchdog_timeout; /* timeout in seconds */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy hrtime_t ntwdt_cyclic_interval; /* cyclic interval */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy cyc_handler_t ntwdt_cycl_hdlr;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy cyc_time_t ntwdt_cycl_time;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy uint32_t ntwdt_watchdog_flags;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy} ntwdt_runstate_t;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy/*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * softstate of NTWDT
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoytypedef struct {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy kmutex_t ntwdt_mutex;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy dev_info_t *ntwdt_dip; /* dip */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy int ntwdt_open_flag; /* file open ? */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_runstate_t *ntwdt_run_state; /* wdog state */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy cyclic_id_t ntwdt_cycl_id;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy} ntwdt_state_t;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic void *ntwdt_statep; /* softstate */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic dev_info_t *ntwdt_dip;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic ddi_softintr_t ntwdt_cyclic_softint_id;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic int ntwdt_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic int ntwdt_attach(dev_info_t *, ddi_attach_cmd_t);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic int ntwdt_detach(dev_info_t *, ddi_detach_cmd_t);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic int ntwdt_open(dev_t *, int, int, cred_t *);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic int ntwdt_close(dev_t, int, int, cred_t *);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic int ntwdt_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic int ntwdt_chk_watchdog_support();
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic void ntwdt_arm_watchdog(ntwdt_runstate_t *ntwdt_state);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic void ntwdt_cyclic_pat(void);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic uint_t ntwdt_cyclic_softint(caddr_t arg);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic void ntwdt_start_timer(ntwdt_state_t *ntwdt_ptr);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic void ntwdt_stop_timer_lock(void *arg);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic void ntwdt_stop_timer(void *arg);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic void ntwdt_enforce_timeout();
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic struct cb_ops ntwdt_cb_ops = {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_open, /* cb_open */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_close, /* cb_close */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy nodev, /* cb_strategy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy nodev, /* cb_print */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy nodev, /* cb_dump */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy nodev, /* cb_read */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy nodev, /* cb_write */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_ioctl, /* cb_ioctl */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy nodev, /* cb_devmap */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy nodev, /* cb_mmap */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy nodev, /* cb_segmap */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy nochpoll, /* cb_chpoll */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ddi_prop_op, /* cb_prop_op */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NULL, /* cb_str */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy D_NEW | D_MP /* cb_flag */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy};
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic struct dev_ops ntwdt_dev_ops = {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy DEVO_REV, /* devo_rev */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy 0, /* devo_refcnt */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_info, /* devo_info */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy nulldev, /* devo_identify */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy nulldev, /* devo_probe */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_attach, /* devo_attach */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_detach, /* devo_detach */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy nodev, /* devo_reset */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy &ntwdt_cb_ops, /* devo_cb_ops */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NULL, /* devo_bus_ops */
193974072f41a843678abf5f61979c748687e66bSherry Moore nulldev, /* devo_power */
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_quiesce_not_supported, /* devo_quiesce */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy};
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic struct modldrv modldrv = {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy &mod_driverops,
193974072f41a843678abf5f61979c748687e66bSherry Moore "Application Watchdog Driver",
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy &ntwdt_dev_ops
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy};
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic struct modlinkage modlinkage = {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy MODREV_1,
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy (void *)&modldrv,
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NULL
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy};
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyint
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy_init(void)
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy{
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy int error = 0;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NTWDT_DBG(NTWDT_DBG_ENTRY, ("_init"));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /* Initialize the soft state structures */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if ((error = ddi_soft_state_init(&ntwdt_statep,
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy sizeof (ntwdt_state_t), 1)) != 0) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (error);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /* Install the loadable module */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if ((error = mod_install(&modlinkage)) != 0) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ddi_soft_state_fini(&ntwdt_statep);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (error);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy}
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyint
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy_info(struct modinfo *modinfop)
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy{
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NTWDT_DBG(NTWDT_DBG_ENTRY, ("_info"));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (mod_info(&modlinkage, modinfop));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy}
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyint
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy_fini(void)
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy{
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy int retval;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NTWDT_DBG(NTWDT_DBG_ENTRY, ("_fini"));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if ((retval = mod_remove(&modlinkage)) == 0) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ddi_soft_state_fini(&ntwdt_statep);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (retval);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy}
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic int
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyntwdt_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy{
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy int instance;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state_t *ntwdt_ptr = NULL; /* pointer to ntwdt_runstatep */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_runstate_t *ntwdt_runstatep = NULL;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy cyc_handler_t *hdlr = NULL;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy switch (cmd) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy case DDI_ATTACH:
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy break;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy case DDI_RESUME:
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (DDI_SUCCESS);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy default:
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (DDI_FAILURE);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ntwdt_chk_watchdog_support() != 0) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (DDI_FAILURE);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy instance = ddi_get_instance(dip);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ASSERT(instance == 0);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ddi_soft_state_zalloc(ntwdt_statep, instance) != DDI_SUCCESS) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (DDI_FAILURE);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_ptr = ddi_get_soft_state(ntwdt_statep, instance);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ASSERT(ntwdt_ptr != NULL);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_dip = dip;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_ptr->ntwdt_dip = dip;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_ptr->ntwdt_cycl_id = CYCLIC_NONE;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_init(&ntwdt_ptr->ntwdt_mutex, NULL,
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy MUTEX_DRIVER, NULL);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * Initialize the watchdog structure
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_ptr->ntwdt_run_state =
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy kmem_zalloc(sizeof (ntwdt_runstate_t), KM_SLEEP);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_runstatep = ntwdt_ptr->ntwdt_run_state;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ddi_get_soft_iblock_cookie(dip, DDI_SOFTINT_LOW,
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy &ntwdt_runstatep->ntwdt_runstate_mtx_cookie) != DDI_SUCCESS) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy cmn_err(CE_WARN, "init of iblock cookie failed "
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy "for ntwdt_runstate_mutex");
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy goto err1;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy } else {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_init(&ntwdt_runstatep->ntwdt_runstate_mutex,
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NULL,
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy MUTEX_DRIVER,
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy (void *)ntwdt_runstatep->ntwdt_runstate_mtx_cookie);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /* Cyclic fires once per second: */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_runstatep->ntwdt_cyclic_interval = NTWDT_CYCLIC_INTERVAL;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /* init the Cyclic that drives the NTWDT */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy hdlr = &ntwdt_runstatep->ntwdt_cycl_hdlr;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy hdlr->cyh_level = CY_LOCK_LEVEL;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy hdlr->cyh_func = (cyc_func_t)ntwdt_cyclic_pat;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy hdlr->cyh_arg = NULL;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /* Softint that will be triggered by Cyclic that drives NTWDT */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ddi_add_softintr(dip, DDI_SOFTINT_LOW, &ntwdt_cyclic_softint_id,
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NULL, NULL, ntwdt_cyclic_softint, (caddr_t)ntwdt_ptr)
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy != DDI_SUCCESS) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy cmn_err(CE_WARN, "failed to add cyclic softintr");
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy goto err2;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * Create Minor Node as last activity. This prevents
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * application from accessing our implementation until it
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * is initialized.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ddi_create_minor_node(dip, NTWDT_MINOR_NODE, S_IFCHR, 0,
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy DDI_PSEUDO, NULL) == DDI_FAILURE) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy cmn_err(CE_WARN, "failed to create Minor Node: %s",
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NTWDT_MINOR_NODE);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy goto err3;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /* Display our driver info in the banner */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ddi_report_dev(dip);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (DDI_SUCCESS);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyerr3:
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ddi_remove_softintr(ntwdt_cyclic_softint_id);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyerr2:
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_destroy(&ntwdt_runstatep->ntwdt_runstate_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyerr1:
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /* clean up the driver stuff here */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy kmem_free(ntwdt_runstatep, sizeof (ntwdt_runstate_t));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_ptr->ntwdt_run_state = NULL;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_destroy(&ntwdt_ptr->ntwdt_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ddi_soft_state_free(ntwdt_statep, instance);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_dip = NULL;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (DDI_FAILURE);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy}
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy/*ARGSUSED*/
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic int
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyntwdt_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy{
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy dev_t dev;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy int instance;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy int error = DDI_SUCCESS;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy switch (infocmd) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy case DDI_INFO_DEVT2DEVINFO:
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy dev = (dev_t)arg;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (getminor(dev) == 0) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy *result = (void *)ntwdt_dip;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy } else {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy error = DDI_FAILURE;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy break;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy case DDI_INFO_DEVT2INSTANCE:
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy dev = (dev_t)arg;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy instance = getminor(dev);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy *result = (void *)(uintptr_t)instance;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy break;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy default:
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy error = DDI_FAILURE;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (error);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy}
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy/*ARGSUSED*/
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic int
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyntwdt_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy{
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy int instance = ddi_get_instance(dip);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state_t *ntwdt_ptr = NULL;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_ptr = ddi_get_soft_state(ntwdt_statep, instance);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ntwdt_ptr == NULL) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (DDI_FAILURE);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy switch (cmd) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy case DDI_SUSPEND:
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (DDI_SUCCESS);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy case DDI_DETACH:
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * release resources in opposite (LIFO) order as
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * were allocated in attach.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ddi_remove_minor_node(dip, NULL);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_stop_timer_lock((void *)ntwdt_ptr);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ddi_remove_softintr(ntwdt_cyclic_softint_id);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_destroy(
193974072f41a843678abf5f61979c748687e66bSherry Moore &ntwdt_ptr->ntwdt_run_state->ntwdt_runstate_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy kmem_free(ntwdt_ptr->ntwdt_run_state,
193974072f41a843678abf5f61979c748687e66bSherry Moore sizeof (ntwdt_runstate_t));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_ptr->ntwdt_run_state = NULL;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_destroy(&ntwdt_ptr->ntwdt_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ddi_soft_state_free(ntwdt_statep, instance);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_dip = NULL;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (DDI_SUCCESS);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy default:
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (DDI_FAILURE);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy}
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy/*ARGSUSED*/
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic int
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyntwdt_open(dev_t *devp, int flag, int otyp, cred_t *credp)
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy{
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy int instance = getminor(*devp);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy int retval = 0;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state_t *ntwdt_ptr = getstate(instance);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ntwdt_ptr == NULL) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (ENXIO);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * ensure caller is a priviledged process.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (drv_priv(credp) != 0) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (EPERM);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_enter(&ntwdt_ptr->ntwdt_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ntwdt_ptr->ntwdt_open_flag) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy retval = EAGAIN;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy } else {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_ptr->ntwdt_open_flag = 1;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_exit(&ntwdt_ptr->ntwdt_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (retval);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy}
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy/*ARGSUSED*/
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic int
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyntwdt_close(dev_t dev, int flag, int otyp, cred_t *credp)
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy{
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy int instance = getminor(dev);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state_t *ntwdt_ptr = getstate(instance);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ntwdt_ptr == NULL) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (ENXIO);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_enter(&ntwdt_ptr->ntwdt_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_ptr->ntwdt_open_flag = 0;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_exit(&ntwdt_ptr->ntwdt_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (0);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy}
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy/*ARGSUSED*/
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic int
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyntwdt_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy int *rvalp)
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy{
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy int instance = getminor(dev);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy int retval = 0;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state_t *ntwdt_ptr = NULL;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_runstate_t *ntwdt_state;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy lom_dogstate_t lom_dogstate;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy lom_dogctl_t lom_dogctl;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy uint32_t lom_dogtime;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if ((ntwdt_ptr = getstate(instance)) == NULL) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (ENXIO);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state = ntwdt_ptr->ntwdt_run_state;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy switch (cmd) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy case LOMIOCDOGSTATE:
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_enter(&ntwdt_state->ntwdt_runstate_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy lom_dogstate.reset_enable = ntwdt_state->ntwdt_reset_enabled;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy lom_dogstate.dog_enable = ntwdt_state->ntwdt_watchdog_enabled;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy lom_dogstate.dog_timeout = ntwdt_state->ntwdt_watchdog_timeout;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_exit(&ntwdt_state->ntwdt_runstate_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ddi_copyout((caddr_t)&lom_dogstate, (caddr_t)arg,
193974072f41a843678abf5f61979c748687e66bSherry Moore sizeof (lom_dogstate_t), mode) != 0) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy retval = EFAULT;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy break;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy case LOMIOCDOGCTL:
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ddi_copyin((caddr_t)arg, (caddr_t)&lom_dogctl,
193974072f41a843678abf5f61979c748687e66bSherry Moore sizeof (lom_dogctl_t), mode) != 0) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy retval = EFAULT;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy break;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NTWDT_DBG(NTWDT_DBG_IOCTL, ("reset_enable: %d, and dog_enable: "
193974072f41a843678abf5f61979c748687e66bSherry Moore "%d, watchdog_timeout %d", lom_dogctl.reset_enable,
193974072f41a843678abf5f61979c748687e66bSherry Moore lom_dogctl.dog_enable,
193974072f41a843678abf5f61979c748687e66bSherry Moore ntwdt_state->ntwdt_watchdog_timeout));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * ignore request to enable reset while disabling watchdog.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (!lom_dogctl.dog_enable && lom_dogctl.reset_enable) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NTWDT_DBG(NTWDT_DBG_IOCTL, ("invalid combination of "
193974072f41a843678abf5f61979c748687e66bSherry Moore "reset_enable: %d, and dog_enable: %d",
193974072f41a843678abf5f61979c748687e66bSherry Moore lom_dogctl.reset_enable,
193974072f41a843678abf5f61979c748687e66bSherry Moore lom_dogctl.dog_enable));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy retval = EINVAL;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy break;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_enter(&ntwdt_state->ntwdt_runstate_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ntwdt_state->ntwdt_watchdog_timeout == 0) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * the LOMIOCDOGTIME has never been used to setup
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * a valid timeout.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NTWDT_DBG(NTWDT_DBG_IOCTL, ("timeout has not been set"
193974072f41a843678abf5f61979c748687e66bSherry Moore "watchdog_timeout: %d",
193974072f41a843678abf5f61979c748687e66bSherry Moore ntwdt_state->ntwdt_watchdog_timeout));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy retval = EINVAL;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy goto end;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * Store the user specified state in the softstate.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state->ntwdt_reset_enabled = lom_dogctl.reset_enable;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state->ntwdt_watchdog_enabled = lom_dogctl.dog_enable;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ntwdt_state->ntwdt_watchdog_enabled != 0) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * The user wants to enable the watchdog.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * Arm the watchdog and start the cyclic.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_arm_watchdog(ntwdt_state);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ntwdt_state->ntwdt_timer_running == 0) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_start_timer(ntwdt_ptr);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NTWDT_DBG(NTWDT_DBG_IOCTL, ("AWDT is enabled"));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy } else {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * The user wants to disable the watchdog.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ntwdt_state->ntwdt_timer_running != 0) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_stop_timer(ntwdt_ptr);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NTWDT_DBG(NTWDT_DBG_IOCTL, ("AWDT is disabled"));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_exit(&ntwdt_state->ntwdt_runstate_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy break;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy case LOMIOCDOGTIME:
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ddi_copyin((caddr_t)arg, (caddr_t)&lom_dogtime,
193974072f41a843678abf5f61979c748687e66bSherry Moore sizeof (uint32_t), mode) != 0) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy retval = EFAULT;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy break;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NTWDT_DBG(NTWDT_DBG_IOCTL, ("user set timeout: %d",
193974072f41a843678abf5f61979c748687e66bSherry Moore lom_dogtime));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * Ensure specified timeout is valid.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if ((lom_dogtime == 0) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (lom_dogtime > (uint32_t)NTWDT_MAX_TIMEOUT)) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy retval = EINVAL;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NTWDT_DBG(NTWDT_DBG_IOCTL, ("user set invalid "
193974072f41a843678abf5f61979c748687e66bSherry Moore "timeout: %d", (int)TICK_TO_MSEC(lom_dogtime)));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy break;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_enter(&ntwdt_state->ntwdt_runstate_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state->ntwdt_watchdog_timeout = lom_dogtime;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * If awdt is currently running, re-arm it with the
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * newly-specified timeout value.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ntwdt_state->ntwdt_timer_running != 0) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_arm_watchdog(ntwdt_state);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_exit(&ntwdt_state->ntwdt_runstate_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy break;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy case LOMIOCDOGPAT:
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * Allow user to pat the watchdog timer.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NTWDT_DBG(NTWDT_DBG_IOCTL, ("DOGPAT is invoked"));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_enter(&ntwdt_state->ntwdt_runstate_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * If awdt is not enabled or underlying cyclic is not
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * running, exit.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (!(ntwdt_state->ntwdt_watchdog_enabled &&
193974072f41a843678abf5f61979c748687e66bSherry Moore ntwdt_state->ntwdt_timer_running)) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NTWDT_DBG(NTWDT_DBG_IOCTL, ("PAT: AWDT not enabled"));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy goto end;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ntwdt_state->ntwdt_watchdog_expired == 0) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * re-arm the awdt.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_arm_watchdog(ntwdt_state);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NTWDT_DBG(NTWDT_DBG_IOCTL, ("AWDT patted, "
193974072f41a843678abf5f61979c748687e66bSherry Moore "remainning seconds: %d",
193974072f41a843678abf5f61979c748687e66bSherry Moore ntwdt_state->ntwdt_time_remaining));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_exit(&ntwdt_state->ntwdt_runstate_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy break;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy default:
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy retval = EINVAL;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy break;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (retval);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyend:
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_exit(&ntwdt_state->ntwdt_runstate_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (retval);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy}
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic void
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyntwdt_cyclic_pat(void)
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy{
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ddi_trigger_softintr(ntwdt_cyclic_softint_id);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy}
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic uint_t
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyntwdt_cyclic_softint(caddr_t arg)
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy{
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /*LINTED E_BAD_PTR_CAST_ALIGN*/
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state_t *ntwdt_ptr = (ntwdt_state_t *)arg;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_runstate_t *ntwdt_state;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state = ntwdt_ptr->ntwdt_run_state;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_enter(&ntwdt_state->ntwdt_runstate_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if ((ntwdt_state->ntwdt_watchdog_flags & NTWDT_FLAG_SKIP_CYCLIC) != 0) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state->ntwdt_watchdog_flags &= ~NTWDT_FLAG_SKIP_CYCLIC;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy goto end;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if ((ntwdt_state->ntwdt_timer_running == 0) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (ntwdt_ptr->ntwdt_cycl_id == CYCLIC_NONE) ||
193974072f41a843678abf5f61979c748687e66bSherry Moore (ntwdt_state->ntwdt_watchdog_enabled == 0)) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy goto end;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NTWDT_DBG(NTWDT_DBG_IOCTL, ("cyclic_softint: %d"
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni "ddi_get_lbolt64(): %d\n", ntwdt_state->ntwdt_watchdog_timeout,
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni (int)TICK_TO_MSEC(ddi_get_lbolt64())));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * Decrement the virtual watchdog timer and check if it has expired.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state->ntwdt_time_remaining -= NTWDT_DECREMENT_INTERVAL;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ntwdt_state->ntwdt_time_remaining == 0) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy cmn_err(CE_WARN, "application-watchdog expired");
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state->ntwdt_watchdog_expired = 1;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ntwdt_state->ntwdt_reset_enabled != 0) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * The user wants to reset the system.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_exit(&ntwdt_state->ntwdt_runstate_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NTWDT_DBG(NTWDT_DBG_NTWDT, ("recovery being done"));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_enforce_timeout();
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy } else {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NTWDT_DBG(NTWDT_DBG_NTWDT, ("no recovery being done"));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state->ntwdt_watchdog_enabled = 0;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * Schedule Callout to stop the cyclic.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy (void) timeout(ntwdt_stop_timer_lock, ntwdt_ptr, 0);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy } else {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy _NOTE(EMPTY)
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NTWDT_DBG(NTWDT_DBG_NTWDT, ("time remaining in AWDT: %d secs",
193974072f41a843678abf5f61979c748687e66bSherry Moore (int)TICK_TO_MSEC(ntwdt_state->ntwdt_time_remaining)));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyend:
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_exit(&ntwdt_state->ntwdt_runstate_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (DDI_INTR_CLAIMED);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy}
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic void
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyntwdt_arm_watchdog(ntwdt_runstate_t *ntwdt_state)
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy{
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state->ntwdt_time_remaining = ntwdt_state->ntwdt_watchdog_timeout;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ntwdt_state->ntwdt_timer_running != 0) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state->ntwdt_watchdog_flags |= NTWDT_FLAG_SKIP_CYCLIC;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy } else {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state->ntwdt_watchdog_flags &= ~NTWDT_FLAG_SKIP_CYCLIC;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy}
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic void
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyntwdt_start_timer(ntwdt_state_t *ntwdt_ptr)
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy{
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_runstate_t *ntwdt_state = ntwdt_ptr->ntwdt_run_state;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy cyc_handler_t *hdlr = &ntwdt_state->ntwdt_cycl_hdlr;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy cyc_time_t *when = &ntwdt_state->ntwdt_cycl_time;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy /*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * Init the cyclic.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy when->cyt_interval = ntwdt_state->ntwdt_cyclic_interval;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy when->cyt_when = gethrtime() + when->cyt_interval;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state->ntwdt_watchdog_expired = 0;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state->ntwdt_timer_running = 1;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_enter(&cpu_lock);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ntwdt_ptr->ntwdt_cycl_id == CYCLIC_NONE) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_ptr->ntwdt_cycl_id = cyclic_add(hdlr, when);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_exit(&cpu_lock);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NTWDT_DBG(NTWDT_DBG_NTWDT, ("cyclic-driven timer is started"));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy}
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic void
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyntwdt_stop_timer(void *arg)
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy{
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state_t *ntwdt_ptr = (ntwdt_state_t *)arg;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_runstate_t *ntwdt_state = ntwdt_ptr->ntwdt_run_state;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_enter(&cpu_lock);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ntwdt_ptr->ntwdt_cycl_id != CYCLIC_NONE) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy cyclic_remove(ntwdt_ptr->ntwdt_cycl_id);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_exit(&cpu_lock);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state->ntwdt_watchdog_flags = 0;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state->ntwdt_timer_running = 0;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_ptr->ntwdt_cycl_id = CYCLIC_NONE;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NTWDT_DBG(NTWDT_DBG_NTWDT, ("cyclic-driven timer is stopped"));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy}
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy/*
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * This is a wrapper function for ntwdt_stop_timer as some callers
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy * will already have the appropriate mutex locked, and others not.
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy */
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic void
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyntwdt_stop_timer_lock(void *arg)
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy{
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_state_t *ntwdt_ptr = (ntwdt_state_t *)arg;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_enter(&ntwdt_ptr->ntwdt_run_state->ntwdt_runstate_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy ntwdt_stop_timer(arg);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy mutex_exit(&ntwdt_ptr->ntwdt_run_state->ntwdt_runstate_mutex);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy}
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic void
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyntwdt_enforce_timeout()
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy{
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if (ntwdt_disable_timeout_action != 0) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy cmn_err(CE_NOTE, "Appication watchdog timer expired, "
193974072f41a843678abf5f61979c748687e66bSherry Moore "taking no action");
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy NTWDT_DBG(NTWDT_DBG_NTWDT, ("dump cores and rebooting ..."));
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy (void) kadmin(A_DUMP, AD_BOOT, NULL, kcred);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy cmn_err(CE_PANIC, "kadmin(A_DUMP, AD_BOOT) failed");
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy _NOTE(NOTREACHED);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy}
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoystatic int
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoyntwdt_chk_watchdog_support()
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy{
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy int retval = 0;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy if ((boothowto & RB_DEBUG) != 0) {
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy cmn_err(CE_WARN, "kernel debugger was booted; "
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy "application watchdog is not available.");
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy retval = ENOTSUP;
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy }
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy return (retval);
927a453e165c072d45bd6aa2945b3db0fce17c56wentaoy}