static int disk_callback_fabric(di_minor_t minor, di_node_t node) { char disk[DISK_SUBPATH_MAX]; int lun; int count; int *intp; uchar_t *str; uchar_t *wwn; uchar_t ascii_wwn[ASCIIWWNSIZE]; if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "client-guid", (char **)&wwn) > 0) { if (strlcpy((char *)ascii_wwn, (char *)wwn, sizeof (ascii_wwn)) >= sizeof (ascii_wwn)) { devfsadm_errprint("SUNW_disk_link: GUID too long:%d", strlen((char *)wwn)); return (DEVFSADM_CONTINUE); } lun = 0; } else if (di_prop_lookup_bytes(DDI_DEV_T_ANY, node, "port-wwn", &wwn) > 0) { if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, SCSI_ADDR_PROP_LUN, &intp) > 0) { lun = *intp; } else { lun = 0; } for (count = 0, str = ascii_wwn; count < 8; count++, str += 2) { (void) sprintf((caddr_t)str, "%02x", wwn[count]); } *str = '\0'; } else { return (DEVFSADM_CONTINUE); } for (str = ascii_wwn; *str != '\0'; str++) { *str = DISK_LINK_TO_UPPER(*str); } (void) snprintf(disk, DISK_SUBPATH_MAX, "t%sd%d", ascii_wwn, lun); disk_common(minor, node, disk, RM_STALE); return (DEVFSADM_CONTINUE); }
int sunos_get_active_config_descriptor(struct libusb_device *dev, uint8_t *buf, size_t len, int *host_endian) { sunos_dev_priv_t *dpriv = (sunos_dev_priv_t *)dev->os_priv; struct libusb_config_descriptor *cfg; int proplen; di_node_t node; uint8_t *rdata; /* * Keep raw configuration descriptors updated, in case config * has ever been changed through setCfg. */ if ((node = di_init(dpriv->phypath, DINFOCPYALL)) == DI_NODE_NIL) { usbi_dbg("di_int() failed: %s", strerror(errno)); return (LIBUSB_ERROR_IO); } proplen = di_prop_lookup_bytes(DDI_DEV_T_ANY, node, "usb-raw-cfg-descriptors", &rdata); if (proplen <= 0) { usbi_dbg("can't find raw config descriptors"); return (LIBUSB_ERROR_IO); } dpriv->raw_cfgdescr = realloc(dpriv->raw_cfgdescr, proplen); if (dpriv->raw_cfgdescr == NULL) { return (LIBUSB_ERROR_NO_MEM); } else { bcopy(rdata, dpriv->raw_cfgdescr, proplen); dpriv->cfgvalue = ((struct libusb_config_descriptor *) rdata)->bConfigurationValue; } di_fini(node); cfg = (struct libusb_config_descriptor *)dpriv->raw_cfgdescr; len = MIN(len, libusb_le16_to_cpu(cfg->wTotalLength)); memcpy(buf, dpriv->raw_cfgdescr, len); *host_endian = 0; usbi_dbg("path:%s len %d", dpriv->phypath, len); return (len); }
static char * get_byte_prop(char *prop_name, di_node_t node) { int cnt; uchar_t *bytes; int i; char str[MAXPATHLEN]; cnt = di_prop_lookup_bytes(DDI_DEV_T_ANY, node, prop_name, &bytes); if (cnt < 1) { return (NULL); } str[0] = 0; for (i = 0; i < cnt; i++) { char bstr[8]; /* a byte is only 2 hex chars + null */ (void) snprintf(bstr, sizeof (bstr), "%.2x", bytes[i]); (void) strlcat(str, bstr, sizeof (str)); } return (strdup(str)); }
static int sunos_fill_in_dev_info(di_node_t node, struct libusb_device *dev) { int proplen; int n, *addr, *port_prop; char *phypath; uint8_t *rdata; struct libusb_device_descriptor *descr; sunos_dev_priv_t *dpriv = (sunos_dev_priv_t *)dev->os_priv; /* Device descriptors */ proplen = di_prop_lookup_bytes(DDI_DEV_T_ANY, node, "usb-dev-descriptor", &rdata); if (proplen <= 0) { return (LIBUSB_ERROR_IO); } descr = (struct libusb_device_descriptor *)rdata; bcopy(descr, &dpriv->dev_descr, LIBUSB_DT_DEVICE_SIZE); dpriv->dev_descr.bcdUSB = libusb_cpu_to_le16(descr->bcdUSB); dpriv->dev_descr.idVendor = libusb_cpu_to_le16(descr->idVendor); dpriv->dev_descr.idProduct = libusb_cpu_to_le16(descr->idProduct); dpriv->dev_descr.bcdDevice = libusb_cpu_to_le16(descr->bcdDevice); /* Raw configuration descriptors */ proplen = di_prop_lookup_bytes(DDI_DEV_T_ANY, node, "usb-raw-cfg-descriptors", &rdata); if (proplen <= 0) { usbi_dbg("can't find raw config descriptors"); return (LIBUSB_ERROR_IO); } dpriv->raw_cfgdescr = calloc(1, proplen); if (dpriv->raw_cfgdescr == NULL) { return (LIBUSB_ERROR_NO_MEM); } else { bcopy(rdata, dpriv->raw_cfgdescr, proplen); dpriv->cfgvalue = ((struct libusb_config_descriptor *) rdata)->bConfigurationValue; } n = di_prop_lookup_ints(DDI_DEV_T_ANY, node, "reg", &port_prop); if ((n != 1) || (*port_prop <= 0)) { return (LIBUSB_ERROR_IO); } dev->port_number = *port_prop; /* device physical path */ phypath = di_devfs_path(node); if (phypath) { dpriv->phypath = strdup(phypath); di_devfs_path_free(phypath); } else { free(dpriv->raw_cfgdescr); return (LIBUSB_ERROR_IO); } /* address */ n = di_prop_lookup_ints(DDI_DEV_T_ANY, node, "assigned-address", &addr); if (n != 1 || *addr == 0) { usbi_dbg("can't get address"); } else { dev->device_address = *addr; } /* speed */ if (di_prop_exists(DDI_DEV_T_ANY, node, "low-speed") == 1) { dev->speed = LIBUSB_SPEED_LOW; } else if (di_prop_exists(DDI_DEV_T_ANY, node, "high-speed") == 1) { dev->speed = LIBUSB_SPEED_HIGH; } else if (di_prop_exists(DDI_DEV_T_ANY, node, "full-speed") == 1) { dev->speed = LIBUSB_SPEED_FULL; } else if (di_prop_exists(DDI_DEV_T_ANY, node, "super-speed") == 1) { dev->speed = LIBUSB_SPEED_SUPER; } usbi_dbg("vid=%x pid=%x, path=%s, bus_nmber=0x%x, port_number=%d, " "speed=%d", dpriv->dev_descr.idVendor, dpriv->dev_descr.idProduct, dpriv->phypath, dev->bus_number, dev->port_number, dev->speed); return (LIBUSB_SUCCESS); }
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; }
static int get_drv_info(di_node_t node, led_dtls_t *dtls) { int *target_data; uchar_t *port_data = NULL; di_minor_t min_node; int i, r; int t = -1; int *newStatus = malloc(dtls->n_disks * sizeof (int)); if (newStatus == NULL) return (0); for (i = 0; i < dtls->n_disks; i++) { newStatus[i] = MINORS_UNKNOWN; } r = di_prop_lookup_ints(DDI_DEV_T_ANY, node, HW_PROP_TARGET, &target_data); for (i = 0; i < r; i++) { t = target_data[i]; if ((t >= 0) && (t < dtls->n_disks)) { /* set no minors until we know */ newStatus[t] = NO_MINORS; break; /* go with this node */ } } if ((t >= 0) && (t < dtls->n_disks)) { r = di_prop_lookup_bytes( DDI_DEV_T_ANY, node, HW_PROP_PORT, &port_data); /* * The first byte of the array dtls->disk_port[t] contains * the length of the residue. So 255 is the maximum length * which can be handled. Limit the property data to this. */ if (r > 255) { r = 0; } if ((r > 0) && (port_data != NULL)) { if ((dtls->disk_port[t] != NULL) && (*(dtls->disk_port[t]) != r)) { /* * existing data is of different length, * free it and malloc a fresh array. */ free(dtls->disk_port[t]); dtls->disk_port[t] = NULL; } if (dtls->disk_port[t] == NULL) { dtls->disk_port[t] = malloc(r + 1); } if (dtls->disk_port[t] != NULL) { *(dtls->disk_port[t]) = (uchar_t)r; (void) memcpy(dtls->disk_port[t] + 1, port_data, r); } } min_node = di_minor_next(node, DI_MINOR_NIL); if (min_node != DI_MINOR_NIL) { /* * device has minor device node(s) */ newStatus[t] = HAS_MINORS; /* got minor(s) */ } } /* * propagate attachment status and note changes * don't propagate to absent disks, otherwise we may not detect a * status change when they're replugged. */ r = 0; for (i = 0; i < dtls->n_disks; i++) { if ((newStatus[i] != MINORS_UNKNOWN) && dtls->disk_detected[i] && (dtls->disk_ready[i] != newStatus[i])) { dtls->disk_ready[i] = newStatus[i]; r = 1; } } free(newStatus); return (r); }