/* * xVM virtual block device * * VBDs are enumerated into xenstore by xend and named using * the linux dev_t values for 'hd' and 'xvd' devices. Linux * dev_t's are 16-bit values. The upper 8 bits identify the major # * of the device (hd, xvd) and the lower 8 bits the instance and partition * * For PV guests, VBDs are named by the virt-tools using * the form xvd[a-p][1-15]. The corresponding Solaris /dev/dsk name * created by this generator will be c0t[0-15]d[0-15]sN, * were the target (t) value represents [a-p] and the * disk (d) value is either 0 (e.g. xvda) or contains the partition * information if it has been specified [1-15] (e.g. xvda1) * * For PV guests using the legacy naming (0, 1, 2, ...) * the Solaris disk names created will be c0d[0..767]sN * The Solaris version of virt-install based on virtinst.101 * named PV disks as sequential integers. With virtinst.300_1 and * beyond, the virt-* tools will no longer create legacy disk * names. */ static int disk_callback_xvmd(di_minor_t minor, di_node_t node) { #define HD_BASE (3 << 8) #define XVBDMAJ 202 char *addr; char disk[16]; uint_t targ; uint_t lun = 0; uint_t fmaj; addr = di_bus_addr(node); targ = strtol(addr, (char **)NULL, 10); fmaj = targ >> 8; /* legacy device address */ if (targ < HD_BASE) (void) snprintf(disk, sizeof (disk), "d%d", targ); /* PV VBD */ else if (fmaj == XVBDMAJ) { lun = targ & 0xf; targ = (targ & 0xff) >> 4; (void) snprintf(disk, sizeof (disk), "t%dd%d", targ, lun); /* HVM device names are generated using the standard generator */ } else {
static int find_fru_node(di_node_t node, void *arg) { frutree_locnode_t *locp = NULL; char *char_di_bus_addr = NULL; int busaddr = 0; int di_busaddr = 0; char bus_addr[PICL_PROPNAMELEN_MAX]; frutree_devinfo_t *devinfo = NULL; devinfo = *(frutree_devinfo_t **)arg; locp = *(frutree_locnode_t **)devinfo->arg; if (devinfo->rnode == node) { return (DI_WALK_CONTINUE); } char_di_bus_addr = di_bus_addr(node); if (char_di_bus_addr == NULL) { return (DI_WALK_PRUNECHILD); } if (ptree_get_propval_by_name(locp->locnodeh, PICL_PROP_BUS_ADDR, bus_addr, sizeof (bus_addr)) != PICL_SUCCESS) { return (DI_WALK_PRUNECHILD); } if (strstr(bus_addr, ",") != NULL) { /* bus addr is of type 1,0 */ if (strcmp(bus_addr, char_di_bus_addr) == 0) { devinfo->retval = PICL_SUCCESS; return (DI_WALK_TERMINATE); } else { return (DI_WALK_PRUNECHILD); } } else { /* bus addr is of type 0x */ /* check if the values are same */ errno = 0; busaddr = strtol(bus_addr, (char **)NULL, 16); if (errno != 0) { return (DI_WALK_PRUNECHILD); } errno = 0; di_busaddr = strtol(char_di_bus_addr, (char **)NULL, 16); if (errno != 0) { return (DI_WALK_PRUNECHILD); } if (di_busaddr == busaddr) { devinfo->retval = PICL_SUCCESS; return (DI_WALK_TERMINATE); } else { return (DI_WALK_PRUNECHILD); } } }
did_t * split_bus_address(did_hash_t *dhash, di_node_t dp, uint_t baseaddr, uint_t bussep, int minbrd, int maxbrd, int *brd, int *br, int *bus, di_prom_handle_t promtree, topo_mod_t *mod) { uint_t bc, ac; char *comma; char *bac; char *ba; int e; if ((ba = di_bus_addr(dp)) == NULL || (bac = topo_mod_strdup(mod, ba)) == NULL) return (NULL); topo_mod_dprintf(mod, "Transcribing %s into board, bus, etc.\n", bac); if ((comma = strchr(bac, ',')) == NULL) { topo_mod_strfree(mod, bac); return (NULL); } *comma = '\0'; bc = strtonum(mod, bac, &e); *comma = ','; if (e < 0) { topo_mod_dprintf(mod, "Trouble interpreting %s before comma.\n", bac); topo_mod_strfree(mod, bac); return (NULL); } ac = strtonum(mod, comma + 1, &e); if (e < 0) { topo_mod_dprintf(mod, "Trouble interpreting %s after comma.\n", bac); topo_mod_strfree(mod, bac); return (NULL); } topo_mod_strfree(mod, bac); *brd = ((bc - baseaddr) / bussep) + minbrd; *br = (bc - baseaddr) % bussep; *bus = ((ac == IOB_BUSADDR1) ? 0 : 1); if (*brd < minbrd || *brd > maxbrd || (*br != 0 && *br != 1) || (ac != IOB_BUSADDR1 && ac != IOB_BUSADDR2)) { topo_mod_dprintf(mod, "Trouble with transcription\n"); topo_mod_dprintf(mod, "brd=%d br=%d bus=%d bc=%x ac=%x\n", *brd, *br, *bus, bc, ac); return (NULL); } return (did_create(dhash, dp, *brd, *br, NO_RC, *bus, promtree)); }
static int disk_callback_nchan(di_minor_t minor, di_node_t node) { char *addr; char disk[10]; uint_t lun; addr = di_bus_addr(node); (void) sscanf(addr, "%X", &lun); (void) sprintf(disk, "d%d", lun); disk_common(minor, node, disk, 0); return (DEVFSADM_CONTINUE); }
static int sunos_add_devices(di_devlink_t link, void *arg) { struct devlink_cbarg *largs = (struct devlink_cbarg *)arg; struct node_args *nargs; di_node_t myself, pnode; uint64_t session_id = 0; uint16_t bdf = 0; struct libusb_device *dev; sunos_dev_priv_t *devpriv; const char *path, *newpath; int n, i; int *addr_prop; uint8_t bus_number = 0; nargs = (struct node_args *)largs->nargs; myself = largs->myself; if (nargs->last_ugenpath) { /* the same node's links */ return (DI_WALK_CONTINUE); } /* * Construct session ID. * session ID = ...parent hub addr|hub addr|dev addr. */ pnode = myself; i = 0; while (pnode != DI_NODE_NIL) { if (di_prop_exists(DDI_DEV_T_ANY, pnode, "root-hub") == 1) { /* walk to root */ uint32_t *regbuf = NULL; uint32_t reg; n = di_prop_lookup_ints(DDI_DEV_T_ANY, pnode, "reg", (int **)®buf); reg = regbuf[0]; bdf = (PCI_REG_BUS_G(reg) << 8) | (PCI_REG_DEV_G(reg) << 3) | PCI_REG_FUNC_G(reg); session_id |= (bdf << i * 8); /* same as 'unit-address' property */ bus_number = (PCI_REG_DEV_G(reg) << 3) | PCI_REG_FUNC_G(reg); usbi_dbg("device bus address=%s:%x", di_bus_addr(pnode), bus_number); break; } /* usb_addr */ n = di_prop_lookup_ints(DDI_DEV_T_ANY, pnode, "assigned-address", &addr_prop); if ((n != 1) || (addr_prop[0] == 0)) { usbi_dbg("cannot get valid usb_addr"); return (DI_WALK_CONTINUE); } session_id |= ((addr_prop[0] & 0xff) << i * 8); if (++i > 7) break; pnode = di_parent_node(pnode); } path = di_devlink_path(link); dev = usbi_get_device_by_session_id(nargs->ctx, session_id); if (dev == NULL) { dev = usbi_alloc_device(nargs->ctx, session_id); if (dev == NULL) { usbi_dbg("can't alloc device"); return (DI_WALK_TERMINATE); } devpriv = (sunos_dev_priv_t *)dev->os_priv; if ((newpath = strrchr(path, '/')) == NULL) { libusb_unref_device(dev); return (DI_WALK_TERMINATE); } devpriv->ugenpath = strndup(path, strlen(path) - strlen(newpath)); dev->bus_number = bus_number; if (sunos_fill_in_dev_info(myself, dev) != LIBUSB_SUCCESS) { libusb_unref_device(dev); return (DI_WALK_TERMINATE); } if (usbi_sanitize_device(dev) < 0) { libusb_unref_device(dev); usbi_dbg("sanatize failed: "); return (DI_WALK_TERMINATE); } } else { usbi_dbg("Dev %s exists", path); } devpriv = (sunos_dev_priv_t *)dev->os_priv; if (nargs->last_ugenpath == NULL) { /* first device */ nargs->last_ugenpath = devpriv->ugenpath; if (discovered_devs_append(*(nargs->discdevs), dev) == NULL) { usbi_dbg("cannot append device"); } /* * we alloc and hence ref this dev. We don't need to ref it * hereafter. Front end or app should take care of their ref. */ libusb_unref_device(dev); } usbi_dbg("Device %s %s id=0x%llx, devcount:%d, bdf=%x", devpriv->ugenpath, path, (uint64_t)session_id, (*nargs->discdevs)->len, bdf); return (DI_WALK_CONTINUE); }
static int solarisWalkDeviceNode(di_node_t Node, void *pvArg) { PUSBDEVICELIST pList = (PUSBDEVICELIST)pvArg; AssertPtrReturn(pList, DI_WALK_TERMINATE); /* * Check if it's a USB device in the first place. */ bool fUSBDevice = false; char *pszCompatNames = NULL; int cCompatNames = di_compatible_names(Node, &pszCompatNames); for (int i = 0; i < cCompatNames; i++, pszCompatNames += strlen(pszCompatNames) + 1) if (!strncmp(pszCompatNames, "usb", 3)) { fUSBDevice = true; break; } if (!fUSBDevice) return DI_WALK_CONTINUE; /* * Check if it's a device node or interface. */ int *pInt = NULL; char *pStr = NULL; int rc = DI_WALK_CONTINUE; if (di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "interface", &pInt) < 0) { /* It's a device node. */ char *pszDevicePath = di_devfs_path(Node); PUSBDEVICE pCur = (PUSBDEVICE)RTMemAllocZ(sizeof(*pCur)); if (!pCur) { LogRel(("USBService: failed to allocate %d bytes for PUSBDEVICE.\n", sizeof(*pCur))); return DI_WALK_TERMINATE; } bool fValidDevice = false; do { AssertBreak(pszDevicePath); char *pszDriverName = di_driver_name(Node); /* * Skip hubs */ if ( pszDriverName && !strcmp(pszDriverName, "hubd")) { break; } /* * Mandatory. * snv_85 and above have usb-dev-descriptor node properties, but older one's do not. * So if we cannot obtain the entire device descriptor, we try falling back to the * individual properties (those must not fail, if it does we drop the device). */ uchar_t *pDevData = NULL; int cbProp = di_prop_lookup_bytes(DDI_DEV_T_ANY, Node, "usb-dev-descriptor", &pDevData); if ( cbProp > 0 && pDevData) { usb_dev_descr_t *pDeviceDescriptor = (usb_dev_descr_t *)pDevData; pCur->bDeviceClass = pDeviceDescriptor->bDeviceClass; pCur->bDeviceSubClass = pDeviceDescriptor->bDeviceSubClass; pCur->bDeviceProtocol = pDeviceDescriptor->bDeviceProtocol; pCur->idVendor = pDeviceDescriptor->idVendor; pCur->idProduct = pDeviceDescriptor->idProduct; pCur->bcdDevice = pDeviceDescriptor->bcdDevice; pCur->bcdUSB = pDeviceDescriptor->bcdUSB; pCur->bNumConfigurations = pDeviceDescriptor->bNumConfigurations; pCur->fPartialDescriptor = false; } else { AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-vendor-id", &pInt) > 0); pCur->idVendor = (uint16_t)*pInt; AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-product-id", &pInt) > 0); pCur->idProduct = (uint16_t)*pInt; AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-revision-id", &pInt) > 0); pCur->bcdDevice = (uint16_t)*pInt; AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-release", &pInt) > 0); pCur->bcdUSB = (uint16_t)*pInt; pCur->fPartialDescriptor = true; } char *pszPortAddr = di_bus_addr(Node); if (pszPortAddr) pCur->bPort = RTStrToUInt8(pszPortAddr); /* Bus & Port are mixed up (kernel driver/userland) */ else pCur->bPort = 0; char pathBuf[PATH_MAX]; RTStrPrintf(pathBuf, sizeof(pathBuf), "%s", pszDevicePath); RTPathStripFilename(pathBuf); char szBuf[PATH_MAX + 48]; RTStrPrintf(szBuf, sizeof(szBuf), "%#x:%#x:%d:%s", pCur->idVendor, pCur->idProduct, pCur->bcdDevice, pathBuf); pCur->pszAddress = RTStrDup(szBuf); pCur->pszDevicePath = RTStrDup(pszDevicePath); AssertBreak(pCur->pszDevicePath); /* * Optional (some devices don't have all these) */ if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "usb-product-name", &pStr) > 0) pCur->pszProduct = RTStrDup(pStr); if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "usb-vendor-name", &pStr) > 0) pCur->pszManufacturer = RTStrDup(pStr); if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "usb-serialno", &pStr) > 0) pCur->pszSerialNumber = RTStrDup(pStr); if (di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "low-speed", &pInt) >= 0) pCur->enmSpeed = USBDEVICESPEED_LOW; else if (di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "high-speed", &pInt) >= 0) pCur->enmSpeed = USBDEVICESPEED_HIGH; else pCur->enmSpeed = USBDEVICESPEED_FULL; /* Determine state of the USB device. */ pCur->enmState = solarisDetermineUSBDeviceState(pCur, Node); /* * Valid device, add it to the list. */ fValidDevice = true; pCur->pPrev = pList->pTail; if (pList->pTail) pList->pTail = pList->pTail->pNext = pCur; else pList->pTail = pList->pHead = pCur; rc = DI_WALK_CONTINUE; } while(0); di_devfs_path_free(pszDevicePath); if (!fValidDevice) solarisFreeUSBDevice(pCur); } return rc; }
/* * initializes the port driver and instance fields based on libdevinfo */ picl_errno_t get_port_info(frutree_portnode_t *portp) { picl_errno_t rc; di_node_t rnode, curr, peer; char devfs_path[PICL_PROPNAMELEN_MAX]; char bus_addr[PICL_PROPNAMELEN_MAX]; char *di_busaddr = NULL, *di_drv = NULL; int di_int_busaddr, int_busaddr; if ((rc = ptree_get_propval_by_name(portp->portnodeh, PICL_PROP_DEVFS_PATH, devfs_path, sizeof (devfs_path))) != PICL_SUCCESS) { return (rc); } if (ptree_get_propval_by_name(portp->portnodeh, PICL_PROP_BUS_ADDR, bus_addr, sizeof (bus_addr)) != PICL_SUCCESS) { return (rc); } rnode = di_init(devfs_path, DINFOCPYALL); if (rnode == DI_NODE_NIL) { return (PICL_FAILURE); } peer = di_child_node(rnode); while (peer != DI_NODE_NIL) { curr = peer; peer = di_sibling_node(curr); di_busaddr = di_bus_addr(curr); if (di_busaddr == NULL) { continue; } /* compare the bus_addr */ if (strstr(bus_addr, ",") != NULL) { /* bus addr is of type 1,0 */ if (strcmp(bus_addr, di_busaddr) != 0) { continue; } } else { /* bus addr is of type 0x */ errno = 0; int_busaddr = strtol(bus_addr, (char **)NULL, 16); if (errno != 0) { continue; } errno = 0; di_int_busaddr = strtol(di_busaddr, (char **)NULL, 16); if (errno != 0) { continue; } if (di_int_busaddr != int_busaddr) { continue; } } di_drv = di_driver_name(curr); if (di_drv == NULL) { di_fini(rnode); return (PICL_FAILURE); } /* initialize the driver name and instance number */ (void) strncpy(portp->driver, di_drv, sizeof (portp->driver)); portp->instance = di_instance(curr); di_fini(rnode); return (PICL_SUCCESS); } di_fini(rnode); return (PICL_NODENOTFOUND); }
static int walk_tree(di_node_t node, void *arg) { char *path = NULL; char *bus_addr = NULL; char *char_di_bus_addr = NULL; int busaddr = 0; int di_busaddr = 0; char *node_name = NULL; frutree_devinfo_t *devinfo; frutree_frunode_t *frup = NULL; devinfo = *(frutree_devinfo_t **)arg; frup = (frutree_frunode_t *)devinfo->arg; if (frup == NULL) { return (DI_WALK_TERMINATE); } if (devinfo->rnode == node) { /* skip the root node */ return (DI_WALK_CONTINUE); } bus_addr = devinfo->bus_addr; char_di_bus_addr = di_bus_addr(node); if (char_di_bus_addr == NULL) { /* * look for reg property * This applies to only cPCI devices */ if (strstr(bus_addr, ",") != NULL) { /* bus addr is of type 1,0 */ /* we dont handle this case yet */ return (DI_WALK_PRUNECHILD); } di_busaddr = get_reg_dev(node); if (di_busaddr == -1) { /* reg prop not found */ return (DI_WALK_PRUNECHILD); } /* check if the bus addresses are same */ errno = 0; busaddr = strtol(bus_addr, (char **)NULL, 16); if (errno != 0) { return (DI_WALK_TERMINATE); } if (di_busaddr != busaddr) { return (DI_WALK_PRUNECHILD); } /* build the fru path name */ /* parent_path/nodename@bus_addr */ node_name = di_node_name(node); if (node_name == NULL) { return (DI_WALK_TERMINATE); } (void) snprintf(devinfo->path, sizeof (devinfo->path), "%s/%s@%s", frup->fru_path, node_name, bus_addr); return (DI_WALK_TERMINATE); } if (strstr(bus_addr, ",") != NULL) { /* bus addr is of type 1,0 */ if (strcmp(bus_addr, char_di_bus_addr) != 0) { return (DI_WALK_PRUNECHILD); } } else { /* bus addr is of type 0x */ /* check if the values are same */ errno = 0; busaddr = strtol(bus_addr, (char **)NULL, 16); if (errno != 0) { return (DI_WALK_TERMINATE); } errno = 0; di_busaddr = strtol(char_di_bus_addr, (char **)NULL, 16); if (errno != 0) { return (DI_WALK_TERMINATE); } if (di_busaddr != busaddr) { return (DI_WALK_PRUNECHILD); } } /* node found */ path = di_devfs_path(node); (void) strncpy(devinfo->path, path, sizeof (devinfo->path)); di_devfs_path_free(path); return (DI_WALK_TERMINATE); }
/* * probe for port nodes */ static int probe_tree(di_node_t node, void *arg) { char *nodetype = NULL; char *devfs_path = NULL; char *bus_addr = NULL; char *drv_name = NULL; plist_t *listptr = NULL; port_info_t *port_info = NULL; frutree_port_type_t port_type = UNKNOWN_PORT; di_minor_t minor = DI_MINOR_NIL; if (arg == NULL) { return (DI_WALK_TERMINATE); } listptr = (plist_t *)arg; while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) { nodetype = di_minor_nodetype(minor); if (nodetype == NULL) { continue; } if (strcmp(nodetype, DDI_NT_NET) == 0) { port_type = NETWORK_PORT; } else if (strcmp(nodetype, DDI_NT_PARALLEL) == 0) { port_type = PARALLEL_PORT; } else if ((strcmp(nodetype, DDI_NT_SERIAL) == 0) || (strcmp(nodetype, DDI_NT_SERIAL_MB) == 0) || (strcmp(nodetype, DDI_NT_SERIAL_DO) == 0) || (strcmp(nodetype, DDI_NT_SERIAL_MB_DO) == 0)) { port_type = SERIAL_PORT; } else { continue; } /* found port node */ devfs_path = di_devfs_path(node); if (devfs_path == NULL) { continue; } bus_addr = di_bus_addr(node); drv_name = di_driver_name(node); if ((bus_addr == NULL) || (drv_name == NULL)) { di_devfs_path_free(devfs_path); continue; } port_info = malloc(sizeof (port_info_t)); if (port_info == NULL) { di_devfs_path_free(devfs_path); return (PICL_NOSPACE); } (void) strncpy(port_info->devfs_path, devfs_path, sizeof (port_info->devfs_path)); (void) strncpy(port_info->bus_addr, bus_addr, sizeof (port_info->bus_addr)); (void) strncpy(port_info->drv_name, drv_name, sizeof (port_info->drv_name)); port_info->type = port_type; port_info->instance = di_instance(node); port_info->geo_addr = -1; port_info->next = NULL; switch (port_type) { case NETWORK_PORT: listptr->n_network++; break; case SERIAL_PORT: listptr->n_serial++; break; case PARALLEL_PORT: listptr->n_parallel++; break; } /* add to the list */ if (listptr->first == NULL) { /* 1st node */ listptr->first = port_info; listptr->last = NULL; } else if (listptr->last != NULL) { /* last node */ listptr->last->next = port_info; listptr->last = port_info; } else { /* 2nd node */ listptr->first->next = port_info; listptr->last = port_info; } di_devfs_path_free(devfs_path); return (DI_WALK_CONTINUE); } return (DI_WALK_CONTINUE); }
/* * 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; } } }