xref: /onnv-gate/usr/src/cmd/dcs/sparc/sun4u/rsrc_info.c (revision 1772:78cca3d2cc4b)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*1772Sjl139090  * Common Development and Distribution License (the "License").
6*1772Sjl139090  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*1772Sjl139090  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23*1772Sjl139090  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate  * Routines for traversing and packing/unpacking the handle
300Sstevel@tonic-gate  * returned from ri_init.
310Sstevel@tonic-gate  */
320Sstevel@tonic-gate 
330Sstevel@tonic-gate #include <stdlib.h>
340Sstevel@tonic-gate #include <strings.h>
350Sstevel@tonic-gate #include "rsrc_info.h"
360Sstevel@tonic-gate #include "rsrc_info_impl.h"
370Sstevel@tonic-gate 
38*1772Sjl139090 static int ap_list_pack(ri_ap_t *, char **, size_t *, int);
390Sstevel@tonic-gate static int ap_list_unpack(char *, size_t, ri_ap_t **);
40*1772Sjl139090 static int ap_pack(ri_ap_t *, char **, size_t *, int);
410Sstevel@tonic-gate static int ap_unpack(char *, size_t, ri_ap_t *);
42*1772Sjl139090 static int dev_list_pack(ri_dev_t *, char **, size_t *, int);
430Sstevel@tonic-gate static int dev_list_unpack(char *, size_t, ri_dev_t **);
44*1772Sjl139090 static int dev_pack(ri_dev_t *, char **, size_t *, int);
450Sstevel@tonic-gate static int dev_unpack(char *, size_t, ri_dev_t *);
46*1772Sjl139090 static int client_list_pack(ri_client_t *, char **, size_t *, int);
470Sstevel@tonic-gate static int client_list_unpack(char *, size_t, ri_client_t **);
48*1772Sjl139090 static int client_pack(ri_client_t *, char **, size_t *, int);
490Sstevel@tonic-gate static int client_unpack(char *, size_t, ri_client_t *);
50*1772Sjl139090 static int pack_add_byte_array(nvlist_t *, char *, nvlist_t *, int);
510Sstevel@tonic-gate static int lookup_unpack_byte_array(nvlist_t *, char *, nvlist_t **);
520Sstevel@tonic-gate static void ri_ap_free(ri_ap_t *);
530Sstevel@tonic-gate 
540Sstevel@tonic-gate void
ri_fini(ri_hdl_t * hdl)550Sstevel@tonic-gate ri_fini(ri_hdl_t *hdl)
560Sstevel@tonic-gate {
570Sstevel@tonic-gate 	ri_ap_t		*ap;
580Sstevel@tonic-gate 	ri_client_t	*client;
590Sstevel@tonic-gate 
600Sstevel@tonic-gate 	if (hdl == NULL)
610Sstevel@tonic-gate 		return;
620Sstevel@tonic-gate 
630Sstevel@tonic-gate 	while ((ap = hdl->aps) != NULL) {
640Sstevel@tonic-gate 		hdl->aps = ap->next;
650Sstevel@tonic-gate 		ri_ap_free(ap);
660Sstevel@tonic-gate 	}
670Sstevel@tonic-gate 	while ((client = hdl->cpu_cap_clients) != NULL) {
680Sstevel@tonic-gate 		hdl->cpu_cap_clients = client->next;
690Sstevel@tonic-gate 		ri_client_free(client);
700Sstevel@tonic-gate 	}
710Sstevel@tonic-gate 	while ((client = hdl->mem_cap_clients) != NULL) {
720Sstevel@tonic-gate 		hdl->mem_cap_clients = client->next;
730Sstevel@tonic-gate 		ri_client_free(client);
740Sstevel@tonic-gate 	}
750Sstevel@tonic-gate 	free(hdl);
760Sstevel@tonic-gate }
770Sstevel@tonic-gate 
780Sstevel@tonic-gate static void
ri_ap_free(ri_ap_t * ap)790Sstevel@tonic-gate ri_ap_free(ri_ap_t *ap)
800Sstevel@tonic-gate {
810Sstevel@tonic-gate 	ri_dev_t	*dev;
820Sstevel@tonic-gate 
830Sstevel@tonic-gate 	assert(ap != NULL);
840Sstevel@tonic-gate 
850Sstevel@tonic-gate 	if (ap->conf_props != NULL)
860Sstevel@tonic-gate 		nvlist_free(ap->conf_props);
870Sstevel@tonic-gate 
880Sstevel@tonic-gate 	while ((dev = ap->cpus) != NULL) {
890Sstevel@tonic-gate 		ap->cpus = dev->next;
900Sstevel@tonic-gate 		ri_dev_free(dev);
910Sstevel@tonic-gate 	}
920Sstevel@tonic-gate 	while ((dev = ap->mems) != NULL) {
930Sstevel@tonic-gate 		ap->mems = dev->next;
940Sstevel@tonic-gate 		ri_dev_free(dev);
950Sstevel@tonic-gate 	}
960Sstevel@tonic-gate 	while ((dev = ap->ios) != NULL) {
970Sstevel@tonic-gate 		ap->ios = dev->next;
980Sstevel@tonic-gate 		ri_dev_free(dev);
990Sstevel@tonic-gate 	}
1000Sstevel@tonic-gate 	free(ap);
1010Sstevel@tonic-gate }
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate void
ri_dev_free(ri_dev_t * dev)1040Sstevel@tonic-gate ri_dev_free(ri_dev_t *dev)
1050Sstevel@tonic-gate {
1060Sstevel@tonic-gate 	ri_client_t	*client;
1070Sstevel@tonic-gate 
1080Sstevel@tonic-gate 	assert(dev != NULL);
1090Sstevel@tonic-gate 
1100Sstevel@tonic-gate 	nvlist_free(dev->conf_props);
1110Sstevel@tonic-gate 	while ((client = dev->rcm_clients) != NULL) {
1120Sstevel@tonic-gate 		dev->rcm_clients = client->next;
1130Sstevel@tonic-gate 		ri_client_free(client);
1140Sstevel@tonic-gate 	}
1150Sstevel@tonic-gate 	free(dev);
1160Sstevel@tonic-gate }
1170Sstevel@tonic-gate 
1180Sstevel@tonic-gate void
ri_client_free(ri_client_t * client)1190Sstevel@tonic-gate ri_client_free(ri_client_t *client)
1200Sstevel@tonic-gate {
1210Sstevel@tonic-gate 	assert(client != NULL);
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate 	if (client->usg_props != NULL)
1240Sstevel@tonic-gate 		nvlist_free(client->usg_props);
1250Sstevel@tonic-gate 	if (client->v_props != NULL)
1260Sstevel@tonic-gate 		nvlist_free(client->v_props);
1270Sstevel@tonic-gate 	free(client);
1280Sstevel@tonic-gate }
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate /*
1310Sstevel@tonic-gate  * Pack everything contained in the handle up inside out.
1320Sstevel@tonic-gate  */
1330Sstevel@tonic-gate int
ri_pack(ri_hdl_t * hdl,caddr_t * bufp,size_t * sizep,int encoding)134*1772Sjl139090 ri_pack(ri_hdl_t *hdl, caddr_t *bufp, size_t *sizep, int encoding)
1350Sstevel@tonic-gate {
1360Sstevel@tonic-gate 	nvlist_t	*nvl = NULL;
1370Sstevel@tonic-gate 	char		*buf = NULL;
1380Sstevel@tonic-gate 	size_t		size = 0;
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate 	if (bufp == NULL || sizep == NULL)
1410Sstevel@tonic-gate 		return (RI_INVAL);
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate 	*sizep = 0;
1440Sstevel@tonic-gate 	*bufp = NULL;
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate 	/*
1470Sstevel@tonic-gate 	 * Check the handle. If it is NULL, there
1480Sstevel@tonic-gate 	 * is nothing to pack, so we are done.
1490Sstevel@tonic-gate 	 */
1500Sstevel@tonic-gate 	if (hdl == NULL) {
1510Sstevel@tonic-gate 		return (RI_SUCCESS);
1520Sstevel@tonic-gate 	}
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
1550Sstevel@tonic-gate 		dprintf((stderr, "nvlist_alloc fail\n", errno));
1560Sstevel@tonic-gate 		goto fail;
1570Sstevel@tonic-gate 	}
1580Sstevel@tonic-gate 
1590Sstevel@tonic-gate 	if (nvlist_add_int32(nvl, RI_HDL_FLAGS, hdl->flags) != 0) {
1600Sstevel@tonic-gate 		dprintf((stderr, "nvlist_add_int32 fail\n"));
1610Sstevel@tonic-gate 		goto fail;
1620Sstevel@tonic-gate 	}
1630Sstevel@tonic-gate 
164*1772Sjl139090 	if (ap_list_pack(hdl->aps, &buf, &size, encoding) != 0 ||
1650Sstevel@tonic-gate 	    nvlist_add_byte_array(nvl, RI_HDL_APS, (uchar_t *)buf, size) != 0) {
1660Sstevel@tonic-gate 		goto fail;
1670Sstevel@tonic-gate 	}
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate 	s_free(buf);
170*1772Sjl139090 	if (client_list_pack(hdl->cpu_cap_clients, &buf, &size,
171*1772Sjl139090 	    encoding) != 0 ||
1720Sstevel@tonic-gate 	    nvlist_add_byte_array(nvl, RI_HDL_CPU_CAPS, (uchar_t *)buf,
1730Sstevel@tonic-gate 	    size) != 0) {
1740Sstevel@tonic-gate 		goto fail;
1750Sstevel@tonic-gate 	}
1760Sstevel@tonic-gate 
1770Sstevel@tonic-gate 	s_free(buf);
178*1772Sjl139090 	if (client_list_pack(hdl->mem_cap_clients, &buf, &size,
179*1772Sjl139090 	    encoding) != 0 ||
1800Sstevel@tonic-gate 	    nvlist_add_byte_array(nvl, RI_HDL_MEM_CAPS, (uchar_t *)buf,
1810Sstevel@tonic-gate 	    size) != 0) {
1820Sstevel@tonic-gate 		goto fail;
1830Sstevel@tonic-gate 	}
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate 	s_free(buf);
186*1772Sjl139090 	if (nvlist_pack(nvl, &buf, &size, encoding, 0) != 0) {
1870Sstevel@tonic-gate 		dprintf((stderr, "nvlist_pack fail\n"));
1880Sstevel@tonic-gate 		goto fail;
1890Sstevel@tonic-gate 	}
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate 	nvlist_free(nvl);
1920Sstevel@tonic-gate 	*bufp = buf;
1930Sstevel@tonic-gate 	*sizep = size;
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate 	return (RI_SUCCESS);
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate fail:
1980Sstevel@tonic-gate 	s_free(buf);
1990Sstevel@tonic-gate 	if (nvl != NULL)
2000Sstevel@tonic-gate 		nvlist_free(nvl);
2010Sstevel@tonic-gate 
2020Sstevel@tonic-gate 	return (RI_FAILURE);
2030Sstevel@tonic-gate }
2040Sstevel@tonic-gate 
2050Sstevel@tonic-gate /*
2060Sstevel@tonic-gate  * Pack a list of attachment point handles.
2070Sstevel@tonic-gate  */
2080Sstevel@tonic-gate static int
ap_list_pack(ri_ap_t * aplist,char ** bufp,size_t * sizep,int encoding)209*1772Sjl139090 ap_list_pack(ri_ap_t *aplist, char **bufp, size_t *sizep, int encoding)
2100Sstevel@tonic-gate {
2110Sstevel@tonic-gate 	nvlist_t	*nvl = NULL;
2120Sstevel@tonic-gate 	char		*buf = NULL;
2130Sstevel@tonic-gate 	size_t		size;
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate 	assert(bufp != NULL && sizep != NULL);
2160Sstevel@tonic-gate 
2170Sstevel@tonic-gate 	*sizep = 0;
2180Sstevel@tonic-gate 	*bufp = NULL;
2190Sstevel@tonic-gate 
2200Sstevel@tonic-gate 	if (nvlist_alloc(&nvl, 0, 0) != 0) {
2210Sstevel@tonic-gate 		dprintf((stderr, "nvlist_alloc fail\n"));
2220Sstevel@tonic-gate 		return (-1);
2230Sstevel@tonic-gate 	}
2240Sstevel@tonic-gate 
2250Sstevel@tonic-gate 	while (aplist != NULL) {
2260Sstevel@tonic-gate 		s_free(buf);
227*1772Sjl139090 		if (ap_pack(aplist, &buf, &size, encoding) != 0)
2280Sstevel@tonic-gate 			goto fail;
2290Sstevel@tonic-gate 
2300Sstevel@tonic-gate 		if (nvlist_add_byte_array(nvl, RI_AP_T, (uchar_t *)buf,
2310Sstevel@tonic-gate 		    size) != 0) {
2320Sstevel@tonic-gate 			dprintf((stderr, "nvlist_add_byte_array fail "
2330Sstevel@tonic-gate 			    "(%s)\n", RI_AP_T));
2340Sstevel@tonic-gate 			goto fail;
2350Sstevel@tonic-gate 		}
2360Sstevel@tonic-gate 		aplist = aplist->next;
2370Sstevel@tonic-gate 	}
2380Sstevel@tonic-gate 
2390Sstevel@tonic-gate 	s_free(buf);
240*1772Sjl139090 	if (nvlist_pack(nvl, &buf, &size, encoding, 0) != 0) {
2410Sstevel@tonic-gate 		dprintf((stderr, "nvlist_pack fail\n"));
2420Sstevel@tonic-gate 		goto fail;
2430Sstevel@tonic-gate 	}
2440Sstevel@tonic-gate 
2450Sstevel@tonic-gate 	nvlist_free(nvl);
2460Sstevel@tonic-gate 	*bufp = buf;
2470Sstevel@tonic-gate 	*sizep = size;
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate 	return (0);
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate fail:
2520Sstevel@tonic-gate 	s_free(buf);
2530Sstevel@tonic-gate 	if (nvl != NULL)
2540Sstevel@tonic-gate 		nvlist_free(nvl);
2550Sstevel@tonic-gate 
2560Sstevel@tonic-gate 	return (-1);
2570Sstevel@tonic-gate }
2580Sstevel@tonic-gate 
2590Sstevel@tonic-gate /*
2600Sstevel@tonic-gate  * Pack a list of ri_dev_t's.
2610Sstevel@tonic-gate  */
2620Sstevel@tonic-gate static int
dev_list_pack(ri_dev_t * devlist,char ** bufp,size_t * sizep,int encoding)263*1772Sjl139090 dev_list_pack(ri_dev_t *devlist, char **bufp, size_t *sizep, int encoding)
2640Sstevel@tonic-gate {
2650Sstevel@tonic-gate 	nvlist_t	*nvl = NULL;
2660Sstevel@tonic-gate 	char		*buf = NULL;
2670Sstevel@tonic-gate 	size_t		size = 0;
2680Sstevel@tonic-gate 
2690Sstevel@tonic-gate 	assert(bufp != NULL && sizep != NULL);
2700Sstevel@tonic-gate 
2710Sstevel@tonic-gate 	*sizep = 0;
2720Sstevel@tonic-gate 	*bufp = NULL;
2730Sstevel@tonic-gate 
2740Sstevel@tonic-gate 	if (nvlist_alloc(&nvl, 0, 0) != 0) {
2750Sstevel@tonic-gate 		dprintf((stderr, "nvlist_alloc fail\n"));
2760Sstevel@tonic-gate 		return (-1);
2770Sstevel@tonic-gate 	}
2780Sstevel@tonic-gate 
2790Sstevel@tonic-gate 	while (devlist != NULL) {
2800Sstevel@tonic-gate 		s_free(buf);
281*1772Sjl139090 		if (dev_pack(devlist, &buf, &size, encoding) != 0)
2820Sstevel@tonic-gate 			goto fail;
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate 		if (nvlist_add_byte_array(nvl, RI_DEV_T, (uchar_t *)buf,
2850Sstevel@tonic-gate 		    size) != 0) {
2860Sstevel@tonic-gate 			dprintf((stderr, "nvlist_add_byte_array fail "
2870Sstevel@tonic-gate 			    "(%s)\n", RI_DEV_T));
2880Sstevel@tonic-gate 			goto fail;
2890Sstevel@tonic-gate 		}
2900Sstevel@tonic-gate 		devlist = devlist->next;
2910Sstevel@tonic-gate 	}
2920Sstevel@tonic-gate 
2930Sstevel@tonic-gate 	s_free(buf);
294*1772Sjl139090 	if (nvlist_pack(nvl, &buf, &size, encoding, 0) != 0) {
2950Sstevel@tonic-gate 		dprintf((stderr, "nvlist_pack fail\n"));
2960Sstevel@tonic-gate 		goto fail;
2970Sstevel@tonic-gate 	}
2980Sstevel@tonic-gate 
2990Sstevel@tonic-gate 	nvlist_free(nvl);
3000Sstevel@tonic-gate 	*bufp = buf;
3010Sstevel@tonic-gate 	*sizep = size;
3020Sstevel@tonic-gate 
3030Sstevel@tonic-gate 	return (0);
3040Sstevel@tonic-gate 
3050Sstevel@tonic-gate fail:
3060Sstevel@tonic-gate 	s_free(buf);
3070Sstevel@tonic-gate 	if (nvl != NULL)
3080Sstevel@tonic-gate 		nvlist_free(nvl);
3090Sstevel@tonic-gate 
3100Sstevel@tonic-gate 	return (-1);
3110Sstevel@tonic-gate }
3120Sstevel@tonic-gate 
3130Sstevel@tonic-gate /*
3140Sstevel@tonic-gate  * Pack a list of ri_client_t's.
3150Sstevel@tonic-gate  */
3160Sstevel@tonic-gate static int
client_list_pack(ri_client_t * client_list,char ** bufp,size_t * sizep,int encoding)317*1772Sjl139090 client_list_pack(ri_client_t *client_list, char **bufp, size_t *sizep,
318*1772Sjl139090     int encoding)
3190Sstevel@tonic-gate {
3200Sstevel@tonic-gate 	nvlist_t	*nvl = NULL;
3210Sstevel@tonic-gate 	char		*buf = NULL;
3220Sstevel@tonic-gate 	size_t		size = 0;
3230Sstevel@tonic-gate 
3240Sstevel@tonic-gate 	assert(bufp != NULL && sizep != NULL);
3250Sstevel@tonic-gate 
3260Sstevel@tonic-gate 	*sizep = 0;
3270Sstevel@tonic-gate 	*bufp = NULL;
3280Sstevel@tonic-gate 
3290Sstevel@tonic-gate 	if (nvlist_alloc(&nvl, 0, 0) != 0) {
3300Sstevel@tonic-gate 		dprintf((stderr, "nvlist_alloc fail\n"));
3310Sstevel@tonic-gate 		return (-1);
3320Sstevel@tonic-gate 	}
3330Sstevel@tonic-gate 
3340Sstevel@tonic-gate 	while (client_list != NULL) {
3350Sstevel@tonic-gate 		s_free(buf);
336*1772Sjl139090 		if (client_pack(client_list, &buf, &size, encoding) != 0)
3370Sstevel@tonic-gate 			goto fail;
3380Sstevel@tonic-gate 
3390Sstevel@tonic-gate 		if (nvlist_add_byte_array(nvl, RI_CLIENT_T, (uchar_t *)buf,
3400Sstevel@tonic-gate 		    size) != 0) {
3410Sstevel@tonic-gate 			dprintf((stderr, "nvlist_add_byte_array fail "
3420Sstevel@tonic-gate 			    "(%s)\n", RI_CLIENT_T));
3430Sstevel@tonic-gate 			goto fail;
3440Sstevel@tonic-gate 		}
3450Sstevel@tonic-gate 		client_list = client_list->next;
3460Sstevel@tonic-gate 	}
3470Sstevel@tonic-gate 
3480Sstevel@tonic-gate 	s_free(buf);
349*1772Sjl139090 	if (nvlist_pack(nvl, &buf, &size, encoding, 0) != 0) {
3500Sstevel@tonic-gate 		dprintf((stderr, "nvlist_pack fail\n"));
3510Sstevel@tonic-gate 		goto fail;
3520Sstevel@tonic-gate 	}
3530Sstevel@tonic-gate 
3540Sstevel@tonic-gate 	nvlist_free(nvl);
3550Sstevel@tonic-gate 	*bufp = buf;
3560Sstevel@tonic-gate 	*sizep = size;
3570Sstevel@tonic-gate 
3580Sstevel@tonic-gate 	return (0);
3590Sstevel@tonic-gate 
3600Sstevel@tonic-gate fail:
3610Sstevel@tonic-gate 	s_free(buf);
3620Sstevel@tonic-gate 	if (nvl != NULL)
3630Sstevel@tonic-gate 		nvlist_free(nvl);
3640Sstevel@tonic-gate 
3650Sstevel@tonic-gate 	return (-1);
3660Sstevel@tonic-gate }
3670Sstevel@tonic-gate 
3680Sstevel@tonic-gate static int
ap_pack(ri_ap_t * ap,char ** bufp,size_t * sizep,int encoding)369*1772Sjl139090 ap_pack(ri_ap_t *ap, char **bufp, size_t *sizep, int encoding)
3700Sstevel@tonic-gate {
3710Sstevel@tonic-gate 	nvlist_t	*nvl = NULL;
3720Sstevel@tonic-gate 	char		*buf = NULL;
3730Sstevel@tonic-gate 	size_t		size = 0;
3740Sstevel@tonic-gate 
3750Sstevel@tonic-gate 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
3760Sstevel@tonic-gate 		dprintf((stderr, "nvlist_alloc fail\n"));
3770Sstevel@tonic-gate 		return (-1);
3780Sstevel@tonic-gate 	}
3790Sstevel@tonic-gate 
380*1772Sjl139090 	if (pack_add_byte_array(ap->conf_props, RI_AP_PROPS, nvl,
381*1772Sjl139090 	    encoding) != 0)
3820Sstevel@tonic-gate 		goto fail;
3830Sstevel@tonic-gate 
384*1772Sjl139090 	if (dev_list_pack(ap->cpus, &buf, &size, encoding) != 0)
3850Sstevel@tonic-gate 		goto fail;
3860Sstevel@tonic-gate 
3870Sstevel@tonic-gate 	if (nvlist_add_byte_array(nvl, RI_AP_CPUS, (uchar_t *)buf,
3880Sstevel@tonic-gate 	    size) != 0) {
3890Sstevel@tonic-gate 		dprintf((stderr, "nvlist_add_byte_array (%s)\n", RI_AP_CPUS));
3900Sstevel@tonic-gate 		goto fail;
3910Sstevel@tonic-gate 	}
3920Sstevel@tonic-gate 
3930Sstevel@tonic-gate 	s_free(buf);
394*1772Sjl139090 	if (dev_list_pack(ap->mems, &buf, &size, encoding) != 0)
3950Sstevel@tonic-gate 		goto fail;
3960Sstevel@tonic-gate 
3970Sstevel@tonic-gate 	if (nvlist_add_byte_array(nvl, RI_AP_MEMS, (uchar_t *)buf,
3980Sstevel@tonic-gate 	    size) != 0) {
3990Sstevel@tonic-gate 		dprintf((stderr, "nvlist_add_byte_array (%s)n", RI_AP_MEMS));
4000Sstevel@tonic-gate 		goto fail;
4010Sstevel@tonic-gate 	}
4020Sstevel@tonic-gate 
4030Sstevel@tonic-gate 	s_free(buf);
404*1772Sjl139090 	if (dev_list_pack(ap->ios, &buf, &size, encoding) != 0)
4050Sstevel@tonic-gate 		goto fail;
4060Sstevel@tonic-gate 
4070Sstevel@tonic-gate 	if (nvlist_add_byte_array(nvl, RI_AP_IOS, (uchar_t *)buf,
4080Sstevel@tonic-gate 	    size) != 0) {
4090Sstevel@tonic-gate 		dprintf((stderr, "nvlist_add_byte_array (%s)n", RI_AP_IOS));
4100Sstevel@tonic-gate 		goto fail;
4110Sstevel@tonic-gate 	}
4120Sstevel@tonic-gate 
4130Sstevel@tonic-gate 	s_free(buf);
414*1772Sjl139090 	if (nvlist_pack(nvl, &buf, &size, encoding, 0) != 0) {
4150Sstevel@tonic-gate 		dprintf((stderr, "nvlist_pack fail\n"));
4160Sstevel@tonic-gate 		goto fail;
4170Sstevel@tonic-gate 	}
4180Sstevel@tonic-gate 
4190Sstevel@tonic-gate 	nvlist_free(nvl);
4200Sstevel@tonic-gate 	*bufp = buf;
4210Sstevel@tonic-gate 	*sizep = size;
4220Sstevel@tonic-gate 
4230Sstevel@tonic-gate 	return (0);
4240Sstevel@tonic-gate 
4250Sstevel@tonic-gate fail:
4260Sstevel@tonic-gate 	s_free(buf);
4270Sstevel@tonic-gate 	if (nvl != NULL)
4280Sstevel@tonic-gate 		nvlist_free(nvl);
4290Sstevel@tonic-gate 
4300Sstevel@tonic-gate 	return (-1);
4310Sstevel@tonic-gate }
4320Sstevel@tonic-gate 
4330Sstevel@tonic-gate static int
dev_pack(ri_dev_t * dev,char ** bufp,size_t * sizep,int encoding)434*1772Sjl139090 dev_pack(ri_dev_t *dev, char **bufp, size_t *sizep, int encoding)
4350Sstevel@tonic-gate {
4360Sstevel@tonic-gate 	nvlist_t	*nvl = NULL;
4370Sstevel@tonic-gate 	char		*buf = NULL;
4380Sstevel@tonic-gate 	size_t		size = 0;
4390Sstevel@tonic-gate 
4400Sstevel@tonic-gate 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
4410Sstevel@tonic-gate 		dprintf((stderr, "nvlist_alloc fail\n"));
4420Sstevel@tonic-gate 		return (-1);
4430Sstevel@tonic-gate 	}
4440Sstevel@tonic-gate 
445*1772Sjl139090 	if (pack_add_byte_array(dev->conf_props, RI_DEV_PROPS, nvl,
446*1772Sjl139090 	    encoding) != 0)
4470Sstevel@tonic-gate 		goto fail;
4480Sstevel@tonic-gate 
449*1772Sjl139090 	if (client_list_pack(dev->rcm_clients, &buf, &size, encoding) != 0)
4500Sstevel@tonic-gate 		goto fail;
4510Sstevel@tonic-gate 
4520Sstevel@tonic-gate 	if (nvlist_add_byte_array(nvl, RI_DEV_CLIENTS, (uchar_t *)buf,
4530Sstevel@tonic-gate 	    size) != 0) {
4540Sstevel@tonic-gate 		dprintf((stderr, "nvlist_add_byte_array (%s)n",
4550Sstevel@tonic-gate 		    RI_DEV_CLIENTS));
4560Sstevel@tonic-gate 		goto fail;
4570Sstevel@tonic-gate 	}
4580Sstevel@tonic-gate 
4590Sstevel@tonic-gate 	s_free(buf);
460*1772Sjl139090 	if (nvlist_pack(nvl, &buf, &size, encoding, 0) != 0) {
4610Sstevel@tonic-gate 		dprintf((stderr, "nvlist_pack fail\n"));
4620Sstevel@tonic-gate 		goto fail;
4630Sstevel@tonic-gate 	}
4640Sstevel@tonic-gate 
4650Sstevel@tonic-gate 	nvlist_free(nvl);
4660Sstevel@tonic-gate 	*bufp = buf;
4670Sstevel@tonic-gate 	*sizep = size;
4680Sstevel@tonic-gate 
4690Sstevel@tonic-gate 	return (0);
4700Sstevel@tonic-gate 
4710Sstevel@tonic-gate fail:
4720Sstevel@tonic-gate 	s_free(buf);
4730Sstevel@tonic-gate 	if (nvl != NULL)
4740Sstevel@tonic-gate 		nvlist_free(nvl);
4750Sstevel@tonic-gate 
4760Sstevel@tonic-gate 	return (-1);
4770Sstevel@tonic-gate }
4780Sstevel@tonic-gate 
4790Sstevel@tonic-gate static int
client_pack(ri_client_t * client,char ** bufp,size_t * sizep,int encoding)480*1772Sjl139090 client_pack(ri_client_t *client, char **bufp, size_t *sizep, int encoding)
4810Sstevel@tonic-gate {
4820Sstevel@tonic-gate 	nvlist_t	*nvl = NULL;
4830Sstevel@tonic-gate 	char		*buf = NULL;
4840Sstevel@tonic-gate 	size_t		size = 0;
4850Sstevel@tonic-gate 
4860Sstevel@tonic-gate 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
4870Sstevel@tonic-gate 		dprintf((stderr, "nvlist_alloc fail\n"));
4880Sstevel@tonic-gate 		return (-1);
4890Sstevel@tonic-gate 	}
4900Sstevel@tonic-gate 
4910Sstevel@tonic-gate 	if (pack_add_byte_array(client->usg_props, RI_CLIENT_USAGE_PROPS,
492*1772Sjl139090 	    nvl, encoding) != 0) {
4930Sstevel@tonic-gate 		goto fail;
4940Sstevel@tonic-gate 	}
4950Sstevel@tonic-gate 
4960Sstevel@tonic-gate 	/*
4970Sstevel@tonic-gate 	 * This will only be present if RI_VERBOSE was specified
4980Sstevel@tonic-gate 	 * in the call to ri_init.
4990Sstevel@tonic-gate 	 */
5000Sstevel@tonic-gate 	if (client->v_props != NULL && pack_add_byte_array(client->v_props,
501*1772Sjl139090 	    RI_CLIENT_VERB_PROPS, nvl, encoding) != 0) {
5020Sstevel@tonic-gate 		goto fail;
5030Sstevel@tonic-gate 	}
5040Sstevel@tonic-gate 
505*1772Sjl139090 	if (nvlist_pack(nvl, &buf, &size, encoding, 0) != 0) {
5060Sstevel@tonic-gate 		dprintf((stderr, "nvlist_pack fail\n"));
5070Sstevel@tonic-gate 		goto fail;
5080Sstevel@tonic-gate 	}
5090Sstevel@tonic-gate 
5100Sstevel@tonic-gate 	nvlist_free(nvl);
5110Sstevel@tonic-gate 	*bufp = buf;
5120Sstevel@tonic-gate 	*sizep = size;
5130Sstevel@tonic-gate 
5140Sstevel@tonic-gate 	return (0);
5150Sstevel@tonic-gate 
5160Sstevel@tonic-gate fail:
5170Sstevel@tonic-gate 	s_free(buf);
5180Sstevel@tonic-gate 	if (nvl != NULL)
5190Sstevel@tonic-gate 		nvlist_free(nvl);
5200Sstevel@tonic-gate 
5210Sstevel@tonic-gate 	return (-1);
5220Sstevel@tonic-gate }
5230Sstevel@tonic-gate 
5240Sstevel@tonic-gate /*
5250Sstevel@tonic-gate  * Pack nvlist_t and add as byte array to another nvlist_t.
5260Sstevel@tonic-gate  */
5270Sstevel@tonic-gate static int
pack_add_byte_array(nvlist_t * nvl_packme,char * name,nvlist_t * nvl,int encoding)528*1772Sjl139090 pack_add_byte_array(nvlist_t *nvl_packme, char *name, nvlist_t *nvl,
529*1772Sjl139090     int encoding)
5300Sstevel@tonic-gate {
5310Sstevel@tonic-gate 	char	*buf = NULL;
5320Sstevel@tonic-gate 	size_t	size = 0;
5330Sstevel@tonic-gate 
534*1772Sjl139090 	if (nvlist_pack(nvl_packme, &buf, &size, encoding, 0) != 0) {
5350Sstevel@tonic-gate 		dprintf((stderr, "nvlist_pack fail (%s)\n", name));
5360Sstevel@tonic-gate 		s_free(buf);
5370Sstevel@tonic-gate 		return (-1);
5380Sstevel@tonic-gate 	}
5390Sstevel@tonic-gate 
5400Sstevel@tonic-gate 	if (nvlist_add_byte_array(nvl, name, (uchar_t *)buf, size) != 0) {
5410Sstevel@tonic-gate 		dprintf((stderr, "nvlist_add_byte_array fail (%s)\n", name));
5420Sstevel@tonic-gate 		return (-1);
5430Sstevel@tonic-gate 	}
5440Sstevel@tonic-gate 
5450Sstevel@tonic-gate 	s_free(buf);
5460Sstevel@tonic-gate 	return (0);
5470Sstevel@tonic-gate }
5480Sstevel@tonic-gate 
5490Sstevel@tonic-gate /*
5500Sstevel@tonic-gate  * Unpack buf into ri_hdl_t.
5510Sstevel@tonic-gate  */
5520Sstevel@tonic-gate int
ri_unpack(caddr_t buf,size_t size,ri_hdl_t ** hdlp)5530Sstevel@tonic-gate ri_unpack(caddr_t buf, size_t size, ri_hdl_t **hdlp)
5540Sstevel@tonic-gate {
5550Sstevel@tonic-gate 	ri_hdl_t	*ri_hdl = NULL;
5560Sstevel@tonic-gate 	nvlist_t	*nvl = NULL;
5570Sstevel@tonic-gate 
5580Sstevel@tonic-gate 	if (hdlp == NULL)
5590Sstevel@tonic-gate 		return (RI_INVAL);
5600Sstevel@tonic-gate 
5610Sstevel@tonic-gate 	*hdlp = NULL;
5620Sstevel@tonic-gate 	if ((ri_hdl = calloc(1, sizeof (*ri_hdl))) == NULL) {
5630Sstevel@tonic-gate 		dprintf((stderr, "calloc: %s\n", strerror(errno)));
5640Sstevel@tonic-gate 		return (RI_FAILURE);
5650Sstevel@tonic-gate 	}
5660Sstevel@tonic-gate 
5670Sstevel@tonic-gate 	if (nvlist_unpack(buf, size, &nvl, 0) != 0) {
5680Sstevel@tonic-gate 		dprintf((stderr, "nvlist_unpack fail\n"));
5690Sstevel@tonic-gate 		goto fail;
5700Sstevel@tonic-gate 	}
5710Sstevel@tonic-gate 
5720Sstevel@tonic-gate 	if (nvlist_lookup_int32(nvl, RI_HDL_FLAGS, &ri_hdl->flags) != 0) {
5730Sstevel@tonic-gate 		dprintf((stderr, "nvlist_lookup_int32 fail (%s)\n",
5740Sstevel@tonic-gate 		    RI_HDL_FLAGS));
5750Sstevel@tonic-gate 		goto fail;
5760Sstevel@tonic-gate 	}
5770Sstevel@tonic-gate 
5780Sstevel@tonic-gate 	buf = NULL;
5790Sstevel@tonic-gate 	size = 0;
5800Sstevel@tonic-gate 	if (nvlist_lookup_byte_array(nvl, RI_HDL_APS, (uchar_t **)&buf,
5810Sstevel@tonic-gate 	    (uint_t *)&size) != 0) {
5820Sstevel@tonic-gate 		dprintf((stderr, "nvlist_lookup_int32 fail (%s)\n",
5830Sstevel@tonic-gate 		    RI_HDL_APS));
5840Sstevel@tonic-gate 		goto fail;
5850Sstevel@tonic-gate 	}
5860Sstevel@tonic-gate 
5870Sstevel@tonic-gate 	if (ap_list_unpack(buf, size, &ri_hdl->aps) != 0)
5880Sstevel@tonic-gate 		goto fail;
5890Sstevel@tonic-gate 
5900Sstevel@tonic-gate 	buf = NULL;
5910Sstevel@tonic-gate 	size = 0;
5920Sstevel@tonic-gate 	if (nvlist_lookup_byte_array(nvl, RI_HDL_CPU_CAPS, (uchar_t **)&buf,
5930Sstevel@tonic-gate 	    (uint_t *)&size) != 0) {
5940Sstevel@tonic-gate 		dprintf((stderr, "nvlist_lookup_byte_array fail (%s)\n",
5950Sstevel@tonic-gate 		    RI_HDL_CPU_CAPS));
5960Sstevel@tonic-gate 		goto fail;
5970Sstevel@tonic-gate 	}
5980Sstevel@tonic-gate 
5990Sstevel@tonic-gate 	if (client_list_unpack(buf, size, &ri_hdl->cpu_cap_clients) != 0)
6000Sstevel@tonic-gate 		goto fail;
6010Sstevel@tonic-gate 
6020Sstevel@tonic-gate 	buf = NULL;
6030Sstevel@tonic-gate 	size = 0;
6040Sstevel@tonic-gate 	if (nvlist_lookup_byte_array(nvl, RI_HDL_MEM_CAPS, (uchar_t **)&buf,
6050Sstevel@tonic-gate 	    (uint_t *)&size) != 0) {
6060Sstevel@tonic-gate 		dprintf((stderr, "nvlist_lookup_byte_array fail (%s)\n",
6070Sstevel@tonic-gate 		    RI_HDL_MEM_CAPS));
6080Sstevel@tonic-gate 		goto fail;
6090Sstevel@tonic-gate 	}
6100Sstevel@tonic-gate 
6110Sstevel@tonic-gate 	if (client_list_unpack(buf, size, &ri_hdl->mem_cap_clients) != 0)
6120Sstevel@tonic-gate 		goto fail;
6130Sstevel@tonic-gate 
6140Sstevel@tonic-gate 	*hdlp = ri_hdl;
6150Sstevel@tonic-gate 
6160Sstevel@tonic-gate 	return (0);
6170Sstevel@tonic-gate 
6180Sstevel@tonic-gate fail:
6190Sstevel@tonic-gate 	free(ri_hdl);
6200Sstevel@tonic-gate 	if (nvl != NULL)
6210Sstevel@tonic-gate 		nvlist_free(nvl);
6220Sstevel@tonic-gate 
6230Sstevel@tonic-gate 	return (-1);
6240Sstevel@tonic-gate }
6250Sstevel@tonic-gate 
6260Sstevel@tonic-gate static int
ap_list_unpack(char * buf,size_t size,ri_ap_t ** aps)6270Sstevel@tonic-gate ap_list_unpack(char *buf, size_t size, ri_ap_t **aps)
6280Sstevel@tonic-gate {
6290Sstevel@tonic-gate 	nvpair_t	*nvp = NULL;
6300Sstevel@tonic-gate 	nvlist_t	*nvl;
6310Sstevel@tonic-gate 	ri_ap_t		*aplist = NULL;
6320Sstevel@tonic-gate 	ri_ap_t		*prev = NULL;
6330Sstevel@tonic-gate 	ri_ap_t		*tmp = NULL;
6340Sstevel@tonic-gate 
6350Sstevel@tonic-gate 	if (nvlist_unpack(buf, size, &nvl, 0) != 0) {
6360Sstevel@tonic-gate 		dprintf((stderr, "nvlist_unpack fail\n"));
6370Sstevel@tonic-gate 		return (-1);
6380Sstevel@tonic-gate 	}
6390Sstevel@tonic-gate 
6400Sstevel@tonic-gate 	while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
6410Sstevel@tonic-gate 		assert(strcmp(nvpair_name(nvp), RI_AP_T) == 0 &&
6420Sstevel@tonic-gate 		    nvpair_type(nvp) == DATA_TYPE_BYTE_ARRAY);
6430Sstevel@tonic-gate 
6440Sstevel@tonic-gate 		if ((tmp = calloc(1, sizeof (*tmp))) == NULL) {
6450Sstevel@tonic-gate 			dprintf((stderr, "calloc: %s\n", strerror(errno)));
6460Sstevel@tonic-gate 			goto fail;
6470Sstevel@tonic-gate 		}
6480Sstevel@tonic-gate 
6490Sstevel@tonic-gate 		buf = NULL;
6500Sstevel@tonic-gate 		size = 0;
6510Sstevel@tonic-gate 		if (nvpair_value_byte_array(nvp, (uchar_t **)&buf,
6520Sstevel@tonic-gate 		    (uint_t *)&size) != 0) {
6530Sstevel@tonic-gate 			dprintf((stderr, "nvpair_value_byte_array fail\n"));
6540Sstevel@tonic-gate 			goto fail;
6550Sstevel@tonic-gate 		}
6560Sstevel@tonic-gate 
6570Sstevel@tonic-gate 		if (ap_unpack(buf, size, tmp) != 0)
6580Sstevel@tonic-gate 			goto fail;
6590Sstevel@tonic-gate 
6600Sstevel@tonic-gate 		if (aplist == NULL) {
6610Sstevel@tonic-gate 			prev = aplist = tmp;
6620Sstevel@tonic-gate 		} else {
6630Sstevel@tonic-gate 			prev->next = tmp;
6640Sstevel@tonic-gate 			prev = tmp;
6650Sstevel@tonic-gate 		}
6660Sstevel@tonic-gate 	}
6670Sstevel@tonic-gate 
6680Sstevel@tonic-gate 	nvlist_free(nvl);
6690Sstevel@tonic-gate 	*aps = aplist;
6700Sstevel@tonic-gate 
6710Sstevel@tonic-gate 	return (0);
6720Sstevel@tonic-gate 
6730Sstevel@tonic-gate fail:
6740Sstevel@tonic-gate 	if (nvl != NULL)
6750Sstevel@tonic-gate 		nvlist_free(nvl);
6760Sstevel@tonic-gate 	if (aplist != NULL) {
6770Sstevel@tonic-gate 		while ((tmp = aplist) != NULL) {
6780Sstevel@tonic-gate 			aplist = aplist->next;
6790Sstevel@tonic-gate 			ri_ap_free(tmp);
6800Sstevel@tonic-gate 		}
6810Sstevel@tonic-gate 	}
6820Sstevel@tonic-gate 
6830Sstevel@tonic-gate 	return (-1);
6840Sstevel@tonic-gate }
6850Sstevel@tonic-gate 
6860Sstevel@tonic-gate static int
dev_list_unpack(char * buf,size_t size,ri_dev_t ** devs)6870Sstevel@tonic-gate dev_list_unpack(char *buf, size_t size, ri_dev_t **devs)
6880Sstevel@tonic-gate {
6890Sstevel@tonic-gate 	nvpair_t	*nvp = NULL;
6900Sstevel@tonic-gate 	nvlist_t	*nvl;
6910Sstevel@tonic-gate 	ri_dev_t	*devlist = NULL;
6920Sstevel@tonic-gate 	ri_dev_t	*prev = NULL;
6930Sstevel@tonic-gate 	ri_dev_t	*tmp = NULL;
6940Sstevel@tonic-gate 
6950Sstevel@tonic-gate 	if (nvlist_unpack(buf, size, &nvl, 0) != 0) {
6960Sstevel@tonic-gate 		dprintf((stderr, "nvlist_unpack fail\n"));
6970Sstevel@tonic-gate 		return (-1);
6980Sstevel@tonic-gate 	}
6990Sstevel@tonic-gate 
7000Sstevel@tonic-gate 	while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
7010Sstevel@tonic-gate 		assert(strcmp(nvpair_name(nvp), RI_DEV_T) == 0 &&
7020Sstevel@tonic-gate 		    nvpair_type(nvp) == DATA_TYPE_BYTE_ARRAY);
7030Sstevel@tonic-gate 
7040Sstevel@tonic-gate 		if ((tmp = calloc(1, sizeof (*tmp))) == NULL) {
7050Sstevel@tonic-gate 			dprintf((stderr, "calloc: %s\n", strerror(errno)));
7060Sstevel@tonic-gate 			goto fail;
7070Sstevel@tonic-gate 		}
7080Sstevel@tonic-gate 
7090Sstevel@tonic-gate 		if (nvpair_value_byte_array(nvp, (uchar_t **)&buf,
7100Sstevel@tonic-gate 		    (uint_t *)&size) != 0) {
7110Sstevel@tonic-gate 			dprintf((stderr, "nvpair_value_byte_array fail\n"));
7120Sstevel@tonic-gate 			goto fail;
7130Sstevel@tonic-gate 		}
7140Sstevel@tonic-gate 
7150Sstevel@tonic-gate 		if (dev_unpack(buf, size, tmp) != 0)
7160Sstevel@tonic-gate 			goto fail;
7170Sstevel@tonic-gate 
7180Sstevel@tonic-gate 		if (devlist == NULL) {
7190Sstevel@tonic-gate 			prev = devlist = tmp;
7200Sstevel@tonic-gate 		} else {
7210Sstevel@tonic-gate 			prev->next = tmp;
7220Sstevel@tonic-gate 			prev = tmp;
7230Sstevel@tonic-gate 		}
7240Sstevel@tonic-gate 	}
7250Sstevel@tonic-gate 
7260Sstevel@tonic-gate 	nvlist_free(nvl);
7270Sstevel@tonic-gate 	*devs = devlist;
7280Sstevel@tonic-gate 
7290Sstevel@tonic-gate 	return (0);
7300Sstevel@tonic-gate 
7310Sstevel@tonic-gate fail:
7320Sstevel@tonic-gate 	if (nvl != NULL)
7330Sstevel@tonic-gate 		nvlist_free(nvl);
7340Sstevel@tonic-gate 	if (devlist != NULL) {
7350Sstevel@tonic-gate 		while ((tmp = devlist) != NULL) {
7360Sstevel@tonic-gate 			devlist = devlist->next;
7370Sstevel@tonic-gate 			ri_dev_free(tmp);
7380Sstevel@tonic-gate 		}
7390Sstevel@tonic-gate 	}
7400Sstevel@tonic-gate 
7410Sstevel@tonic-gate 	return (-1);
7420Sstevel@tonic-gate }
7430Sstevel@tonic-gate 
7440Sstevel@tonic-gate static int
client_list_unpack(char * buf,size_t size,ri_client_t ** clients)7450Sstevel@tonic-gate client_list_unpack(char *buf, size_t size, ri_client_t **clients)
7460Sstevel@tonic-gate {
7470Sstevel@tonic-gate 	nvpair_t	*nvp = NULL;
7480Sstevel@tonic-gate 	nvlist_t	*nvl;
7490Sstevel@tonic-gate 	ri_client_t	*client_list = NULL;
7500Sstevel@tonic-gate 	ri_client_t	*prev = NULL;
7510Sstevel@tonic-gate 	ri_client_t	*tmp = NULL;
7520Sstevel@tonic-gate 
7530Sstevel@tonic-gate 	if (nvlist_unpack(buf, size, &nvl, 0) != 0) {
7540Sstevel@tonic-gate 		dprintf((stderr, "nvlist_unpack fail\n"));
7550Sstevel@tonic-gate 		return (-1);
7560Sstevel@tonic-gate 	}
7570Sstevel@tonic-gate 
7580Sstevel@tonic-gate 	while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
7590Sstevel@tonic-gate 		assert(strcmp(nvpair_name(nvp), RI_CLIENT_T) == 0);
7600Sstevel@tonic-gate 		assert(nvpair_type(nvp) == DATA_TYPE_BYTE_ARRAY);
7610Sstevel@tonic-gate 
7620Sstevel@tonic-gate 		if ((tmp = calloc(1, sizeof (*tmp))) == NULL) {
7630Sstevel@tonic-gate 			dprintf((stderr, "calloc: %s\n", strerror(errno)));
7640Sstevel@tonic-gate 			goto fail;
7650Sstevel@tonic-gate 		}
7660Sstevel@tonic-gate 
7670Sstevel@tonic-gate 		buf = NULL;
7680Sstevel@tonic-gate 		size = 0;
7690Sstevel@tonic-gate 		if (nvpair_value_byte_array(nvp, (uchar_t **)&buf,
7700Sstevel@tonic-gate 		    (uint_t *)&size) != 0) {
7710Sstevel@tonic-gate 			dprintf((stderr, "nvpair_value_byte_array fail\n"));
7720Sstevel@tonic-gate 			goto fail;
7730Sstevel@tonic-gate 		}
7740Sstevel@tonic-gate 
7750Sstevel@tonic-gate 		if (client_unpack(buf, size, tmp) != 0)
7760Sstevel@tonic-gate 			goto fail;
7770Sstevel@tonic-gate 
7780Sstevel@tonic-gate 		if (client_list == NULL) {
7790Sstevel@tonic-gate 			prev = client_list = tmp;
7800Sstevel@tonic-gate 		} else {
7810Sstevel@tonic-gate 			prev->next = tmp;
7820Sstevel@tonic-gate 			prev = tmp;
7830Sstevel@tonic-gate 		}
7840Sstevel@tonic-gate 	}
7850Sstevel@tonic-gate 
7860Sstevel@tonic-gate 	nvlist_free(nvl);
7870Sstevel@tonic-gate 	*clients = client_list;
7880Sstevel@tonic-gate 
7890Sstevel@tonic-gate 	return (0);
7900Sstevel@tonic-gate 
7910Sstevel@tonic-gate fail:
7920Sstevel@tonic-gate 	if (nvl != NULL)
7930Sstevel@tonic-gate 		nvlist_free(nvl);
7940Sstevel@tonic-gate 	if (client_list != NULL) {
7950Sstevel@tonic-gate 		while ((tmp = client_list) != NULL) {
7960Sstevel@tonic-gate 			client_list = client_list->next;
7970Sstevel@tonic-gate 			ri_client_free(tmp);
7980Sstevel@tonic-gate 		}
7990Sstevel@tonic-gate 	}
8000Sstevel@tonic-gate 
8010Sstevel@tonic-gate 	return (-1);
8020Sstevel@tonic-gate }
8030Sstevel@tonic-gate 
8040Sstevel@tonic-gate static int
client_unpack(char * buf,size_t size,ri_client_t * client)8050Sstevel@tonic-gate client_unpack(char *buf, size_t size, ri_client_t *client)
8060Sstevel@tonic-gate {
8070Sstevel@tonic-gate 	nvlist_t	*nvl;
8080Sstevel@tonic-gate 
8090Sstevel@tonic-gate 	if (nvlist_unpack(buf, size, &nvl, 0) != 0) {
8100Sstevel@tonic-gate 		dprintf((stderr, "nvlist_unpack fail\n"));
8110Sstevel@tonic-gate 		return (-1);
8120Sstevel@tonic-gate 	}
8130Sstevel@tonic-gate 
8140Sstevel@tonic-gate 	if (lookup_unpack_byte_array(nvl, RI_CLIENT_USAGE_PROPS,
8150Sstevel@tonic-gate 	    &client->usg_props) != 0) {
8160Sstevel@tonic-gate 		nvlist_free(nvl);
8170Sstevel@tonic-gate 		return (-1);
8180Sstevel@tonic-gate 	}
8190Sstevel@tonic-gate 
8200Sstevel@tonic-gate #ifdef DEBUG
8210Sstevel@tonic-gate 	nvlist_print(stderr, client->usg_props);
8220Sstevel@tonic-gate #endif /* DEBUG */
8230Sstevel@tonic-gate 
8240Sstevel@tonic-gate 	/*
8250Sstevel@tonic-gate 	 * Verbose properties for RCM clients only present if
8260Sstevel@tonic-gate 	 * RI_VERBOSE was specified for ri_init.
8270Sstevel@tonic-gate 	 */
8280Sstevel@tonic-gate 	buf = NULL;
8290Sstevel@tonic-gate 	size = 0;
8300Sstevel@tonic-gate 	if (nvlist_lookup_byte_array(nvl, RI_CLIENT_VERB_PROPS,
8310Sstevel@tonic-gate 	    (uchar_t **)&buf, (uint_t *)&size) == 0) {
8320Sstevel@tonic-gate 		if (nvlist_unpack(buf, size, &client->v_props, 0) != 0) {
8330Sstevel@tonic-gate 			dprintf((stderr, "nvlist_unpack fail (%s)\n",
8340Sstevel@tonic-gate 			    RI_CLIENT_VERB_PROPS));
8350Sstevel@tonic-gate 			nvlist_free(nvl);
8360Sstevel@tonic-gate 			return (-1);
8370Sstevel@tonic-gate 		}
8380Sstevel@tonic-gate 	}
8390Sstevel@tonic-gate 
8400Sstevel@tonic-gate 	nvlist_free(nvl);
8410Sstevel@tonic-gate 
8420Sstevel@tonic-gate 	return (0);
8430Sstevel@tonic-gate }
8440Sstevel@tonic-gate 
8450Sstevel@tonic-gate static int
dev_unpack(char * buf,size_t size,ri_dev_t * dev)8460Sstevel@tonic-gate dev_unpack(char *buf, size_t size, ri_dev_t *dev)
8470Sstevel@tonic-gate {
8480Sstevel@tonic-gate 	nvlist_t	*nvl;
8490Sstevel@tonic-gate 
8500Sstevel@tonic-gate 	if (nvlist_unpack(buf, size, &nvl, 0) != 0) {
8510Sstevel@tonic-gate 		dprintf((stderr, "nvlist_unpack fail\n"));
8520Sstevel@tonic-gate 		return (-1);
8530Sstevel@tonic-gate 	}
8540Sstevel@tonic-gate 
8550Sstevel@tonic-gate 	if (lookup_unpack_byte_array(nvl, RI_DEV_PROPS,
8560Sstevel@tonic-gate 	    &dev->conf_props) != 0) {
8570Sstevel@tonic-gate 		nvlist_free(nvl);
8580Sstevel@tonic-gate 		return (-1);
8590Sstevel@tonic-gate 	}
8600Sstevel@tonic-gate 
8610Sstevel@tonic-gate #ifdef DEBUG
8620Sstevel@tonic-gate 	nvlist_print(stderr, dev->conf_props);
8630Sstevel@tonic-gate #endif /* DEBUG */
8640Sstevel@tonic-gate 
8650Sstevel@tonic-gate 	if (nvlist_lookup_byte_array(nvl, RI_DEV_CLIENTS, (uchar_t **)&buf,
8660Sstevel@tonic-gate 	    (uint_t *)&size) != 0) {
8670Sstevel@tonic-gate 		dprintf((stderr, "nvlist_lookup_byte_array fail (%s)\n",
8680Sstevel@tonic-gate 		    RI_DEV_CLIENTS));
8690Sstevel@tonic-gate 		nvlist_free(nvl);
8700Sstevel@tonic-gate 		return (-1);
8710Sstevel@tonic-gate 	}
8720Sstevel@tonic-gate 
8730Sstevel@tonic-gate 	if (client_list_unpack(buf, size, &dev->rcm_clients) != 0) {
8740Sstevel@tonic-gate 		nvlist_free(nvl);
8750Sstevel@tonic-gate 		return (-1);
8760Sstevel@tonic-gate 	}
8770Sstevel@tonic-gate 
8780Sstevel@tonic-gate 	nvlist_free(nvl);
8790Sstevel@tonic-gate 
8800Sstevel@tonic-gate 	return (0);
8810Sstevel@tonic-gate }
8820Sstevel@tonic-gate 
8830Sstevel@tonic-gate static int
ap_unpack(char * buf,size_t size,ri_ap_t * ap)8840Sstevel@tonic-gate ap_unpack(char *buf, size_t size, ri_ap_t *ap)
8850Sstevel@tonic-gate {
8860Sstevel@tonic-gate 	nvlist_t	*nvl;
8870Sstevel@tonic-gate 
8880Sstevel@tonic-gate 	if (nvlist_unpack(buf, size, &nvl, 0) != 0) {
8890Sstevel@tonic-gate 		dprintf((stderr, "nvlist_unpack fail\n"));
8900Sstevel@tonic-gate 		return (-1);
8910Sstevel@tonic-gate 	}
8920Sstevel@tonic-gate 
8930Sstevel@tonic-gate 	if (lookup_unpack_byte_array(nvl, RI_AP_PROPS, &ap->conf_props) != 0) {
8940Sstevel@tonic-gate 		nvlist_free(nvl);
8950Sstevel@tonic-gate 		return (-1);
8960Sstevel@tonic-gate 	}
8970Sstevel@tonic-gate 
8980Sstevel@tonic-gate #ifdef DEBUG
8990Sstevel@tonic-gate 	nvlist_print(stderr, ap->conf_props);
9000Sstevel@tonic-gate #endif /* DEBUG */
9010Sstevel@tonic-gate 
9020Sstevel@tonic-gate 	if (nvlist_lookup_byte_array(nvl, RI_AP_CPUS, (uchar_t **)&buf,
9030Sstevel@tonic-gate 	    (uint_t *)&size) != 0) {
9040Sstevel@tonic-gate 		dprintf((stderr, "nvlist_lookup_byte_array fail (%s)\n",
9050Sstevel@tonic-gate 		    RI_AP_CPUS));
9060Sstevel@tonic-gate 		nvlist_free(nvl);
9070Sstevel@tonic-gate 		return (-1);
9080Sstevel@tonic-gate 	}
9090Sstevel@tonic-gate 
9100Sstevel@tonic-gate 	if (dev_list_unpack(buf, size, &ap->cpus) != 0) {
9110Sstevel@tonic-gate 		nvlist_free(nvl);
9120Sstevel@tonic-gate 		return (-1);
9130Sstevel@tonic-gate 	}
9140Sstevel@tonic-gate 
9150Sstevel@tonic-gate 	if (nvlist_lookup_byte_array(nvl, RI_AP_MEMS, (uchar_t **)&buf,
9160Sstevel@tonic-gate 	    (uint_t *)&size) != 0) {
9170Sstevel@tonic-gate 		dprintf((stderr, "nvlist_lookup_byte_array fail (%s)\n",
9180Sstevel@tonic-gate 		    RI_AP_MEMS));
9190Sstevel@tonic-gate 		nvlist_free(nvl);
9200Sstevel@tonic-gate 		return (-1);
9210Sstevel@tonic-gate 	}
9220Sstevel@tonic-gate 
9230Sstevel@tonic-gate 	if (dev_list_unpack(buf, size, &ap->mems) != 0) {
9240Sstevel@tonic-gate 		nvlist_free(nvl);
9250Sstevel@tonic-gate 		return (-1);
9260Sstevel@tonic-gate 	}
9270Sstevel@tonic-gate 
9280Sstevel@tonic-gate 	if (nvlist_lookup_byte_array(nvl, RI_AP_IOS, (uchar_t **)&buf,
9290Sstevel@tonic-gate 	    (uint_t *)&size) != 0) {
9300Sstevel@tonic-gate 		dprintf((stderr, "nvlist_lookup_byte_array fail (%s)\n",
9310Sstevel@tonic-gate 		    RI_AP_IOS));
9320Sstevel@tonic-gate 		nvlist_free(nvl);
9330Sstevel@tonic-gate 		return (-1);
9340Sstevel@tonic-gate 	}
9350Sstevel@tonic-gate 
9360Sstevel@tonic-gate 	if (dev_list_unpack(buf, size, &ap->ios) != 0) {
9370Sstevel@tonic-gate 		nvlist_free(nvl);
9380Sstevel@tonic-gate 		return (-1);
9390Sstevel@tonic-gate 	}
9400Sstevel@tonic-gate 
9410Sstevel@tonic-gate 	nvlist_free(nvl);
9420Sstevel@tonic-gate 
9430Sstevel@tonic-gate 	return (0);
9440Sstevel@tonic-gate }
9450Sstevel@tonic-gate 
9460Sstevel@tonic-gate /*
9470Sstevel@tonic-gate  * Lookup byte array in old nvlist_t and unpack into new nvlist_t.
9480Sstevel@tonic-gate  */
9490Sstevel@tonic-gate static int
lookup_unpack_byte_array(nvlist_t * old_nvl,char * name,nvlist_t ** new_nvl)9500Sstevel@tonic-gate lookup_unpack_byte_array(nvlist_t *old_nvl, char *name, nvlist_t **new_nvl)
9510Sstevel@tonic-gate {
9520Sstevel@tonic-gate 	char	*buf = NULL;
9530Sstevel@tonic-gate 	size_t	size = 0;
9540Sstevel@tonic-gate 
9550Sstevel@tonic-gate 	if (nvlist_lookup_byte_array(old_nvl, name, (uchar_t **)&buf,
9560Sstevel@tonic-gate 	    (uint_t *)&size) != 0) {
9570Sstevel@tonic-gate 		dprintf((stderr, "nvlist_lookup_byte_array fail (%s)\n",
9580Sstevel@tonic-gate 		    name));
9590Sstevel@tonic-gate 		return (-1);
9600Sstevel@tonic-gate 	}
9610Sstevel@tonic-gate 
9620Sstevel@tonic-gate 	if (nvlist_unpack(buf, size, new_nvl, 0) != 0) {
9630Sstevel@tonic-gate 		dprintf((stderr, "nvlist_unpack fail (%s)\n", name));
9640Sstevel@tonic-gate 		return (-1);
9650Sstevel@tonic-gate 	}
9660Sstevel@tonic-gate 
9670Sstevel@tonic-gate 	return (0);
9680Sstevel@tonic-gate }
9690Sstevel@tonic-gate 
9700Sstevel@tonic-gate ri_ap_t *
ri_ap_next(ri_hdl_t * hdl,ri_ap_t * ap)9710Sstevel@tonic-gate ri_ap_next(ri_hdl_t *hdl, ri_ap_t *ap)
9720Sstevel@tonic-gate {
9730Sstevel@tonic-gate 	if (hdl == NULL) {
9740Sstevel@tonic-gate 		errno = EINVAL;
9750Sstevel@tonic-gate 		return (NULL);
9760Sstevel@tonic-gate 	}
9770Sstevel@tonic-gate 	return ((ap == NULL) ? hdl->aps : ap->next);
9780Sstevel@tonic-gate }
9790Sstevel@tonic-gate 
9800Sstevel@tonic-gate nvlist_t *
ri_ap_conf_props(ri_ap_t * ap)9810Sstevel@tonic-gate ri_ap_conf_props(ri_ap_t *ap)
9820Sstevel@tonic-gate {
9830Sstevel@tonic-gate 	if (ap == NULL) {
9840Sstevel@tonic-gate 		errno = EINVAL;
9850Sstevel@tonic-gate 		return (NULL);
9860Sstevel@tonic-gate 	}
9870Sstevel@tonic-gate 	return (ap->conf_props);
9880Sstevel@tonic-gate }
9890Sstevel@tonic-gate 
9900Sstevel@tonic-gate ri_dev_t *
ri_cpu_next(ri_ap_t * ap,ri_dev_t * cpu)9910Sstevel@tonic-gate ri_cpu_next(ri_ap_t *ap, ri_dev_t *cpu)
9920Sstevel@tonic-gate {
9930Sstevel@tonic-gate 	if (ap == NULL) {
9940Sstevel@tonic-gate 		errno = EINVAL;
9950Sstevel@tonic-gate 		return (NULL);
9960Sstevel@tonic-gate 	}
9970Sstevel@tonic-gate 	return ((cpu == NULL) ? ap->cpus : cpu->next);
9980Sstevel@tonic-gate }
9990Sstevel@tonic-gate 
10000Sstevel@tonic-gate ri_dev_t *
ri_mem_next(ri_ap_t * ap,ri_dev_t * mem)10010Sstevel@tonic-gate ri_mem_next(ri_ap_t *ap, ri_dev_t *mem)
10020Sstevel@tonic-gate {
10030Sstevel@tonic-gate 	if (ap == NULL) {
10040Sstevel@tonic-gate 		errno = EINVAL;
10050Sstevel@tonic-gate 		return (NULL);
10060Sstevel@tonic-gate 	}
10070Sstevel@tonic-gate 	return ((mem == NULL) ? ap->mems : mem->next);
10080Sstevel@tonic-gate }
10090Sstevel@tonic-gate 
10100Sstevel@tonic-gate ri_dev_t *
ri_io_next(ri_ap_t * ap,ri_dev_t * io)10110Sstevel@tonic-gate ri_io_next(ri_ap_t *ap, ri_dev_t *io)
10120Sstevel@tonic-gate {
10130Sstevel@tonic-gate 	if (ap == NULL) {
10140Sstevel@tonic-gate 		errno = EINVAL;
10150Sstevel@tonic-gate 		return (NULL);
10160Sstevel@tonic-gate 	}
10170Sstevel@tonic-gate 	return ((io == NULL) ? ap->ios : io->next);
10180Sstevel@tonic-gate }
10190Sstevel@tonic-gate 
10200Sstevel@tonic-gate ri_client_t *
ri_client_next(ri_dev_t * dev,ri_client_t * rcm_client)10210Sstevel@tonic-gate ri_client_next(ri_dev_t *dev, ri_client_t *rcm_client)
10220Sstevel@tonic-gate {
10230Sstevel@tonic-gate 	if (dev == NULL) {
10240Sstevel@tonic-gate 		errno = EINVAL;
10250Sstevel@tonic-gate 		return (NULL);
10260Sstevel@tonic-gate 	}
10270Sstevel@tonic-gate 	return ((rcm_client == NULL) ? dev->rcm_clients : rcm_client->next);
10280Sstevel@tonic-gate }
10290Sstevel@tonic-gate 
10300Sstevel@tonic-gate nvlist_t *
ri_dev_conf_props(ri_dev_t * dev)10310Sstevel@tonic-gate ri_dev_conf_props(ri_dev_t *dev)
10320Sstevel@tonic-gate {
10330Sstevel@tonic-gate 	if (dev == NULL) {
10340Sstevel@tonic-gate 		errno = EINVAL;
10350Sstevel@tonic-gate 		return (NULL);
10360Sstevel@tonic-gate 	}
10370Sstevel@tonic-gate 	return (dev->conf_props);
10380Sstevel@tonic-gate }
10390Sstevel@tonic-gate 
10400Sstevel@tonic-gate nvlist_t *
ri_client_usage_props(ri_client_t * rcm_client)10410Sstevel@tonic-gate ri_client_usage_props(ri_client_t *rcm_client)
10420Sstevel@tonic-gate {
10430Sstevel@tonic-gate 	if (rcm_client == NULL) {
10440Sstevel@tonic-gate 		errno = EINVAL;
10450Sstevel@tonic-gate 		return (NULL);
10460Sstevel@tonic-gate 	}
10470Sstevel@tonic-gate 	return (rcm_client->usg_props);
10480Sstevel@tonic-gate }
10490Sstevel@tonic-gate 
10500Sstevel@tonic-gate nvlist_t *
ri_client_verbose_props(ri_client_t * rcm_client)10510Sstevel@tonic-gate ri_client_verbose_props(ri_client_t *rcm_client)
10520Sstevel@tonic-gate {
10530Sstevel@tonic-gate 	if (rcm_client == NULL) {
10540Sstevel@tonic-gate 		errno = EINVAL;
10550Sstevel@tonic-gate 		return (NULL);
10560Sstevel@tonic-gate 	}
10570Sstevel@tonic-gate 	return (rcm_client->v_props);
10580Sstevel@tonic-gate }
10590Sstevel@tonic-gate 
10600Sstevel@tonic-gate ri_client_t *
ri_cpu_cap_client_next(ri_hdl_t * hdl,ri_client_t * rcm_client)10610Sstevel@tonic-gate ri_cpu_cap_client_next(ri_hdl_t *hdl, ri_client_t *rcm_client)
10620Sstevel@tonic-gate {
10630Sstevel@tonic-gate 	if (hdl == NULL) {
10640Sstevel@tonic-gate 		errno = EINVAL;
10650Sstevel@tonic-gate 		return (NULL);
10660Sstevel@tonic-gate 	}
10670Sstevel@tonic-gate 	return ((rcm_client == NULL) ? hdl->cpu_cap_clients : rcm_client->next);
10680Sstevel@tonic-gate }
10690Sstevel@tonic-gate 
10700Sstevel@tonic-gate ri_client_t *
ri_mem_cap_client_next(ri_hdl_t * hdl,ri_client_t * rcm_client)10710Sstevel@tonic-gate ri_mem_cap_client_next(ri_hdl_t *hdl, ri_client_t *rcm_client)
10720Sstevel@tonic-gate {
10730Sstevel@tonic-gate 	if (hdl == NULL) {
10740Sstevel@tonic-gate 		errno = EINVAL;
10750Sstevel@tonic-gate 		return (NULL);
10760Sstevel@tonic-gate 	}
10770Sstevel@tonic-gate 	return ((rcm_client == NULL) ? hdl->mem_cap_clients : rcm_client->next);
10780Sstevel@tonic-gate }
1079