92 static topo_propval_t *
93 propval_get(topo_pgroup_t *pg, const char *pname)
94 {
95 topo_proplist_t *pvl;
96
97 if (pg == NULL)
98 return (NULL);
99
100 for (pvl = topo_list_next(&pg->tpg_pvals); pvl != NULL;
101 pvl = topo_list_next(pvl)) {
102 if (strcmp(pvl->tp_pval->tp_name, pname) == 0)
103 return (pvl->tp_pval);
104 }
105
106 return (NULL);
107 }
108
109 static int
110 method_geterror(nvlist_t *nvl, int err, int *errp)
111 {
112 if (nvl != NULL)
113 nvlist_free(nvl);
114
115 *errp = err;
116
117 return (-1);
118 }
119
120 static int
121 prop_method_get(tnode_t *node, topo_propval_t *pv, topo_propmethod_t *pm,
122 nvlist_t *pargs, int *err)
123 {
124 int ret;
125 nvlist_t *args, *nvl;
126 char *name;
127 topo_type_t type;
128
129 if (topo_hdl_nvalloc(pv->tp_hdl, &args, NV_UNIQUE_NAME) < 0 ||
130 nvlist_add_nvlist(args, TOPO_PROP_ARGS, pm->tpm_args) != 0)
131 return (method_geterror(NULL, ETOPO_PROP_NVL, err));
132
148 args, &nvl, err) < 0) {
149 topo_node_lock(node);
150 topo_prop_rele(pv);
151 return (method_geterror(args, *err, err));
152 }
153 topo_node_lock(node);
154 topo_prop_rele(pv);
155
156 nvlist_free(args);
157
158 /* Verify the property contents */
159 ret = nvlist_lookup_string(nvl, TOPO_PROP_VAL_NAME, &name);
160 if (ret != 0 || strcmp(name, pv->tp_name) != 0)
161 return (method_geterror(nvl, ETOPO_PROP_NAME, err));
162
163 ret = nvlist_lookup_uint32(nvl, TOPO_PROP_VAL_TYPE, (uint32_t *)&type);
164 if (ret != 0 || type != pv->tp_type)
165 return (method_geterror(nvl, ETOPO_PROP_TYPE, err));
166
167 /* Release the last value and re-assign to the new value */
168 if (pv->tp_val != NULL)
169 nvlist_free(pv->tp_val);
170 pv->tp_val = nvl;
171
172 return (0);
173 }
174
175 static topo_propval_t *
176 prop_get(tnode_t *node, const char *pgname, const char *pname, nvlist_t *pargs,
177 int *err)
178 {
179 topo_propval_t *pv = NULL;
180
181 if ((pv = propval_get(pgroup_get(node, pgname), pname)) == NULL) {
182 *err = ETOPO_PROP_NOENT;
183 return (NULL);
184 }
185
186 if (pv->tp_flag & TOPO_PROP_NONVOLATILE && pv->tp_val != NULL)
187 return (pv);
188
838
839 if (ret != 0) {
840 topo_node_unlock(node);
841 return (-1);
842 }
843
844 pv->tp_val = nvl;
845 topo_node_unlock(node);
846 return (0);
847 }
848
849 static int
850 register_methoderror(tnode_t *node, topo_propmethod_t *pm, int *errp, int l,
851 int err)
852 {
853 topo_hdl_t *thp = node->tn_hdl;
854
855 if (pm != NULL) {
856 if (pm->tpm_name != NULL)
857 topo_hdl_strfree(thp, pm->tpm_name);
858 if (pm->tpm_args != NULL)
859 nvlist_free(pm->tpm_args);
860 topo_hdl_free(thp, pm, sizeof (topo_propmethod_t));
861 }
862
863 *errp = err;
864
865 if (l != 0)
866 topo_node_unlock(node);
867
868 return (-1);
869 }
870
871 int
872 prop_method_register(tnode_t *node, const char *pgname, const char *pname,
873 topo_type_t ptype, const char *mname, topo_version_t version,
874 const nvlist_t *args, int *err)
875 {
876 topo_hdl_t *thp = node->tn_hdl;
877 topo_propmethod_t *pm = NULL;
878 topo_propval_t *pv = NULL;
1290 if (pip != NULL) {
1291 if (pip->tpi_name != NULL)
1292 topo_hdl_strfree(thp, (char *)pip->tpi_name);
1293 topo_hdl_free(thp, pip, sizeof (topo_pgroup_info_t));
1294 }
1295
1296 topo_hdl_free(thp, pg, sizeof (topo_pgroup_t));
1297 }
1298 topo_node_unlock(node);
1299 }
1300
1301 static void
1302 propmethod_destroy(topo_hdl_t *thp, topo_propval_t *pv)
1303 {
1304 topo_propmethod_t *pm;
1305
1306 pm = pv->tp_method;
1307 if (pm != NULL) {
1308 if (pm->tpm_name != NULL)
1309 topo_hdl_strfree(thp, pm->tpm_name);
1310 if (pm->tpm_args != NULL)
1311 nvlist_free(pm->tpm_args);
1312 topo_hdl_free(thp, pm, sizeof (topo_propmethod_t));
1313 pv->tp_method = NULL;
1314 }
1315 }
1316
1317 static void
1318 topo_propval_destroy(topo_propval_t *pv)
1319 {
1320 topo_hdl_t *thp;
1321
1322 if (pv == NULL)
1323 return;
1324
1325 thp = pv->tp_hdl;
1326
1327 if (pv->tp_name != NULL)
1328 topo_hdl_strfree(thp, pv->tp_name);
1329
1330 if (pv->tp_val != NULL)
1331 nvlist_free(pv->tp_val);
1332
1333 propmethod_destroy(thp, pv);
1334
1335 topo_hdl_free(thp, pv, sizeof (topo_propval_t));
1336 }
1337
1338 void
1339 topo_prop_hold(topo_propval_t *pv)
1340 {
1341 pv->tp_refs++;
1342 }
1343
1344 void
1345 topo_prop_rele(topo_propval_t *pv)
1346 {
1347 pv->tp_refs--;
1348
1349 assert(pv->tp_refs >= 0);
1350
1386 return (-1);
1387
1388 if (pv->tp_val == NULL) {
1389 *err = ETOPO_PROP_NOENT;
1390 return (-1);
1391 }
1392
1393 if (topo_hdl_nvdup(pv->tp_hdl, pv->tp_val, nvl) != 0) {
1394 *err = ETOPO_PROP_NOMEM;
1395 return (-1);
1396 }
1397
1398 return (0);
1399 }
1400
1401 static int
1402 get_pgrp_seterror(tnode_t *node, nvlist_t *nvl, int *errp, int err)
1403 {
1404 topo_node_unlock(node);
1405
1406 if (nvl != NULL)
1407 nvlist_free(nvl);
1408
1409 *errp = err;
1410
1411 return (-1);
1412 }
1413
1414 int
1415 topo_prop_getpgrp(tnode_t *node, const char *pgname, nvlist_t **pgrp,
1416 int *err)
1417 {
1418 int ret;
1419 topo_hdl_t *thp = node->tn_hdl;
1420 nvlist_t *nvl, *pvnvl;
1421 topo_pgroup_t *pg;
1422 topo_propval_t *pv;
1423 topo_proplist_t *pvl;
1424
1425 if (topo_hdl_nvalloc(thp, &nvl, 0) != 0) {
1426 *err = ETOPO_NOMEM;
1459 return (get_pgrp_seterror(node, nvl, err, ret));
1460 }
1461
1462 nvlist_free(pvnvl);
1463 }
1464 topo_node_unlock(node);
1465 *pgrp = nvl;
1466 return (0);
1467 }
1468
1469 topo_node_unlock(node);
1470 *err = ETOPO_PROP_NOENT;
1471 return (-1);
1472 }
1473
1474 static nvlist_t *
1475 get_all_seterror(tnode_t *node, nvlist_t *nvl, int *errp, int err)
1476 {
1477 topo_node_unlock(node);
1478
1479 if (nvl != NULL)
1480 nvlist_free(nvl);
1481
1482 *errp = err;
1483
1484 return (NULL);
1485 }
1486
1487 nvlist_t *
1488 topo_prop_getprops(tnode_t *node, int *err)
1489 {
1490 int ret;
1491 topo_hdl_t *thp = node->tn_hdl;
1492 nvlist_t *nvl, *pgnvl, *pvnvl;
1493 topo_pgroup_t *pg;
1494 topo_propval_t *pv;
1495 topo_proplist_t *pvl;
1496
1497 topo_node_lock(node);
1498 if (topo_hdl_nvalloc(thp, &nvl, 0) != 0) {
1499 return (get_all_seterror(node, NULL, err, ETOPO_NOMEM));
|
92 static topo_propval_t *
93 propval_get(topo_pgroup_t *pg, const char *pname)
94 {
95 topo_proplist_t *pvl;
96
97 if (pg == NULL)
98 return (NULL);
99
100 for (pvl = topo_list_next(&pg->tpg_pvals); pvl != NULL;
101 pvl = topo_list_next(pvl)) {
102 if (strcmp(pvl->tp_pval->tp_name, pname) == 0)
103 return (pvl->tp_pval);
104 }
105
106 return (NULL);
107 }
108
109 static int
110 method_geterror(nvlist_t *nvl, int err, int *errp)
111 {
112 nvlist_free(nvl);
113
114 *errp = err;
115
116 return (-1);
117 }
118
119 static int
120 prop_method_get(tnode_t *node, topo_propval_t *pv, topo_propmethod_t *pm,
121 nvlist_t *pargs, int *err)
122 {
123 int ret;
124 nvlist_t *args, *nvl;
125 char *name;
126 topo_type_t type;
127
128 if (topo_hdl_nvalloc(pv->tp_hdl, &args, NV_UNIQUE_NAME) < 0 ||
129 nvlist_add_nvlist(args, TOPO_PROP_ARGS, pm->tpm_args) != 0)
130 return (method_geterror(NULL, ETOPO_PROP_NVL, err));
131
147 args, &nvl, err) < 0) {
148 topo_node_lock(node);
149 topo_prop_rele(pv);
150 return (method_geterror(args, *err, err));
151 }
152 topo_node_lock(node);
153 topo_prop_rele(pv);
154
155 nvlist_free(args);
156
157 /* Verify the property contents */
158 ret = nvlist_lookup_string(nvl, TOPO_PROP_VAL_NAME, &name);
159 if (ret != 0 || strcmp(name, pv->tp_name) != 0)
160 return (method_geterror(nvl, ETOPO_PROP_NAME, err));
161
162 ret = nvlist_lookup_uint32(nvl, TOPO_PROP_VAL_TYPE, (uint32_t *)&type);
163 if (ret != 0 || type != pv->tp_type)
164 return (method_geterror(nvl, ETOPO_PROP_TYPE, err));
165
166 /* Release the last value and re-assign to the new value */
167 nvlist_free(pv->tp_val);
168 pv->tp_val = nvl;
169
170 return (0);
171 }
172
173 static topo_propval_t *
174 prop_get(tnode_t *node, const char *pgname, const char *pname, nvlist_t *pargs,
175 int *err)
176 {
177 topo_propval_t *pv = NULL;
178
179 if ((pv = propval_get(pgroup_get(node, pgname), pname)) == NULL) {
180 *err = ETOPO_PROP_NOENT;
181 return (NULL);
182 }
183
184 if (pv->tp_flag & TOPO_PROP_NONVOLATILE && pv->tp_val != NULL)
185 return (pv);
186
836
837 if (ret != 0) {
838 topo_node_unlock(node);
839 return (-1);
840 }
841
842 pv->tp_val = nvl;
843 topo_node_unlock(node);
844 return (0);
845 }
846
847 static int
848 register_methoderror(tnode_t *node, topo_propmethod_t *pm, int *errp, int l,
849 int err)
850 {
851 topo_hdl_t *thp = node->tn_hdl;
852
853 if (pm != NULL) {
854 if (pm->tpm_name != NULL)
855 topo_hdl_strfree(thp, pm->tpm_name);
856 nvlist_free(pm->tpm_args);
857 topo_hdl_free(thp, pm, sizeof (topo_propmethod_t));
858 }
859
860 *errp = err;
861
862 if (l != 0)
863 topo_node_unlock(node);
864
865 return (-1);
866 }
867
868 int
869 prop_method_register(tnode_t *node, const char *pgname, const char *pname,
870 topo_type_t ptype, const char *mname, topo_version_t version,
871 const nvlist_t *args, int *err)
872 {
873 topo_hdl_t *thp = node->tn_hdl;
874 topo_propmethod_t *pm = NULL;
875 topo_propval_t *pv = NULL;
1287 if (pip != NULL) {
1288 if (pip->tpi_name != NULL)
1289 topo_hdl_strfree(thp, (char *)pip->tpi_name);
1290 topo_hdl_free(thp, pip, sizeof (topo_pgroup_info_t));
1291 }
1292
1293 topo_hdl_free(thp, pg, sizeof (topo_pgroup_t));
1294 }
1295 topo_node_unlock(node);
1296 }
1297
1298 static void
1299 propmethod_destroy(topo_hdl_t *thp, topo_propval_t *pv)
1300 {
1301 topo_propmethod_t *pm;
1302
1303 pm = pv->tp_method;
1304 if (pm != NULL) {
1305 if (pm->tpm_name != NULL)
1306 topo_hdl_strfree(thp, pm->tpm_name);
1307 nvlist_free(pm->tpm_args);
1308 topo_hdl_free(thp, pm, sizeof (topo_propmethod_t));
1309 pv->tp_method = NULL;
1310 }
1311 }
1312
1313 static void
1314 topo_propval_destroy(topo_propval_t *pv)
1315 {
1316 topo_hdl_t *thp;
1317
1318 if (pv == NULL)
1319 return;
1320
1321 thp = pv->tp_hdl;
1322
1323 if (pv->tp_name != NULL)
1324 topo_hdl_strfree(thp, pv->tp_name);
1325
1326 nvlist_free(pv->tp_val);
1327
1328 propmethod_destroy(thp, pv);
1329
1330 topo_hdl_free(thp, pv, sizeof (topo_propval_t));
1331 }
1332
1333 void
1334 topo_prop_hold(topo_propval_t *pv)
1335 {
1336 pv->tp_refs++;
1337 }
1338
1339 void
1340 topo_prop_rele(topo_propval_t *pv)
1341 {
1342 pv->tp_refs--;
1343
1344 assert(pv->tp_refs >= 0);
1345
1381 return (-1);
1382
1383 if (pv->tp_val == NULL) {
1384 *err = ETOPO_PROP_NOENT;
1385 return (-1);
1386 }
1387
1388 if (topo_hdl_nvdup(pv->tp_hdl, pv->tp_val, nvl) != 0) {
1389 *err = ETOPO_PROP_NOMEM;
1390 return (-1);
1391 }
1392
1393 return (0);
1394 }
1395
1396 static int
1397 get_pgrp_seterror(tnode_t *node, nvlist_t *nvl, int *errp, int err)
1398 {
1399 topo_node_unlock(node);
1400
1401 nvlist_free(nvl);
1402
1403 *errp = err;
1404
1405 return (-1);
1406 }
1407
1408 int
1409 topo_prop_getpgrp(tnode_t *node, const char *pgname, nvlist_t **pgrp,
1410 int *err)
1411 {
1412 int ret;
1413 topo_hdl_t *thp = node->tn_hdl;
1414 nvlist_t *nvl, *pvnvl;
1415 topo_pgroup_t *pg;
1416 topo_propval_t *pv;
1417 topo_proplist_t *pvl;
1418
1419 if (topo_hdl_nvalloc(thp, &nvl, 0) != 0) {
1420 *err = ETOPO_NOMEM;
1453 return (get_pgrp_seterror(node, nvl, err, ret));
1454 }
1455
1456 nvlist_free(pvnvl);
1457 }
1458 topo_node_unlock(node);
1459 *pgrp = nvl;
1460 return (0);
1461 }
1462
1463 topo_node_unlock(node);
1464 *err = ETOPO_PROP_NOENT;
1465 return (-1);
1466 }
1467
1468 static nvlist_t *
1469 get_all_seterror(tnode_t *node, nvlist_t *nvl, int *errp, int err)
1470 {
1471 topo_node_unlock(node);
1472
1473 nvlist_free(nvl);
1474
1475 *errp = err;
1476
1477 return (NULL);
1478 }
1479
1480 nvlist_t *
1481 topo_prop_getprops(tnode_t *node, int *err)
1482 {
1483 int ret;
1484 topo_hdl_t *thp = node->tn_hdl;
1485 nvlist_t *nvl, *pgnvl, *pvnvl;
1486 topo_pgroup_t *pg;
1487 topo_propval_t *pv;
1488 topo_proplist_t *pvl;
1489
1490 topo_node_lock(node);
1491 if (topo_hdl_nvalloc(thp, &nvl, 0) != 0) {
1492 return (get_all_seterror(node, NULL, err, ETOPO_NOMEM));
|