int di_bytes_get(topo_mod_t *mod, di_node_t n, const char *pnm, int *sz, uchar_t **db) { di_prom_handle_t ptp = DI_PROM_HANDLE_NIL; di_prom_prop_t pp = DI_PROM_PROP_NIL; di_prop_t hp = DI_PROP_NIL; if ((ptp = topo_mod_prominfo(mod)) == DI_PROM_HANDLE_NIL) return (-1); *sz = -1; while ((hp = di_prop_next(n, hp)) != DI_PROP_NIL) { if (strcmp(di_prop_name(hp), pnm) == 0) { if ((*sz = di_prop_bytes(hp, db)) < 0) continue; break; } } if (*sz < 0) { while ((pp = di_prom_prop_next(ptp, n, pp)) != DI_PROM_PROP_NIL) { if (strcmp(di_prom_prop_name(pp), pnm) == 0) { *sz = di_prom_prop_data(pp, db); if (*sz < 0) continue; break; } } } if (*sz < 0) return (-1); return (0); }
/* * In this comment typed properties are those of type DI_PROP_TYPE_UNDEF_IT, * DI_PROP_TYPE_BOOLEAN, DI_PROP_TYPE_INT, DI_PROP_TYPE_INT64, * DI_PROP_TYPE_BYTE, and DI_PROP_TYPE_STRING. * * The guessing algorithm is: * 1. If the property is typed and the type is consistent with the value of * the property, then the property is of that type. If the type is not * consistent with value of the property, then the type is treated as * alien to prtconf. * 2. If the property is of type DI_PROP_TYPE_UNKNOWN the following steps * are carried out. * a. If the value of the property is consistent with a string property, * the type of the property is DI_PROP_TYPE_STRING. * b. Otherwise, if the value of the property is consistent with an integer * property, the type of the property is DI_PROP_TYPE_INT. * c. Otherwise, the property type is treated as alien to prtconf. * 3. If the property type is alien to prtconf, then the property value is * read by the appropriate routine for untyped properties and the following * steps are carried out. * a. If the length that the property routine returned is zero, the * property is of type DI_PROP_TYPE_BOOLEAN. * b. Otherwise, if the length that the property routine returned is * positive, then the property value is treated as raw data of type * DI_PROP_TYPE_UNKNOWN. * c. Otherwise, if the length that the property routine returned is * negative, then there is some internal inconsistency and this is * treated as an error and no type is determined. * * * Joyent/jwilsdon: This function was taken and modified from: * * <illumos>/usr/src/cmd/prtconf/pdevinfo.c * */ static int prop_type_guess(di_prop_t prop, void **prop_data, int *prop_type) { int len, type; type = di_prop_type(prop); switch (type) { case DI_PROP_TYPE_UNDEF_IT: case DI_PROP_TYPE_BOOLEAN: *prop_data = NULL; *prop_type = type; return (0); case DI_PROP_TYPE_INT: len = di_prop_ints(prop, (int **)prop_data); break; case DI_PROP_TYPE_INT64: len = di_prop_int64(prop, (int64_t **)prop_data); break; case DI_PROP_TYPE_BYTE: len = di_prop_bytes(prop, (uchar_t **)prop_data); break; case DI_PROP_TYPE_STRING: len = di_prop_strings(prop, (char **)prop_data); break; case DI_PROP_TYPE_UNKNOWN: len = di_prop_strings(prop, (char **)prop_data); if ((len > 0) && ((*(char **)prop_data)[0] != 0)) { *prop_type = DI_PROP_TYPE_STRING; return (len); } len = di_prop_ints(prop, (int **)prop_data); type = DI_PROP_TYPE_INT; break; default: len = -1; } if (len > 0) { *prop_type = type; return (len); } len = di_prop_rawdata(prop, (uchar_t **)prop_data); if (len < 0) { return (-1); } else if (len == 0) { *prop_type = DI_PROP_TYPE_BOOLEAN; return (0); } *prop_type = DI_PROP_TYPE_UNKNOWN; return (len); }
/* * If this devinfo node was added by the PCI hotplug framework it * doesn't have the PROM properties, but hopefully has the properties * we're looking for attached directly to the devinfo node. We only * care about the first four bytes of the property, which we read as * our unsigned integer. The remaining bytes are ignored. If we * don't find the property we're looking for, or can't get its value, * 'val' remains unchanged and we return -1. Otherwise 'val' gets the * property value and we return 0. */ static int hwprop2uint(di_node_t n, const char *propnm, uint_t *val) { di_prop_t hp = DI_PROP_NIL; uchar_t *buf; while ((hp = di_prop_next(n, hp)) != DI_PROP_NIL) { if (strcmp(di_prop_name(hp), propnm) == 0) { if (di_prop_bytes(hp, &buf) < sizeof (uint_t)) continue; bcopy(buf, val, sizeof (uint_t)); return (0); } } return (-1); }
/* * This function is identical to the one in the picldevtree plugin. * Unfortunately we can't just reuse that code. */ static void add_devinfo_props(picl_nodehdl_t nodeh, di_node_t di_node) { int instance; char *di_val; di_prop_t di_prop; int di_ptype; ptree_propinfo_t propinfo; instance = di_instance(di_node); (void) ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION, PICL_PTYPE_INT, PICL_READ, sizeof (instance), PICL_PROP_INSTANCE, NULL, NULL); (void) ptree_create_and_add_prop(nodeh, &propinfo, &instance, NULL); di_val = di_bus_addr(di_node); if (di_val) { (void) ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION, PICL_PTYPE_CHARSTRING, PICL_READ, strlen(di_val) + 1, PICL_PROP_BUS_ADDR, NULL, NULL); (void) ptree_create_and_add_prop(nodeh, &propinfo, di_val, NULL); } di_val = di_binding_name(di_node); if (di_val) { (void) ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION, PICL_PTYPE_CHARSTRING, PICL_READ, strlen(di_val) + 1, PICL_PROP_BINDING_NAME, NULL, NULL); (void) ptree_create_and_add_prop(nodeh, &propinfo, di_val, NULL); } di_val = di_driver_name(di_node); if (di_val) { (void) ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION, PICL_PTYPE_CHARSTRING, PICL_READ, strlen(di_val) + 1, PICL_PROP_DRIVER_NAME, NULL, NULL); (void) ptree_create_and_add_prop(nodeh, &propinfo, di_val, NULL); } di_val = di_devfs_path(di_node); if (di_val) { (void) ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION, PICL_PTYPE_CHARSTRING, PICL_READ, strlen(di_val) + 1, PICL_PROP_DEVFS_PATH, NULL, NULL); (void) ptree_create_and_add_prop(nodeh, &propinfo, di_val, NULL); di_devfs_path_free(di_val); } for (di_prop = di_prop_next(di_node, DI_PROP_NIL); di_prop != DI_PROP_NIL; di_prop = di_prop_next(di_node, di_prop)) { di_val = di_prop_name(di_prop); di_ptype = di_prop_type(di_prop); switch (di_ptype) { case DI_PROP_TYPE_BOOLEAN: (void) ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION, PICL_PTYPE_VOID, PICL_READ, (size_t)0, di_val, NULL, NULL); (void) ptree_create_and_add_prop(nodeh, &propinfo, NULL, NULL); break; case DI_PROP_TYPE_INT: { int *idata; int len; len = di_prop_ints(di_prop, &idata); if (len < 0) /* Recieved error, so ignore prop */ break; if (len == 1) (void) ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION, PICL_PTYPE_INT, PICL_READ, len * sizeof (int), di_val, NULL, NULL); else (void) ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION, PICL_PTYPE_BYTEARRAY, PICL_READ, len * sizeof (int), di_val, NULL, NULL); (void) ptree_create_and_add_prop(nodeh, &propinfo, idata, NULL); } break; case DI_PROP_TYPE_STRING: { char *sdata; int len; len = di_prop_strings(di_prop, &sdata); if (len < 0) break; if (len == 1) { (void) ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION, PICL_PTYPE_CHARSTRING, PICL_READ, strlen(sdata) + 1, di_val, NULL, NULL); (void) ptree_create_and_add_prop(nodeh, &propinfo, sdata, NULL); } else { (void) add_string_list_prop(nodeh, di_val, sdata, len); } } break; case DI_PROP_TYPE_BYTE: { int len; unsigned char *bdata; len = di_prop_bytes(di_prop, &bdata); if (len < 0) break; (void) ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION, PICL_PTYPE_BYTEARRAY, PICL_READ, len, di_val, NULL, NULL); (void) ptree_create_and_add_prop(nodeh, &propinfo, bdata, NULL); } break; case DI_PROP_TYPE_UNKNOWN: break; case DI_PROP_TYPE_UNDEF_IT: break; default: break; } } }