11ae08745Sheppo /*
21ae08745Sheppo * CDDL HEADER START
31ae08745Sheppo *
41ae08745Sheppo * The contents of this file are subject to the terms of the
51ae08745Sheppo * Common Development and Distribution License (the "License").
61ae08745Sheppo * You may not use this file except in compliance with the License.
71ae08745Sheppo *
81ae08745Sheppo * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91ae08745Sheppo * or http://www.opensolaris.org/os/licensing.
101ae08745Sheppo * See the License for the specific language governing permissions
111ae08745Sheppo * and limitations under the License.
121ae08745Sheppo *
131ae08745Sheppo * When distributing Covered Code, include this CDDL HEADER in each
141ae08745Sheppo * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151ae08745Sheppo * If applicable, add the following below this CDDL HEADER, with the
161ae08745Sheppo * fields enclosed by brackets "[]" replaced with your own identifying
171ae08745Sheppo * information: Portions Copyright [yyyy] [name of copyright owner]
181ae08745Sheppo *
191ae08745Sheppo * CDDL HEADER END
201ae08745Sheppo */
211ae08745Sheppo
221ae08745Sheppo /*
23*f500b196SRichard Bean * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
241ae08745Sheppo * Use is subject to license terms.
251ae08745Sheppo */
261ae08745Sheppo
271ae08745Sheppo /*
281ae08745Sheppo * sun4v Fault Isolation Services Module
291ae08745Sheppo */
301ae08745Sheppo
311ae08745Sheppo #include <sys/modctl.h>
321ae08745Sheppo #include <sys/cmn_err.h>
331ae08745Sheppo #include <sys/machsystm.h>
341ae08745Sheppo #include <sys/processor.h>
351ae08745Sheppo #include <sys/mem.h>
361ae08745Sheppo #include <vm/page.h>
371ae08745Sheppo #include <sys/note.h>
381ae08745Sheppo #include <sys/ds.h>
391ae08745Sheppo #include <sys/fault_iso.h>
401ae08745Sheppo
411ae08745Sheppo /*
421ae08745Sheppo * Debugging routines
431ae08745Sheppo */
441ae08745Sheppo #ifdef DEBUG
451ae08745Sheppo uint_t fi_debug = 0x0;
461ae08745Sheppo #define FI_DBG if (fi_debug) cmn_err
471ae08745Sheppo #else /* DEBUG */
481ae08745Sheppo #define FI_DBG _NOTE(CONSTCOND) if (0) cmn_err
491ae08745Sheppo #endif /* DEBUG */
501ae08745Sheppo
511ae08745Sheppo /*
521ae08745Sheppo * Domains Services interaction
531ae08745Sheppo */
541ae08745Sheppo static ds_svc_hdl_t cpu_handle;
551ae08745Sheppo static ds_svc_hdl_t mem_handle;
561ae08745Sheppo
571ae08745Sheppo static ds_ver_t fi_vers[] = { { 1, 0 } };
581ae08745Sheppo #define FI_NVERS (sizeof (fi_vers) / sizeof (fi_vers[0]))
591ae08745Sheppo
601ae08745Sheppo static ds_capability_t cpu_cap = {
611ae08745Sheppo "fma-cpu-service", /* svc_id */
621ae08745Sheppo fi_vers, /* vers */
631ae08745Sheppo FI_NVERS /* nvers */
641ae08745Sheppo };
651ae08745Sheppo
661ae08745Sheppo static ds_capability_t mem_cap = {
671ae08745Sheppo "fma-mem-service", /* svc_id */
681ae08745Sheppo fi_vers, /* vers */
691ae08745Sheppo FI_NVERS /* nvers */
701ae08745Sheppo };
711ae08745Sheppo
721ae08745Sheppo static void fi_reg_handler(ds_cb_arg_t arg, ds_ver_t *ver, ds_svc_hdl_t hdl);
731ae08745Sheppo static void fi_unreg_handler(ds_cb_arg_t arg);
741ae08745Sheppo
751ae08745Sheppo static void cpu_data_handler(ds_cb_arg_t arg, void *buf, size_t buflen);
761ae08745Sheppo static void mem_data_handler(ds_cb_arg_t arg, void *buf, size_t buflen);
771ae08745Sheppo
781ae08745Sheppo static ds_clnt_ops_t cpu_ops = {
791ae08745Sheppo fi_reg_handler, /* ds_reg_cb */
801ae08745Sheppo fi_unreg_handler, /* ds_unreg_cb */
811ae08745Sheppo cpu_data_handler, /* ds_data_cb */
821ae08745Sheppo &cpu_handle /* cb_arg */
831ae08745Sheppo };
841ae08745Sheppo
851ae08745Sheppo static ds_clnt_ops_t mem_ops = {
861ae08745Sheppo fi_reg_handler, /* ds_reg_cb */
871ae08745Sheppo fi_unreg_handler, /* ds_unreg_cb */
881ae08745Sheppo mem_data_handler, /* ds_data_cb */
891ae08745Sheppo &mem_handle /* cb_arg */
901ae08745Sheppo };
911ae08745Sheppo
921ae08745Sheppo static int fi_init(void);
931ae08745Sheppo static void fi_fini(void);
941ae08745Sheppo
951ae08745Sheppo static struct modlmisc modlmisc = {
961ae08745Sheppo &mod_miscops,
97*f500b196SRichard Bean "sun4v Fault Isolation Services"
981ae08745Sheppo };
991ae08745Sheppo
1001ae08745Sheppo static struct modlinkage modlinkage = {
1011ae08745Sheppo MODREV_1,
1021ae08745Sheppo (void *)&modlmisc,
1031ae08745Sheppo NULL
1041ae08745Sheppo };
1051ae08745Sheppo
1061ae08745Sheppo int
_init(void)1071ae08745Sheppo _init(void)
1081ae08745Sheppo {
1091ae08745Sheppo int rv;
1101ae08745Sheppo
1111ae08745Sheppo if ((rv = fi_init()) != 0)
1121ae08745Sheppo return (rv);
1131ae08745Sheppo
1141ae08745Sheppo if ((rv = mod_install(&modlinkage)) != 0)
1151ae08745Sheppo fi_fini();
1161ae08745Sheppo
1171ae08745Sheppo return (rv);
1181ae08745Sheppo }
1191ae08745Sheppo
1201ae08745Sheppo int
_info(struct modinfo * modinfop)1211ae08745Sheppo _info(struct modinfo *modinfop)
1221ae08745Sheppo {
1231ae08745Sheppo return (mod_info(&modlinkage, modinfop));
1241ae08745Sheppo }
1251ae08745Sheppo
1261ae08745Sheppo int fi_allow_unload;
1271ae08745Sheppo
1281ae08745Sheppo int
_fini(void)1291ae08745Sheppo _fini(void)
1301ae08745Sheppo {
1311ae08745Sheppo int status;
1321ae08745Sheppo
1331ae08745Sheppo if (fi_allow_unload == 0)
1341ae08745Sheppo return (EBUSY);
1351ae08745Sheppo
1361ae08745Sheppo if ((status = mod_remove(&modlinkage)) == 0)
1371ae08745Sheppo fi_fini();
1381ae08745Sheppo
1391ae08745Sheppo return (status);
1401ae08745Sheppo }
1411ae08745Sheppo
1421ae08745Sheppo static int
fi_init(void)1431ae08745Sheppo fi_init(void)
1441ae08745Sheppo {
1451ae08745Sheppo int rv;
1461ae08745Sheppo
1471ae08745Sheppo /* register CPU service with domain services framework */
1481ae08745Sheppo rv = ds_cap_init(&cpu_cap, &cpu_ops);
1491ae08745Sheppo if (rv != 0) {
1501ae08745Sheppo FI_DBG(CE_CONT, "ds_cap_init failed: %d", rv);
1511ae08745Sheppo return (rv);
1521ae08745Sheppo }
1531ae08745Sheppo
1541ae08745Sheppo /* register MEM servicewith domain services framework */
1551ae08745Sheppo rv = ds_cap_init(&mem_cap, &mem_ops);
1561ae08745Sheppo if (rv != 0) {
1571ae08745Sheppo FI_DBG(CE_CONT, "ds_cap_init failed: %d", rv);
1581ae08745Sheppo (void) ds_cap_fini(&cpu_cap);
1591ae08745Sheppo return (rv);
1601ae08745Sheppo }
1611ae08745Sheppo
1621ae08745Sheppo return (rv);
1631ae08745Sheppo }
1641ae08745Sheppo
1651ae08745Sheppo static void
fi_fini(void)1661ae08745Sheppo fi_fini(void)
1671ae08745Sheppo {
1681ae08745Sheppo /*
1691ae08745Sheppo * Stop incoming requests from Zeus
1701ae08745Sheppo */
1711ae08745Sheppo (void) ds_cap_fini(&cpu_cap);
1721ae08745Sheppo (void) ds_cap_fini(&mem_cap);
1731ae08745Sheppo }
1741ae08745Sheppo
1751ae08745Sheppo static void
cpu_data_handler(ds_cb_arg_t arg,void * buf,size_t buflen)1761ae08745Sheppo cpu_data_handler(ds_cb_arg_t arg, void *buf, size_t buflen)
1771ae08745Sheppo {
1781ae08745Sheppo _NOTE(ARGUNUSED(arg))
1791ae08745Sheppo
1801ae08745Sheppo fma_cpu_service_req_t *msg = buf;
1811ae08745Sheppo fma_cpu_resp_t resp_msg;
1821ae08745Sheppo int rv = 0;
1831ae08745Sheppo int cpu_status;
1841ae08745Sheppo int resp_back = 0;
1851ae08745Sheppo
1861ae08745Sheppo /*
1871ae08745Sheppo * If the buffer is the wrong size for CPU calls or is NULL then
1881ae08745Sheppo * do not return any message. The call from the ldom mgr. will time out
1891ae08745Sheppo * and the response will be NULL.
1901ae08745Sheppo */
1911ae08745Sheppo if (msg == NULL || buflen != sizeof (fma_cpu_service_req_t)) {
1921ae08745Sheppo return;
1931ae08745Sheppo }
1941ae08745Sheppo
1951ae08745Sheppo FI_DBG(CE_CONT, "req_num = %ld, msg_type = %d, cpu_id = %d\n",
1961ae08745Sheppo msg->req_num, msg->msg_type, msg->cpu_id);
1971ae08745Sheppo
1981ae08745Sheppo resp_msg.req_num = msg->req_num;
1991ae08745Sheppo
2001ae08745Sheppo switch (msg->msg_type) {
2011ae08745Sheppo case FMA_CPU_REQ_STATUS:
2021ae08745Sheppo rv = p_online_internal(msg->cpu_id, P_STATUS,
2031ae08745Sheppo &cpu_status);
2041ae08745Sheppo if (rv == EINVAL) {
2051ae08745Sheppo FI_DBG(CE_CONT, "Failed p_online call failed."
2061ae08745Sheppo "Invalid CPU\n");
2071ae08745Sheppo resp_msg.result = FMA_CPU_RESP_FAILURE;
2081ae08745Sheppo resp_msg.status = FMA_CPU_STAT_ILLEGAL;
2091ae08745Sheppo resp_back = 1;
2101ae08745Sheppo }
2111ae08745Sheppo break;
2121ae08745Sheppo case FMA_CPU_REQ_OFFLINE:
213d10e4ef2Snarayan rv = p_online_internal(msg->cpu_id, P_FAULTED,
2141ae08745Sheppo &cpu_status);
2151ae08745Sheppo if (rv == EINVAL) {
2161ae08745Sheppo FI_DBG(CE_CONT, "Failed p_online call failed."
2171ae08745Sheppo "Invalid CPU\n");
2181ae08745Sheppo resp_msg.result = FMA_CPU_RESP_FAILURE;
2191ae08745Sheppo resp_msg.status = FMA_CPU_STAT_ILLEGAL;
2201ae08745Sheppo resp_back = 1;
2211ae08745Sheppo } else if (rv == EBUSY) {
2221ae08745Sheppo FI_DBG(CE_CONT, "Failed p_online call failed."
2231ae08745Sheppo "Tried to offline while busy\n");
2241ae08745Sheppo resp_msg.result = FMA_CPU_RESP_FAILURE;
2251ae08745Sheppo resp_msg.status = FMA_CPU_STAT_ONLINE;
2261ae08745Sheppo resp_back = 1;
2271ae08745Sheppo }
2281ae08745Sheppo break;
2291ae08745Sheppo case FMA_CPU_REQ_ONLINE:
2301ae08745Sheppo rv = p_online_internal(msg->cpu_id, P_ONLINE,
2311ae08745Sheppo &cpu_status);
2321ae08745Sheppo if (rv == EINVAL) {
2331ae08745Sheppo FI_DBG(CE_CONT, "Failed p_online call failed."
2341ae08745Sheppo "Invalid CPU\n");
2351ae08745Sheppo resp_msg.result = FMA_CPU_RESP_FAILURE;
2361ae08745Sheppo resp_msg.status = FMA_CPU_STAT_ILLEGAL;
2371ae08745Sheppo resp_back = 1;
2381ae08745Sheppo } else if (rv == ENOTSUP) {
2391ae08745Sheppo FI_DBG(CE_CONT, "Failed p_online call failed."
2401ae08745Sheppo "Online not supported for single CPU\n");
2411ae08745Sheppo resp_msg.result = FMA_CPU_RESP_FAILURE;
2421ae08745Sheppo resp_msg.status = FMA_CPU_STAT_OFFLINE;
2431ae08745Sheppo resp_back = 1;
2441ae08745Sheppo }
2451ae08745Sheppo break;
2461ae08745Sheppo default:
2471ae08745Sheppo /*
2481ae08745Sheppo * If the msg_type was of unknown type simply return and
2491ae08745Sheppo * have the ldom mgr. time out with a NULL response.
2501ae08745Sheppo */
2511ae08745Sheppo return;
2521ae08745Sheppo }
2531ae08745Sheppo
2541ae08745Sheppo if (rv != 0) {
2551ae08745Sheppo if (resp_back) {
2561ae08745Sheppo if ((rv = ds_cap_send(cpu_handle, &resp_msg,
2571ae08745Sheppo sizeof (resp_msg))) != 0) {
2581ae08745Sheppo FI_DBG(CE_CONT, "ds_cap_send failed (%d)\n",
2591ae08745Sheppo rv);
2601ae08745Sheppo }
2611ae08745Sheppo return;
2621ae08745Sheppo }
2631ae08745Sheppo ASSERT((rv == EINVAL) || ((rv == EBUSY) &&
2641ae08745Sheppo (msg->msg_type == FMA_CPU_REQ_OFFLINE)) ||
2654f7823a1Snevin ((rv == ENOTSUP) && (msg->msg_type == FMA_CPU_REQ_ONLINE)));
2661ae08745Sheppo
2671ae08745Sheppo cmn_err(CE_WARN, "p_online_internal error not handled "
2681ae08745Sheppo "rv = %d\n", rv);
2691ae08745Sheppo }
2701ae08745Sheppo
2711ae08745Sheppo resp_msg.req_num = msg->req_num;
2721ae08745Sheppo resp_msg.result = FMA_CPU_RESP_OK;
2731ae08745Sheppo
2741ae08745Sheppo switch (cpu_status) {
2751ae08745Sheppo case P_OFFLINE:
2761ae08745Sheppo case P_FAULTED:
2771ae08745Sheppo case P_POWEROFF:
2781ae08745Sheppo case P_SPARE:
2791ae08745Sheppo resp_msg.status = FMA_CPU_STAT_OFFLINE;
2801ae08745Sheppo break;
2811ae08745Sheppo case P_ONLINE:
2821ae08745Sheppo case P_NOINTR:
2831ae08745Sheppo resp_msg.status = FMA_CPU_STAT_ONLINE;
2841ae08745Sheppo break;
2851ae08745Sheppo default:
2861ae08745Sheppo resp_msg.status = FMA_CPU_STAT_ILLEGAL;
2871ae08745Sheppo }
2881ae08745Sheppo
2891ae08745Sheppo if ((rv = ds_cap_send(cpu_handle, &resp_msg,
2901ae08745Sheppo sizeof (resp_msg))) != 0) {
2911ae08745Sheppo FI_DBG(CE_CONT, "ds_cap_send failed (%d)\n", rv);
2921ae08745Sheppo }
2931ae08745Sheppo }
2941ae08745Sheppo
2951ae08745Sheppo static void
mem_data_handler(ds_cb_arg_t arg,void * buf,size_t buflen)2961ae08745Sheppo mem_data_handler(ds_cb_arg_t arg, void *buf, size_t buflen)
2971ae08745Sheppo {
2981ae08745Sheppo _NOTE(ARGUNUSED(arg))
2991ae08745Sheppo
3001ae08745Sheppo fma_mem_service_req_t *msg = buf;
3011ae08745Sheppo fma_mem_resp_t resp_msg;
3021ae08745Sheppo int rv = 0;
3031ae08745Sheppo
3041ae08745Sheppo /*
3051ae08745Sheppo * If the buffer is the wrong size for Mem calls or is NULL then
3061ae08745Sheppo * do not return any message. The call from the ldom mgr. will time out
3071ae08745Sheppo * and the response will be NULL.
3081ae08745Sheppo */
3091ae08745Sheppo if (msg == NULL || buflen != sizeof (fma_mem_service_req_t)) {
3101ae08745Sheppo return;
3111ae08745Sheppo }
3121ae08745Sheppo
3131ae08745Sheppo FI_DBG(CE_CONT, "req_num = %ld, msg_type = %d, memory addr = 0x%lx"
3141ae08745Sheppo "memory length = 0x%lx\n", msg->req_num, msg->msg_type,
3151ae08745Sheppo msg->real_addr, msg->length);
3161ae08745Sheppo
3171ae08745Sheppo resp_msg.req_num = msg->req_num;
3181ae08745Sheppo resp_msg.res_addr = msg->real_addr;
3191ae08745Sheppo resp_msg.res_length = msg->length;
3201ae08745Sheppo
3211ae08745Sheppo /*
3221ae08745Sheppo * Information about return values for page calls can be referenced
3231ae08745Sheppo * in usr/src/uts/common/vm/page_retire.c
3241ae08745Sheppo */
3251ae08745Sheppo switch (msg->msg_type) {
3261ae08745Sheppo case FMA_MEM_REQ_STATUS:
3271ae08745Sheppo rv = page_retire_check(msg->real_addr, NULL);
3281ae08745Sheppo switch (rv) {
3291ae08745Sheppo /* Page is retired */
3301ae08745Sheppo case 0:
3311ae08745Sheppo resp_msg.result = FMA_MEM_RESP_OK;
3321ae08745Sheppo resp_msg.status = FMA_MEM_STAT_RETIRED;
3331ae08745Sheppo break;
3341ae08745Sheppo /* Page is pending. Send back failure and not retired */
3351ae08745Sheppo case EAGAIN:
3361ae08745Sheppo resp_msg.result = FMA_MEM_RESP_FAILURE;
3371ae08745Sheppo resp_msg.status = FMA_MEM_STAT_NOTRETIRED;
3381ae08745Sheppo break;
3391ae08745Sheppo /* Page is not retired. */
3401ae08745Sheppo case EIO:
3414f7823a1Snevin resp_msg.result = FMA_MEM_RESP_OK;
3421ae08745Sheppo resp_msg.status = FMA_MEM_STAT_NOTRETIRED;
3431ae08745Sheppo break;
3441ae08745Sheppo /* PA is not valid */
3451ae08745Sheppo case EINVAL:
3461ae08745Sheppo resp_msg.result = FMA_MEM_RESP_FAILURE;
3471ae08745Sheppo resp_msg.status = FMA_MEM_STAT_ILLEGAL;
3481ae08745Sheppo break;
3491ae08745Sheppo default:
3501ae08745Sheppo ASSERT((rv == 0) || (rv == EAGAIN) || (rv == EIO) ||
3511ae08745Sheppo (rv == EINVAL));
3521ae08745Sheppo cmn_err(CE_WARN, "fault_iso: return value from "
3531ae08745Sheppo "page_retire_check invalid: %d\n", rv);
3541ae08745Sheppo }
3551ae08745Sheppo break;
3561ae08745Sheppo case FMA_MEM_REQ_RETIRE:
3571ae08745Sheppo rv = page_retire(msg->real_addr, PR_FMA);
3581ae08745Sheppo switch (rv) {
3591ae08745Sheppo /* Page retired successfully */
3601ae08745Sheppo case 0:
3611ae08745Sheppo resp_msg.result = FMA_MEM_RESP_OK;
3621ae08745Sheppo resp_msg.status = FMA_MEM_STAT_RETIRED;
3631ae08745Sheppo break;
3641ae08745Sheppo /* Tried to retire and now Pending retirement */
3651ae08745Sheppo case EAGAIN:
3661ae08745Sheppo resp_msg.result = FMA_MEM_RESP_FAILURE;
3671ae08745Sheppo resp_msg.status = FMA_MEM_STAT_NOTRETIRED;
3681ae08745Sheppo break;
3691ae08745Sheppo /* Did not try to retire. Page already retired */
3701ae08745Sheppo case EIO:
3711ae08745Sheppo resp_msg.result = FMA_MEM_RESP_FAILURE;
3721ae08745Sheppo resp_msg.status = FMA_MEM_STAT_RETIRED;
3731ae08745Sheppo break;
3741ae08745Sheppo /* PA is not valid */
3751ae08745Sheppo case EINVAL:
3761ae08745Sheppo resp_msg.result = FMA_MEM_RESP_FAILURE;
3771ae08745Sheppo resp_msg.status = FMA_MEM_STAT_ILLEGAL;
3781ae08745Sheppo break;
3791ae08745Sheppo default:
3801ae08745Sheppo ASSERT((rv == 0) || (rv == EAGAIN) || (rv == EIO) ||
3811ae08745Sheppo (rv == EINVAL));
3821ae08745Sheppo cmn_err(CE_WARN, "fault_iso: return value from "
3831ae08745Sheppo "page_retire invalid: %d\n", rv);
3841ae08745Sheppo }
3851ae08745Sheppo break;
3861ae08745Sheppo case FMA_MEM_REQ_RESURRECT:
3871ae08745Sheppo rv = page_unretire(msg->real_addr);
3881ae08745Sheppo switch (rv) {
3891ae08745Sheppo /* Page succesfullly unretired */
3901ae08745Sheppo case 0:
3911ae08745Sheppo resp_msg.result = FMA_MEM_RESP_OK;
3921ae08745Sheppo resp_msg.status = FMA_MEM_STAT_NOTRETIRED;
3931ae08745Sheppo break;
3941ae08745Sheppo /* Page could not be locked. Still retired */
3951ae08745Sheppo case EAGAIN:
3961ae08745Sheppo resp_msg.result = FMA_MEM_RESP_FAILURE;
3971ae08745Sheppo resp_msg.status = FMA_MEM_STAT_RETIRED;
3981ae08745Sheppo break;
3991ae08745Sheppo /* Page was not retired already */
4001ae08745Sheppo case EIO:
4011ae08745Sheppo resp_msg.result = FMA_MEM_RESP_FAILURE;
4021ae08745Sheppo resp_msg.status = FMA_MEM_STAT_NOTRETIRED;
4031ae08745Sheppo break;
4041ae08745Sheppo /* PA is not valid */
4051ae08745Sheppo case EINVAL:
4061ae08745Sheppo resp_msg.result = FMA_MEM_RESP_FAILURE;
4071ae08745Sheppo resp_msg.status = FMA_MEM_STAT_ILLEGAL;
4081ae08745Sheppo break;
4091ae08745Sheppo default:
4101ae08745Sheppo ASSERT((rv == 0) || (rv == EAGAIN) || (rv == EIO) ||
4111ae08745Sheppo (rv == EINVAL));
4121ae08745Sheppo cmn_err(CE_WARN, "fault_iso: return value from "
4131ae08745Sheppo "page_unretire invalid: %d\n", rv);
4141ae08745Sheppo }
4151ae08745Sheppo break;
4161ae08745Sheppo default:
4171ae08745Sheppo /*
4181ae08745Sheppo * If the msg_type was of unknown type simply return and
4191ae08745Sheppo * have the ldom mgr. time out with a NULL response.
4201ae08745Sheppo */
4211ae08745Sheppo return;
4221ae08745Sheppo }
4231ae08745Sheppo
4241ae08745Sheppo if ((rv = ds_cap_send(mem_handle, &resp_msg, sizeof (resp_msg))) != 0) {
4251ae08745Sheppo FI_DBG(CE_CONT, "ds_cap_send failed (%d)\n", rv);
4261ae08745Sheppo }
4271ae08745Sheppo }
4281ae08745Sheppo
4291ae08745Sheppo static void
fi_reg_handler(ds_cb_arg_t arg,ds_ver_t * ver,ds_svc_hdl_t hdl)4301ae08745Sheppo fi_reg_handler(ds_cb_arg_t arg, ds_ver_t *ver, ds_svc_hdl_t hdl)
4311ae08745Sheppo {
4321ae08745Sheppo FI_DBG(CE_CONT, "fi_reg_handler: arg=0x%p, ver=%d.%d, hdl=0x%lx\n",
4331ae08745Sheppo arg, ver->major, ver->minor, hdl);
4341ae08745Sheppo
4351ae08745Sheppo if ((ds_svc_hdl_t *)arg == &cpu_handle)
4361ae08745Sheppo cpu_handle = hdl;
4371ae08745Sheppo if ((ds_svc_hdl_t *)arg == &mem_handle)
4381ae08745Sheppo mem_handle = hdl;
4391ae08745Sheppo }
4401ae08745Sheppo
4411ae08745Sheppo static void
fi_unreg_handler(ds_cb_arg_t arg)4421ae08745Sheppo fi_unreg_handler(ds_cb_arg_t arg)
4431ae08745Sheppo {
4441ae08745Sheppo FI_DBG(CE_CONT, "fi_unreg_handler: arg=0x%p\n", arg);
4451ae08745Sheppo
4461ae08745Sheppo if ((ds_svc_hdl_t *)arg == &cpu_handle)
4471ae08745Sheppo cpu_handle = DS_INVALID_HDL;
4481ae08745Sheppo if ((ds_svc_hdl_t *)arg == &mem_handle)
4491ae08745Sheppo mem_handle = DS_INVALID_HDL;
4501ae08745Sheppo }
451