1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright (c) 2000-2001 by Sun Microsystems, Inc.
24*7c478bd9Sstevel@tonic-gate  * All rights reserved.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate /*
30*7c478bd9Sstevel@tonic-gate  * Routines for traversing and packing/unpacking the handle
31*7c478bd9Sstevel@tonic-gate  * returned from ri_init.
32*7c478bd9Sstevel@tonic-gate  */
33*7c478bd9Sstevel@tonic-gate 
34*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
35*7c478bd9Sstevel@tonic-gate #include <strings.h>
36*7c478bd9Sstevel@tonic-gate #include "rsrc_info.h"
37*7c478bd9Sstevel@tonic-gate #include "rsrc_info_impl.h"
38*7c478bd9Sstevel@tonic-gate 
39*7c478bd9Sstevel@tonic-gate static int ap_list_pack(ri_ap_t *, char **, size_t *);
40*7c478bd9Sstevel@tonic-gate static int ap_list_unpack(char *, size_t, ri_ap_t **);
41*7c478bd9Sstevel@tonic-gate static int ap_pack(ri_ap_t *, char **, size_t *);
42*7c478bd9Sstevel@tonic-gate static int ap_unpack(char *, size_t, ri_ap_t *);
43*7c478bd9Sstevel@tonic-gate static int dev_list_pack(ri_dev_t *, char **, size_t *);
44*7c478bd9Sstevel@tonic-gate static int dev_list_unpack(char *, size_t, ri_dev_t **);
45*7c478bd9Sstevel@tonic-gate static int dev_pack(ri_dev_t *, char **, size_t *);
46*7c478bd9Sstevel@tonic-gate static int dev_unpack(char *, size_t, ri_dev_t *);
47*7c478bd9Sstevel@tonic-gate static int client_list_pack(ri_client_t *, char **, size_t *);
48*7c478bd9Sstevel@tonic-gate static int client_list_unpack(char *, size_t, ri_client_t **);
49*7c478bd9Sstevel@tonic-gate static int client_pack(ri_client_t *, char **, size_t *);
50*7c478bd9Sstevel@tonic-gate static int client_unpack(char *, size_t, ri_client_t *);
51*7c478bd9Sstevel@tonic-gate static int pack_add_byte_array(nvlist_t *, char *, nvlist_t *);
52*7c478bd9Sstevel@tonic-gate static int lookup_unpack_byte_array(nvlist_t *, char *, nvlist_t **);
53*7c478bd9Sstevel@tonic-gate static void ri_ap_free(ri_ap_t *);
54*7c478bd9Sstevel@tonic-gate 
55*7c478bd9Sstevel@tonic-gate void
56*7c478bd9Sstevel@tonic-gate ri_fini(ri_hdl_t *hdl)
57*7c478bd9Sstevel@tonic-gate {
58*7c478bd9Sstevel@tonic-gate 	ri_ap_t		*ap;
59*7c478bd9Sstevel@tonic-gate 	ri_client_t	*client;
60*7c478bd9Sstevel@tonic-gate 
61*7c478bd9Sstevel@tonic-gate 	if (hdl == NULL)
62*7c478bd9Sstevel@tonic-gate 		return;
63*7c478bd9Sstevel@tonic-gate 
64*7c478bd9Sstevel@tonic-gate 	while ((ap = hdl->aps) != NULL) {
65*7c478bd9Sstevel@tonic-gate 		hdl->aps = ap->next;
66*7c478bd9Sstevel@tonic-gate 		ri_ap_free(ap);
67*7c478bd9Sstevel@tonic-gate 	}
68*7c478bd9Sstevel@tonic-gate 	while ((client = hdl->cpu_cap_clients) != NULL) {
69*7c478bd9Sstevel@tonic-gate 		hdl->cpu_cap_clients = client->next;
70*7c478bd9Sstevel@tonic-gate 		ri_client_free(client);
71*7c478bd9Sstevel@tonic-gate 	}
72*7c478bd9Sstevel@tonic-gate 	while ((client = hdl->mem_cap_clients) != NULL) {
73*7c478bd9Sstevel@tonic-gate 		hdl->mem_cap_clients = client->next;
74*7c478bd9Sstevel@tonic-gate 		ri_client_free(client);
75*7c478bd9Sstevel@tonic-gate 	}
76*7c478bd9Sstevel@tonic-gate 	free(hdl);
77*7c478bd9Sstevel@tonic-gate }
78*7c478bd9Sstevel@tonic-gate 
79*7c478bd9Sstevel@tonic-gate static void
80*7c478bd9Sstevel@tonic-gate ri_ap_free(ri_ap_t *ap)
81*7c478bd9Sstevel@tonic-gate {
82*7c478bd9Sstevel@tonic-gate 	ri_dev_t	*dev;
83*7c478bd9Sstevel@tonic-gate 
84*7c478bd9Sstevel@tonic-gate 	assert(ap != NULL);
85*7c478bd9Sstevel@tonic-gate 
86*7c478bd9Sstevel@tonic-gate 	if (ap->conf_props != NULL)
87*7c478bd9Sstevel@tonic-gate 		nvlist_free(ap->conf_props);
88*7c478bd9Sstevel@tonic-gate 
89*7c478bd9Sstevel@tonic-gate 	while ((dev = ap->cpus) != NULL) {
90*7c478bd9Sstevel@tonic-gate 		ap->cpus = dev->next;
91*7c478bd9Sstevel@tonic-gate 		ri_dev_free(dev);
92*7c478bd9Sstevel@tonic-gate 	}
93*7c478bd9Sstevel@tonic-gate 	while ((dev = ap->mems) != NULL) {
94*7c478bd9Sstevel@tonic-gate 		ap->mems = dev->next;
95*7c478bd9Sstevel@tonic-gate 		ri_dev_free(dev);
96*7c478bd9Sstevel@tonic-gate 	}
97*7c478bd9Sstevel@tonic-gate 	while ((dev = ap->ios) != NULL) {
98*7c478bd9Sstevel@tonic-gate 		ap->ios = dev->next;
99*7c478bd9Sstevel@tonic-gate 		ri_dev_free(dev);
100*7c478bd9Sstevel@tonic-gate 	}
101*7c478bd9Sstevel@tonic-gate 	free(ap);
102*7c478bd9Sstevel@tonic-gate }
103*7c478bd9Sstevel@tonic-gate 
104*7c478bd9Sstevel@tonic-gate void
105*7c478bd9Sstevel@tonic-gate ri_dev_free(ri_dev_t *dev)
106*7c478bd9Sstevel@tonic-gate {
107*7c478bd9Sstevel@tonic-gate 	ri_client_t	*client;
108*7c478bd9Sstevel@tonic-gate 
109*7c478bd9Sstevel@tonic-gate 	assert(dev != NULL);
110*7c478bd9Sstevel@tonic-gate 
111*7c478bd9Sstevel@tonic-gate 	nvlist_free(dev->conf_props);
112*7c478bd9Sstevel@tonic-gate 	while ((client = dev->rcm_clients) != NULL) {
113*7c478bd9Sstevel@tonic-gate 		dev->rcm_clients = client->next;
114*7c478bd9Sstevel@tonic-gate 		ri_client_free(client);
115*7c478bd9Sstevel@tonic-gate 	}
116*7c478bd9Sstevel@tonic-gate 	free(dev);
117*7c478bd9Sstevel@tonic-gate }
118*7c478bd9Sstevel@tonic-gate 
119*7c478bd9Sstevel@tonic-gate void
120*7c478bd9Sstevel@tonic-gate ri_client_free(ri_client_t *client)
121*7c478bd9Sstevel@tonic-gate {
122*7c478bd9Sstevel@tonic-gate 	assert(client != NULL);
123*7c478bd9Sstevel@tonic-gate 
124*7c478bd9Sstevel@tonic-gate 	if (client->usg_props != NULL)
125*7c478bd9Sstevel@tonic-gate 		nvlist_free(client->usg_props);
126*7c478bd9Sstevel@tonic-gate 	if (client->v_props != NULL)
127*7c478bd9Sstevel@tonic-gate 		nvlist_free(client->v_props);
128*7c478bd9Sstevel@tonic-gate 	free(client);
129*7c478bd9Sstevel@tonic-gate }
130*7c478bd9Sstevel@tonic-gate 
131*7c478bd9Sstevel@tonic-gate /*
132*7c478bd9Sstevel@tonic-gate  * Pack everything contained in the handle up inside out.
133*7c478bd9Sstevel@tonic-gate  */
134*7c478bd9Sstevel@tonic-gate int
135*7c478bd9Sstevel@tonic-gate ri_pack(ri_hdl_t *hdl, caddr_t *bufp, size_t *sizep)
136*7c478bd9Sstevel@tonic-gate {
137*7c478bd9Sstevel@tonic-gate 	nvlist_t	*nvl = NULL;
138*7c478bd9Sstevel@tonic-gate 	char		*buf = NULL;
139*7c478bd9Sstevel@tonic-gate 	size_t		size = 0;
140*7c478bd9Sstevel@tonic-gate 
141*7c478bd9Sstevel@tonic-gate 	if (bufp == NULL || sizep == NULL)
142*7c478bd9Sstevel@tonic-gate 		return (RI_INVAL);
143*7c478bd9Sstevel@tonic-gate 
144*7c478bd9Sstevel@tonic-gate 	*sizep = 0;
145*7c478bd9Sstevel@tonic-gate 	*bufp = NULL;
146*7c478bd9Sstevel@tonic-gate 
147*7c478bd9Sstevel@tonic-gate 	/*
148*7c478bd9Sstevel@tonic-gate 	 * Check the handle. If it is NULL, there
149*7c478bd9Sstevel@tonic-gate 	 * is nothing to pack, so we are done.
150*7c478bd9Sstevel@tonic-gate 	 */
151*7c478bd9Sstevel@tonic-gate 	if (hdl == NULL) {
152*7c478bd9Sstevel@tonic-gate 		return (RI_SUCCESS);
153*7c478bd9Sstevel@tonic-gate 	}
154*7c478bd9Sstevel@tonic-gate 
155*7c478bd9Sstevel@tonic-gate 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
156*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_alloc fail\n", errno));
157*7c478bd9Sstevel@tonic-gate 		goto fail;
158*7c478bd9Sstevel@tonic-gate 	}
159*7c478bd9Sstevel@tonic-gate 
160*7c478bd9Sstevel@tonic-gate 	if (nvlist_add_int32(nvl, RI_HDL_FLAGS, hdl->flags) != 0) {
161*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_add_int32 fail\n"));
162*7c478bd9Sstevel@tonic-gate 		goto fail;
163*7c478bd9Sstevel@tonic-gate 	}
164*7c478bd9Sstevel@tonic-gate 
165*7c478bd9Sstevel@tonic-gate 	if (ap_list_pack(hdl->aps, &buf, &size) != 0 ||
166*7c478bd9Sstevel@tonic-gate 	    nvlist_add_byte_array(nvl, RI_HDL_APS, (uchar_t *)buf, size) != 0) {
167*7c478bd9Sstevel@tonic-gate 		goto fail;
168*7c478bd9Sstevel@tonic-gate 	}
169*7c478bd9Sstevel@tonic-gate 
170*7c478bd9Sstevel@tonic-gate 	s_free(buf);
171*7c478bd9Sstevel@tonic-gate 	if (client_list_pack(hdl->cpu_cap_clients, &buf, &size) != 0 ||
172*7c478bd9Sstevel@tonic-gate 	    nvlist_add_byte_array(nvl, RI_HDL_CPU_CAPS, (uchar_t *)buf,
173*7c478bd9Sstevel@tonic-gate 	    size) != 0) {
174*7c478bd9Sstevel@tonic-gate 		goto fail;
175*7c478bd9Sstevel@tonic-gate 	}
176*7c478bd9Sstevel@tonic-gate 
177*7c478bd9Sstevel@tonic-gate 	s_free(buf);
178*7c478bd9Sstevel@tonic-gate 	if (client_list_pack(hdl->mem_cap_clients, &buf, &size) != 0 ||
179*7c478bd9Sstevel@tonic-gate 	    nvlist_add_byte_array(nvl, RI_HDL_MEM_CAPS, (uchar_t *)buf,
180*7c478bd9Sstevel@tonic-gate 	    size) != 0) {
181*7c478bd9Sstevel@tonic-gate 		goto fail;
182*7c478bd9Sstevel@tonic-gate 	}
183*7c478bd9Sstevel@tonic-gate 
184*7c478bd9Sstevel@tonic-gate 	s_free(buf);
185*7c478bd9Sstevel@tonic-gate 	if (nvlist_pack(nvl, &buf, &size, NV_ENCODE_NATIVE, 0) != 0) {
186*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_pack fail\n"));
187*7c478bd9Sstevel@tonic-gate 		goto fail;
188*7c478bd9Sstevel@tonic-gate 	}
189*7c478bd9Sstevel@tonic-gate 
190*7c478bd9Sstevel@tonic-gate 	nvlist_free(nvl);
191*7c478bd9Sstevel@tonic-gate 	*bufp = buf;
192*7c478bd9Sstevel@tonic-gate 	*sizep = size;
193*7c478bd9Sstevel@tonic-gate 
194*7c478bd9Sstevel@tonic-gate 	return (RI_SUCCESS);
195*7c478bd9Sstevel@tonic-gate 
196*7c478bd9Sstevel@tonic-gate fail:
197*7c478bd9Sstevel@tonic-gate 	s_free(buf);
198*7c478bd9Sstevel@tonic-gate 	if (nvl != NULL)
199*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
200*7c478bd9Sstevel@tonic-gate 
201*7c478bd9Sstevel@tonic-gate 	return (RI_FAILURE);
202*7c478bd9Sstevel@tonic-gate }
203*7c478bd9Sstevel@tonic-gate 
204*7c478bd9Sstevel@tonic-gate /*
205*7c478bd9Sstevel@tonic-gate  * Pack a list of attachment point handles.
206*7c478bd9Sstevel@tonic-gate  */
207*7c478bd9Sstevel@tonic-gate static int
208*7c478bd9Sstevel@tonic-gate ap_list_pack(ri_ap_t *aplist, char **bufp, size_t *sizep)
209*7c478bd9Sstevel@tonic-gate {
210*7c478bd9Sstevel@tonic-gate 	nvlist_t	*nvl = NULL;
211*7c478bd9Sstevel@tonic-gate 	char		*buf = NULL;
212*7c478bd9Sstevel@tonic-gate 	size_t		size;
213*7c478bd9Sstevel@tonic-gate 
214*7c478bd9Sstevel@tonic-gate 	assert(bufp != NULL && sizep != NULL);
215*7c478bd9Sstevel@tonic-gate 
216*7c478bd9Sstevel@tonic-gate 	*sizep = 0;
217*7c478bd9Sstevel@tonic-gate 	*bufp = NULL;
218*7c478bd9Sstevel@tonic-gate 
219*7c478bd9Sstevel@tonic-gate 	if (nvlist_alloc(&nvl, 0, 0) != 0) {
220*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_alloc fail\n"));
221*7c478bd9Sstevel@tonic-gate 		return (-1);
222*7c478bd9Sstevel@tonic-gate 	}
223*7c478bd9Sstevel@tonic-gate 
224*7c478bd9Sstevel@tonic-gate 	while (aplist != NULL) {
225*7c478bd9Sstevel@tonic-gate 		s_free(buf);
226*7c478bd9Sstevel@tonic-gate 		if (ap_pack(aplist, &buf, &size) != 0)
227*7c478bd9Sstevel@tonic-gate 			goto fail;
228*7c478bd9Sstevel@tonic-gate 
229*7c478bd9Sstevel@tonic-gate 		if (nvlist_add_byte_array(nvl, RI_AP_T, (uchar_t *)buf,
230*7c478bd9Sstevel@tonic-gate 		    size) != 0) {
231*7c478bd9Sstevel@tonic-gate 			dprintf((stderr, "nvlist_add_byte_array fail "
232*7c478bd9Sstevel@tonic-gate 			    "(%s)\n", RI_AP_T));
233*7c478bd9Sstevel@tonic-gate 			goto fail;
234*7c478bd9Sstevel@tonic-gate 		}
235*7c478bd9Sstevel@tonic-gate 		aplist = aplist->next;
236*7c478bd9Sstevel@tonic-gate 	}
237*7c478bd9Sstevel@tonic-gate 
238*7c478bd9Sstevel@tonic-gate 	s_free(buf);
239*7c478bd9Sstevel@tonic-gate 	if (nvlist_pack(nvl, &buf, &size, NV_ENCODE_NATIVE, 0) != 0) {
240*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_pack fail\n"));
241*7c478bd9Sstevel@tonic-gate 		goto fail;
242*7c478bd9Sstevel@tonic-gate 	}
243*7c478bd9Sstevel@tonic-gate 
244*7c478bd9Sstevel@tonic-gate 	nvlist_free(nvl);
245*7c478bd9Sstevel@tonic-gate 	*bufp = buf;
246*7c478bd9Sstevel@tonic-gate 	*sizep = size;
247*7c478bd9Sstevel@tonic-gate 
248*7c478bd9Sstevel@tonic-gate 	return (0);
249*7c478bd9Sstevel@tonic-gate 
250*7c478bd9Sstevel@tonic-gate fail:
251*7c478bd9Sstevel@tonic-gate 	s_free(buf);
252*7c478bd9Sstevel@tonic-gate 	if (nvl != NULL)
253*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
254*7c478bd9Sstevel@tonic-gate 
255*7c478bd9Sstevel@tonic-gate 	return (-1);
256*7c478bd9Sstevel@tonic-gate }
257*7c478bd9Sstevel@tonic-gate 
258*7c478bd9Sstevel@tonic-gate /*
259*7c478bd9Sstevel@tonic-gate  * Pack a list of ri_dev_t's.
260*7c478bd9Sstevel@tonic-gate  */
261*7c478bd9Sstevel@tonic-gate static int
262*7c478bd9Sstevel@tonic-gate dev_list_pack(ri_dev_t *devlist, char **bufp, size_t *sizep)
263*7c478bd9Sstevel@tonic-gate {
264*7c478bd9Sstevel@tonic-gate 	nvlist_t	*nvl = NULL;
265*7c478bd9Sstevel@tonic-gate 	char		*buf = NULL;
266*7c478bd9Sstevel@tonic-gate 	size_t		size = 0;
267*7c478bd9Sstevel@tonic-gate 
268*7c478bd9Sstevel@tonic-gate 	assert(bufp != NULL && sizep != NULL);
269*7c478bd9Sstevel@tonic-gate 
270*7c478bd9Sstevel@tonic-gate 	*sizep = 0;
271*7c478bd9Sstevel@tonic-gate 	*bufp = NULL;
272*7c478bd9Sstevel@tonic-gate 
273*7c478bd9Sstevel@tonic-gate 	if (nvlist_alloc(&nvl, 0, 0) != 0) {
274*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_alloc fail\n"));
275*7c478bd9Sstevel@tonic-gate 		return (-1);
276*7c478bd9Sstevel@tonic-gate 	}
277*7c478bd9Sstevel@tonic-gate 
278*7c478bd9Sstevel@tonic-gate 	while (devlist != NULL) {
279*7c478bd9Sstevel@tonic-gate 		s_free(buf);
280*7c478bd9Sstevel@tonic-gate 		if (dev_pack(devlist, &buf, &size) != 0)
281*7c478bd9Sstevel@tonic-gate 			goto fail;
282*7c478bd9Sstevel@tonic-gate 
283*7c478bd9Sstevel@tonic-gate 		if (nvlist_add_byte_array(nvl, RI_DEV_T, (uchar_t *)buf,
284*7c478bd9Sstevel@tonic-gate 		    size) != 0) {
285*7c478bd9Sstevel@tonic-gate 			dprintf((stderr, "nvlist_add_byte_array fail "
286*7c478bd9Sstevel@tonic-gate 			    "(%s)\n", RI_DEV_T));
287*7c478bd9Sstevel@tonic-gate 			goto fail;
288*7c478bd9Sstevel@tonic-gate 		}
289*7c478bd9Sstevel@tonic-gate 		devlist = devlist->next;
290*7c478bd9Sstevel@tonic-gate 	}
291*7c478bd9Sstevel@tonic-gate 
292*7c478bd9Sstevel@tonic-gate 	s_free(buf);
293*7c478bd9Sstevel@tonic-gate 	if (nvlist_pack(nvl, &buf, &size, NV_ENCODE_NATIVE, 0) != 0) {
294*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_pack fail\n"));
295*7c478bd9Sstevel@tonic-gate 		goto fail;
296*7c478bd9Sstevel@tonic-gate 	}
297*7c478bd9Sstevel@tonic-gate 
298*7c478bd9Sstevel@tonic-gate 	nvlist_free(nvl);
299*7c478bd9Sstevel@tonic-gate 	*bufp = buf;
300*7c478bd9Sstevel@tonic-gate 	*sizep = size;
301*7c478bd9Sstevel@tonic-gate 
302*7c478bd9Sstevel@tonic-gate 	return (0);
303*7c478bd9Sstevel@tonic-gate 
304*7c478bd9Sstevel@tonic-gate fail:
305*7c478bd9Sstevel@tonic-gate 	s_free(buf);
306*7c478bd9Sstevel@tonic-gate 	if (nvl != NULL)
307*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
308*7c478bd9Sstevel@tonic-gate 
309*7c478bd9Sstevel@tonic-gate 	return (-1);
310*7c478bd9Sstevel@tonic-gate }
311*7c478bd9Sstevel@tonic-gate 
312*7c478bd9Sstevel@tonic-gate /*
313*7c478bd9Sstevel@tonic-gate  * Pack a list of ri_client_t's.
314*7c478bd9Sstevel@tonic-gate  */
315*7c478bd9Sstevel@tonic-gate static int
316*7c478bd9Sstevel@tonic-gate client_list_pack(ri_client_t *client_list, char **bufp, size_t *sizep)
317*7c478bd9Sstevel@tonic-gate {
318*7c478bd9Sstevel@tonic-gate 	nvlist_t	*nvl = NULL;
319*7c478bd9Sstevel@tonic-gate 	char		*buf = NULL;
320*7c478bd9Sstevel@tonic-gate 	size_t		size = 0;
321*7c478bd9Sstevel@tonic-gate 
322*7c478bd9Sstevel@tonic-gate 	assert(bufp != NULL && sizep != NULL);
323*7c478bd9Sstevel@tonic-gate 
324*7c478bd9Sstevel@tonic-gate 	*sizep = 0;
325*7c478bd9Sstevel@tonic-gate 	*bufp = NULL;
326*7c478bd9Sstevel@tonic-gate 
327*7c478bd9Sstevel@tonic-gate 	if (nvlist_alloc(&nvl, 0, 0) != 0) {
328*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_alloc fail\n"));
329*7c478bd9Sstevel@tonic-gate 		return (-1);
330*7c478bd9Sstevel@tonic-gate 	}
331*7c478bd9Sstevel@tonic-gate 
332*7c478bd9Sstevel@tonic-gate 	while (client_list != NULL) {
333*7c478bd9Sstevel@tonic-gate 		s_free(buf);
334*7c478bd9Sstevel@tonic-gate 		if (client_pack(client_list, &buf, &size) != 0)
335*7c478bd9Sstevel@tonic-gate 			goto fail;
336*7c478bd9Sstevel@tonic-gate 
337*7c478bd9Sstevel@tonic-gate 		if (nvlist_add_byte_array(nvl, RI_CLIENT_T, (uchar_t *)buf,
338*7c478bd9Sstevel@tonic-gate 		    size) != 0) {
339*7c478bd9Sstevel@tonic-gate 			dprintf((stderr, "nvlist_add_byte_array fail "
340*7c478bd9Sstevel@tonic-gate 			    "(%s)\n", RI_CLIENT_T));
341*7c478bd9Sstevel@tonic-gate 			goto fail;
342*7c478bd9Sstevel@tonic-gate 		}
343*7c478bd9Sstevel@tonic-gate 		client_list = client_list->next;
344*7c478bd9Sstevel@tonic-gate 	}
345*7c478bd9Sstevel@tonic-gate 
346*7c478bd9Sstevel@tonic-gate 	s_free(buf);
347*7c478bd9Sstevel@tonic-gate 	if (nvlist_pack(nvl, &buf, &size, NV_ENCODE_NATIVE, 0) != 0) {
348*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_pack fail\n"));
349*7c478bd9Sstevel@tonic-gate 		goto fail;
350*7c478bd9Sstevel@tonic-gate 	}
351*7c478bd9Sstevel@tonic-gate 
352*7c478bd9Sstevel@tonic-gate 	nvlist_free(nvl);
353*7c478bd9Sstevel@tonic-gate 	*bufp = buf;
354*7c478bd9Sstevel@tonic-gate 	*sizep = size;
355*7c478bd9Sstevel@tonic-gate 
356*7c478bd9Sstevel@tonic-gate 	return (0);
357*7c478bd9Sstevel@tonic-gate 
358*7c478bd9Sstevel@tonic-gate fail:
359*7c478bd9Sstevel@tonic-gate 	s_free(buf);
360*7c478bd9Sstevel@tonic-gate 	if (nvl != NULL)
361*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
362*7c478bd9Sstevel@tonic-gate 
363*7c478bd9Sstevel@tonic-gate 	return (-1);
364*7c478bd9Sstevel@tonic-gate }
365*7c478bd9Sstevel@tonic-gate 
366*7c478bd9Sstevel@tonic-gate static int
367*7c478bd9Sstevel@tonic-gate ap_pack(ri_ap_t *ap, char **bufp, size_t *sizep)
368*7c478bd9Sstevel@tonic-gate {
369*7c478bd9Sstevel@tonic-gate 	nvlist_t	*nvl = NULL;
370*7c478bd9Sstevel@tonic-gate 	char		*buf = NULL;
371*7c478bd9Sstevel@tonic-gate 	size_t		size = 0;
372*7c478bd9Sstevel@tonic-gate 
373*7c478bd9Sstevel@tonic-gate 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
374*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_alloc fail\n"));
375*7c478bd9Sstevel@tonic-gate 		return (-1);
376*7c478bd9Sstevel@tonic-gate 	}
377*7c478bd9Sstevel@tonic-gate 
378*7c478bd9Sstevel@tonic-gate 	if (pack_add_byte_array(ap->conf_props, RI_AP_PROPS, nvl) != 0)
379*7c478bd9Sstevel@tonic-gate 		goto fail;
380*7c478bd9Sstevel@tonic-gate 
381*7c478bd9Sstevel@tonic-gate 	if (dev_list_pack(ap->cpus, &buf, &size) != 0)
382*7c478bd9Sstevel@tonic-gate 		goto fail;
383*7c478bd9Sstevel@tonic-gate 
384*7c478bd9Sstevel@tonic-gate 	if (nvlist_add_byte_array(nvl, RI_AP_CPUS, (uchar_t *)buf,
385*7c478bd9Sstevel@tonic-gate 	    size) != 0) {
386*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_add_byte_array (%s)\n", RI_AP_CPUS));
387*7c478bd9Sstevel@tonic-gate 		goto fail;
388*7c478bd9Sstevel@tonic-gate 	}
389*7c478bd9Sstevel@tonic-gate 
390*7c478bd9Sstevel@tonic-gate 	s_free(buf);
391*7c478bd9Sstevel@tonic-gate 	if (dev_list_pack(ap->mems, &buf, &size) != 0)
392*7c478bd9Sstevel@tonic-gate 		goto fail;
393*7c478bd9Sstevel@tonic-gate 
394*7c478bd9Sstevel@tonic-gate 	if (nvlist_add_byte_array(nvl, RI_AP_MEMS, (uchar_t *)buf,
395*7c478bd9Sstevel@tonic-gate 	    size) != 0) {
396*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_add_byte_array (%s)n", RI_AP_MEMS));
397*7c478bd9Sstevel@tonic-gate 		goto fail;
398*7c478bd9Sstevel@tonic-gate 	}
399*7c478bd9Sstevel@tonic-gate 
400*7c478bd9Sstevel@tonic-gate 	s_free(buf);
401*7c478bd9Sstevel@tonic-gate 	if (dev_list_pack(ap->ios, &buf, &size) != 0)
402*7c478bd9Sstevel@tonic-gate 		goto fail;
403*7c478bd9Sstevel@tonic-gate 
404*7c478bd9Sstevel@tonic-gate 	if (nvlist_add_byte_array(nvl, RI_AP_IOS, (uchar_t *)buf,
405*7c478bd9Sstevel@tonic-gate 	    size) != 0) {
406*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_add_byte_array (%s)n", RI_AP_IOS));
407*7c478bd9Sstevel@tonic-gate 		goto fail;
408*7c478bd9Sstevel@tonic-gate 	}
409*7c478bd9Sstevel@tonic-gate 
410*7c478bd9Sstevel@tonic-gate 	s_free(buf);
411*7c478bd9Sstevel@tonic-gate 	if (nvlist_pack(nvl, &buf, &size, NV_ENCODE_NATIVE, 0) != 0) {
412*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_pack fail\n"));
413*7c478bd9Sstevel@tonic-gate 		goto fail;
414*7c478bd9Sstevel@tonic-gate 	}
415*7c478bd9Sstevel@tonic-gate 
416*7c478bd9Sstevel@tonic-gate 	nvlist_free(nvl);
417*7c478bd9Sstevel@tonic-gate 	*bufp = buf;
418*7c478bd9Sstevel@tonic-gate 	*sizep = size;
419*7c478bd9Sstevel@tonic-gate 
420*7c478bd9Sstevel@tonic-gate 	return (0);
421*7c478bd9Sstevel@tonic-gate 
422*7c478bd9Sstevel@tonic-gate fail:
423*7c478bd9Sstevel@tonic-gate 	s_free(buf);
424*7c478bd9Sstevel@tonic-gate 	if (nvl != NULL)
425*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
426*7c478bd9Sstevel@tonic-gate 
427*7c478bd9Sstevel@tonic-gate 	return (-1);
428*7c478bd9Sstevel@tonic-gate }
429*7c478bd9Sstevel@tonic-gate 
430*7c478bd9Sstevel@tonic-gate static int
431*7c478bd9Sstevel@tonic-gate dev_pack(ri_dev_t *dev, char **bufp, size_t *sizep)
432*7c478bd9Sstevel@tonic-gate {
433*7c478bd9Sstevel@tonic-gate 	nvlist_t	*nvl = NULL;
434*7c478bd9Sstevel@tonic-gate 	char		*buf = NULL;
435*7c478bd9Sstevel@tonic-gate 	size_t		size = 0;
436*7c478bd9Sstevel@tonic-gate 
437*7c478bd9Sstevel@tonic-gate 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
438*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_alloc fail\n"));
439*7c478bd9Sstevel@tonic-gate 		return (-1);
440*7c478bd9Sstevel@tonic-gate 	}
441*7c478bd9Sstevel@tonic-gate 
442*7c478bd9Sstevel@tonic-gate 	if (pack_add_byte_array(dev->conf_props, RI_DEV_PROPS, nvl) != 0)
443*7c478bd9Sstevel@tonic-gate 		goto fail;
444*7c478bd9Sstevel@tonic-gate 
445*7c478bd9Sstevel@tonic-gate 	if (client_list_pack(dev->rcm_clients, &buf, &size) != 0)
446*7c478bd9Sstevel@tonic-gate 		goto fail;
447*7c478bd9Sstevel@tonic-gate 
448*7c478bd9Sstevel@tonic-gate 	if (nvlist_add_byte_array(nvl, RI_DEV_CLIENTS, (uchar_t *)buf,
449*7c478bd9Sstevel@tonic-gate 	    size) != 0) {
450*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_add_byte_array (%s)n",
451*7c478bd9Sstevel@tonic-gate 		    RI_DEV_CLIENTS));
452*7c478bd9Sstevel@tonic-gate 		goto fail;
453*7c478bd9Sstevel@tonic-gate 	}
454*7c478bd9Sstevel@tonic-gate 
455*7c478bd9Sstevel@tonic-gate 	s_free(buf);
456*7c478bd9Sstevel@tonic-gate 	if (nvlist_pack(nvl, &buf, &size, NV_ENCODE_NATIVE, 0) != 0) {
457*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_pack fail\n"));
458*7c478bd9Sstevel@tonic-gate 		goto fail;
459*7c478bd9Sstevel@tonic-gate 	}
460*7c478bd9Sstevel@tonic-gate 
461*7c478bd9Sstevel@tonic-gate 	nvlist_free(nvl);
462*7c478bd9Sstevel@tonic-gate 	*bufp = buf;
463*7c478bd9Sstevel@tonic-gate 	*sizep = size;
464*7c478bd9Sstevel@tonic-gate 
465*7c478bd9Sstevel@tonic-gate 	return (0);
466*7c478bd9Sstevel@tonic-gate 
467*7c478bd9Sstevel@tonic-gate fail:
468*7c478bd9Sstevel@tonic-gate 	s_free(buf);
469*7c478bd9Sstevel@tonic-gate 	if (nvl != NULL)
470*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
471*7c478bd9Sstevel@tonic-gate 
472*7c478bd9Sstevel@tonic-gate 	return (-1);
473*7c478bd9Sstevel@tonic-gate }
474*7c478bd9Sstevel@tonic-gate 
475*7c478bd9Sstevel@tonic-gate static int
476*7c478bd9Sstevel@tonic-gate client_pack(ri_client_t *client, char **bufp, size_t *sizep)
477*7c478bd9Sstevel@tonic-gate {
478*7c478bd9Sstevel@tonic-gate 	nvlist_t	*nvl = NULL;
479*7c478bd9Sstevel@tonic-gate 	char		*buf = NULL;
480*7c478bd9Sstevel@tonic-gate 	size_t		size = 0;
481*7c478bd9Sstevel@tonic-gate 
482*7c478bd9Sstevel@tonic-gate 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
483*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_alloc fail\n"));
484*7c478bd9Sstevel@tonic-gate 		return (-1);
485*7c478bd9Sstevel@tonic-gate 	}
486*7c478bd9Sstevel@tonic-gate 
487*7c478bd9Sstevel@tonic-gate 	if (pack_add_byte_array(client->usg_props, RI_CLIENT_USAGE_PROPS,
488*7c478bd9Sstevel@tonic-gate 	    nvl) != 0) {
489*7c478bd9Sstevel@tonic-gate 		goto fail;
490*7c478bd9Sstevel@tonic-gate 	}
491*7c478bd9Sstevel@tonic-gate 
492*7c478bd9Sstevel@tonic-gate 	/*
493*7c478bd9Sstevel@tonic-gate 	 * This will only be present if RI_VERBOSE was specified
494*7c478bd9Sstevel@tonic-gate 	 * in the call to ri_init.
495*7c478bd9Sstevel@tonic-gate 	 */
496*7c478bd9Sstevel@tonic-gate 	if (client->v_props != NULL && pack_add_byte_array(client->v_props,
497*7c478bd9Sstevel@tonic-gate 	    RI_CLIENT_VERB_PROPS, nvl) != 0) {
498*7c478bd9Sstevel@tonic-gate 		goto fail;
499*7c478bd9Sstevel@tonic-gate 	}
500*7c478bd9Sstevel@tonic-gate 
501*7c478bd9Sstevel@tonic-gate 	if (nvlist_pack(nvl, &buf, &size, NV_ENCODE_NATIVE, 0) != 0) {
502*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_pack fail\n"));
503*7c478bd9Sstevel@tonic-gate 		goto fail;
504*7c478bd9Sstevel@tonic-gate 	}
505*7c478bd9Sstevel@tonic-gate 
506*7c478bd9Sstevel@tonic-gate 	nvlist_free(nvl);
507*7c478bd9Sstevel@tonic-gate 	*bufp = buf;
508*7c478bd9Sstevel@tonic-gate 	*sizep = size;
509*7c478bd9Sstevel@tonic-gate 
510*7c478bd9Sstevel@tonic-gate 	return (0);
511*7c478bd9Sstevel@tonic-gate 
512*7c478bd9Sstevel@tonic-gate fail:
513*7c478bd9Sstevel@tonic-gate 	s_free(buf);
514*7c478bd9Sstevel@tonic-gate 	if (nvl != NULL)
515*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
516*7c478bd9Sstevel@tonic-gate 
517*7c478bd9Sstevel@tonic-gate 	return (-1);
518*7c478bd9Sstevel@tonic-gate }
519*7c478bd9Sstevel@tonic-gate 
520*7c478bd9Sstevel@tonic-gate /*
521*7c478bd9Sstevel@tonic-gate  * Pack nvlist_t and add as byte array to another nvlist_t.
522*7c478bd9Sstevel@tonic-gate  */
523*7c478bd9Sstevel@tonic-gate static int
524*7c478bd9Sstevel@tonic-gate pack_add_byte_array(nvlist_t *nvl_packme, char *name, nvlist_t *nvl)
525*7c478bd9Sstevel@tonic-gate {
526*7c478bd9Sstevel@tonic-gate 	char	*buf = NULL;
527*7c478bd9Sstevel@tonic-gate 	size_t	size = 0;
528*7c478bd9Sstevel@tonic-gate 
529*7c478bd9Sstevel@tonic-gate 	if (nvlist_pack(nvl_packme, &buf, &size, NV_ENCODE_NATIVE, 0) != 0) {
530*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_pack fail (%s)\n", name));
531*7c478bd9Sstevel@tonic-gate 		s_free(buf);
532*7c478bd9Sstevel@tonic-gate 		return (-1);
533*7c478bd9Sstevel@tonic-gate 	}
534*7c478bd9Sstevel@tonic-gate 
535*7c478bd9Sstevel@tonic-gate 	if (nvlist_add_byte_array(nvl, name, (uchar_t *)buf, size) != 0) {
536*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_add_byte_array fail (%s)\n", name));
537*7c478bd9Sstevel@tonic-gate 		return (-1);
538*7c478bd9Sstevel@tonic-gate 	}
539*7c478bd9Sstevel@tonic-gate 
540*7c478bd9Sstevel@tonic-gate 	s_free(buf);
541*7c478bd9Sstevel@tonic-gate 	return (0);
542*7c478bd9Sstevel@tonic-gate }
543*7c478bd9Sstevel@tonic-gate 
544*7c478bd9Sstevel@tonic-gate /*
545*7c478bd9Sstevel@tonic-gate  * Unpack buf into ri_hdl_t.
546*7c478bd9Sstevel@tonic-gate  */
547*7c478bd9Sstevel@tonic-gate int
548*7c478bd9Sstevel@tonic-gate ri_unpack(caddr_t buf, size_t size, ri_hdl_t **hdlp)
549*7c478bd9Sstevel@tonic-gate {
550*7c478bd9Sstevel@tonic-gate 	ri_hdl_t	*ri_hdl = NULL;
551*7c478bd9Sstevel@tonic-gate 	nvlist_t	*nvl = NULL;
552*7c478bd9Sstevel@tonic-gate 
553*7c478bd9Sstevel@tonic-gate 	if (hdlp == NULL)
554*7c478bd9Sstevel@tonic-gate 		return (RI_INVAL);
555*7c478bd9Sstevel@tonic-gate 
556*7c478bd9Sstevel@tonic-gate 	*hdlp = NULL;
557*7c478bd9Sstevel@tonic-gate 	if ((ri_hdl = calloc(1, sizeof (*ri_hdl))) == NULL) {
558*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "calloc: %s\n", strerror(errno)));
559*7c478bd9Sstevel@tonic-gate 		return (RI_FAILURE);
560*7c478bd9Sstevel@tonic-gate 	}
561*7c478bd9Sstevel@tonic-gate 
562*7c478bd9Sstevel@tonic-gate 	if (nvlist_unpack(buf, size, &nvl, 0) != 0) {
563*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_unpack fail\n"));
564*7c478bd9Sstevel@tonic-gate 		goto fail;
565*7c478bd9Sstevel@tonic-gate 	}
566*7c478bd9Sstevel@tonic-gate 
567*7c478bd9Sstevel@tonic-gate 	if (nvlist_lookup_int32(nvl, RI_HDL_FLAGS, &ri_hdl->flags) != 0) {
568*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_lookup_int32 fail (%s)\n",
569*7c478bd9Sstevel@tonic-gate 		    RI_HDL_FLAGS));
570*7c478bd9Sstevel@tonic-gate 		goto fail;
571*7c478bd9Sstevel@tonic-gate 	}
572*7c478bd9Sstevel@tonic-gate 
573*7c478bd9Sstevel@tonic-gate 	buf = NULL;
574*7c478bd9Sstevel@tonic-gate 	size = 0;
575*7c478bd9Sstevel@tonic-gate 	if (nvlist_lookup_byte_array(nvl, RI_HDL_APS, (uchar_t **)&buf,
576*7c478bd9Sstevel@tonic-gate 	    (uint_t *)&size) != 0) {
577*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_lookup_int32 fail (%s)\n",
578*7c478bd9Sstevel@tonic-gate 		    RI_HDL_APS));
579*7c478bd9Sstevel@tonic-gate 		goto fail;
580*7c478bd9Sstevel@tonic-gate 	}
581*7c478bd9Sstevel@tonic-gate 
582*7c478bd9Sstevel@tonic-gate 	if (ap_list_unpack(buf, size, &ri_hdl->aps) != 0)
583*7c478bd9Sstevel@tonic-gate 		goto fail;
584*7c478bd9Sstevel@tonic-gate 
585*7c478bd9Sstevel@tonic-gate 	buf = NULL;
586*7c478bd9Sstevel@tonic-gate 	size = 0;
587*7c478bd9Sstevel@tonic-gate 	if (nvlist_lookup_byte_array(nvl, RI_HDL_CPU_CAPS, (uchar_t **)&buf,
588*7c478bd9Sstevel@tonic-gate 	    (uint_t *)&size) != 0) {
589*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_lookup_byte_array fail (%s)\n",
590*7c478bd9Sstevel@tonic-gate 		    RI_HDL_CPU_CAPS));
591*7c478bd9Sstevel@tonic-gate 		goto fail;
592*7c478bd9Sstevel@tonic-gate 	}
593*7c478bd9Sstevel@tonic-gate 
594*7c478bd9Sstevel@tonic-gate 	if (client_list_unpack(buf, size, &ri_hdl->cpu_cap_clients) != 0)
595*7c478bd9Sstevel@tonic-gate 		goto fail;
596*7c478bd9Sstevel@tonic-gate 
597*7c478bd9Sstevel@tonic-gate 	buf = NULL;
598*7c478bd9Sstevel@tonic-gate 	size = 0;
599*7c478bd9Sstevel@tonic-gate 	if (nvlist_lookup_byte_array(nvl, RI_HDL_MEM_CAPS, (uchar_t **)&buf,
600*7c478bd9Sstevel@tonic-gate 	    (uint_t *)&size) != 0) {
601*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_lookup_byte_array fail (%s)\n",
602*7c478bd9Sstevel@tonic-gate 		    RI_HDL_MEM_CAPS));
603*7c478bd9Sstevel@tonic-gate 		goto fail;
604*7c478bd9Sstevel@tonic-gate 	}
605*7c478bd9Sstevel@tonic-gate 
606*7c478bd9Sstevel@tonic-gate 	if (client_list_unpack(buf, size, &ri_hdl->mem_cap_clients) != 0)
607*7c478bd9Sstevel@tonic-gate 		goto fail;
608*7c478bd9Sstevel@tonic-gate 
609*7c478bd9Sstevel@tonic-gate 	*hdlp = ri_hdl;
610*7c478bd9Sstevel@tonic-gate 
611*7c478bd9Sstevel@tonic-gate 	return (0);
612*7c478bd9Sstevel@tonic-gate 
613*7c478bd9Sstevel@tonic-gate fail:
614*7c478bd9Sstevel@tonic-gate 	free(ri_hdl);
615*7c478bd9Sstevel@tonic-gate 	if (nvl != NULL)
616*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
617*7c478bd9Sstevel@tonic-gate 
618*7c478bd9Sstevel@tonic-gate 	return (-1);
619*7c478bd9Sstevel@tonic-gate }
620*7c478bd9Sstevel@tonic-gate 
621*7c478bd9Sstevel@tonic-gate static int
622*7c478bd9Sstevel@tonic-gate ap_list_unpack(char *buf, size_t size, ri_ap_t **aps)
623*7c478bd9Sstevel@tonic-gate {
624*7c478bd9Sstevel@tonic-gate 	nvpair_t	*nvp = NULL;
625*7c478bd9Sstevel@tonic-gate 	nvlist_t	*nvl;
626*7c478bd9Sstevel@tonic-gate 	ri_ap_t		*aplist = NULL;
627*7c478bd9Sstevel@tonic-gate 	ri_ap_t		*prev = NULL;
628*7c478bd9Sstevel@tonic-gate 	ri_ap_t		*tmp = NULL;
629*7c478bd9Sstevel@tonic-gate 
630*7c478bd9Sstevel@tonic-gate 	if (nvlist_unpack(buf, size, &nvl, 0) != 0) {
631*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_unpack fail\n"));
632*7c478bd9Sstevel@tonic-gate 		return (-1);
633*7c478bd9Sstevel@tonic-gate 	}
634*7c478bd9Sstevel@tonic-gate 
635*7c478bd9Sstevel@tonic-gate 	while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
636*7c478bd9Sstevel@tonic-gate 		assert(strcmp(nvpair_name(nvp), RI_AP_T) == 0 &&
637*7c478bd9Sstevel@tonic-gate 		    nvpair_type(nvp) == DATA_TYPE_BYTE_ARRAY);
638*7c478bd9Sstevel@tonic-gate 
639*7c478bd9Sstevel@tonic-gate 		if ((tmp = calloc(1, sizeof (*tmp))) == NULL) {
640*7c478bd9Sstevel@tonic-gate 			dprintf((stderr, "calloc: %s\n", strerror(errno)));
641*7c478bd9Sstevel@tonic-gate 			goto fail;
642*7c478bd9Sstevel@tonic-gate 		}
643*7c478bd9Sstevel@tonic-gate 
644*7c478bd9Sstevel@tonic-gate 		buf = NULL;
645*7c478bd9Sstevel@tonic-gate 		size = 0;
646*7c478bd9Sstevel@tonic-gate 		if (nvpair_value_byte_array(nvp, (uchar_t **)&buf,
647*7c478bd9Sstevel@tonic-gate 		    (uint_t *)&size) != 0) {
648*7c478bd9Sstevel@tonic-gate 			dprintf((stderr, "nvpair_value_byte_array fail\n"));
649*7c478bd9Sstevel@tonic-gate 			goto fail;
650*7c478bd9Sstevel@tonic-gate 		}
651*7c478bd9Sstevel@tonic-gate 
652*7c478bd9Sstevel@tonic-gate 		if (ap_unpack(buf, size, tmp) != 0)
653*7c478bd9Sstevel@tonic-gate 			goto fail;
654*7c478bd9Sstevel@tonic-gate 
655*7c478bd9Sstevel@tonic-gate 		if (aplist == NULL) {
656*7c478bd9Sstevel@tonic-gate 			prev = aplist = tmp;
657*7c478bd9Sstevel@tonic-gate 		} else {
658*7c478bd9Sstevel@tonic-gate 			prev->next = tmp;
659*7c478bd9Sstevel@tonic-gate 			prev = tmp;
660*7c478bd9Sstevel@tonic-gate 		}
661*7c478bd9Sstevel@tonic-gate 	}
662*7c478bd9Sstevel@tonic-gate 
663*7c478bd9Sstevel@tonic-gate 	nvlist_free(nvl);
664*7c478bd9Sstevel@tonic-gate 	*aps = aplist;
665*7c478bd9Sstevel@tonic-gate 
666*7c478bd9Sstevel@tonic-gate 	return (0);
667*7c478bd9Sstevel@tonic-gate 
668*7c478bd9Sstevel@tonic-gate fail:
669*7c478bd9Sstevel@tonic-gate 	if (nvl != NULL)
670*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
671*7c478bd9Sstevel@tonic-gate 	if (aplist != NULL) {
672*7c478bd9Sstevel@tonic-gate 		while ((tmp = aplist) != NULL) {
673*7c478bd9Sstevel@tonic-gate 			aplist = aplist->next;
674*7c478bd9Sstevel@tonic-gate 			ri_ap_free(tmp);
675*7c478bd9Sstevel@tonic-gate 		}
676*7c478bd9Sstevel@tonic-gate 	}
677*7c478bd9Sstevel@tonic-gate 
678*7c478bd9Sstevel@tonic-gate 	return (-1);
679*7c478bd9Sstevel@tonic-gate }
680*7c478bd9Sstevel@tonic-gate 
681*7c478bd9Sstevel@tonic-gate static int
682*7c478bd9Sstevel@tonic-gate dev_list_unpack(char *buf, size_t size, ri_dev_t **devs)
683*7c478bd9Sstevel@tonic-gate {
684*7c478bd9Sstevel@tonic-gate 	nvpair_t	*nvp = NULL;
685*7c478bd9Sstevel@tonic-gate 	nvlist_t	*nvl;
686*7c478bd9Sstevel@tonic-gate 	ri_dev_t	*devlist = NULL;
687*7c478bd9Sstevel@tonic-gate 	ri_dev_t	*prev = NULL;
688*7c478bd9Sstevel@tonic-gate 	ri_dev_t	*tmp = NULL;
689*7c478bd9Sstevel@tonic-gate 
690*7c478bd9Sstevel@tonic-gate 	if (nvlist_unpack(buf, size, &nvl, 0) != 0) {
691*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_unpack fail\n"));
692*7c478bd9Sstevel@tonic-gate 		return (-1);
693*7c478bd9Sstevel@tonic-gate 	}
694*7c478bd9Sstevel@tonic-gate 
695*7c478bd9Sstevel@tonic-gate 	while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
696*7c478bd9Sstevel@tonic-gate 		assert(strcmp(nvpair_name(nvp), RI_DEV_T) == 0 &&
697*7c478bd9Sstevel@tonic-gate 		    nvpair_type(nvp) == DATA_TYPE_BYTE_ARRAY);
698*7c478bd9Sstevel@tonic-gate 
699*7c478bd9Sstevel@tonic-gate 		if ((tmp = calloc(1, sizeof (*tmp))) == NULL) {
700*7c478bd9Sstevel@tonic-gate 			dprintf((stderr, "calloc: %s\n", strerror(errno)));
701*7c478bd9Sstevel@tonic-gate 			goto fail;
702*7c478bd9Sstevel@tonic-gate 		}
703*7c478bd9Sstevel@tonic-gate 
704*7c478bd9Sstevel@tonic-gate 		if (nvpair_value_byte_array(nvp, (uchar_t **)&buf,
705*7c478bd9Sstevel@tonic-gate 		    (uint_t *)&size) != 0) {
706*7c478bd9Sstevel@tonic-gate 			dprintf((stderr, "nvpair_value_byte_array fail\n"));
707*7c478bd9Sstevel@tonic-gate 			goto fail;
708*7c478bd9Sstevel@tonic-gate 		}
709*7c478bd9Sstevel@tonic-gate 
710*7c478bd9Sstevel@tonic-gate 		if (dev_unpack(buf, size, tmp) != 0)
711*7c478bd9Sstevel@tonic-gate 			goto fail;
712*7c478bd9Sstevel@tonic-gate 
713*7c478bd9Sstevel@tonic-gate 		if (devlist == NULL) {
714*7c478bd9Sstevel@tonic-gate 			prev = devlist = tmp;
715*7c478bd9Sstevel@tonic-gate 		} else {
716*7c478bd9Sstevel@tonic-gate 			prev->next = tmp;
717*7c478bd9Sstevel@tonic-gate 			prev = tmp;
718*7c478bd9Sstevel@tonic-gate 		}
719*7c478bd9Sstevel@tonic-gate 	}
720*7c478bd9Sstevel@tonic-gate 
721*7c478bd9Sstevel@tonic-gate 	nvlist_free(nvl);
722*7c478bd9Sstevel@tonic-gate 	*devs = devlist;
723*7c478bd9Sstevel@tonic-gate 
724*7c478bd9Sstevel@tonic-gate 	return (0);
725*7c478bd9Sstevel@tonic-gate 
726*7c478bd9Sstevel@tonic-gate fail:
727*7c478bd9Sstevel@tonic-gate 	if (nvl != NULL)
728*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
729*7c478bd9Sstevel@tonic-gate 	if (devlist != NULL) {
730*7c478bd9Sstevel@tonic-gate 		while ((tmp = devlist) != NULL) {
731*7c478bd9Sstevel@tonic-gate 			devlist = devlist->next;
732*7c478bd9Sstevel@tonic-gate 			ri_dev_free(tmp);
733*7c478bd9Sstevel@tonic-gate 		}
734*7c478bd9Sstevel@tonic-gate 	}
735*7c478bd9Sstevel@tonic-gate 
736*7c478bd9Sstevel@tonic-gate 	return (-1);
737*7c478bd9Sstevel@tonic-gate }
738*7c478bd9Sstevel@tonic-gate 
739*7c478bd9Sstevel@tonic-gate static int
740*7c478bd9Sstevel@tonic-gate client_list_unpack(char *buf, size_t size, ri_client_t **clients)
741*7c478bd9Sstevel@tonic-gate {
742*7c478bd9Sstevel@tonic-gate 	nvpair_t	*nvp = NULL;
743*7c478bd9Sstevel@tonic-gate 	nvlist_t	*nvl;
744*7c478bd9Sstevel@tonic-gate 	ri_client_t	*client_list = NULL;
745*7c478bd9Sstevel@tonic-gate 	ri_client_t	*prev = NULL;
746*7c478bd9Sstevel@tonic-gate 	ri_client_t	*tmp = NULL;
747*7c478bd9Sstevel@tonic-gate 
748*7c478bd9Sstevel@tonic-gate 	if (nvlist_unpack(buf, size, &nvl, 0) != 0) {
749*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_unpack fail\n"));
750*7c478bd9Sstevel@tonic-gate 		return (-1);
751*7c478bd9Sstevel@tonic-gate 	}
752*7c478bd9Sstevel@tonic-gate 
753*7c478bd9Sstevel@tonic-gate 	while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
754*7c478bd9Sstevel@tonic-gate 		assert(strcmp(nvpair_name(nvp), RI_CLIENT_T) == 0);
755*7c478bd9Sstevel@tonic-gate 		assert(nvpair_type(nvp) == DATA_TYPE_BYTE_ARRAY);
756*7c478bd9Sstevel@tonic-gate 
757*7c478bd9Sstevel@tonic-gate 		if ((tmp = calloc(1, sizeof (*tmp))) == NULL) {
758*7c478bd9Sstevel@tonic-gate 			dprintf((stderr, "calloc: %s\n", strerror(errno)));
759*7c478bd9Sstevel@tonic-gate 			goto fail;
760*7c478bd9Sstevel@tonic-gate 		}
761*7c478bd9Sstevel@tonic-gate 
762*7c478bd9Sstevel@tonic-gate 		buf = NULL;
763*7c478bd9Sstevel@tonic-gate 		size = 0;
764*7c478bd9Sstevel@tonic-gate 		if (nvpair_value_byte_array(nvp, (uchar_t **)&buf,
765*7c478bd9Sstevel@tonic-gate 		    (uint_t *)&size) != 0) {
766*7c478bd9Sstevel@tonic-gate 			dprintf((stderr, "nvpair_value_byte_array fail\n"));
767*7c478bd9Sstevel@tonic-gate 			goto fail;
768*7c478bd9Sstevel@tonic-gate 		}
769*7c478bd9Sstevel@tonic-gate 
770*7c478bd9Sstevel@tonic-gate 		if (client_unpack(buf, size, tmp) != 0)
771*7c478bd9Sstevel@tonic-gate 			goto fail;
772*7c478bd9Sstevel@tonic-gate 
773*7c478bd9Sstevel@tonic-gate 		if (client_list == NULL) {
774*7c478bd9Sstevel@tonic-gate 			prev = client_list = tmp;
775*7c478bd9Sstevel@tonic-gate 		} else {
776*7c478bd9Sstevel@tonic-gate 			prev->next = tmp;
777*7c478bd9Sstevel@tonic-gate 			prev = tmp;
778*7c478bd9Sstevel@tonic-gate 		}
779*7c478bd9Sstevel@tonic-gate 	}
780*7c478bd9Sstevel@tonic-gate 
781*7c478bd9Sstevel@tonic-gate 	nvlist_free(nvl);
782*7c478bd9Sstevel@tonic-gate 	*clients = client_list;
783*7c478bd9Sstevel@tonic-gate 
784*7c478bd9Sstevel@tonic-gate 	return (0);
785*7c478bd9Sstevel@tonic-gate 
786*7c478bd9Sstevel@tonic-gate fail:
787*7c478bd9Sstevel@tonic-gate 	if (nvl != NULL)
788*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
789*7c478bd9Sstevel@tonic-gate 	if (client_list != NULL) {
790*7c478bd9Sstevel@tonic-gate 		while ((tmp = client_list) != NULL) {
791*7c478bd9Sstevel@tonic-gate 			client_list = client_list->next;
792*7c478bd9Sstevel@tonic-gate 			ri_client_free(tmp);
793*7c478bd9Sstevel@tonic-gate 		}
794*7c478bd9Sstevel@tonic-gate 	}
795*7c478bd9Sstevel@tonic-gate 
796*7c478bd9Sstevel@tonic-gate 	return (-1);
797*7c478bd9Sstevel@tonic-gate }
798*7c478bd9Sstevel@tonic-gate 
799*7c478bd9Sstevel@tonic-gate static int
800*7c478bd9Sstevel@tonic-gate client_unpack(char *buf, size_t size, ri_client_t *client)
801*7c478bd9Sstevel@tonic-gate {
802*7c478bd9Sstevel@tonic-gate 	nvlist_t	*nvl;
803*7c478bd9Sstevel@tonic-gate 
804*7c478bd9Sstevel@tonic-gate 	if (nvlist_unpack(buf, size, &nvl, 0) != 0) {
805*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_unpack fail\n"));
806*7c478bd9Sstevel@tonic-gate 		return (-1);
807*7c478bd9Sstevel@tonic-gate 	}
808*7c478bd9Sstevel@tonic-gate 
809*7c478bd9Sstevel@tonic-gate 	if (lookup_unpack_byte_array(nvl, RI_CLIENT_USAGE_PROPS,
810*7c478bd9Sstevel@tonic-gate 	    &client->usg_props) != 0) {
811*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
812*7c478bd9Sstevel@tonic-gate 		return (-1);
813*7c478bd9Sstevel@tonic-gate 	}
814*7c478bd9Sstevel@tonic-gate 
815*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
816*7c478bd9Sstevel@tonic-gate 	nvlist_print(stderr, client->usg_props);
817*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */
818*7c478bd9Sstevel@tonic-gate 
819*7c478bd9Sstevel@tonic-gate 	/*
820*7c478bd9Sstevel@tonic-gate 	 * Verbose properties for RCM clients only present if
821*7c478bd9Sstevel@tonic-gate 	 * RI_VERBOSE was specified for ri_init.
822*7c478bd9Sstevel@tonic-gate 	 */
823*7c478bd9Sstevel@tonic-gate 	buf = NULL;
824*7c478bd9Sstevel@tonic-gate 	size = 0;
825*7c478bd9Sstevel@tonic-gate 	if (nvlist_lookup_byte_array(nvl, RI_CLIENT_VERB_PROPS,
826*7c478bd9Sstevel@tonic-gate 	    (uchar_t **)&buf, (uint_t *)&size) == 0) {
827*7c478bd9Sstevel@tonic-gate 		if (nvlist_unpack(buf, size, &client->v_props, 0) != 0) {
828*7c478bd9Sstevel@tonic-gate 			dprintf((stderr, "nvlist_unpack fail (%s)\n",
829*7c478bd9Sstevel@tonic-gate 			    RI_CLIENT_VERB_PROPS));
830*7c478bd9Sstevel@tonic-gate 			nvlist_free(nvl);
831*7c478bd9Sstevel@tonic-gate 			return (-1);
832*7c478bd9Sstevel@tonic-gate 		}
833*7c478bd9Sstevel@tonic-gate 	}
834*7c478bd9Sstevel@tonic-gate 
835*7c478bd9Sstevel@tonic-gate 	nvlist_free(nvl);
836*7c478bd9Sstevel@tonic-gate 
837*7c478bd9Sstevel@tonic-gate 	return (0);
838*7c478bd9Sstevel@tonic-gate }
839*7c478bd9Sstevel@tonic-gate 
840*7c478bd9Sstevel@tonic-gate static int
841*7c478bd9Sstevel@tonic-gate dev_unpack(char *buf, size_t size, ri_dev_t *dev)
842*7c478bd9Sstevel@tonic-gate {
843*7c478bd9Sstevel@tonic-gate 	nvlist_t	*nvl;
844*7c478bd9Sstevel@tonic-gate 
845*7c478bd9Sstevel@tonic-gate 	if (nvlist_unpack(buf, size, &nvl, 0) != 0) {
846*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_unpack fail\n"));
847*7c478bd9Sstevel@tonic-gate 		return (-1);
848*7c478bd9Sstevel@tonic-gate 	}
849*7c478bd9Sstevel@tonic-gate 
850*7c478bd9Sstevel@tonic-gate 	if (lookup_unpack_byte_array(nvl, RI_DEV_PROPS,
851*7c478bd9Sstevel@tonic-gate 	    &dev->conf_props) != 0) {
852*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
853*7c478bd9Sstevel@tonic-gate 		return (-1);
854*7c478bd9Sstevel@tonic-gate 	}
855*7c478bd9Sstevel@tonic-gate 
856*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
857*7c478bd9Sstevel@tonic-gate 	nvlist_print(stderr, dev->conf_props);
858*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */
859*7c478bd9Sstevel@tonic-gate 
860*7c478bd9Sstevel@tonic-gate 	if (nvlist_lookup_byte_array(nvl, RI_DEV_CLIENTS, (uchar_t **)&buf,
861*7c478bd9Sstevel@tonic-gate 	    (uint_t *)&size) != 0) {
862*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_lookup_byte_array fail (%s)\n",
863*7c478bd9Sstevel@tonic-gate 		    RI_DEV_CLIENTS));
864*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
865*7c478bd9Sstevel@tonic-gate 		return (-1);
866*7c478bd9Sstevel@tonic-gate 	}
867*7c478bd9Sstevel@tonic-gate 
868*7c478bd9Sstevel@tonic-gate 	if (client_list_unpack(buf, size, &dev->rcm_clients) != 0) {
869*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
870*7c478bd9Sstevel@tonic-gate 		return (-1);
871*7c478bd9Sstevel@tonic-gate 	}
872*7c478bd9Sstevel@tonic-gate 
873*7c478bd9Sstevel@tonic-gate 	nvlist_free(nvl);
874*7c478bd9Sstevel@tonic-gate 
875*7c478bd9Sstevel@tonic-gate 	return (0);
876*7c478bd9Sstevel@tonic-gate }
877*7c478bd9Sstevel@tonic-gate 
878*7c478bd9Sstevel@tonic-gate static int
879*7c478bd9Sstevel@tonic-gate ap_unpack(char *buf, size_t size, ri_ap_t *ap)
880*7c478bd9Sstevel@tonic-gate {
881*7c478bd9Sstevel@tonic-gate 	nvlist_t	*nvl;
882*7c478bd9Sstevel@tonic-gate 
883*7c478bd9Sstevel@tonic-gate 	if (nvlist_unpack(buf, size, &nvl, 0) != 0) {
884*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_unpack fail\n"));
885*7c478bd9Sstevel@tonic-gate 		return (-1);
886*7c478bd9Sstevel@tonic-gate 	}
887*7c478bd9Sstevel@tonic-gate 
888*7c478bd9Sstevel@tonic-gate 	if (lookup_unpack_byte_array(nvl, RI_AP_PROPS, &ap->conf_props) != 0) {
889*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
890*7c478bd9Sstevel@tonic-gate 		return (-1);
891*7c478bd9Sstevel@tonic-gate 	}
892*7c478bd9Sstevel@tonic-gate 
893*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
894*7c478bd9Sstevel@tonic-gate 	nvlist_print(stderr, ap->conf_props);
895*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */
896*7c478bd9Sstevel@tonic-gate 
897*7c478bd9Sstevel@tonic-gate 	if (nvlist_lookup_byte_array(nvl, RI_AP_CPUS, (uchar_t **)&buf,
898*7c478bd9Sstevel@tonic-gate 	    (uint_t *)&size) != 0) {
899*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_lookup_byte_array fail (%s)\n",
900*7c478bd9Sstevel@tonic-gate 		    RI_AP_CPUS));
901*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
902*7c478bd9Sstevel@tonic-gate 		return (-1);
903*7c478bd9Sstevel@tonic-gate 	}
904*7c478bd9Sstevel@tonic-gate 
905*7c478bd9Sstevel@tonic-gate 	if (dev_list_unpack(buf, size, &ap->cpus) != 0) {
906*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
907*7c478bd9Sstevel@tonic-gate 		return (-1);
908*7c478bd9Sstevel@tonic-gate 	}
909*7c478bd9Sstevel@tonic-gate 
910*7c478bd9Sstevel@tonic-gate 	if (nvlist_lookup_byte_array(nvl, RI_AP_MEMS, (uchar_t **)&buf,
911*7c478bd9Sstevel@tonic-gate 	    (uint_t *)&size) != 0) {
912*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_lookup_byte_array fail (%s)\n",
913*7c478bd9Sstevel@tonic-gate 		    RI_AP_MEMS));
914*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
915*7c478bd9Sstevel@tonic-gate 		return (-1);
916*7c478bd9Sstevel@tonic-gate 	}
917*7c478bd9Sstevel@tonic-gate 
918*7c478bd9Sstevel@tonic-gate 	if (dev_list_unpack(buf, size, &ap->mems) != 0) {
919*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
920*7c478bd9Sstevel@tonic-gate 		return (-1);
921*7c478bd9Sstevel@tonic-gate 	}
922*7c478bd9Sstevel@tonic-gate 
923*7c478bd9Sstevel@tonic-gate 	if (nvlist_lookup_byte_array(nvl, RI_AP_IOS, (uchar_t **)&buf,
924*7c478bd9Sstevel@tonic-gate 	    (uint_t *)&size) != 0) {
925*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_lookup_byte_array fail (%s)\n",
926*7c478bd9Sstevel@tonic-gate 		    RI_AP_IOS));
927*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
928*7c478bd9Sstevel@tonic-gate 		return (-1);
929*7c478bd9Sstevel@tonic-gate 	}
930*7c478bd9Sstevel@tonic-gate 
931*7c478bd9Sstevel@tonic-gate 	if (dev_list_unpack(buf, size, &ap->ios) != 0) {
932*7c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
933*7c478bd9Sstevel@tonic-gate 		return (-1);
934*7c478bd9Sstevel@tonic-gate 	}
935*7c478bd9Sstevel@tonic-gate 
936*7c478bd9Sstevel@tonic-gate 	nvlist_free(nvl);
937*7c478bd9Sstevel@tonic-gate 
938*7c478bd9Sstevel@tonic-gate 	return (0);
939*7c478bd9Sstevel@tonic-gate }
940*7c478bd9Sstevel@tonic-gate 
941*7c478bd9Sstevel@tonic-gate /*
942*7c478bd9Sstevel@tonic-gate  * Lookup byte array in old nvlist_t and unpack into new nvlist_t.
943*7c478bd9Sstevel@tonic-gate  */
944*7c478bd9Sstevel@tonic-gate static int
945*7c478bd9Sstevel@tonic-gate lookup_unpack_byte_array(nvlist_t *old_nvl, char *name, nvlist_t **new_nvl)
946*7c478bd9Sstevel@tonic-gate {
947*7c478bd9Sstevel@tonic-gate 	char	*buf = NULL;
948*7c478bd9Sstevel@tonic-gate 	size_t	size = 0;
949*7c478bd9Sstevel@tonic-gate 
950*7c478bd9Sstevel@tonic-gate 	if (nvlist_lookup_byte_array(old_nvl, name, (uchar_t **)&buf,
951*7c478bd9Sstevel@tonic-gate 	    (uint_t *)&size) != 0) {
952*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_lookup_byte_array fail (%s)\n",
953*7c478bd9Sstevel@tonic-gate 		    name));
954*7c478bd9Sstevel@tonic-gate 		return (-1);
955*7c478bd9Sstevel@tonic-gate 	}
956*7c478bd9Sstevel@tonic-gate 
957*7c478bd9Sstevel@tonic-gate 	if (nvlist_unpack(buf, size, new_nvl, 0) != 0) {
958*7c478bd9Sstevel@tonic-gate 		dprintf((stderr, "nvlist_unpack fail (%s)\n", name));
959*7c478bd9Sstevel@tonic-gate 		return (-1);
960*7c478bd9Sstevel@tonic-gate 	}
961*7c478bd9Sstevel@tonic-gate 
962*7c478bd9Sstevel@tonic-gate 	return (0);
963*7c478bd9Sstevel@tonic-gate }
964*7c478bd9Sstevel@tonic-gate 
965*7c478bd9Sstevel@tonic-gate ri_ap_t *
966*7c478bd9Sstevel@tonic-gate ri_ap_next(ri_hdl_t *hdl, ri_ap_t *ap)
967*7c478bd9Sstevel@tonic-gate {
968*7c478bd9Sstevel@tonic-gate 	if (hdl == NULL) {
969*7c478bd9Sstevel@tonic-gate 		errno = EINVAL;
970*7c478bd9Sstevel@tonic-gate 		return (NULL);
971*7c478bd9Sstevel@tonic-gate 	}
972*7c478bd9Sstevel@tonic-gate 	return ((ap == NULL) ? hdl->aps : ap->next);
973*7c478bd9Sstevel@tonic-gate }
974*7c478bd9Sstevel@tonic-gate 
975*7c478bd9Sstevel@tonic-gate nvlist_t *
976*7c478bd9Sstevel@tonic-gate ri_ap_conf_props(ri_ap_t *ap)
977*7c478bd9Sstevel@tonic-gate {
978*7c478bd9Sstevel@tonic-gate 	if (ap == NULL) {
979*7c478bd9Sstevel@tonic-gate 		errno = EINVAL;
980*7c478bd9Sstevel@tonic-gate 		return (NULL);
981*7c478bd9Sstevel@tonic-gate 	}
982*7c478bd9Sstevel@tonic-gate 	return (ap->conf_props);
983*7c478bd9Sstevel@tonic-gate }
984*7c478bd9Sstevel@tonic-gate 
985*7c478bd9Sstevel@tonic-gate ri_dev_t *
986*7c478bd9Sstevel@tonic-gate ri_cpu_next(ri_ap_t *ap, ri_dev_t *cpu)
987*7c478bd9Sstevel@tonic-gate {
988*7c478bd9Sstevel@tonic-gate 	if (ap == NULL) {
989*7c478bd9Sstevel@tonic-gate 		errno = EINVAL;
990*7c478bd9Sstevel@tonic-gate 		return (NULL);
991*7c478bd9Sstevel@tonic-gate 	}
992*7c478bd9Sstevel@tonic-gate 	return ((cpu == NULL) ? ap->cpus : cpu->next);
993*7c478bd9Sstevel@tonic-gate }
994*7c478bd9Sstevel@tonic-gate 
995*7c478bd9Sstevel@tonic-gate ri_dev_t *
996*7c478bd9Sstevel@tonic-gate ri_mem_next(ri_ap_t *ap, ri_dev_t *mem)
997*7c478bd9Sstevel@tonic-gate {
998*7c478bd9Sstevel@tonic-gate 	if (ap == NULL) {
999*7c478bd9Sstevel@tonic-gate 		errno = EINVAL;
1000*7c478bd9Sstevel@tonic-gate 		return (NULL);
1001*7c478bd9Sstevel@tonic-gate 	}
1002*7c478bd9Sstevel@tonic-gate 	return ((mem == NULL) ? ap->mems : mem->next);
1003*7c478bd9Sstevel@tonic-gate }
1004*7c478bd9Sstevel@tonic-gate 
1005*7c478bd9Sstevel@tonic-gate ri_dev_t *
1006*7c478bd9Sstevel@tonic-gate ri_io_next(ri_ap_t *ap, ri_dev_t *io)
1007*7c478bd9Sstevel@tonic-gate {
1008*7c478bd9Sstevel@tonic-gate 	if (ap == NULL) {
1009*7c478bd9Sstevel@tonic-gate 		errno = EINVAL;
1010*7c478bd9Sstevel@tonic-gate 		return (NULL);
1011*7c478bd9Sstevel@tonic-gate 	}
1012*7c478bd9Sstevel@tonic-gate 	return ((io == NULL) ? ap->ios : io->next);
1013*7c478bd9Sstevel@tonic-gate }
1014*7c478bd9Sstevel@tonic-gate 
1015*7c478bd9Sstevel@tonic-gate ri_client_t *
1016*7c478bd9Sstevel@tonic-gate ri_client_next(ri_dev_t *dev, ri_client_t *rcm_client)
1017*7c478bd9Sstevel@tonic-gate {
1018*7c478bd9Sstevel@tonic-gate 	if (dev == NULL) {
1019*7c478bd9Sstevel@tonic-gate 		errno = EINVAL;
1020*7c478bd9Sstevel@tonic-gate 		return (NULL);
1021*7c478bd9Sstevel@tonic-gate 	}
1022*7c478bd9Sstevel@tonic-gate 	return ((rcm_client == NULL) ? dev->rcm_clients : rcm_client->next);
1023*7c478bd9Sstevel@tonic-gate }
1024*7c478bd9Sstevel@tonic-gate 
1025*7c478bd9Sstevel@tonic-gate nvlist_t *
1026*7c478bd9Sstevel@tonic-gate ri_dev_conf_props(ri_dev_t *dev)
1027*7c478bd9Sstevel@tonic-gate {
1028*7c478bd9Sstevel@tonic-gate 	if (dev == NULL) {
1029*7c478bd9Sstevel@tonic-gate 		errno = EINVAL;
1030*7c478bd9Sstevel@tonic-gate 		return (NULL);
1031*7c478bd9Sstevel@tonic-gate 	}
1032*7c478bd9Sstevel@tonic-gate 	return (dev->conf_props);
1033*7c478bd9Sstevel@tonic-gate }
1034*7c478bd9Sstevel@tonic-gate 
1035*7c478bd9Sstevel@tonic-gate nvlist_t *
1036*7c478bd9Sstevel@tonic-gate ri_client_usage_props(ri_client_t *rcm_client)
1037*7c478bd9Sstevel@tonic-gate {
1038*7c478bd9Sstevel@tonic-gate 	if (rcm_client == NULL) {
1039*7c478bd9Sstevel@tonic-gate 		errno = EINVAL;
1040*7c478bd9Sstevel@tonic-gate 		return (NULL);
1041*7c478bd9Sstevel@tonic-gate 	}
1042*7c478bd9Sstevel@tonic-gate 	return (rcm_client->usg_props);
1043*7c478bd9Sstevel@tonic-gate }
1044*7c478bd9Sstevel@tonic-gate 
1045*7c478bd9Sstevel@tonic-gate nvlist_t *
1046*7c478bd9Sstevel@tonic-gate ri_client_verbose_props(ri_client_t *rcm_client)
1047*7c478bd9Sstevel@tonic-gate {
1048*7c478bd9Sstevel@tonic-gate 	if (rcm_client == NULL) {
1049*7c478bd9Sstevel@tonic-gate 		errno = EINVAL;
1050*7c478bd9Sstevel@tonic-gate 		return (NULL);
1051*7c478bd9Sstevel@tonic-gate 	}
1052*7c478bd9Sstevel@tonic-gate 	return (rcm_client->v_props);
1053*7c478bd9Sstevel@tonic-gate }
1054*7c478bd9Sstevel@tonic-gate 
1055*7c478bd9Sstevel@tonic-gate ri_client_t *
1056*7c478bd9Sstevel@tonic-gate ri_cpu_cap_client_next(ri_hdl_t *hdl, ri_client_t *rcm_client)
1057*7c478bd9Sstevel@tonic-gate {
1058*7c478bd9Sstevel@tonic-gate 	if (hdl == NULL) {
1059*7c478bd9Sstevel@tonic-gate 		errno = EINVAL;
1060*7c478bd9Sstevel@tonic-gate 		return (NULL);
1061*7c478bd9Sstevel@tonic-gate 	}
1062*7c478bd9Sstevel@tonic-gate 	return ((rcm_client == NULL) ? hdl->cpu_cap_clients : rcm_client->next);
1063*7c478bd9Sstevel@tonic-gate }
1064*7c478bd9Sstevel@tonic-gate 
1065*7c478bd9Sstevel@tonic-gate ri_client_t *
1066*7c478bd9Sstevel@tonic-gate ri_mem_cap_client_next(ri_hdl_t *hdl, ri_client_t *rcm_client)
1067*7c478bd9Sstevel@tonic-gate {
1068*7c478bd9Sstevel@tonic-gate 	if (hdl == NULL) {
1069*7c478bd9Sstevel@tonic-gate 		errno = EINVAL;
1070*7c478bd9Sstevel@tonic-gate 		return (NULL);
1071*7c478bd9Sstevel@tonic-gate 	}
1072*7c478bd9Sstevel@tonic-gate 	return ((rcm_client == NULL) ? hdl->mem_cap_clients : rcm_client->next);
1073*7c478bd9Sstevel@tonic-gate }
1074