示例#1
0
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);
}
示例#2
0
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);
}
示例#3
0
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));
}
示例#4
0
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;
}
示例#6
0
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);
}