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 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 1211ae08745Sheppo _info(struct modinfo *modinfop) 1221ae08745Sheppo { 1231ae08745Sheppo return (mod_info(&modlinkage, modinfop)); 1241ae08745Sheppo } 1251ae08745Sheppo 1261ae08745Sheppo int fi_allow_unload; 1271ae08745Sheppo 1281ae08745Sheppo int 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 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 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 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 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 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 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