fault_iso.c revision f500b19684bd0346ac05bec02a50af07f369da1a
/*
* 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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* sun4v Fault Isolation Services Module
*/
#include <sys/machsystm.h>
#include <sys/processor.h>
#include <sys/fault_iso.h>
/*
* Debugging routines
*/
#ifdef DEBUG
#else /* DEBUG */
#endif /* DEBUG */
/*
* Domains Services interaction
*/
static ds_svc_hdl_t cpu_handle;
static ds_svc_hdl_t mem_handle;
static ds_capability_t cpu_cap = {
"fma-cpu-service", /* svc_id */
fi_vers, /* vers */
FI_NVERS /* nvers */
};
static ds_capability_t mem_cap = {
"fma-mem-service", /* svc_id */
fi_vers, /* vers */
FI_NVERS /* nvers */
};
static ds_clnt_ops_t cpu_ops = {
fi_reg_handler, /* ds_reg_cb */
fi_unreg_handler, /* ds_unreg_cb */
cpu_data_handler, /* ds_data_cb */
&cpu_handle /* cb_arg */
};
static ds_clnt_ops_t mem_ops = {
fi_reg_handler, /* ds_reg_cb */
fi_unreg_handler, /* ds_unreg_cb */
mem_data_handler, /* ds_data_cb */
&mem_handle /* cb_arg */
};
static int fi_init(void);
static void fi_fini(void);
"sun4v Fault Isolation Services"
};
static struct modlinkage modlinkage = {
(void *)&modlmisc,
};
int
_init(void)
{
int rv;
return (rv);
fi_fini();
return (rv);
}
int
{
}
int fi_allow_unload;
int
_fini(void)
{
int status;
if (fi_allow_unload == 0)
return (EBUSY);
fi_fini();
return (status);
}
static int
fi_init(void)
{
int rv;
/* register CPU service with domain services framework */
if (rv != 0) {
return (rv);
}
/* register MEM servicewith domain services framework */
if (rv != 0) {
(void) ds_cap_fini(&cpu_cap);
return (rv);
}
return (rv);
}
static void
fi_fini(void)
{
/*
* Stop incoming requests from Zeus
*/
(void) ds_cap_fini(&cpu_cap);
(void) ds_cap_fini(&mem_cap);
}
static void
{
int rv = 0;
int cpu_status;
int resp_back = 0;
/*
* If the buffer is the wrong size for CPU calls or is NULL then
* do not return any message. The call from the ldom mgr. will time out
* and the response will be NULL.
*/
return;
}
case FMA_CPU_REQ_STATUS:
&cpu_status);
"Invalid CPU\n");
resp_back = 1;
}
break;
case FMA_CPU_REQ_OFFLINE:
&cpu_status);
"Invalid CPU\n");
resp_back = 1;
"Tried to offline while busy\n");
resp_back = 1;
}
break;
case FMA_CPU_REQ_ONLINE:
&cpu_status);
"Invalid CPU\n");
resp_back = 1;
"Online not supported for single CPU\n");
resp_back = 1;
}
break;
default:
/*
* If the msg_type was of unknown type simply return and
* have the ldom mgr. time out with a NULL response.
*/
return;
}
if (rv != 0) {
if (resp_back) {
sizeof (resp_msg))) != 0) {
rv);
}
return;
}
"rv = %d\n", rv);
}
switch (cpu_status) {
case P_OFFLINE:
case P_FAULTED:
case P_POWEROFF:
case P_SPARE:
break;
case P_ONLINE:
case P_NOINTR:
break;
default:
}
sizeof (resp_msg))) != 0) {
}
}
static void
{
int rv = 0;
/*
* If the buffer is the wrong size for Mem calls or is NULL then
* do not return any message. The call from the ldom mgr. will time out
* and the response will be NULL.
*/
return;
}
/*
* Information about return values for page calls can be referenced
*/
case FMA_MEM_REQ_STATUS:
switch (rv) {
/* Page is retired */
case 0:
break;
/* Page is pending. Send back failure and not retired */
case EAGAIN:
break;
/* Page is not retired. */
case EIO:
break;
/* PA is not valid */
case EINVAL:
break;
default:
"page_retire_check invalid: %d\n", rv);
}
break;
case FMA_MEM_REQ_RETIRE:
switch (rv) {
/* Page retired successfully */
case 0:
break;
/* Tried to retire and now Pending retirement */
case EAGAIN:
break;
/* Did not try to retire. Page already retired */
case EIO:
break;
/* PA is not valid */
case EINVAL:
break;
default:
"page_retire invalid: %d\n", rv);
}
break;
case FMA_MEM_REQ_RESURRECT:
switch (rv) {
/* Page succesfullly unretired */
case 0:
break;
/* Page could not be locked. Still retired */
case EAGAIN:
break;
/* Page was not retired already */
case EIO:
break;
/* PA is not valid */
case EINVAL:
break;
default:
"page_unretire invalid: %d\n", rv);
}
break;
default:
/*
* If the msg_type was of unknown type simply return and
* have the ldom mgr. time out with a NULL response.
*/
return;
}
}
}
static void
{
cpu_handle = hdl;
mem_handle = hdl;
}
static void
{
}