xref: /onnv-gate/usr/src/uts/i86pc/io/dr/dr_mem_acpi.c (revision 12004:93f274d4a367)
1*12004Sjiang.liu@intel.com /*
2*12004Sjiang.liu@intel.com  * CDDL HEADER START
3*12004Sjiang.liu@intel.com  *
4*12004Sjiang.liu@intel.com  * The contents of this file are subject to the terms of the
5*12004Sjiang.liu@intel.com  * Common Development and Distribution License (the "License").
6*12004Sjiang.liu@intel.com  * You may not use this file except in compliance with the License.
7*12004Sjiang.liu@intel.com  *
8*12004Sjiang.liu@intel.com  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*12004Sjiang.liu@intel.com  * or http://www.opensolaris.org/os/licensing.
10*12004Sjiang.liu@intel.com  * See the License for the specific language governing permissions
11*12004Sjiang.liu@intel.com  * and limitations under the License.
12*12004Sjiang.liu@intel.com  *
13*12004Sjiang.liu@intel.com  * When distributing Covered Code, include this CDDL HEADER in each
14*12004Sjiang.liu@intel.com  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*12004Sjiang.liu@intel.com  * If applicable, add the following below this CDDL HEADER, with the
16*12004Sjiang.liu@intel.com  * fields enclosed by brackets "[]" replaced with your own identifying
17*12004Sjiang.liu@intel.com  * information: Portions Copyright [yyyy] [name of copyright owner]
18*12004Sjiang.liu@intel.com  *
19*12004Sjiang.liu@intel.com  * CDDL HEADER END
20*12004Sjiang.liu@intel.com  */
21*12004Sjiang.liu@intel.com 
22*12004Sjiang.liu@intel.com /*
23*12004Sjiang.liu@intel.com  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24*12004Sjiang.liu@intel.com  * Use is subject to license terms.
25*12004Sjiang.liu@intel.com  */
26*12004Sjiang.liu@intel.com /*
27*12004Sjiang.liu@intel.com  * Copyright (c) 2010, Intel Corporation.
28*12004Sjiang.liu@intel.com  * All rights reserved.
29*12004Sjiang.liu@intel.com  */
30*12004Sjiang.liu@intel.com 
31*12004Sjiang.liu@intel.com /*
32*12004Sjiang.liu@intel.com  * DR memory support routines.
33*12004Sjiang.liu@intel.com  */
34*12004Sjiang.liu@intel.com 
35*12004Sjiang.liu@intel.com #include <sys/note.h>
36*12004Sjiang.liu@intel.com #include <sys/debug.h>
37*12004Sjiang.liu@intel.com #include <sys/types.h>
38*12004Sjiang.liu@intel.com #include <sys/errno.h>
39*12004Sjiang.liu@intel.com #include <sys/param.h>
40*12004Sjiang.liu@intel.com #include <sys/kmem.h>
41*12004Sjiang.liu@intel.com #include <sys/kobj.h>
42*12004Sjiang.liu@intel.com #include <sys/conf.h>
43*12004Sjiang.liu@intel.com #include <sys/dditypes.h>
44*12004Sjiang.liu@intel.com #include <sys/ddi.h>
45*12004Sjiang.liu@intel.com #include <sys/sunddi.h>
46*12004Sjiang.liu@intel.com #include <sys/sunndi.h>
47*12004Sjiang.liu@intel.com #include <sys/ddi_impldefs.h>
48*12004Sjiang.liu@intel.com #include <sys/ndi_impldefs.h>
49*12004Sjiang.liu@intel.com #include <sys/sysmacros.h>
50*12004Sjiang.liu@intel.com #include <sys/machsystm.h>
51*12004Sjiang.liu@intel.com #include <sys/promif.h>
52*12004Sjiang.liu@intel.com #include <sys/lgrp.h>
53*12004Sjiang.liu@intel.com #include <sys/mem_config.h>
54*12004Sjiang.liu@intel.com #include <vm/seg_kmem.h>
55*12004Sjiang.liu@intel.com #include <vm/page.h>
56*12004Sjiang.liu@intel.com 
57*12004Sjiang.liu@intel.com #include <sys/dr.h>
58*12004Sjiang.liu@intel.com #include <sys/dr_util.h>
59*12004Sjiang.liu@intel.com #include <sys/drmach.h>
60*12004Sjiang.liu@intel.com 
61*12004Sjiang.liu@intel.com extern struct memlist	*phys_install;
62*12004Sjiang.liu@intel.com 
63*12004Sjiang.liu@intel.com /* TODO: push this reference below drmach line */
64*12004Sjiang.liu@intel.com extern int		kcage_on;
65*12004Sjiang.liu@intel.com 
66*12004Sjiang.liu@intel.com /* for the DR*INTERNAL_ERROR macros.  see sys/dr.h. */
67*12004Sjiang.liu@intel.com static char *dr_ie_fmt = "dr_mem_acpi.c %d";
68*12004Sjiang.liu@intel.com 
69*12004Sjiang.liu@intel.com static void		dr_init_mem_unit_data(dr_mem_unit_t *mp);
70*12004Sjiang.liu@intel.com 
71*12004Sjiang.liu@intel.com /*
72*12004Sjiang.liu@intel.com  * dr_mem_unit_t.sbm_flags
73*12004Sjiang.liu@intel.com  */
74*12004Sjiang.liu@intel.com #define	DR_MFLAG_RESERVED	0x01	/* mem unit reserved for delete */
75*12004Sjiang.liu@intel.com #define	DR_MFLAG_SOURCE		0x02	/* source brd of copy/rename op */
76*12004Sjiang.liu@intel.com #define	DR_MFLAG_TARGET		0x04	/* target brd of copy/rename op */
77*12004Sjiang.liu@intel.com #define	DR_MFLAG_RELOWNER	0x20	/* memory release (delete) owner */
78*12004Sjiang.liu@intel.com #define	DR_MFLAG_RELDONE	0x40	/* memory release (delete) done */
79*12004Sjiang.liu@intel.com 
80*12004Sjiang.liu@intel.com /* helper macros */
81*12004Sjiang.liu@intel.com #define	_ptob64(p) ((uint64_t)(p) << PAGESHIFT)
82*12004Sjiang.liu@intel.com #define	_b64top(b) ((pgcnt_t)((b) >> PAGESHIFT))
83*12004Sjiang.liu@intel.com 
84*12004Sjiang.liu@intel.com static struct memlist *
dr_get_memlist(dr_mem_unit_t * mp)85*12004Sjiang.liu@intel.com dr_get_memlist(dr_mem_unit_t *mp)
86*12004Sjiang.liu@intel.com {
87*12004Sjiang.liu@intel.com 	struct memlist	*mlist = NULL;
88*12004Sjiang.liu@intel.com 	sbd_error_t	*err;
89*12004Sjiang.liu@intel.com 	static fn_t	f = "dr_get_memlist";
90*12004Sjiang.liu@intel.com 
91*12004Sjiang.liu@intel.com 	PR_MEM("%s for %s...\n", f, mp->sbm_cm.sbdev_path);
92*12004Sjiang.liu@intel.com 
93*12004Sjiang.liu@intel.com 	/*
94*12004Sjiang.liu@intel.com 	 * Return cached memlist, if present.
95*12004Sjiang.liu@intel.com 	 * This memlist will be present following an
96*12004Sjiang.liu@intel.com 	 * unconfigure (a.k.a: detach) of this memunit.
97*12004Sjiang.liu@intel.com 	 * It should only be used in the case were a configure
98*12004Sjiang.liu@intel.com 	 * is bringing this memunit back in without going
99*12004Sjiang.liu@intel.com 	 * through the disconnect and connect states.
100*12004Sjiang.liu@intel.com 	 */
101*12004Sjiang.liu@intel.com 	if (mp->sbm_mlist) {
102*12004Sjiang.liu@intel.com 		PR_MEM("%s: found cached memlist\n", f);
103*12004Sjiang.liu@intel.com 
104*12004Sjiang.liu@intel.com 		mlist = memlist_dup(mp->sbm_mlist);
105*12004Sjiang.liu@intel.com 	} else {
106*12004Sjiang.liu@intel.com 		uint64_t basepa = _ptob64(mp->sbm_basepfn);
107*12004Sjiang.liu@intel.com 
108*12004Sjiang.liu@intel.com 		/* attempt to construct a memlist using phys_install */
109*12004Sjiang.liu@intel.com 
110*12004Sjiang.liu@intel.com 		/* round down to slice base address */
111*12004Sjiang.liu@intel.com 		basepa &= ~mp->sbm_alignment_mask;
112*12004Sjiang.liu@intel.com 
113*12004Sjiang.liu@intel.com 		/* get a copy of phys_install to edit */
114*12004Sjiang.liu@intel.com 		memlist_read_lock();
115*12004Sjiang.liu@intel.com 		mlist = memlist_dup(phys_install);
116*12004Sjiang.liu@intel.com 		memlist_read_unlock();
117*12004Sjiang.liu@intel.com 
118*12004Sjiang.liu@intel.com 		/* trim lower irrelevant span */
119*12004Sjiang.liu@intel.com 		if (mlist)
120*12004Sjiang.liu@intel.com 			mlist = memlist_del_span(mlist, 0ull, basepa);
121*12004Sjiang.liu@intel.com 
122*12004Sjiang.liu@intel.com 		/* trim upper irrelevant span */
123*12004Sjiang.liu@intel.com 		if (mlist) {
124*12004Sjiang.liu@intel.com 			uint64_t endpa, toppa;
125*12004Sjiang.liu@intel.com 
126*12004Sjiang.liu@intel.com 			toppa = mp->sbm_slice_top;
127*12004Sjiang.liu@intel.com 			endpa = _ptob64(physmax + 1);
128*12004Sjiang.liu@intel.com 			if (endpa > toppa)
129*12004Sjiang.liu@intel.com 				mlist = memlist_del_span(
130*12004Sjiang.liu@intel.com 				    mlist, toppa,
131*12004Sjiang.liu@intel.com 				    endpa - toppa);
132*12004Sjiang.liu@intel.com 		}
133*12004Sjiang.liu@intel.com 
134*12004Sjiang.liu@intel.com 		if (mlist) {
135*12004Sjiang.liu@intel.com 			/* successfully built a memlist */
136*12004Sjiang.liu@intel.com 			PR_MEM("%s: derived memlist from phys_install\n", f);
137*12004Sjiang.liu@intel.com 		}
138*12004Sjiang.liu@intel.com 
139*12004Sjiang.liu@intel.com 		/* if no mlist yet, try platform layer */
140*12004Sjiang.liu@intel.com 		if (!mlist) {
141*12004Sjiang.liu@intel.com 			err = drmach_mem_get_memlist(
142*12004Sjiang.liu@intel.com 			    mp->sbm_cm.sbdev_id, &mlist);
143*12004Sjiang.liu@intel.com 			if (err) {
144*12004Sjiang.liu@intel.com 				DRERR_SET_C(&mp->sbm_cm.sbdev_error, &err);
145*12004Sjiang.liu@intel.com 				mlist = NULL; /* paranoia */
146*12004Sjiang.liu@intel.com 			}
147*12004Sjiang.liu@intel.com 		}
148*12004Sjiang.liu@intel.com 	}
149*12004Sjiang.liu@intel.com 
150*12004Sjiang.liu@intel.com 	PR_MEM("%s: memlist for %s\n", f, mp->sbm_cm.sbdev_path);
151*12004Sjiang.liu@intel.com 	PR_MEMLIST_DUMP(mlist);
152*12004Sjiang.liu@intel.com 
153*12004Sjiang.liu@intel.com 	return (mlist);
154*12004Sjiang.liu@intel.com }
155*12004Sjiang.liu@intel.com 
156*12004Sjiang.liu@intel.com /*ARGSUSED*/
157*12004Sjiang.liu@intel.com void
dr_release_mem(dr_common_unit_t * cp)158*12004Sjiang.liu@intel.com dr_release_mem(dr_common_unit_t *cp)
159*12004Sjiang.liu@intel.com {
160*12004Sjiang.liu@intel.com }
161*12004Sjiang.liu@intel.com 
162*12004Sjiang.liu@intel.com void
dr_attach_mem(dr_handle_t * hp,dr_common_unit_t * cp)163*12004Sjiang.liu@intel.com dr_attach_mem(dr_handle_t *hp, dr_common_unit_t *cp)
164*12004Sjiang.liu@intel.com {
165*12004Sjiang.liu@intel.com 	dr_mem_unit_t	*mp = (dr_mem_unit_t *)cp;
166*12004Sjiang.liu@intel.com 	struct memlist	*ml, *mc;
167*12004Sjiang.liu@intel.com 	sbd_error_t	*err;
168*12004Sjiang.liu@intel.com 	static fn_t	f = "dr_attach_mem";
169*12004Sjiang.liu@intel.com 	uint64_t	dr_physmax;
170*12004Sjiang.liu@intel.com 
171*12004Sjiang.liu@intel.com 	PR_MEM("%s...\n", f);
172*12004Sjiang.liu@intel.com 
173*12004Sjiang.liu@intel.com 	dr_lock_status(hp->h_bd);
174*12004Sjiang.liu@intel.com 	err = drmach_configure(cp->sbdev_id, 0);
175*12004Sjiang.liu@intel.com 	dr_unlock_status(hp->h_bd);
176*12004Sjiang.liu@intel.com 	if (err) {
177*12004Sjiang.liu@intel.com 		DRERR_SET_C(&cp->sbdev_error, &err);
178*12004Sjiang.liu@intel.com 		return;
179*12004Sjiang.liu@intel.com 	}
180*12004Sjiang.liu@intel.com 
181*12004Sjiang.liu@intel.com 	ml = dr_get_memlist(mp);
182*12004Sjiang.liu@intel.com 
183*12004Sjiang.liu@intel.com 	/* Skip memory with address above plat_dr_physmax or kpm_size */
184*12004Sjiang.liu@intel.com 	dr_physmax = plat_dr_physmax ? ptob(plat_dr_physmax) : UINT64_MAX;
185*12004Sjiang.liu@intel.com 	if (kpm_size < dr_physmax)
186*12004Sjiang.liu@intel.com 		dr_physmax = kpm_size;
187*12004Sjiang.liu@intel.com 	ml = memlist_del_span(ml, dr_physmax, UINT64_MAX - dr_physmax);
188*12004Sjiang.liu@intel.com 
189*12004Sjiang.liu@intel.com 	for (mc = ml; mc; mc = mc->ml_next) {
190*12004Sjiang.liu@intel.com 		int		 rv;
191*12004Sjiang.liu@intel.com 		sbd_error_t	*err;
192*12004Sjiang.liu@intel.com 
193*12004Sjiang.liu@intel.com 		rv = kphysm_add_memory_dynamic(
194*12004Sjiang.liu@intel.com 		    (pfn_t)btop(mc->ml_address),
195*12004Sjiang.liu@intel.com 		    (pgcnt_t)btop(mc->ml_size));
196*12004Sjiang.liu@intel.com 		if (rv != KPHYSM_OK) {
197*12004Sjiang.liu@intel.com 			/*
198*12004Sjiang.liu@intel.com 			 * translate kphysm error and
199*12004Sjiang.liu@intel.com 			 * store in devlist error
200*12004Sjiang.liu@intel.com 			 */
201*12004Sjiang.liu@intel.com 			switch (rv) {
202*12004Sjiang.liu@intel.com 			case KPHYSM_ERESOURCE:
203*12004Sjiang.liu@intel.com 				rv = ESBD_NOMEM;
204*12004Sjiang.liu@intel.com 				break;
205*12004Sjiang.liu@intel.com 
206*12004Sjiang.liu@intel.com 			case KPHYSM_EFAULT:
207*12004Sjiang.liu@intel.com 				rv = ESBD_FAULT;
208*12004Sjiang.liu@intel.com 				break;
209*12004Sjiang.liu@intel.com 
210*12004Sjiang.liu@intel.com 			default:
211*12004Sjiang.liu@intel.com 				rv = ESBD_INTERNAL;
212*12004Sjiang.liu@intel.com 				break;
213*12004Sjiang.liu@intel.com 			}
214*12004Sjiang.liu@intel.com 
215*12004Sjiang.liu@intel.com 			if (rv == ESBD_INTERNAL) {
216*12004Sjiang.liu@intel.com 				DR_DEV_INTERNAL_ERROR(&mp->sbm_cm);
217*12004Sjiang.liu@intel.com 			} else
218*12004Sjiang.liu@intel.com 				dr_dev_err(CE_WARN, &mp->sbm_cm, rv);
219*12004Sjiang.liu@intel.com 			break;
220*12004Sjiang.liu@intel.com 		}
221*12004Sjiang.liu@intel.com 
222*12004Sjiang.liu@intel.com 		err = drmach_mem_add_span(
223*12004Sjiang.liu@intel.com 		    mp->sbm_cm.sbdev_id, mc->ml_address, mc->ml_size);
224*12004Sjiang.liu@intel.com 		if (err) {
225*12004Sjiang.liu@intel.com 			DRERR_SET_C(&mp->sbm_cm.sbdev_error, &err);
226*12004Sjiang.liu@intel.com 			break;
227*12004Sjiang.liu@intel.com 		}
228*12004Sjiang.liu@intel.com 	}
229*12004Sjiang.liu@intel.com 
230*12004Sjiang.liu@intel.com 	memlist_delete(ml);
231*12004Sjiang.liu@intel.com 	dr_init_mem_unit_data(mp);
232*12004Sjiang.liu@intel.com 
233*12004Sjiang.liu@intel.com 	/* back out if configure failed */
234*12004Sjiang.liu@intel.com 	if (mp->sbm_cm.sbdev_error != NULL) {
235*12004Sjiang.liu@intel.com 		dr_lock_status(hp->h_bd);
236*12004Sjiang.liu@intel.com 		err = drmach_unconfigure(cp->sbdev_id, 0);
237*12004Sjiang.liu@intel.com 		if (err)
238*12004Sjiang.liu@intel.com 			sbd_err_clear(&err);
239*12004Sjiang.liu@intel.com 		dr_unlock_status(hp->h_bd);
240*12004Sjiang.liu@intel.com 	}
241*12004Sjiang.liu@intel.com }
242*12004Sjiang.liu@intel.com 
243*12004Sjiang.liu@intel.com /*ARGSUSED*/
244*12004Sjiang.liu@intel.com void
dr_detach_mem(dr_handle_t * hp,dr_common_unit_t * cp)245*12004Sjiang.liu@intel.com dr_detach_mem(dr_handle_t *hp, dr_common_unit_t *cp)
246*12004Sjiang.liu@intel.com {
247*12004Sjiang.liu@intel.com }
248*12004Sjiang.liu@intel.com 
249*12004Sjiang.liu@intel.com /*
250*12004Sjiang.liu@intel.com  * This routine acts as a wrapper for kphysm_del_span_query in order to
251*12004Sjiang.liu@intel.com  * support potential memory holes in a board's physical address space.
252*12004Sjiang.liu@intel.com  * It calls kphysm_del_span_query for each node in a memlist and accumulates
253*12004Sjiang.liu@intel.com  * the results in *mp.
254*12004Sjiang.liu@intel.com  */
255*12004Sjiang.liu@intel.com static int
dr_del_mlist_query(struct memlist * mlist,memquery_t * mp)256*12004Sjiang.liu@intel.com dr_del_mlist_query(struct memlist *mlist, memquery_t *mp)
257*12004Sjiang.liu@intel.com {
258*12004Sjiang.liu@intel.com 	int		 rv = 0;
259*12004Sjiang.liu@intel.com 
260*12004Sjiang.liu@intel.com 	if (mlist == NULL)
261*12004Sjiang.liu@intel.com 		cmn_err(CE_WARN, "dr_del_mlist_query: mlist=NULL\n");
262*12004Sjiang.liu@intel.com 
263*12004Sjiang.liu@intel.com 	mp->phys_pages = 0;
264*12004Sjiang.liu@intel.com 	mp->managed = 0;
265*12004Sjiang.liu@intel.com 	mp->nonrelocatable = 0;
266*12004Sjiang.liu@intel.com 	mp->first_nonrelocatable = 0;
267*12004Sjiang.liu@intel.com 	mp->last_nonrelocatable = 0;
268*12004Sjiang.liu@intel.com 
269*12004Sjiang.liu@intel.com 	return (rv);
270*12004Sjiang.liu@intel.com }
271*12004Sjiang.liu@intel.com 
272*12004Sjiang.liu@intel.com /*
273*12004Sjiang.liu@intel.com  * NOTE: This routine is only partially smart about multiple
274*12004Sjiang.liu@intel.com  *	 mem-units.  Need to make mem-status structure smart
275*12004Sjiang.liu@intel.com  *	 about them also.
276*12004Sjiang.liu@intel.com  */
277*12004Sjiang.liu@intel.com int
dr_mem_status(dr_handle_t * hp,dr_devset_t devset,sbd_dev_stat_t * dsp)278*12004Sjiang.liu@intel.com dr_mem_status(dr_handle_t *hp, dr_devset_t devset, sbd_dev_stat_t *dsp)
279*12004Sjiang.liu@intel.com {
280*12004Sjiang.liu@intel.com 	int		m, mix;
281*12004Sjiang.liu@intel.com 	memquery_t	mq;
282*12004Sjiang.liu@intel.com 	dr_board_t	*bp;
283*12004Sjiang.liu@intel.com 	dr_mem_unit_t	*mp;
284*12004Sjiang.liu@intel.com 	sbd_mem_stat_t	*msp;
285*12004Sjiang.liu@intel.com 	static fn_t	f = "dr_mem_status";
286*12004Sjiang.liu@intel.com 
287*12004Sjiang.liu@intel.com 	bp = hp->h_bd;
288*12004Sjiang.liu@intel.com 	devset &= DR_DEVS_PRESENT(bp);
289*12004Sjiang.liu@intel.com 
290*12004Sjiang.liu@intel.com 	for (m = mix = 0; m < MAX_MEM_UNITS_PER_BOARD; m++) {
291*12004Sjiang.liu@intel.com 		int		rv;
292*12004Sjiang.liu@intel.com 		sbd_error_t	*err;
293*12004Sjiang.liu@intel.com 		drmach_status_t	 pstat;
294*12004Sjiang.liu@intel.com 		dr_mem_unit_t	*p_mp;
295*12004Sjiang.liu@intel.com 
296*12004Sjiang.liu@intel.com 		if (DEVSET_IN_SET(devset, SBD_COMP_MEM, m) == 0)
297*12004Sjiang.liu@intel.com 			continue;
298*12004Sjiang.liu@intel.com 
299*12004Sjiang.liu@intel.com 		mp = dr_get_mem_unit(bp, m);
300*12004Sjiang.liu@intel.com 
301*12004Sjiang.liu@intel.com 		if (mp->sbm_cm.sbdev_state == DR_STATE_EMPTY) {
302*12004Sjiang.liu@intel.com 			/* present, but not fully initialized */
303*12004Sjiang.liu@intel.com 			continue;
304*12004Sjiang.liu@intel.com 		}
305*12004Sjiang.liu@intel.com 
306*12004Sjiang.liu@intel.com 		if (mp->sbm_cm.sbdev_id == (drmachid_t)0)
307*12004Sjiang.liu@intel.com 			continue;
308*12004Sjiang.liu@intel.com 
309*12004Sjiang.liu@intel.com 		/* fetch platform status */
310*12004Sjiang.liu@intel.com 		err = drmach_status(mp->sbm_cm.sbdev_id, &pstat);
311*12004Sjiang.liu@intel.com 		if (err) {
312*12004Sjiang.liu@intel.com 			DRERR_SET_C(&mp->sbm_cm.sbdev_error, &err);
313*12004Sjiang.liu@intel.com 			continue;
314*12004Sjiang.liu@intel.com 		}
315*12004Sjiang.liu@intel.com 
316*12004Sjiang.liu@intel.com 		msp = &dsp->d_mem;
317*12004Sjiang.liu@intel.com 		bzero((caddr_t)msp, sizeof (*msp));
318*12004Sjiang.liu@intel.com 
319*12004Sjiang.liu@intel.com 		(void) strlcpy(msp->ms_cm.c_id.c_name, pstat.type,
320*12004Sjiang.liu@intel.com 		    sizeof (msp->ms_cm.c_id.c_name));
321*12004Sjiang.liu@intel.com 		msp->ms_cm.c_id.c_type = mp->sbm_cm.sbdev_type;
322*12004Sjiang.liu@intel.com 		msp->ms_cm.c_id.c_unit = mp->sbm_cm.sbdev_unum;
323*12004Sjiang.liu@intel.com 		msp->ms_cm.c_cond = mp->sbm_cm.sbdev_cond;
324*12004Sjiang.liu@intel.com 		msp->ms_cm.c_busy = mp->sbm_cm.sbdev_busy | pstat.busy;
325*12004Sjiang.liu@intel.com 		msp->ms_cm.c_time = mp->sbm_cm.sbdev_time;
326*12004Sjiang.liu@intel.com 		msp->ms_cm.c_ostate = mp->sbm_cm.sbdev_ostate;
327*12004Sjiang.liu@intel.com 
328*12004Sjiang.liu@intel.com 		msp->ms_totpages = mp->sbm_npages;
329*12004Sjiang.liu@intel.com 		msp->ms_basepfn = mp->sbm_basepfn;
330*12004Sjiang.liu@intel.com 		msp->ms_pageslost = mp->sbm_pageslost;
331*12004Sjiang.liu@intel.com 		msp->ms_cage_enabled = kcage_on;
332*12004Sjiang.liu@intel.com 
333*12004Sjiang.liu@intel.com 		if (mp->sbm_flags & DR_MFLAG_RESERVED)
334*12004Sjiang.liu@intel.com 			p_mp = mp->sbm_peer;
335*12004Sjiang.liu@intel.com 		else
336*12004Sjiang.liu@intel.com 			p_mp = NULL;
337*12004Sjiang.liu@intel.com 
338*12004Sjiang.liu@intel.com 		if (p_mp == NULL) {
339*12004Sjiang.liu@intel.com 			msp->ms_peer_is_target = 0;
340*12004Sjiang.liu@intel.com 			msp->ms_peer_ap_id[0] = '\0';
341*12004Sjiang.liu@intel.com 		} else if (p_mp->sbm_flags & DR_MFLAG_RESERVED) {
342*12004Sjiang.liu@intel.com 			char *path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
343*12004Sjiang.liu@intel.com 			char *minor;
344*12004Sjiang.liu@intel.com 
345*12004Sjiang.liu@intel.com 			/*
346*12004Sjiang.liu@intel.com 			 * b_dip doesn't have to be held for ddi_pathname()
347*12004Sjiang.liu@intel.com 			 * because the board struct (dr_board_t) will be
348*12004Sjiang.liu@intel.com 			 * destroyed before b_dip detaches.
349*12004Sjiang.liu@intel.com 			 */
350*12004Sjiang.liu@intel.com 			(void) ddi_pathname(bp->b_dip, path);
351*12004Sjiang.liu@intel.com 			minor = strchr(p_mp->sbm_cm.sbdev_path, ':');
352*12004Sjiang.liu@intel.com 
353*12004Sjiang.liu@intel.com 			(void) snprintf(msp->ms_peer_ap_id,
354*12004Sjiang.liu@intel.com 			    sizeof (msp->ms_peer_ap_id), "%s%s",
355*12004Sjiang.liu@intel.com 			    path, (minor == NULL) ? "" : minor);
356*12004Sjiang.liu@intel.com 
357*12004Sjiang.liu@intel.com 			kmem_free(path, MAXPATHLEN);
358*12004Sjiang.liu@intel.com 
359*12004Sjiang.liu@intel.com 			if (p_mp->sbm_flags & DR_MFLAG_TARGET)
360*12004Sjiang.liu@intel.com 				msp->ms_peer_is_target = 1;
361*12004Sjiang.liu@intel.com 		}
362*12004Sjiang.liu@intel.com 
363*12004Sjiang.liu@intel.com 		/*
364*12004Sjiang.liu@intel.com 		 * kphysm_del_span_query can report non-reloc pages = total
365*12004Sjiang.liu@intel.com 		 * pages for memory that is not yet configured
366*12004Sjiang.liu@intel.com 		 */
367*12004Sjiang.liu@intel.com 		if (mp->sbm_cm.sbdev_state != DR_STATE_UNCONFIGURED) {
368*12004Sjiang.liu@intel.com 			struct memlist *ml;
369*12004Sjiang.liu@intel.com 
370*12004Sjiang.liu@intel.com 			ml = dr_get_memlist(mp);
371*12004Sjiang.liu@intel.com 			rv = ml ? dr_del_mlist_query(ml, &mq) : -1;
372*12004Sjiang.liu@intel.com 			memlist_delete(ml);
373*12004Sjiang.liu@intel.com 
374*12004Sjiang.liu@intel.com 			if (rv == KPHYSM_OK) {
375*12004Sjiang.liu@intel.com 				msp->ms_managed_pages = mq.managed;
376*12004Sjiang.liu@intel.com 				msp->ms_noreloc_pages = mq.nonrelocatable;
377*12004Sjiang.liu@intel.com 				msp->ms_noreloc_first =
378*12004Sjiang.liu@intel.com 				    mq.first_nonrelocatable;
379*12004Sjiang.liu@intel.com 				msp->ms_noreloc_last =
380*12004Sjiang.liu@intel.com 				    mq.last_nonrelocatable;
381*12004Sjiang.liu@intel.com 				msp->ms_cm.c_sflags = 0;
382*12004Sjiang.liu@intel.com 				if (mq.nonrelocatable &&
383*12004Sjiang.liu@intel.com 				    drmach_copy_rename_need_suspend(
384*12004Sjiang.liu@intel.com 				    mp->sbm_cm.sbdev_id)) {
385*12004Sjiang.liu@intel.com 					SBD_SET_SUSPEND(SBD_CMD_UNCONFIGURE,
386*12004Sjiang.liu@intel.com 					    msp->ms_cm.c_sflags);
387*12004Sjiang.liu@intel.com 				}
388*12004Sjiang.liu@intel.com 			} else {
389*12004Sjiang.liu@intel.com 				PR_MEM("%s: kphysm_del_span_query() = %d\n",
390*12004Sjiang.liu@intel.com 				    f, rv);
391*12004Sjiang.liu@intel.com 			}
392*12004Sjiang.liu@intel.com 		}
393*12004Sjiang.liu@intel.com 
394*12004Sjiang.liu@intel.com 		/*
395*12004Sjiang.liu@intel.com 		 * Check source unit state during copy-rename
396*12004Sjiang.liu@intel.com 		 */
397*12004Sjiang.liu@intel.com 		if ((mp->sbm_flags & DR_MFLAG_SOURCE) &&
398*12004Sjiang.liu@intel.com 		    (mp->sbm_cm.sbdev_state == DR_STATE_UNREFERENCED ||
399*12004Sjiang.liu@intel.com 		    mp->sbm_cm.sbdev_state == DR_STATE_RELEASE))
400*12004Sjiang.liu@intel.com 			msp->ms_cm.c_ostate = SBD_STAT_CONFIGURED;
401*12004Sjiang.liu@intel.com 
402*12004Sjiang.liu@intel.com 		mix++;
403*12004Sjiang.liu@intel.com 		dsp++;
404*12004Sjiang.liu@intel.com 	}
405*12004Sjiang.liu@intel.com 
406*12004Sjiang.liu@intel.com 	return (mix);
407*12004Sjiang.liu@intel.com }
408*12004Sjiang.liu@intel.com 
409*12004Sjiang.liu@intel.com /*ARGSUSED*/
410*12004Sjiang.liu@intel.com int
dr_pre_attach_mem(dr_handle_t * hp,dr_common_unit_t ** devlist,int devnum)411*12004Sjiang.liu@intel.com dr_pre_attach_mem(dr_handle_t *hp, dr_common_unit_t **devlist, int devnum)
412*12004Sjiang.liu@intel.com {
413*12004Sjiang.liu@intel.com 	int		err_flag = 0;
414*12004Sjiang.liu@intel.com 	int		d;
415*12004Sjiang.liu@intel.com 	sbd_error_t	*err;
416*12004Sjiang.liu@intel.com 	static fn_t	f = "dr_pre_attach_mem";
417*12004Sjiang.liu@intel.com 
418*12004Sjiang.liu@intel.com 	PR_MEM("%s...\n", f);
419*12004Sjiang.liu@intel.com 
420*12004Sjiang.liu@intel.com 	for (d = 0; d < devnum; d++) {
421*12004Sjiang.liu@intel.com 		dr_mem_unit_t	*mp = (dr_mem_unit_t *)devlist[d];
422*12004Sjiang.liu@intel.com 		dr_state_t	state;
423*12004Sjiang.liu@intel.com 
424*12004Sjiang.liu@intel.com 		cmn_err(CE_CONT, "OS configure %s", mp->sbm_cm.sbdev_path);
425*12004Sjiang.liu@intel.com 
426*12004Sjiang.liu@intel.com 		state = mp->sbm_cm.sbdev_state;
427*12004Sjiang.liu@intel.com 		switch (state) {
428*12004Sjiang.liu@intel.com 		case DR_STATE_UNCONFIGURED:
429*12004Sjiang.liu@intel.com 			PR_MEM("%s: recovering from UNCONFIG for %s\n",
430*12004Sjiang.liu@intel.com 			    f, mp->sbm_cm.sbdev_path);
431*12004Sjiang.liu@intel.com 
432*12004Sjiang.liu@intel.com 			/* use memlist cached by dr_post_detach_mem_unit */
433*12004Sjiang.liu@intel.com 			ASSERT(mp->sbm_mlist != NULL);
434*12004Sjiang.liu@intel.com 			PR_MEM("%s: re-configuring cached memlist for %s:\n",
435*12004Sjiang.liu@intel.com 			    f, mp->sbm_cm.sbdev_path);
436*12004Sjiang.liu@intel.com 			PR_MEMLIST_DUMP(mp->sbm_mlist);
437*12004Sjiang.liu@intel.com 
438*12004Sjiang.liu@intel.com 			/* kphysm del handle should be have been freed */
439*12004Sjiang.liu@intel.com 			ASSERT((mp->sbm_flags & DR_MFLAG_RELOWNER) == 0);
440*12004Sjiang.liu@intel.com 
441*12004Sjiang.liu@intel.com 			/*FALLTHROUGH*/
442*12004Sjiang.liu@intel.com 
443*12004Sjiang.liu@intel.com 		case DR_STATE_CONNECTED:
444*12004Sjiang.liu@intel.com 			PR_MEM("%s: reprogramming mem hardware on %s\n",
445*12004Sjiang.liu@intel.com 			    f, mp->sbm_cm.sbdev_bp->b_path);
446*12004Sjiang.liu@intel.com 
447*12004Sjiang.liu@intel.com 			PR_MEM("%s: enabling %s\n",
448*12004Sjiang.liu@intel.com 			    f, mp->sbm_cm.sbdev_path);
449*12004Sjiang.liu@intel.com 
450*12004Sjiang.liu@intel.com 			err = drmach_mem_enable(mp->sbm_cm.sbdev_id);
451*12004Sjiang.liu@intel.com 			if (err) {
452*12004Sjiang.liu@intel.com 				DRERR_SET_C(&mp->sbm_cm.sbdev_error, &err);
453*12004Sjiang.liu@intel.com 				err_flag = 1;
454*12004Sjiang.liu@intel.com 			}
455*12004Sjiang.liu@intel.com 			break;
456*12004Sjiang.liu@intel.com 
457*12004Sjiang.liu@intel.com 		default:
458*12004Sjiang.liu@intel.com 			dr_dev_err(CE_WARN, &mp->sbm_cm, ESBD_STATE);
459*12004Sjiang.liu@intel.com 			err_flag = 1;
460*12004Sjiang.liu@intel.com 			break;
461*12004Sjiang.liu@intel.com 		}
462*12004Sjiang.liu@intel.com 
463*12004Sjiang.liu@intel.com 		/* exit for loop if error encountered */
464*12004Sjiang.liu@intel.com 		if (err_flag)
465*12004Sjiang.liu@intel.com 			break;
466*12004Sjiang.liu@intel.com 	}
467*12004Sjiang.liu@intel.com 
468*12004Sjiang.liu@intel.com 	return (err_flag ? -1 : 0);
469*12004Sjiang.liu@intel.com }
470*12004Sjiang.liu@intel.com 
471*12004Sjiang.liu@intel.com /*ARGSUSED*/
472*12004Sjiang.liu@intel.com int
dr_post_attach_mem(dr_handle_t * hp,dr_common_unit_t ** devlist,int devnum)473*12004Sjiang.liu@intel.com dr_post_attach_mem(dr_handle_t *hp, dr_common_unit_t **devlist, int devnum)
474*12004Sjiang.liu@intel.com {
475*12004Sjiang.liu@intel.com 	int		d;
476*12004Sjiang.liu@intel.com 	static fn_t	f = "dr_post_attach_mem";
477*12004Sjiang.liu@intel.com 
478*12004Sjiang.liu@intel.com 	PR_MEM("%s...\n", f);
479*12004Sjiang.liu@intel.com 
480*12004Sjiang.liu@intel.com 	for (d = 0; d < devnum; d++) {
481*12004Sjiang.liu@intel.com 		dr_mem_unit_t	*mp = (dr_mem_unit_t *)devlist[d];
482*12004Sjiang.liu@intel.com 		struct memlist	*mlist, *ml;
483*12004Sjiang.liu@intel.com 
484*12004Sjiang.liu@intel.com 		mlist = dr_get_memlist(mp);
485*12004Sjiang.liu@intel.com 
486*12004Sjiang.liu@intel.com 		/*
487*12004Sjiang.liu@intel.com 		 * Verify the memory really did successfully attach
488*12004Sjiang.liu@intel.com 		 * by checking for its existence in phys_install.
489*12004Sjiang.liu@intel.com 		 */
490*12004Sjiang.liu@intel.com 		memlist_read_lock();
491*12004Sjiang.liu@intel.com 		if (memlist_intersect(phys_install, mlist) == 0) {
492*12004Sjiang.liu@intel.com 			memlist_read_unlock();
493*12004Sjiang.liu@intel.com 
494*12004Sjiang.liu@intel.com 			DR_DEV_INTERNAL_ERROR(&mp->sbm_cm);
495*12004Sjiang.liu@intel.com 
496*12004Sjiang.liu@intel.com 			PR_MEM("%s: %s memlist not in phys_install",
497*12004Sjiang.liu@intel.com 			    f, mp->sbm_cm.sbdev_path);
498*12004Sjiang.liu@intel.com 
499*12004Sjiang.liu@intel.com 			memlist_delete(mlist);
500*12004Sjiang.liu@intel.com 			continue;
501*12004Sjiang.liu@intel.com 		}
502*12004Sjiang.liu@intel.com 		memlist_read_unlock();
503*12004Sjiang.liu@intel.com 
504*12004Sjiang.liu@intel.com 		for (ml = mlist; ml != NULL; ml = ml->ml_next) {
505*12004Sjiang.liu@intel.com 			sbd_error_t *err;
506*12004Sjiang.liu@intel.com 
507*12004Sjiang.liu@intel.com 			err = drmach_mem_add_span(
508*12004Sjiang.liu@intel.com 			    mp->sbm_cm.sbdev_id,
509*12004Sjiang.liu@intel.com 			    ml->ml_address,
510*12004Sjiang.liu@intel.com 			    ml->ml_size);
511*12004Sjiang.liu@intel.com 			if (err)
512*12004Sjiang.liu@intel.com 				DRERR_SET_C(&mp->sbm_cm.sbdev_error, &err);
513*12004Sjiang.liu@intel.com 		}
514*12004Sjiang.liu@intel.com 
515*12004Sjiang.liu@intel.com 		memlist_delete(mlist);
516*12004Sjiang.liu@intel.com 
517*12004Sjiang.liu@intel.com 		/*
518*12004Sjiang.liu@intel.com 		 * Destroy cached memlist, if any.
519*12004Sjiang.liu@intel.com 		 * There will be a cached memlist in sbm_mlist if
520*12004Sjiang.liu@intel.com 		 * this board is being configured directly after
521*12004Sjiang.liu@intel.com 		 * an unconfigure.
522*12004Sjiang.liu@intel.com 		 * To support this transition, dr_post_detach_mem
523*12004Sjiang.liu@intel.com 		 * left a copy of the last known memlist in sbm_mlist.
524*12004Sjiang.liu@intel.com 		 * This memlist could differ from any derived from
525*12004Sjiang.liu@intel.com 		 * hardware if while this memunit was last configured
526*12004Sjiang.liu@intel.com 		 * the system detected and deleted bad pages from
527*12004Sjiang.liu@intel.com 		 * phys_install.  The location of those bad pages
528*12004Sjiang.liu@intel.com 		 * will be reflected in the cached memlist.
529*12004Sjiang.liu@intel.com 		 */
530*12004Sjiang.liu@intel.com 		if (mp->sbm_mlist) {
531*12004Sjiang.liu@intel.com 			memlist_delete(mp->sbm_mlist);
532*12004Sjiang.liu@intel.com 			mp->sbm_mlist = NULL;
533*12004Sjiang.liu@intel.com 		}
534*12004Sjiang.liu@intel.com 	}
535*12004Sjiang.liu@intel.com 
536*12004Sjiang.liu@intel.com 	return (0);
537*12004Sjiang.liu@intel.com }
538*12004Sjiang.liu@intel.com 
539*12004Sjiang.liu@intel.com /*ARGSUSED*/
540*12004Sjiang.liu@intel.com int
dr_pre_detach_mem(dr_handle_t * hp,dr_common_unit_t ** devlist,int devnum)541*12004Sjiang.liu@intel.com dr_pre_detach_mem(dr_handle_t *hp, dr_common_unit_t **devlist, int devnum)
542*12004Sjiang.liu@intel.com {
543*12004Sjiang.liu@intel.com 	return (-1);
544*12004Sjiang.liu@intel.com }
545*12004Sjiang.liu@intel.com 
546*12004Sjiang.liu@intel.com /*ARGSUSED*/
547*12004Sjiang.liu@intel.com int
dr_post_detach_mem(dr_handle_t * hp,dr_common_unit_t ** devlist,int devnum)548*12004Sjiang.liu@intel.com dr_post_detach_mem(dr_handle_t *hp, dr_common_unit_t **devlist, int devnum)
549*12004Sjiang.liu@intel.com {
550*12004Sjiang.liu@intel.com 	return (-1);
551*12004Sjiang.liu@intel.com }
552*12004Sjiang.liu@intel.com 
553*12004Sjiang.liu@intel.com /*
554*12004Sjiang.liu@intel.com  * Successful return from this function will have the memory
555*12004Sjiang.liu@intel.com  * handle in bp->b_dev[..mem-unit...].sbm_memhandle allocated
556*12004Sjiang.liu@intel.com  * and waiting.  This routine's job is to select the memory that
557*12004Sjiang.liu@intel.com  * actually has to be released (detached) which may not necessarily
558*12004Sjiang.liu@intel.com  * be the same memory node that came in in devlist[],
559*12004Sjiang.liu@intel.com  * i.e. a copy-rename is needed.
560*12004Sjiang.liu@intel.com  */
561*12004Sjiang.liu@intel.com /*ARGSUSED*/
562*12004Sjiang.liu@intel.com int
dr_pre_release_mem(dr_handle_t * hp,dr_common_unit_t ** devlist,int devnum)563*12004Sjiang.liu@intel.com dr_pre_release_mem(dr_handle_t *hp, dr_common_unit_t **devlist, int devnum)
564*12004Sjiang.liu@intel.com {
565*12004Sjiang.liu@intel.com 	return (-1);
566*12004Sjiang.liu@intel.com }
567*12004Sjiang.liu@intel.com 
568*12004Sjiang.liu@intel.com /*ARGSUSED*/
569*12004Sjiang.liu@intel.com void
dr_release_mem_done(dr_common_unit_t * cp)570*12004Sjiang.liu@intel.com dr_release_mem_done(dr_common_unit_t *cp)
571*12004Sjiang.liu@intel.com {
572*12004Sjiang.liu@intel.com }
573*12004Sjiang.liu@intel.com 
574*12004Sjiang.liu@intel.com /*ARGSUSED*/
575*12004Sjiang.liu@intel.com int
dr_disconnect_mem(dr_mem_unit_t * mp)576*12004Sjiang.liu@intel.com dr_disconnect_mem(dr_mem_unit_t *mp)
577*12004Sjiang.liu@intel.com {
578*12004Sjiang.liu@intel.com 	return (-1);
579*12004Sjiang.liu@intel.com }
580*12004Sjiang.liu@intel.com 
581*12004Sjiang.liu@intel.com /*ARGSUSED*/
582*12004Sjiang.liu@intel.com int
dr_cancel_mem(dr_mem_unit_t * s_mp)583*12004Sjiang.liu@intel.com dr_cancel_mem(dr_mem_unit_t *s_mp)
584*12004Sjiang.liu@intel.com {
585*12004Sjiang.liu@intel.com 	return (-1);
586*12004Sjiang.liu@intel.com }
587*12004Sjiang.liu@intel.com 
588*12004Sjiang.liu@intel.com void
dr_init_mem_unit(dr_mem_unit_t * mp)589*12004Sjiang.liu@intel.com dr_init_mem_unit(dr_mem_unit_t *mp)
590*12004Sjiang.liu@intel.com {
591*12004Sjiang.liu@intel.com 	dr_state_t	new_state;
592*12004Sjiang.liu@intel.com 
593*12004Sjiang.liu@intel.com 	if (DR_DEV_IS_ATTACHED(&mp->sbm_cm)) {
594*12004Sjiang.liu@intel.com 		new_state = DR_STATE_CONFIGURED;
595*12004Sjiang.liu@intel.com 		mp->sbm_cm.sbdev_cond = SBD_COND_OK;
596*12004Sjiang.liu@intel.com 	} else if (DR_DEV_IS_PRESENT(&mp->sbm_cm)) {
597*12004Sjiang.liu@intel.com 		new_state = DR_STATE_CONNECTED;
598*12004Sjiang.liu@intel.com 		mp->sbm_cm.sbdev_cond = SBD_COND_OK;
599*12004Sjiang.liu@intel.com 	} else if (mp->sbm_cm.sbdev_id != (drmachid_t)0) {
600*12004Sjiang.liu@intel.com 		new_state = DR_STATE_OCCUPIED;
601*12004Sjiang.liu@intel.com 	} else {
602*12004Sjiang.liu@intel.com 		new_state = DR_STATE_EMPTY;
603*12004Sjiang.liu@intel.com 	}
604*12004Sjiang.liu@intel.com 
605*12004Sjiang.liu@intel.com 	if (DR_DEV_IS_PRESENT(&mp->sbm_cm))
606*12004Sjiang.liu@intel.com 		dr_init_mem_unit_data(mp);
607*12004Sjiang.liu@intel.com 
608*12004Sjiang.liu@intel.com 	/* delay transition until fully initialized */
609*12004Sjiang.liu@intel.com 	dr_device_transition(&mp->sbm_cm, new_state);
610*12004Sjiang.liu@intel.com }
611*12004Sjiang.liu@intel.com 
612*12004Sjiang.liu@intel.com static void
dr_init_mem_unit_data(dr_mem_unit_t * mp)613*12004Sjiang.liu@intel.com dr_init_mem_unit_data(dr_mem_unit_t *mp)
614*12004Sjiang.liu@intel.com {
615*12004Sjiang.liu@intel.com 	drmachid_t	id = mp->sbm_cm.sbdev_id;
616*12004Sjiang.liu@intel.com 	drmach_mem_info_t	minfo;
617*12004Sjiang.liu@intel.com 	sbd_error_t	*err;
618*12004Sjiang.liu@intel.com 	static fn_t	f = "dr_init_mem_unit_data";
619*12004Sjiang.liu@intel.com 
620*12004Sjiang.liu@intel.com 	PR_MEM("%s...\n", f);
621*12004Sjiang.liu@intel.com 
622*12004Sjiang.liu@intel.com 	/* a little sanity checking */
623*12004Sjiang.liu@intel.com 	ASSERT(mp->sbm_peer == NULL);
624*12004Sjiang.liu@intel.com 	ASSERT(mp->sbm_flags == 0);
625*12004Sjiang.liu@intel.com 
626*12004Sjiang.liu@intel.com 	if (err = drmach_mem_get_info(id, &minfo)) {
627*12004Sjiang.liu@intel.com 		DRERR_SET_C(&mp->sbm_cm.sbdev_error, &err);
628*12004Sjiang.liu@intel.com 		return;
629*12004Sjiang.liu@intel.com 	}
630*12004Sjiang.liu@intel.com 	mp->sbm_basepfn = _b64top(minfo.mi_basepa);
631*12004Sjiang.liu@intel.com 	mp->sbm_npages = _b64top(minfo.mi_size);
632*12004Sjiang.liu@intel.com 	mp->sbm_alignment_mask = minfo.mi_alignment_mask;
633*12004Sjiang.liu@intel.com 	mp->sbm_slice_base = minfo.mi_slice_base;
634*12004Sjiang.liu@intel.com 	mp->sbm_slice_top = minfo.mi_slice_top;
635*12004Sjiang.liu@intel.com 	mp->sbm_slice_size = minfo.mi_slice_size;
636*12004Sjiang.liu@intel.com 
637*12004Sjiang.liu@intel.com 	PR_MEM("%s: %s (basepfn = 0x%lx, npgs = %ld)\n",
638*12004Sjiang.liu@intel.com 	    f, mp->sbm_cm.sbdev_path, mp->sbm_basepfn, mp->sbm_npages);
639*12004Sjiang.liu@intel.com }
640