Home | History | Annotate | Download | only in cpumem-diagnosis
      1  1186  ayznaga /*
      2  1186  ayznaga  * CDDL HEADER START
      3  1186  ayznaga  *
      4  1186  ayznaga  * The contents of this file are subject to the terms of the
      5  6208  mb91622  * Common Development and Distribution License (the "License").
      6  6208  mb91622  * You may not use this file except in compliance with the License.
      7  1186  ayznaga  *
      8  1186  ayznaga  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  1186  ayznaga  * or http://www.opensolaris.org/os/licensing.
     10  1186  ayznaga  * See the License for the specific language governing permissions
     11  1186  ayznaga  * and limitations under the License.
     12  1186  ayznaga  *
     13  1186  ayznaga  * When distributing Covered Code, include this CDDL HEADER in each
     14  1186  ayznaga  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  1186  ayznaga  * If applicable, add the following below this CDDL HEADER, with the
     16  1186  ayznaga  * fields enclosed by brackets "[]" replaced with your own identifying
     17  1186  ayznaga  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  1186  ayznaga  *
     19  1186  ayznaga  * CDDL HEADER END
     20  1186  ayznaga  */
     21  1186  ayznaga /*
     22  6208  mb91622  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     23  1186  ayznaga  * Use is subject to license terms.
     24  1186  ayznaga  */
     25  1186  ayznaga 
     26  1186  ayznaga #pragma ident	"%Z%%M%	%I%	%E% SMI"
     27  1186  ayznaga 
     28  1186  ayznaga #include <strings.h>
     29  1186  ayznaga #include <string.h>
     30  1186  ayznaga #include <errno.h>
     31  1186  ayznaga #include <fm/fmd_api.h>
     32  1186  ayznaga #include <sys/fm/protocol.h>
     33  1186  ayznaga #include <sys/async.h>
     34  1186  ayznaga #include <sys/time.h>
     35  1186  ayznaga #include <cmd.h>
     36  1186  ayznaga #include <cmd_state.h>
     37  1186  ayznaga #include <cmd_mem.h>
     38  1186  ayznaga #include <cmd_dp.h>
     39  1186  ayznaga #include <cmd_dp_page.h>
     40  1186  ayznaga #include <libnvpair.h>
     41  1186  ayznaga #include <fcntl.h>
     42  1186  ayznaga #include <unistd.h>
     43  1186  ayznaga #include <sys/mem.h>
     44  1186  ayznaga #include <sys/plat_datapath.h>
     45  1186  ayznaga 
     46  1186  ayznaga /*ARGSUSED*/
     47  1186  ayznaga static nvlist_t *
     48  1186  ayznaga dp_cpu_fmri(fmd_hdl_t *hdl, uint32_t cpuid, uint64_t serial_id)
     49  1186  ayznaga {
     50  1186  ayznaga 	nvlist_t	*nvl = NULL;
     51  1186  ayznaga 	int		err;
     52  1414    cindi 	char sbuf[21]; /* sizeof (UINT64_MAX) + '\0' */
     53  1186  ayznaga 
     54  1186  ayznaga 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
     55  1186  ayznaga 		return (NULL);
     56  1186  ayznaga 
     57  1186  ayznaga 	err = nvlist_add_string(nvl, FM_FMRI_SCHEME, FM_FMRI_SCHEME_CPU);
     58  1186  ayznaga 	err |= nvlist_add_uint8(nvl, FM_VERSION, FM_CPU_SCHEME_VERSION);
     59  1186  ayznaga 	err |= nvlist_add_uint32(nvl, FM_FMRI_CPU_ID, cpuid);
     60  1414    cindi 
     61  1414    cindi 	/*
     62  1414    cindi 	 * Version 1 calls for a string-based serial number
     63  1414    cindi 	 */
     64  1414    cindi 	(void) snprintf(sbuf, sizeof (sbuf), "%llX", (u_longlong_t)serial_id);
     65  1414    cindi 	err |= nvlist_add_string(nvl, FM_FMRI_CPU_SERIAL_ID, sbuf);
     66  1186  ayznaga 	if (err != 0) {
     67  1186  ayznaga 		nvlist_free(nvl);
     68  1186  ayznaga 		return (NULL);
     69  1186  ayznaga 	}
     70  1186  ayznaga 	return (nvl);
     71  1186  ayznaga }
     72  1186  ayznaga 
     73  1186  ayznaga cmd_dp_t *
     74  1186  ayznaga cmd_dp_lookup_fault(fmd_hdl_t *hdl, uint32_t cpuid)
     75  1186  ayznaga {
     76  1186  ayznaga 	cmd_dp_t	*ptr;
     77  1186  ayznaga 	int		i, found = 0;
     78  1186  ayznaga 
     79  1186  ayznaga 	/*
     80  1186  ayznaga 	 * Scan the cmd.cmd_datapaths list to see if there is
     81  1186  ayznaga 	 * a fault event present that impacts 'cpuid'
     82  1186  ayznaga 	 */
     83  1186  ayznaga 	for (ptr = cmd_list_next(&cmd.cmd_datapaths); ptr != NULL;
     84  6208  mb91622 	    ptr = cmd_list_next(ptr)) {
     85  1186  ayznaga 		if (ptr->dp_erpt_type == DP_FAULT) {
     86  1186  ayznaga 			for (i = 0; i < ptr->dp_ncpus; i++) {
     87  1186  ayznaga 				if (ptr->dp_cpuid_list[i] == cpuid) {
     88  1186  ayznaga 					found = 1;
     89  1186  ayznaga 					break;
     90  1186  ayznaga 				}
     91  1186  ayznaga 			}
     92  1186  ayznaga 		}
     93  1186  ayznaga 		if (found)
     94  1186  ayznaga 			break;
     95  1186  ayznaga 	}
     96  1186  ayznaga 
     97  1186  ayznaga 	/*
     98  1186  ayznaga 	 * Check if the FMRI for the found cpuid exists in the domain.
     99  1186  ayznaga 	 * If it does not, it implies a DR has been done and this DP_FAULT
    100  1186  ayznaga 	 * is no longer needed.
    101  1186  ayznaga 	 */
    102  1186  ayznaga 	if (ptr != NULL) {
    103  1186  ayznaga 		nvlist_t	*nvl;
    104  1186  ayznaga 
    105  1186  ayznaga 		nvl = dp_cpu_fmri(hdl, ptr->dp_cpuid_list[i],
    106  1186  ayznaga 		    ptr->dp_serid_list[i]);
    107  1186  ayznaga 
    108  1186  ayznaga 		if (nvl != NULL) {
    109  1186  ayznaga 			if (!fmd_nvl_fmri_present(hdl, nvl)) {
    110  1186  ayznaga 				cmd_dp_destroy(hdl, ptr);
    111  1186  ayznaga 				ptr = NULL;
    112  1186  ayznaga 			}
    113  1186  ayznaga 			nvlist_free(nvl);
    114  1186  ayznaga 		}
    115  1186  ayznaga 	}
    116  1186  ayznaga 	return (ptr);
    117  1186  ayznaga }
    118  1186  ayznaga 
    119  1186  ayznaga cmd_dp_t *
    120  1186  ayznaga cmd_dp_lookup_error(cmd_dp_t *dp)
    121  1186  ayznaga {
    122  1186  ayznaga 	cmd_dp_t	*ptr;
    123  1186  ayznaga 
    124  1186  ayznaga 	/*
    125  1186  ayznaga 	 * Scan the cmd.cmd_datapaths list to see if there is
    126  1186  ayznaga 	 * an existing error that matches 'dp'. A match is if
    127  1186  ayznaga 	 * both dp_err and the base cpuid are identical
    128  1186  ayznaga 	 */
    129  1186  ayznaga 	for (ptr = cmd_list_next(&cmd.cmd_datapaths); ptr != NULL;
    130  6208  mb91622 	    ptr = cmd_list_next(ptr)) {
    131  1186  ayznaga 		if (ptr->dp_erpt_type == DP_ERROR) {
    132  1186  ayznaga 			if ((ptr->dp_err == dp->dp_err) &&
    133  1186  ayznaga 			    (ptr->dp_cpuid_list[0] == dp->dp_cpuid_list[0]))
    134  1186  ayznaga 				return (ptr);
    135  1186  ayznaga 		}
    136  1186  ayznaga 	}
    137  1186  ayznaga 	return (NULL);
    138  1186  ayznaga }
    139  1186  ayznaga 
    140  1186  ayznaga /*
    141  1186  ayznaga  * Allocates an nvlist_t, and sets ASRU information according to
    142  1186  ayznaga  * the cmd_dp_t provided.
    143  1186  ayznaga  */
    144  1186  ayznaga /*ARGSUSED*/
    145  1186  ayznaga nvlist_t *
    146  1186  ayznaga cmd_dp_setasru(fmd_hdl_t *hdl, cmd_dp_t *dpt)
    147  1186  ayznaga {
    148  1186  ayznaga 	nvlist_t	*asru, *hcelem[DP_MAX_ASRUS];
    149  1186  ayznaga 	int		i, j, sz, err;
    150  1186  ayznaga 	char		buf[DP_MAX_BUF];
    151  1186  ayznaga 
    152  1186  ayznaga 	sz = dpt->dp_ncpus;
    153  1186  ayznaga 
    154  1186  ayznaga 	/* put ASRUs in an nvlist */
    155  1186  ayznaga 	for (i = 0; i < sz; i++) {
    156  1186  ayznaga 		(void) snprintf(buf, DP_MAX_BUF, "%d", dpt->dp_cpuid_list[i]);
    157  1186  ayznaga 		if (nvlist_alloc(&hcelem[i], NV_UNIQUE_NAME, 0) != 0)
    158  1186  ayznaga 			return (NULL);
    159  1186  ayznaga 
    160  1186  ayznaga 		err = nvlist_add_string(hcelem[i], FM_FMRI_HC_NAME,
    161  6208  mb91622 		    FM_FMRI_CPU_ID);
    162  1186  ayznaga 		err |= nvlist_add_string(hcelem[i], FM_FMRI_HC_ID, buf);
    163  1186  ayznaga 		if (err != 0) {
    164  1186  ayznaga 			for (j = 0; j < i + 1; j++)
    165  1186  ayznaga 				nvlist_free(hcelem[j]);
    166  1186  ayznaga 			return (NULL);
    167  1186  ayznaga 		}
    168  1186  ayznaga 	}
    169  1186  ayznaga 
    170  1186  ayznaga 	/* put it in an HC scheme */
    171  1186  ayznaga 	if (nvlist_alloc(&asru, NV_UNIQUE_NAME, 0) != 0) {
    172  1186  ayznaga 		for (j = 0; j < sz; j++)
    173  1186  ayznaga 			nvlist_free(hcelem[j]);
    174  1186  ayznaga 		return (NULL);
    175  1186  ayznaga 	}
    176  1186  ayznaga 	err = nvlist_add_uint8(asru, FM_VERSION, FM_HC_SCHEME_VERSION);
    177  1186  ayznaga 	err |= nvlist_add_string(asru, FM_FMRI_SCHEME, FM_FMRI_SCHEME_HC);
    178  1186  ayznaga 	err |= nvlist_add_string(asru, FM_FMRI_HC_ROOT, "");
    179  1186  ayznaga 	err |= nvlist_add_uint32(asru, FM_FMRI_HC_LIST_SZ, sz);
    180  1186  ayznaga 	err |= nvlist_add_nvlist_array(asru, FM_FMRI_HC_LIST, &hcelem[0],
    181  6208  mb91622 	    dpt->dp_ncpus);
    182  1186  ayznaga 	if (err != 0) {
    183  1186  ayznaga 		for (j = 0; j < sz; j++)
    184  1186  ayznaga 			nvlist_free(hcelem[j]);
    185  1186  ayznaga 		nvlist_free(asru);
    186  1186  ayznaga 		return (NULL);
    187  1186  ayznaga 	}
    188  1186  ayznaga 
    189  1186  ayznaga 	/* free up memory */
    190  1186  ayznaga 	for (j = 0; j < sz; j++)
    191  1186  ayznaga 		nvlist_free(hcelem[j]);
    192  1186  ayznaga 
    193  1186  ayznaga 	/* return the ASRU */
    194  1186  ayznaga 	return (asru);
    195  1186  ayznaga }
    196  1186  ayznaga 
    197  1186  ayznaga void
    198  1186  ayznaga dp_buf_write(fmd_hdl_t *hdl, cmd_dp_t *dp)
    199  1186  ayznaga {
    200  1186  ayznaga 	size_t sz;
    201  1186  ayznaga 
    202  1186  ayznaga 	if ((sz = fmd_buf_size(hdl, NULL, dp->dp_bufname)) != 0 &&
    203  1186  ayznaga 	    sz != sizeof (cmd_dp_pers_t))
    204  1186  ayznaga 		fmd_buf_destroy(hdl, NULL, dp->dp_bufname);
    205  1186  ayznaga 
    206  1186  ayznaga 	fmd_buf_write(hdl, NULL, dp->dp_bufname, &dp->dp_pers,
    207  1186  ayznaga 	    sizeof (cmd_dp_pers_t));
    208  1186  ayznaga }
    209  1186  ayznaga 
    210  1186  ayznaga static cmd_dp_t *
    211  1186  ayznaga dp_wrapv0(fmd_hdl_t *hdl, cmd_dp_pers_t *pers, size_t psz)
    212  1186  ayznaga {
    213  1186  ayznaga 	cmd_dp_t *dp;
    214  1186  ayznaga 
    215  1186  ayznaga 	if (psz != sizeof (cmd_dp_pers_t)) {
    216  1186  ayznaga 		fmd_hdl_abort(hdl, "size of state doesn't match size of "
    217  1186  ayznaga 		    "version 1 state (%u bytes).\n", sizeof (cmd_dp_pers_t));
    218  1186  ayznaga 	}
    219  1186  ayznaga 
    220  1186  ayznaga 	dp = fmd_hdl_zalloc(hdl, sizeof (cmd_dp_t), FMD_SLEEP);
    221  1186  ayznaga 	bcopy(pers, dp, sizeof (cmd_dp_pers_t));
    222  1186  ayznaga 	fmd_hdl_free(hdl, pers, psz);
    223  1186  ayznaga 	return (dp);
    224  1186  ayznaga }
    225  1186  ayznaga 
    226  1186  ayznaga void *
    227  1186  ayznaga cmd_dp_restore(fmd_hdl_t *hdl, fmd_case_t *cp, cmd_case_ptr_t *ptr)
    228  1186  ayznaga {
    229  1186  ayznaga 	cmd_dp_t *dp;
    230  1186  ayznaga 
    231  1186  ayznaga 	for (dp = cmd_list_next(&cmd.cmd_datapaths); dp != NULL;
    232  1186  ayznaga 	    dp = cmd_list_next(dp)) {
    233  1186  ayznaga 		if (dp->dp_case == cp)
    234  1186  ayznaga 			break;
    235  1186  ayznaga 	}
    236  1186  ayznaga 
    237  1186  ayznaga 	if (dp == NULL) {
    238  1186  ayznaga 		size_t dpsz;
    239  1186  ayznaga 
    240  1186  ayznaga 		fmd_hdl_debug(hdl, "restoring dp from %s\n", ptr->ptr_name);
    241  1186  ayznaga 
    242  1186  ayznaga 		if ((dpsz = fmd_buf_size(hdl, NULL, ptr->ptr_name)) == 0) {
    243  6208  mb91622 			if (fmd_case_solved(hdl, cp) ||
    244  6208  mb91622 			    fmd_case_closed(hdl, cp)) {
    245  6208  mb91622 				fmd_hdl_debug(hdl, "dp %s from case %s not "
    246  6208  mb91622 				    "found. Case is already solved or closed\n",
    247  6208  mb91622 				    ptr->ptr_name, fmd_case_uuid(hdl, cp));
    248  6208  mb91622 				return (NULL);
    249  6208  mb91622 			} else {
    250  6208  mb91622 				fmd_hdl_abort(hdl, "dp referenced by case %s "
    251  6208  mb91622 				    "does not exist in saved state\n",
    252  6208  mb91622 				    fmd_case_uuid(hdl, cp));
    253  6208  mb91622 			}
    254  1186  ayznaga 		} else if (dpsz > CMD_DP_MAXSIZE ||
    255  1186  ayznaga 		    dpsz < CMD_DP_MINSIZE) {
    256  1186  ayznaga 			fmd_hdl_abort(hdl, "dp buffer referenced by "
    257  1186  ayznaga 			    "case %s is out of bounds (is %u bytes, "
    258  1186  ayznaga 			    "max %u, min %u)\n", fmd_case_uuid(hdl, cp),
    259  1186  ayznaga 			    dpsz, CMD_DP_MAXSIZE, CMD_DP_MINSIZE);
    260  1186  ayznaga 		}
    261  1186  ayznaga 
    262  1186  ayznaga 		if ((dp = cmd_buf_read(hdl, NULL, ptr->ptr_name, dpsz)) == NULL)
    263  1186  ayznaga 			fmd_hdl_abort(hdl, "failed to read dp buf %s",
    264  1186  ayznaga 			    ptr->ptr_name);
    265  1186  ayznaga 
    266  1186  ayznaga 		switch (dp->dp_version) {
    267  1186  ayznaga 		case CMD_DP_VERSION_0:
    268  1186  ayznaga 			dp = dp_wrapv0(hdl, (cmd_dp_pers_t *)dp, dpsz);
    269  1186  ayznaga 			break;
    270  1186  ayznaga 		default:
    271  1186  ayznaga 			fmd_hdl_abort(hdl, "unknown version (found %d) "
    272  1186  ayznaga 			    "for dp state referenced by case %s.\n",
    273  1186  ayznaga 			    dp->dp_version, fmd_case_uuid(hdl, cp));
    274  1186  ayznaga 			break;
    275  1186  ayznaga 		}
    276  1186  ayznaga 
    277  1186  ayznaga 		dp->dp_case = cp;
    278  1186  ayznaga 
    279  1186  ayznaga 		if (dp->dp_erpt_type == DP_ERROR) {
    280  1186  ayznaga 			fmd_event_t *ep = fmd_case_getprincipal(hdl, cp);
    281  1186  ayznaga 
    282  1186  ayznaga 			++cmd.cmd_dp_flag;
    283  1186  ayznaga 
    284  1186  ayznaga 			dp->dp_id = fmd_timer_install(hdl,
    285  1186  ayznaga 			    (void *)CMD_TIMERTYPE_DP, ep,
    286  1186  ayznaga 			    (hrtime_t)NANOSEC * (dp->dp_t_value + 120));
    287  1186  ayznaga 		}
    288  1186  ayznaga 
    289  1186  ayznaga 		cmd_list_append(&cmd.cmd_datapaths, dp);
    290  1186  ayznaga 	}
    291  1186  ayznaga 
    292  1186  ayznaga 	return (dp);
    293  1186  ayznaga }
    294  1186  ayznaga 
    295  1186  ayznaga void
    296  1186  ayznaga cmd_dp_close(fmd_hdl_t *hdl, void *arg)
    297  1186  ayznaga {
    298  1186  ayznaga 	cmd_dp_destroy(hdl, arg);
    299  1186  ayznaga }
    300  1186  ayznaga 
    301  1186  ayznaga void
    302  1186  ayznaga cmd_dp_timeout(fmd_hdl_t *hdl, id_t id)
    303  1186  ayznaga {
    304  1186  ayznaga 	cmd_dp_t		*dp;
    305  1186  ayznaga 
    306  1186  ayznaga 	/* close case associated with the timer */
    307  1186  ayznaga 	for (dp = cmd_list_next(&cmd.cmd_datapaths); dp != NULL;
    308  6208  mb91622 	    dp = cmd_list_next(dp)) {
    309  1186  ayznaga 		if (dp->dp_id == id) {
    310  1186  ayznaga 			cmd_dp_destroy(hdl, dp);
    311  1186  ayznaga 			break;
    312  1186  ayznaga 		}
    313  1186  ayznaga 	}
    314  1186  ayznaga 
    315  1186  ayznaga 	fmd_hdl_debug(hdl, "cmd_dp_timeout() complete\n");
    316  1186  ayznaga }
    317  1186  ayznaga 
    318  6471  kd93003 /*
    319  6471  kd93003  * Validate by matching each cmd_dp_t cpu and serial id to what is
    320  6471  kd93003  * installed and active on this machine or domain. Delete the cmd_dp_t
    321  6471  kd93003  * if no match is made.
    322  6471  kd93003  */
    323  1186  ayznaga void
    324  1186  ayznaga cmd_dp_validate(fmd_hdl_t *hdl)
    325  1186  ayznaga {
    326  1186  ayznaga 	cmd_dp_t *dp, *next;
    327  1186  ayznaga 	nvlist_t *nvl;
    328  6471  kd93003 	int i, no_match;
    329  1186  ayznaga 
    330  1186  ayznaga 	for (dp = cmd_list_next(&cmd.cmd_datapaths); dp != NULL; dp = next) {
    331  1186  ayznaga 		next = cmd_list_next(dp);
    332  1186  ayznaga 
    333  6471  kd93003 		for (i = 0, no_match = 0; i < dp->dp_ncpus; i++) {
    334  1186  ayznaga 			nvl = dp_cpu_fmri(hdl, dp->dp_cpuid_list[i],
    335  1186  ayznaga 			    dp->dp_serid_list[i]);
    336  1186  ayznaga 
    337  1186  ayznaga 			if (nvl == NULL)
    338  1186  ayznaga 				fmd_hdl_abort(hdl, "could not make CPU fmri");
    339  1186  ayznaga 
    340  1186  ayznaga 			if (!fmd_nvl_fmri_present(hdl, nvl))
    341  6471  kd93003 				no_match = 1;
    342  1186  ayznaga 
    343  1186  ayznaga 			nvlist_free(nvl);
    344  6471  kd93003 
    345  6471  kd93003 			if (no_match) {
    346  6471  kd93003 				cmd_dp_destroy(hdl, dp);
    347  6471  kd93003 				break;
    348  6471  kd93003 			}
    349  1186  ayznaga 		}
    350  1186  ayznaga 	}
    351  1186  ayznaga }
    352  1186  ayznaga 
    353  1186  ayznaga static void
    354  1186  ayznaga cmd_dp_free(fmd_hdl_t *hdl, cmd_dp_t *dp, int destroy)
    355  1186  ayznaga {
    356  1186  ayznaga 	if (dp->dp_case != NULL)
    357  1186  ayznaga 		cmd_case_fini(hdl, dp->dp_case, destroy);
    358  1186  ayznaga 
    359  1283  ayznaga 	if (destroy && dp->dp_erpt_type == DP_ERROR) {
    360  1186  ayznaga 		--cmd.cmd_dp_flag;
    361  1186  ayznaga 		/*
    362  1186  ayznaga 		 * If there are no active datapath events, replay any
    363  1186  ayznaga 		 * pages that were deferred.
    364  1186  ayznaga 		 */
    365  1186  ayznaga 		if (cmd.cmd_dp_flag == 0)
    366  1186  ayznaga 			cmd_dp_page_replay(hdl);
    367  1186  ayznaga 	}
    368  1186  ayznaga 
    369  1186  ayznaga 	if (destroy)
    370  1186  ayznaga 		fmd_buf_destroy(hdl, NULL, dp->dp_bufname);
    371  1186  ayznaga 
    372  1186  ayznaga 	cmd_list_delete(&cmd.cmd_datapaths, dp);
    373  1186  ayznaga 	fmd_hdl_free(hdl, dp, sizeof (cmd_dp_t));
    374  1186  ayznaga }
    375  1186  ayznaga 
    376  1186  ayznaga void
    377  1186  ayznaga cmd_dp_destroy(fmd_hdl_t *hdl, cmd_dp_t *dp)
    378  1186  ayznaga {
    379  1186  ayznaga 	cmd_dp_free(hdl, dp, FMD_B_TRUE);
    380  1186  ayznaga }
    381  1186  ayznaga 
    382  1186  ayznaga /*ARGSUSED*/
    383  1186  ayznaga int
    384  1186  ayznaga cmd_dp_error(fmd_hdl_t *hdl)
    385  1186  ayznaga {
    386  1186  ayznaga 	if (cmd.cmd_dp_flag)
    387  1186  ayznaga 		return (1);
    388  1186  ayznaga 	else
    389  1186  ayznaga 		return (0);
    390  1186  ayznaga }
    391  1186  ayznaga 
    392  1186  ayznaga int
    393  1186  ayznaga cmd_dp_get_mcid(uint64_t addr, int *mcid)
    394  1186  ayznaga {
    395  1186  ayznaga 	int fd, rc;
    396  1186  ayznaga 	mem_info_t data;
    397  1186  ayznaga 
    398  1186  ayznaga 	if ((fd = open("/dev/mem", O_RDONLY)) < 0)
    399  1186  ayznaga 		return (-1);
    400  1186  ayznaga 
    401  1186  ayznaga 	data.m_addr = addr;
    402  1186  ayznaga 	data.m_synd = 0;
    403  1186  ayznaga 	if ((rc = ioctl(fd, MEM_INFO, &data)) < 0) {
    404  1186  ayznaga 		(void) close(fd);
    405  1186  ayznaga 		return (rc);
    406  1186  ayznaga 	}
    407  1186  ayznaga 
    408  1186  ayznaga 	(void) close(fd);
    409  1186  ayznaga 	*mcid = data.m_mcid;
    410  1186  ayznaga 
    411  1186  ayznaga 	return (0);
    412  1186  ayznaga }
    413  1186  ayznaga 
    414  1186  ayznaga /*ARGSUSED*/
    415  1186  ayznaga int
    416  1186  ayznaga cmd_dp_fault(fmd_hdl_t *hdl, uint64_t addr)
    417  1186  ayznaga {
    418  1186  ayznaga 	int mcid;
    419  1186  ayznaga 
    420  1186  ayznaga 	if (cmd_dp_get_mcid(addr, &mcid) < 0)
    421  1186  ayznaga 		fmd_hdl_abort(hdl, "cmd_dp_get_mcid failed");
    422  1186  ayznaga 
    423  1186  ayznaga 	if (cmd_dp_lookup_fault(hdl, mcid) != NULL)
    424  1186  ayznaga 		return (1);
    425  1186  ayznaga 	else
    426  1186  ayznaga 		return (0);
    427  1186  ayznaga }
    428  1186  ayznaga 
    429  1186  ayznaga void
    430  1186  ayznaga cmd_dp_fini(fmd_hdl_t *hdl)
    431  1186  ayznaga {
    432  1186  ayznaga 	cmd_dp_t *dp;
    433  1186  ayznaga 	cmd_dp_defer_t *dpage;
    434  1186  ayznaga 
    435  1186  ayznaga 	while ((dp = cmd_list_next(&cmd.cmd_datapaths)) != NULL)
    436  1186  ayznaga 		cmd_dp_free(hdl, dp, FMD_B_FALSE);
    437  1186  ayznaga 
    438  1283  ayznaga 	while ((dpage = cmd_list_next(&cmd.cmd_deferred_pages)) != NULL) {
    439  1283  ayznaga 		cmd_list_delete(&cmd.cmd_deferred_pages, dpage);
    440  1186  ayznaga 		fmd_hdl_free(hdl, dpage, sizeof (cmd_dp_defer_t));
    441  1283  ayznaga 	}
    442  1186  ayznaga }
    443