/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* sun4v application watchdog driver
*/
/*
* tunables
*/
int ntwdt_disable_timeout_action = 0;
#ifdef DEBUG
/*
* Flags to set in ntwdt_debug.
*/
#else /* DEBUG */
#endif /* DEBUG */
/*
* The ntwdt cyclic interval in nanosecond unit as cyclic subsystem supports
* nanosecond resolution.
*/
/*
* The ntwdt decrement interval in 1 second resolution.
*/
/*
*/
/*
* Application watchdog state.
*/
typedef struct ntwdt_runstate {
/*
* softstate of NTWDT
*/
typedef struct {
static int ntwdt_chk_watchdog_support();
static void ntwdt_cyclic_pat(void);
static void ntwdt_stop_timer_lock(void *arg);
static void ntwdt_stop_timer(void *arg);
static void ntwdt_enforce_timeout();
ntwdt_open, /* cb_open */
ntwdt_close, /* cb_close */
nodev, /* cb_strategy */
nodev, /* cb_print */
nodev, /* cb_dump */
nodev, /* cb_read */
nodev, /* cb_write */
ntwdt_ioctl, /* cb_ioctl */
nodev, /* cb_devmap */
nodev, /* cb_mmap */
nodev, /* cb_segmap */
nochpoll, /* cb_chpoll */
ddi_prop_op, /* cb_prop_op */
NULL, /* cb_str */
};
DEVO_REV, /* devo_rev */
0, /* devo_refcnt */
ntwdt_info, /* devo_info */
nulldev, /* devo_identify */
nulldev, /* devo_probe */
ntwdt_attach, /* devo_attach */
ntwdt_detach, /* devo_detach */
nodev, /* devo_reset */
&ntwdt_cb_ops, /* devo_cb_ops */
NULL, /* devo_bus_ops */
nulldev, /* devo_power */
ddi_quiesce_not_supported, /* devo_quiesce */
};
"Application Watchdog Driver",
};
(void *)&modldrv,
};
int
_init(void)
{
int error = 0;
/* Initialize the soft state structures */
sizeof (ntwdt_state_t), 1)) != 0) {
return (error);
}
/* Install the loadable module */
}
return (error);
}
int
{
}
int
_fini(void)
{
int retval;
}
return (retval);
}
static int
{
int instance;
switch (cmd) {
case DDI_ATTACH:
break;
case DDI_RESUME:
return (DDI_SUCCESS);
default:
return (DDI_FAILURE);
}
if (ntwdt_chk_watchdog_support() != 0) {
return (DDI_FAILURE);
}
return (DDI_FAILURE);
}
MUTEX_DRIVER, NULL);
/*
* Initialize the watchdog structure
*/
"for ntwdt_runstate_mutex");
goto err1;
} else {
NULL,
(void *)ntwdt_runstatep->ntwdt_runstate_mtx_cookie);
}
/* Cyclic fires once per second: */
/* init the Cyclic that drives the NTWDT */
/* Softint that will be triggered by Cyclic that drives NTWDT */
!= DDI_SUCCESS) {
goto err2;
}
/*
* Create Minor Node as last activity. This prevents
* application from accessing our implementation until it
* is initialized.
*/
goto err3;
}
/* Display our driver info in the banner */
return (DDI_SUCCESS);
err3:
err2:
err1:
/* clean up the driver stuff here */
return (DDI_FAILURE);
}
/*ARGSUSED*/
static int
{
int instance;
switch (infocmd) {
case DDI_INFO_DEVT2DEVINFO:
} else {
error = DDI_FAILURE;
}
break;
case DDI_INFO_DEVT2INSTANCE:
break;
default:
error = DDI_FAILURE;
}
return (error);
}
/*ARGSUSED*/
static int
{
return (DDI_FAILURE);
}
switch (cmd) {
case DDI_SUSPEND:
return (DDI_SUCCESS);
case DDI_DETACH:
/*
* release resources in opposite (LIFO) order as
* were allocated in attach.
*/
ntwdt_stop_timer_lock((void *)ntwdt_ptr);
sizeof (ntwdt_runstate_t));
return (DDI_SUCCESS);
default:
return (DDI_FAILURE);
}
}
/*ARGSUSED*/
static int
{
int retval = 0;
return (ENXIO);
}
/*
* ensure caller is a priviledged process.
*/
return (EPERM);
}
if (ntwdt_ptr->ntwdt_open_flag) {
} else {
}
return (retval);
}
/*ARGSUSED*/
static int
{
return (ENXIO);
}
ntwdt_ptr->ntwdt_open_flag = 0;
return (0);
}
/*ARGSUSED*/
static int
int *rvalp)
{
int retval = 0;
return (ENXIO);
}
switch (cmd) {
case LOMIOCDOGSTATE:
sizeof (lom_dogstate_t), mode) != 0) {
}
break;
case LOMIOCDOGCTL:
sizeof (lom_dogctl_t), mode) != 0) {
break;
}
/*
* ignore request to enable reset while disabling watchdog.
*/
"reset_enable: %d, and dog_enable: %d",
break;
}
if (ntwdt_state->ntwdt_watchdog_timeout == 0) {
/*
* the LOMIOCDOGTIME has never been used to setup
* a valid timeout.
*/
"watchdog_timeout: %d",
goto end;
}
/*
* Store the user specified state in the softstate.
*/
if (ntwdt_state->ntwdt_watchdog_enabled != 0) {
/*
* The user wants to enable the watchdog.
* Arm the watchdog and start the cyclic.
*/
if (ntwdt_state->ntwdt_timer_running == 0) {
}
} else {
/*
* The user wants to disable the watchdog.
*/
if (ntwdt_state->ntwdt_timer_running != 0) {
}
}
break;
case LOMIOCDOGTIME:
break;
}
lom_dogtime));
/*
* Ensure specified timeout is valid.
*/
if ((lom_dogtime == 0) ||
break;
}
/*
* If awdt is currently running, re-arm it with the
* newly-specified timeout value.
*/
if (ntwdt_state->ntwdt_timer_running != 0) {
}
break;
case LOMIOCDOGPAT:
/*
* Allow user to pat the watchdog timer.
*/
/*
* If awdt is not enabled or underlying cyclic is not
* running, exit.
*/
if (!(ntwdt_state->ntwdt_watchdog_enabled &&
goto end;
}
if (ntwdt_state->ntwdt_watchdog_expired == 0) {
/*
* re-arm the awdt.
*/
"remainning seconds: %d",
}
break;
default:
break;
}
return (retval);
end:
return (retval);
}
static void
ntwdt_cyclic_pat(void)
{
}
static uint_t
{
/*LINTED E_BAD_PTR_CAST_ALIGN*/
goto end;
}
if ((ntwdt_state->ntwdt_timer_running == 0) ||
(ntwdt_state->ntwdt_watchdog_enabled == 0)) {
goto end;
}
(int)TICK_TO_MSEC(ddi_get_lbolt64())));
/*
* Decrement the virtual watchdog timer and check if it has expired.
*/
if (ntwdt_state->ntwdt_time_remaining == 0) {
if (ntwdt_state->ntwdt_reset_enabled != 0) {
/*
* The user wants to reset the system.
*/
} else {
}
/*
* Schedule Callout to stop the cyclic.
*/
} else {
}
end:
return (DDI_INTR_CLAIMED);
}
static void
{
if (ntwdt_state->ntwdt_timer_running != 0) {
} else {
}
}
static void
{
/*
* Init the cyclic.
*/
}
}
static void
{
}
}
/*
* This is a wrapper function for ntwdt_stop_timer as some callers
* will already have the appropriate mutex locked, and others not.
*/
static void
{
}
static void
{
if (ntwdt_disable_timeout_action != 0) {
"taking no action");
return;
}
}
static int
{
int retval = 0;
"application watchdog is not available.");
}
return (retval);
}