static void set_trackpoint_sensitivity(struct udev_device *dev, const char *value)
{
        struct udev_device *pdev;
        char val_s[DECIMAL_STR_MAX(int)];
        int r, val_i;

        assert(dev);
        assert(value);

        /* The sensitivity sysfs attr belongs to the serio parent device */
        pdev = udev_device_get_parent_with_subsystem_devtype(dev, "serio", NULL);
        if (!pdev) {
                log_warning("Failed to get serio parent for '%s'", udev_device_get_devnode(dev));
                return;
        }

        r = safe_atoi(value, &val_i);
        if (r < 0) {
                log_error("Unable to parse POINTINGSTICK_SENSITIVITY '%s' for '%s'", value, udev_device_get_devnode(dev));
                return;
        }

        xsprintf(val_s, "%d", val_i);

        r = udev_device_set_sysattr_value(pdev, "sensitivity", val_s);
        if (r < 0)
                log_error_errno(r, "Failed to write 'sensitivity' attribute for '%s': %m", udev_device_get_devnode(pdev));
}
Beispiel #2
0
static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent, char **path)
{
	struct udev *udev  = udev_device_get_udev(parent);
	struct udev_device *targetdev;
	struct udev_device *fcdev = NULL;
	const char *port;
	unsigned int lun;

	targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target");
	if (targetdev == NULL)
		return NULL;

	fcdev = udev_device_new_from_subsystem_sysname(udev, "fc_transport", udev_device_get_sysname(targetdev));
	if (fcdev == NULL)
		return NULL;
	port = udev_device_get_sysattr_value(fcdev, "port_name");
	if (port == NULL) {
		parent = NULL;
		goto out;
	}

	lun = strtoul(udev_device_get_sysnum(parent), NULL, 10);
	path_prepend(path, "fc-%s:0x%04x%04x00000000", port, lun & 0xffff, (lun >> 16) & 0xffff);
out:
	udev_device_unref(fcdev);
	return parent;
}
static int install_force_release(struct udev_device *dev, const unsigned int *release, unsigned int release_count) {
        struct udev_device *atkbd;
        const char *cur;
        char codes[4096];
        char *s;
        size_t l;
        unsigned int i;
        int ret;

        atkbd = udev_device_get_parent_with_subsystem_devtype(dev, "serio", NULL);
        if (!atkbd)
                return -ENODEV;

        cur = udev_device_get_sysattr_value(atkbd, "force_release");
        if (!cur)
                return -ENODEV;

        s = codes;
        l = sizeof(codes);

        /* copy current content */
        l = strpcpy(&s, l, cur);

        /* append new codes */
        for (i = 0; i < release_count; i++)
                l = strpcpyf(&s, l, ",%d", release[i]);

        log_debug("keyboard: updating force-release list with '%s'", codes);
        ret = udev_device_set_sysattr_value(atkbd, "force_release", codes);
        if (ret < 0)
                log_error("Error writing force-release attribute: %s", strerror(-ret));
        return ret;
}
static int builtin_input_id(struct udev_device *dev, int argc, char *argv[], bool test)
{
        struct udev_device *pdev;
        unsigned long bitmask_ev[NBITS(EV_MAX)];
        unsigned long bitmask_abs[NBITS(ABS_MAX)];
        unsigned long bitmask_key[NBITS(KEY_MAX)];
        unsigned long bitmask_rel[NBITS(REL_MAX)];

        /* walk up the parental chain until we find the real input device; the
         * argument is very likely a subdevice of this, like eventN */
        pdev = dev;
        while (pdev != NULL && udev_device_get_sysattr_value(pdev, "capabilities/ev") == NULL)
                pdev = udev_device_get_parent_with_subsystem_devtype(pdev, "input", NULL);

        /* not an "input" class device */
        if (pdev == NULL)
                return EXIT_SUCCESS;

        /* Use this as a flag that input devices were detected, so that this
         * program doesn't need to be called more than once per device */
        udev_builtin_add_property(dev, test, "ID_INPUT", "1");
        get_cap_mask(dev, pdev, "capabilities/ev", bitmask_ev, sizeof(bitmask_ev), test);
        get_cap_mask(dev, pdev, "capabilities/abs", bitmask_abs, sizeof(bitmask_abs), test);
        get_cap_mask(dev, pdev, "capabilities/rel", bitmask_rel, sizeof(bitmask_rel), test);
        get_cap_mask(dev, pdev, "capabilities/key", bitmask_key, sizeof(bitmask_key), test);
        test_pointers(dev, bitmask_ev, bitmask_abs, bitmask_key, bitmask_rel, test);
        test_key(dev, bitmask_ev, bitmask_key, test);
        return EXIT_SUCCESS;
}
static int names_pci(struct udev_device *dev, struct netnames *names) {
        struct udev_device *parent;

        assert(dev);
        assert(names);

        parent = udev_device_get_parent(dev);

        /* there can only ever be one virtio bus per parent device, so we can
           safely ignore any virtio buses. see
           <http://lists.linuxfoundation.org/pipermail/virtualization/2015-August/030331.html> */
        while (parent && streq_ptr("virtio", udev_device_get_subsystem(parent)))
                parent = udev_device_get_parent(parent);

        if (!parent)
                return -ENOENT;

        /* check if our direct parent is a PCI device with no other bus in-between */
        if (streq_ptr("pci", udev_device_get_subsystem(parent))) {
                names->type = NET_PCI;
                names->pcidev = parent;
        } else {
                names->pcidev = udev_device_get_parent_with_subsystem_devtype(dev, "pci", NULL);
                if (!names->pcidev)
                        return -ENOENT;
        }
        dev_pci_onboard(dev, names);
        dev_pci_slot(dev, names);
        return 0;
}
QStringList QDeviceDiscovery::scanConnectedDevices()
{
    QStringList devices;

    if (!m_udev)
        return devices;

    udev_enumerate *ue = udev_enumerate_new(m_udev);
    udev_enumerate_add_match_subsystem(ue, "input");
    udev_enumerate_add_match_subsystem(ue, "drm");

    if (m_types & Device_Mouse)
        udev_enumerate_add_match_property(ue, "ID_INPUT_MOUSE", "1");
    if (m_types & Device_Touchpad)
        udev_enumerate_add_match_property(ue, "ID_INPUT_TOUCHPAD", "1");
    if (m_types & Device_Touchscreen)
        udev_enumerate_add_match_property(ue, "ID_INPUT_TOUCHSCREEN", "1");
    if (m_types & Device_Keyboard) {
        udev_enumerate_add_match_property(ue, "ID_INPUT_KEYBOARD", "1");
        udev_enumerate_add_match_property(ue, "ID_INPUT_KEY", "1");
    }
    if (m_types & Device_Tablet)
        udev_enumerate_add_match_property(ue, "ID_INPUT_TABLET", "1");

    if (udev_enumerate_scan_devices(ue) != 0) {
#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG
        qWarning() << "UDeviceHelper scan connected devices for enumeration failed";
#endif
        return devices;
    }

    udev_list_entry *entry;
    udev_list_entry_foreach (entry, udev_enumerate_get_list_entry(ue)) {
        const char *syspath = udev_list_entry_get_name(entry);
        udev_device *udevice = udev_device_new_from_syspath(m_udev, syspath);
        QString candidate = QString::fromUtf8(udev_device_get_devnode(udevice));
        if ((m_types & Device_InputMask) && candidate.startsWith(QLatin1String(QT_EVDEV_DEVICE)))
            devices << candidate;
        if ((m_types & Device_VideoMask) && candidate.startsWith(QLatin1String(QT_DRM_DEVICE))) {
            if (m_types & Device_DRM_PrimaryGPU) {
                udev_device *pci = udev_device_get_parent_with_subsystem_devtype(udevice, "pci", 0);
                if (pci) {
                    if (qstrcmp(udev_device_get_sysattr_value(pci, "boot_vga"), "1") == 0)
                        devices << candidate;
                }
            } else
                devices << candidate;
        }

        udev_device_unref(udevice);
    }
    udev_enumerate_unref(ue);

#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG
    qWarning() << "UDeviceHelper found matching devices" << devices;
#endif

    return devices;
}
Beispiel #7
0
QUdevDeviceList QUdevPrivate::getUDevDevicesForSubsystem(const QString &strSubSystem, const QString &strDeviceType, const QString &strParentSubSystem, const QString &strParentDeviceType)
{
    struct udev_enumerate *enumerate = udev_enumerate_new(m_pUdev);
    struct udev_list_entry *devices = 0;
    struct udev_list_entry *dev_list_entry = 0;
    struct udev_device *dev = 0;

    QList<QUdevDevice> lDevices;

    if(strSubSystem.isEmpty()) return lDevices;

    //get subsystem enumerator
    udev_enumerate_add_match_subsystem(enumerate, strSubSystem.toLatin1().constData());
    //perform sysfs scanning
    udev_enumerate_scan_devices(enumerate);
    devices = udev_enumerate_get_list_entry(enumerate);

    //iterate over all devices in the enumeration list
    udev_list_entry_foreach(dev_list_entry, devices)
    {
        QUdevDevice udDev;

        //create udev device for the sysfs path returned
        udDev.m_strSysfsPath = QString::fromLatin1(udev_list_entry_get_name(dev_list_entry));        
        dev = udev_device_new_from_syspath(m_pUdev, udDev.m_strSysfsPath.toLatin1().constData());

        //filter the correct device types, ignored if empty device type is specified
        if(strDeviceType.isEmpty() || (QString::fromLatin1(udev_device_get_devtype(dev)) == strDeviceType))
        {
            //get the path inside /dev
            udDev.m_strDevPath = QString::fromLatin1(udev_device_get_devnode(dev));
            udDev.m_strSubsystem = strSubSystem;
            udDev.m_strDeviceType = strDeviceType;

            //if the caller wants a specific parent subsystem/devtype query the sysfs tree here
            if(!strParentSubSystem.isEmpty() && !strParentDeviceType.isEmpty())
            {
                /*
                 * retrieve the parent device with the subsystem/devtype pair of m_strParentSubSystem/m_strParentDeviceType.
                 *
                 * udev_device_get_parent_with_subsystem_devtype() will walk up the complete tree if needed
                 */
                dev = udev_device_get_parent_with_subsystem_devtype(dev, strParentSubSystem.toLatin1().constData(), strParentDeviceType.toLatin1().constData());
            }

            if(dev)
            {
                //fill the device information
                udDev.m_strVendorID = QString::fromLatin1(udev_device_get_sysattr_value(dev,"idVendor"));
                udDev.m_strProductID = QString::fromLatin1(udev_device_get_sysattr_value(dev, "idProduct"));
                udDev.m_strManufacturer = QString::fromLatin1(udev_device_get_sysattr_value(dev,"manufacturer"));
                udDev.m_strProduct = QString::fromLatin1(udev_device_get_sysattr_value(dev,"product"));
                udDev.m_strSerial = QString::fromLatin1(udev_device_get_sysattr_value(dev, "serial"));
                lDevices.append(udDev);
            }

            udev_device_unref(dev);
        }
    }
  /* 
     This implementation uses udev to retrieve capture devices.
     We support both udev and default v4l2 ways to retrieve 
     devices. Udev is not supported on all systems.

   */
  std::vector<V4L2_Device> v4l2_get_devices() {
    
    std::vector<V4L2_Device> result;
    struct udev* udev;
    struct udev_enumerate* enumerate;
    struct udev_list_entry* devices;
    struct udev_list_entry* dev_list_entry;
    struct udev_device* dev;
 
    udev = udev_new();
    if(!udev) {
      printf("Error: Cannot udev_new()\n");
      return result;
    }
 
    enumerate = udev_enumerate_new(udev);
    udev_enumerate_add_match_subsystem(enumerate, "video4linux");
    udev_enumerate_scan_devices(enumerate);
    devices = udev_enumerate_get_list_entry(enumerate);

    udev_list_entry_foreach(dev_list_entry, devices) {

      /* Get the device by syspath. */
      const char* syspath = udev_list_entry_get_name(dev_list_entry);
      dev = udev_device_new_from_syspath(udev, syspath);

      if(!dev) {
        printf("Error: cannot get the device using the syspath: %s\n", syspath);
        continue;
      }

      V4L2_Device v4l2_device;
      v4l2_device.path = udev_device_get_devnode(dev);

      if(v4l2_device.path.size() == 0) {
        printf("Error: Cannot find devpath.\n");
        continue;
      }

      dev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device");

      if(!dev) {
        printf("Error:Cannot find related usb device.\n");
        continue;
      }

      v4l2_device.id_vendor = udev_device_get_sysattr_value(dev, "idVendor");
      v4l2_device.id_product = udev_device_get_sysattr_value(dev, "idProduct");

      result.push_back(v4l2_device);
    }

    udev_enumerate_unref(enumerate);
    udev_unref(udev);
    
    return result;
  }
static int names_usb(struct udev_device *dev, struct netnames *names) {
        struct udev_device *usbdev;
        char name[256];
        char *ports;
        char *config;
        char *interf;
        size_t l;
        char *s;

        assert(dev);
        assert(names);

        usbdev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface");
        if (!usbdev)
                return -ENOENT;

        /* get USB port number chain, configuration, interface */
        strscpy(name, sizeof(name), udev_device_get_sysname(usbdev));
        s = strchr(name, '-');
        if (!s)
                return -EINVAL;
        ports = s+1;

        s = strchr(ports, ':');
        if (!s)
                return -EINVAL;
        s[0] = '\0';
        config = s+1;

        s = strchr(config, '.');
        if (!s)
                return -EINVAL;
        s[0] = '\0';
        interf = s+1;

        /* prefix every port number in the chain with "u" */
        s = ports;
        while ((s = strchr(s, '.')))
                s[0] = 'u';
        s = names->usb_ports;
        l = strpcpyl(&s, sizeof(names->usb_ports), "u", ports, NULL);

        /* append USB config number, suppress the common config == 1 */
        if (!streq(config, "1"))
                l = strpcpyl(&s, sizeof(names->usb_ports), "c", config, NULL);

        /* append USB interface number, suppress the interface == 0 */
        if (!streq(interf, "0"))
                l = strpcpyl(&s, sizeof(names->usb_ports), "i", interf, NULL);
        if (l == 0)
                return -ENAMETOOLONG;

        names->type = NET_USB;
        return 0;
}
Beispiel #10
0
UdevDevice UdevDevice::getParent(const char* subsystem,const char* deviceType)
	{
	/* Get the parent device: */
	udev_device* parent=udev_device_get_parent_with_subsystem_devtype(device,subsystem,deviceType);
	
	/* The parent device is not supposed to be unref'ed, so let's explicitly ref it here so that a later unref won't hurt: */
	if(parent!=0)
		udev_device_ref(parent);
	
	return UdevDevice(parent);
	}
int find_and_open_p6s() {
    int result = -1;
    char buf[300];
    memset(buf, 0, sizeof(buf));

    get_usb_device_syspath(ID_VENDOR_YEALINK,ID_PRODUCT_VOIPUSBPHONE, buf);
    int len = strlen(buf);
    if (len==0) {
        return result;
    }
    printf("Found Skypemate P6S USB at %s \n", buf);

    struct udev* udev;
    struct udev_enumerate* enumerate;
    struct udev_list_entry* dev_list_entry;
    struct udev_device* dev;

    udev = udev_new();
    if (udev<0) {
        perror("error creating udev object");
        return result;
    }

    // enumerating all hidraw devices
    enumerate = udev_enumerate_new(udev);
    udev_enumerate_add_match_subsystem(enumerate, "hidraw");
    udev_enumerate_scan_devices(enumerate);

    dev_list_entry = udev_enumerate_get_list_entry(enumerate);
    while ((dev_list_entry!=0) && (result==-1)) {
        const char* syspath = udev_list_entry_get_name(dev_list_entry);
        dev = udev_device_new_from_syspath(udev, syspath);
        // get hidraw USB parent
        struct udev_device* parent = udev_device_get_parent_with_subsystem_devtype(dev, "usb","usb_device");
        if (parent != 0) {
            const char* parent_syspath = udev_device_get_syspath(parent);
            if ( strcmp(buf, parent_syspath) == 0) {
                // found it
                const char* devnode = udev_device_get_devnode(dev);
                printf("Found corresponding hidraw device: %s \n", devnode);
                result = open(devnode, O_RDONLY);
            }
        }

        udev_device_unref(dev);
        dev_list_entry = udev_list_entry_get_next(dev_list_entry);
    }

    udev_enumerate_unref(enumerate);
    udev_unref(udev);
    return result;
}
Beispiel #12
0
int main (int argc, char** argv)
{
	struct udev *udev;
	struct udev_device *dev;

	char devpath[PATH_MAX];
	unsigned long bitmask_ev[NBITS(EV_MAX)];
	unsigned long bitmask_abs[NBITS(ABS_MAX)];
	unsigned long bitmask_key[NBITS(KEY_MAX)];
        unsigned long bitmask_rel[NBITS(REL_MAX)];

	if (argc != 2) {
		fprintf(stderr, "Usage: %s <device path (without /sys)>\n", argv[0]);
		exit(1);
	}

	/* get the device */
	udev = udev_new();
	if (udev == NULL)
		return 1;

	snprintf(devpath, sizeof(devpath), "%s/%s", udev_get_sys_path(udev), argv[1]);
	dev = udev_device_new_from_syspath(udev, devpath);
	if (dev == NULL) {
		fprintf(stderr, "unable to access '%s'\n", devpath);
		return 1;
	}

	/* walk up the parental chain until we find the real input device; the
	 * argument is very likely a subdevice of this, like eventN */
	while (dev != NULL && udev_device_get_sysattr_value(dev, "capabilities/ev") == NULL)
		dev = udev_device_get_parent_with_subsystem_devtype(dev, "input", NULL);

	/* not an "input" class device */
	if (dev == NULL)
		return 0;

	/* Use this as a flag that input devices were detected, so that this
	 * program doesn't need to be called more than once per device */
	puts("ID_INPUT=1");

	get_cap_mask (dev, "capabilities/ev", bitmask_ev, sizeof (bitmask_ev));
	get_cap_mask (dev, "capabilities/abs", bitmask_abs, sizeof (bitmask_abs));
	get_cap_mask (dev, "capabilities/rel", bitmask_rel, sizeof (bitmask_rel));
	get_cap_mask (dev, "capabilities/key", bitmask_key, sizeof (bitmask_key));

	test_pointers(bitmask_ev, bitmask_abs, bitmask_key, bitmask_rel);

	test_key(bitmask_ev, bitmask_key);

	return 0;
}
Device Device::ancestorOfType(const QString &subsys, const QString &devtype) const
{
    if (!d)
        return Device();

    struct udev_device *p = udev_device_get_parent_with_subsystem_devtype(d->udev,
                                subsys.toLatin1().constData(), devtype.toLatin1().constData());

    if (!p)
        return Device();

    return Device(new DevicePrivate(p));
}
Beispiel #14
0
void QDeviceDiscovery::handleUDevNotification()
{
    if (!m_udevMonitor)
        return;

    struct udev_device *dev;
    QString devNode;

    dev = udev_monitor_receive_device(m_udevMonitor);
    if (!dev)
        goto cleanup;

    const char *action;
    action = udev_device_get_action(dev);
    if (!action)
        goto cleanup;

    const char *str;
    str = udev_device_get_devnode(dev);
    if (!str)
        goto cleanup;

    const char *subsystem;
    devNode = QString::fromUtf8(str);
    if (devNode.startsWith(QLatin1String(QT_EVDEV_DEVICE)))
        subsystem = "input";
    else if (devNode.startsWith(QLatin1String(QT_DRM_DEVICE)))
        subsystem = "drm";
    else goto cleanup;

    // if we cannot determine a type, walk up the device tree
    if (!checkDeviceType(dev)) {
        // does not increase the refcount
        dev = udev_device_get_parent_with_subsystem_devtype(dev, subsystem, 0);
        if (!dev)
            goto cleanup;

        if (!checkDeviceType(dev))
            goto cleanup;
    }

    if (qstrcmp(action, "add") == 0)
        emit deviceDetected(devNode);

    if (qstrcmp(action, "remove") == 0)
        emit deviceRemoved(devNode);

cleanup:
    udev_device_unref(dev);
}
Beispiel #15
0
static int builtin_input_id(struct udev_device *dev, int argc, char *argv[], bool test) {
        struct udev_device *pdev;
        unsigned long bitmask_ev[NBITS(EV_MAX)];
        unsigned long bitmask_abs[NBITS(ABS_MAX)];
        unsigned long bitmask_key[NBITS(KEY_MAX)];
        unsigned long bitmask_rel[NBITS(REL_MAX)];
        unsigned long bitmask_props[NBITS(INPUT_PROP_MAX)];
        const char *sysname, *devnode;
        bool is_pointer;
        bool is_key;

        assert(dev);

        /* walk up the parental chain until we find the real input device; the
         * argument is very likely a subdevice of this, like eventN */
        pdev = dev;
        while (pdev != NULL && udev_device_get_sysattr_value(pdev, "capabilities/ev") == NULL)
                pdev = udev_device_get_parent_with_subsystem_devtype(pdev, "input", NULL);

        if (pdev) {
                /* Use this as a flag that input devices were detected, so that this
                 * program doesn't need to be called more than once per device */
                udev_builtin_add_property(dev, test, "ID_INPUT", "1");
                get_cap_mask(dev, pdev, "capabilities/ev", bitmask_ev, sizeof(bitmask_ev), test);
                get_cap_mask(dev, pdev, "capabilities/abs", bitmask_abs, sizeof(bitmask_abs), test);
                get_cap_mask(dev, pdev, "capabilities/rel", bitmask_rel, sizeof(bitmask_rel), test);
                get_cap_mask(dev, pdev, "capabilities/key", bitmask_key, sizeof(bitmask_key), test);
                get_cap_mask(dev, pdev, "properties", bitmask_props, sizeof(bitmask_props), test);
                is_pointer = test_pointers(dev, bitmask_ev, bitmask_abs,
                                           bitmask_key, bitmask_rel,
                                           bitmask_props, test);
                is_key = test_key(dev, bitmask_ev, bitmask_key, test);
                /* Some evdev nodes have only a scrollwheel */
                if (!is_pointer && !is_key && test_bit(EV_REL, bitmask_ev) &&
                    (test_bit(REL_WHEEL, bitmask_rel) || test_bit(REL_HWHEEL, bitmask_rel)))
                        udev_builtin_add_property(dev, test, "ID_INPUT_KEY", "1");
                if (test_bit(EV_SW, bitmask_ev))
                        udev_builtin_add_property(dev, test, "ID_INPUT_SWITCH", "1");

        }

        devnode = udev_device_get_devnode(dev);
        sysname = udev_device_get_sysname(dev);
        if (devnode && sysname && startswith(sysname, "event"))
                extract_info(dev, devnode, test);

        return EXIT_SUCCESS;
}
Beispiel #16
0
EAPI Eina_Stringshare *
eeze_udev_syspath_get_parent_filtered(const char *syspath, const char *subsystem, const char *devtype)
{
   _udev_device *device, *parent;
   Eina_Stringshare *ret = NULL;

   EINA_SAFETY_ON_NULL_RETURN_VAL(syspath, NULL);

   if (!(device = _new_device(syspath)))
     return NULL;
   parent = udev_device_get_parent_with_subsystem_devtype(device, subsystem, devtype);
   if (parent)
     ret = eina_stringshare_add(udev_device_get_syspath(parent));
   udev_device_unref(device);
   return ret;
}
Beispiel #17
0
static int get_device_string(hid_device *dev, const char *key, wchar_t *string, size_t maxlen)
{
	struct udev *udev;
	struct udev_device *udev_dev, *parent;
	struct stat s;
	int ret = -1;
	
	setlocale(LC_ALL,"");

	/* Create the udev object */
	udev = udev_new();
	if (!udev) {
		printf("Can't create udev\n");
		return -1;
	}

	/* Get the dev_t (major/minor numbers) from the file handle. */
	fstat(dev->device_handle, &s);
	/* Open a udev device from the dev_t. 'c' means character device. */
	udev_dev = udev_device_new_from_devnum(udev, 'c', s.st_rdev);
	if (udev_dev) {
		const char *str;
		/* Find the parent USB Device */
		parent = udev_device_get_parent_with_subsystem_devtype(
		       udev_dev,
		       "usb",
		       "usb_device");
		if (parent) {
			str = udev_device_get_sysattr_value(parent, key);
			if (str) {
				/* Convert the string from UTF-8 to wchar_t */
				ret = mbstowcs(string, str, maxlen);
				goto end;
			}
		}
	}

end:
	udev_device_unref(udev_dev);
	// parent doesn't need to be (and can't be) unref'd.
	// I'm not sure why, but it'll throw double-free() errors.
	udev_unref(udev);

	return ret;
}
Beispiel #18
0
static int names_bcma(struct udev_device *dev, struct netnames *names) {
        struct udev_device *bcmadev;
        unsigned int core;

        bcmadev = udev_device_get_parent_with_subsystem_devtype(dev, "bcma", NULL);
        if (!bcmadev)
                return -ENOENT;

        /* bus num:core num */
        if (sscanf(udev_device_get_sysname(bcmadev), "bcma%*d:%d", &core) != 1)
                return -EINVAL;
        /* suppress the common core == 0 */
        if (core > 0)
                snprintf(names->bcma_core, sizeof(names->bcma_core), "b%d", core);

        names->type = NET_BCMA;
        return 0;
}
Beispiel #19
0
	Array<GamepadDeviceInfo> LinuxGetAttachedJoysticks() {
		Array<GamepadDeviceInfo> deviceInfoArray;
		udev *udev_context;
		udev_enumerate *enumerate;
		udev_list_entry *devices, *dev_list_entry;
		udev_device *dev;
		udev_context = udev_new();
		if (!udev_context) {
			// TODO: Throw error
			return deviceInfoArray;
		}
		enumerate = udev_enumerate_new(udev_context);
		udev_enumerate_add_match_subsystem(enumerate, "input");
		udev_enumerate_scan_devices(enumerate);
		devices = udev_enumerate_get_list_entry(enumerate);
		udev_list_entry_foreach(dev_list_entry, devices) {
			const char *path = NULL, *devnode = NULL;
			path = udev_list_entry_get_name(dev_list_entry);
			dev = udev_device_new_from_syspath(udev_context, path);
			devnode = udev_device_get_devnode(dev);
			dev = udev_device_get_parent_with_subsystem_devtype(
				dev, "usb", "usb_device");
			if (devnode && dev) {
				if (strstr(devnode, "js")) {
					GamepadDeviceInfo deviceInfo;
					deviceInfo.mProductName =
						udev_device_get_sysattr_value(dev, "product");
					deviceInfo.mManufacturer =
						udev_device_get_sysattr_value(dev, "manufacturer");
					deviceInfo.mGuid =
						String(udev_device_get_sysattr_value(dev, "product")) +
						String(udev_device_get_sysattr_value(dev, "idVendor")) +
						String(udev_device_get_sysattr_value(dev, "serial"));
					deviceInfo.mDeviceHandle =
						open(devnode, O_RDONLY | O_NONBLOCK);
					deviceInfoArray.Append(deviceInfo);
				}
			}
			udev_device_unref(dev);
		}
		udev_enumerate_unref(enumerate);
		udev_unref(udev_context);
		return deviceInfoArray;
	}
Beispiel #20
0
char *v4l2cpi_udev_get_serial (const char* devfile)
{
	struct udev *udev;
	struct udev_enumerate *enumerate;
	struct udev_list_entry *devices, *dev_list_entry;
	struct udev_device *dev;
	char *ret = NULL;
	
	udev = udev_new ();
	if (!udev)
		return NULL;
	
	enumerate = udev_enumerate_new (udev);
	udev_enumerate_add_match_subsystem (enumerate, "video4linux");
	udev_enumerate_scan_devices (enumerate);
	devices = udev_enumerate_get_list_entry (enumerate);
	udev_list_entry_foreach (dev_list_entry, devices){
		const char *path;
		
		path = udev_list_entry_get_name (dev_list_entry);
		dev = udev_device_new_from_syspath (udev, path);

		if (!strcmp (udev_device_get_devnode (dev), devfile)){
			dev = udev_device_get_parent_with_subsystem_devtype (dev, "usb", "usb_device");
			if (dev){
				const char *serial;
				
				serial = udev_device_get_sysattr_value(dev, "serial");
				if (serial){
					ret = malloc (strlen (serial)+1);
					strcpy (ret, serial);
				}
				udev_device_unref (dev);
			}
		}
	}
	/* Free the enumerator object */
	udev_enumerate_unref(enumerate);

	udev_unref(udev);

	return ret;
}
Beispiel #21
0
static int names_pci(struct udev_device *dev, struct netnames *names) {
        struct udev_device *parent;

        parent = udev_device_get_parent(dev);
        if (!parent)
                return -ENOENT;
        /* check if our direct parent is a PCI device with no other bus in-between */
        if (streq_ptr("pci", udev_device_get_subsystem(parent))) {
                names->type = NET_PCI;
                names->pcidev = parent;
        } else {
                names->pcidev = udev_device_get_parent_with_subsystem_devtype(dev, "pci", NULL);
                if (!names->pcidev)
                        return -ENOENT;
        }
        dev_pci_onboard(dev, names);
        dev_pci_slot(dev, names);
        return 0;
}
// List of devices: http://www.ideasonboard.org/uvc/ 
// How to use libudev: http://www.signal11.us/oss/udev/
std::vector<LinuxCaptureDevice> VideoCaptureV4L2::getDeviceList() {
  std::vector<LinuxCaptureDevice> found_devices;
  struct udev* udev;
  struct udev_enumerate* enumerate;
  struct udev_list_entry* devices;
  struct udev_list_entry* dev_list_entry;
  struct udev_device* dev;

  udev = udev_new();
  if(!udev) {
    printf("ERROR: cannot udev_new()\n");
    return found_devices;
  }

  enumerate = udev_enumerate_new(udev);
  udev_enumerate_add_match_subsystem(enumerate, "video4linux");
  udev_enumerate_scan_devices(enumerate);
  devices = udev_enumerate_get_list_entry(enumerate);

  udev_list_entry_foreach(dev_list_entry, devices) {
    LinuxCaptureDevice linux_device;

    const char* path = udev_list_entry_get_name(dev_list_entry);
    dev = udev_device_new_from_syspath(udev, path);

    const char* devpath = udev_device_get_devnode(dev);
    linux_device.path.assign(devpath, strlen(devpath));
    
    dev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device");
    if(!dev) {
      printf("VERBOSE: cannot find related usb device.\n");
      found_devices.push_back(linux_device);
      continue;
    }

    const char* id_vendor = udev_device_get_sysattr_value(dev, "idVendor");
    linux_device.id_vendor.assign(id_vendor, strlen(id_vendor));

    const char* id_product = udev_device_get_sysattr_value(dev, "idProduct");
    linux_device.id_product.assign(id_product, strlen(id_product));

    found_devices.push_back(linux_device);
  }
Beispiel #23
0
static int names_pci(struct udev_device *dev, struct netnames *names) {
        struct udev_device *parent;
        static int do_virtio = -1;

        if (do_virtio < 0) {
                _cleanup_free_ char *value = NULL;
                int n = 0;
                do_virtio = 0;
                if (get_proc_cmdline_key("net.ifnames", NULL) > 0)
                        do_virtio = 1;
                else if (get_proc_cmdline_key("net.ifnames=", &value) > 0) {
                        safe_atoi(value, &n);
                        if (n > 0)
                                do_virtio = 1;
                }
        }

        parent = udev_device_get_parent(dev);

        /* there can only ever be one virtio bus per parent device, so we can
           safely ignore any virtio buses. see
           <http://lists.linuxfoundation.org/pipermail/virtualization/2015-August/030331.html> */
        if (do_virtio > 0)
                while (parent && streq_ptr("virtio", udev_device_get_subsystem(parent)))
                        parent = udev_device_get_parent(parent);

        if (!parent)
                return -ENOENT;

        /* check if our direct parent is a PCI device with no other bus in-between */
        if (streq_ptr("pci", udev_device_get_subsystem(parent))) {
                names->type = NET_PCI;
                names->pcidev = parent;
        } else {
                names->pcidev = udev_device_get_parent_with_subsystem_devtype(dev, "pci", NULL);
                if (!names->pcidev)
                        return -ENOENT;
        }
        dev_pci_onboard(dev, names);
        dev_pci_slot(dev, names);
        return 0;
}
Beispiel #24
0
static void add_device(const char *syspath, const char *devname,
			const char *driver, const char *vendor,
			const char *model, struct udev_device *device)
{
	struct udev_device *intf;
	const char *devpath, *devnode, *interface, *number, *label, *sysattr;
	struct modem_info *modem;
	struct device_info *info;

	devpath = udev_device_get_syspath(device);
	if (devpath == NULL)
		return;

	devnode = udev_device_get_devnode(device);
	if (devnode == NULL) {
		devnode = udev_device_get_property_value(device, "INTERFACE");
		if (devnode == NULL)
			return;
	}

	intf = udev_device_get_parent_with_subsystem_devtype(device,
						"usb", "usb_interface");
	if (intf == NULL)
		return;

	modem = g_hash_table_lookup(modem_list, syspath);
	if (modem == NULL) {
		modem = g_try_new0(struct modem_info, 1);
		if (modem == NULL)
			return;

		modem->syspath = g_strdup(syspath);
		modem->devname = g_strdup(devname);
		modem->driver = g_strdup(driver);
		modem->vendor = g_strdup(vendor);
		modem->model = g_strdup(model);

		modem->sysattr = get_sysattr(driver);

		g_hash_table_replace(modem_list, modem->syspath, modem);
	}
Beispiel #25
0
static char *get_leds_syspath_prefix(struct udev_device *udevice)
{
	struct udev_list_entry *dev_list_entry;
	struct udev_enumerate *enumerate;
	struct udev_device *hid_parent;
	const char *syspath;
	char *syspath_prefix;

	hid_parent = udev_device_get_parent_with_subsystem_devtype(udevice,
								"hid", NULL);

	enumerate = udev_enumerate_new(udev_device_get_udev(udevice));
	udev_enumerate_add_match_parent(enumerate, hid_parent);
	udev_enumerate_add_match_subsystem(enumerate, "leds");
	udev_enumerate_scan_devices(enumerate);

	dev_list_entry = udev_enumerate_get_list_entry(enumerate);
	if (!dev_list_entry) {
		syspath_prefix = NULL;
		goto out;
	}

	syspath = udev_list_entry_get_name(dev_list_entry);

	/*
	 * All the sysfs paths of the LEDs have the same structure, just the
	 * number changes, so strip it and store only the common prefix.
	 *
	 * Subtracting 1 here means assuming that the LED number is a single
	 * digit, this is safe as the kernel driver only exposes 4 LEDs.
	 */
	syspath_prefix = strndup(syspath, strlen(syspath) - 1);

out:
	udev_enumerate_unref(enumerate);

	return syspath_prefix;
}
Beispiel #26
0
static int get_supported_device(struct udev_device *udevice, uint16_t *bus)
{
	struct udev_device *hid_parent;
	uint16_t vid, pid;
	const char *hid_id;
	guint i;

	hid_parent = udev_device_get_parent_with_subsystem_devtype(udevice,
								"hid", NULL);
	if (!hid_parent)
		return -1;

	hid_id = udev_device_get_property_value(hid_parent, "HID_ID");

	if (sscanf(hid_id, "%hx:%hx:%hx", bus, &vid, &pid) != 3)
		return -1;

	for (i = 0; i < G_N_ELEMENTS(devices); i++) {
		if (devices[i].vid == vid && devices[i].pid == pid)
			return i;
	}

	return -1;
}
Beispiel #27
0
static struct udev_device *handle_ccw(struct udev_device *parent, struct udev_device *dev, char **path)
{
	struct udev_device *scsi_dev;

	scsi_dev = udev_device_get_parent_with_subsystem_devtype(dev, "scsi", "scsi_device");
	if (scsi_dev != NULL) {
		const char *wwpn;
		const char *lun;
		const char *hba_id;

		hba_id = udev_device_get_sysattr_value(scsi_dev, "hba_id");
		wwpn = udev_device_get_sysattr_value(scsi_dev, "wwpn");
		lun = udev_device_get_sysattr_value(scsi_dev, "fcp_lun");
		if (hba_id != NULL && lun != NULL && wwpn != NULL) {
			path_prepend(path, "ccw-%s-zfcp-%s:%s", hba_id, wwpn, lun);
			goto out;
		}
	}

	path_prepend(path, "ccw-%s", udev_device_get_sysname(parent));
out:
	parent = skip_subsystem(parent, "ccw");
	return parent;
}
Beispiel #28
0
struct hid_device_info  HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
{
	struct udev *udev;
	struct udev_enumerate *enumerate;
	struct udev_list_entry *devices, *dev_list_entry;
	
	struct hid_device_info *root = NULL; // return object
	struct hid_device_info *cur_dev = NULL;
	
	setlocale(LC_ALL,"");

	/* Create the udev object */
	udev = udev_new();
	if (!udev) {
		printf("Can't create udev\n");
		return NULL;
	}

	/* Create a list of the devices in the 'hidraw' subsystem. */
	enumerate = udev_enumerate_new(udev);
	udev_enumerate_add_match_subsystem(enumerate, "hidraw");
	udev_enumerate_scan_devices(enumerate);
	devices = udev_enumerate_get_list_entry(enumerate);
	/* For each item, see if it matches the vid/pid, and if so
	   create a udev_device record for it */
	udev_list_entry_foreach(dev_list_entry, devices) {
		const char *sysfs_path;
		const char *dev_path;
		const char *str;
		struct udev_device *hid_dev; // The device's HID udev node.
		struct udev_device *dev; // The actual hardware device.
		struct udev_device *intf_dev; // The device's interface (in the USB sense).
		unsigned short dev_vid;
		unsigned short dev_pid;
		
		/* Get the filename of the /sys entry for the device
		   and create a udev_device object (dev) representing it */
		sysfs_path = udev_list_entry_get_name(dev_list_entry);
		hid_dev = udev_device_new_from_syspath(udev, sysfs_path);
		dev_path = udev_device_get_devnode(hid_dev);
		
		/* The device pointed to by hid_dev contains information about
		   the hidraw device. In order to get information about the
		   USB device, get the parent device with the
		   subsystem/devtype pair of "usb"/"usb_device". This will
		   be several levels up the tree, but the function will find
		   it.*/
		dev = udev_device_get_parent_with_subsystem_devtype(
		       hid_dev,
		       "usb",
		       "usb_device");
		if (!dev) {
			/* Unable to find parent usb device. */
			goto next;
		}

		/* Get the VID/PID of the device */
		str = udev_device_get_sysattr_value(dev,"idVendor");
		dev_vid = (str)? strtol(str, NULL, 16): 0x0;
		str = udev_device_get_sysattr_value(dev, "idProduct");
		dev_pid = (str)? strtol(str, NULL, 16): 0x0;

		/* Check the VID/PID against the arguments */
		if ((vendor_id == 0x0 && product_id == 0x0) ||
		    (vendor_id == dev_vid && product_id == dev_pid)) {
			struct hid_device_info *tmp;
			size_t len;

		    	/* VID/PID match. Create the record. */
			tmp = malloc(sizeof(struct hid_device_info));
			if (cur_dev) {
				cur_dev->next = tmp;
			}
			else {
				root = tmp;
			}
			cur_dev = tmp;
			
			/* Fill out the record */
			cur_dev->next = NULL;
			str = dev_path;
			if (str) {
				len = strlen(str);
				cur_dev->path = calloc(len+1, sizeof(char));
				strncpy(cur_dev->path, str, len+1);
				cur_dev->path[len] = '\0';
			}
			else
				cur_dev->path = NULL;
			
			/* Serial Number */
			cur_dev->serial_number
				= copy_udev_string(dev, "serial");

			/* Manufacturer and Product strings */
			cur_dev->manufacturer_string
				= copy_udev_string(dev, "manufacturer");
			cur_dev->product_string
				= copy_udev_string(dev, "product");
			
			/* VID/PID */
			cur_dev->vendor_id = dev_vid;
			cur_dev->product_id = dev_pid;

			/* Release Number */
			str = udev_device_get_sysattr_value(dev, "bcdDevice");
			cur_dev->release_number = (str)? strtol(str, NULL, 16): 0x0;
			
			/* Interface Number */
			cur_dev->interface_number = -1;
			/* Get a handle to the interface's udev node. */
			intf_dev = udev_device_get_parent_with_subsystem_devtype(
				   hid_dev,
				   "usb",
				   "usb_interface");
			if (intf_dev) {
				str = udev_device_get_sysattr_value(intf_dev, "bInterfaceNumber");
				cur_dev->interface_number = (str)? strtol(str, NULL, 16): -1;
			}
		}
		else
			goto next;

	next:
		udev_device_unref(hid_dev);
		/* dev and intf_dev don't need to be (and can't be)
		   unref()d.  It will cause a double-free() error.  I'm not
		   sure why.  */
	}
	/* Free the enumerator and udev objects. */
	udev_enumerate_unref(enumerate);
	udev_unref(udev);
	
	return root;
}
Beispiel #29
0
int main (void)
{
	struct udev *udev;
	struct udev_enumerate *enumerate;
	struct udev_list_entry *devices, *dev_list_entry;
	struct udev_device *dev;

	struct udev_monitor *mon;
	int fd;

	/* Create the udev object */
	udev = udev_new();
	if (!udev) {
		printf("Can't create udev\n");
		exit(1);
	}

	/* This section sets up a monitor which will report events when
	   devices attached to the system change.  Events include "add",
	   "remove", "change", "online", and "offline".

	   This section sets up and starts the monitoring. Events are
	   polled for (and delivered) later in the file.

	   It is important that the monitor be set up before the call to
	   udev_enumerate_scan_devices() so that events (and devices) are
	   not missed.  For example, if enumeration happened first, there
	   would be no event generated for a device which was attached after
	   enumeration but before monitoring began.

	   Note that a filter is added so that we only get events for
	   "hidraw" devices. */

	/* Set up a monitor to monitor hidraw devices */
	mon = udev_monitor_new_from_netlink(udev, "udev");
//	udev_monitor_filter_add_match_subsystem_devtype(mon, "hidraw", NULL);
	udev_monitor_filter_add_match_subsystem_devtype(mon, "block", NULL);
	udev_monitor_enable_receiving(mon);
	/* Get the file descriptor (fd) for the monitor.
	   This fd will get passed to select() */
	fd = udev_monitor_get_fd(mon);


	/* Create a list of the devices in the 'hidraw' subsystem. */
	enumerate = udev_enumerate_new(udev);
//	udev_enumerate_add_match_subsystem(enumerate, "hidraw");
	udev_enumerate_add_match_subsystem(enumerate, "block");
	udev_enumerate_scan_devices(enumerate);
	devices = udev_enumerate_get_list_entry(enumerate);
	/* For each item enumerated, print out its information.
	   udev_list_entry_foreach is a macro which expands to
	   a loop. The loop will be executed for each member in
	   devices, setting dev_list_entry to a list entry
	   which contains the device's path in /sys. */
	udev_list_entry_foreach(dev_list_entry, devices) {
		const char *path;

		/* Get the filename of the /sys entry for the device
		   and create a udev_device object (dev) representing it */
		path = udev_list_entry_get_name(dev_list_entry);
		dev = udev_device_new_from_syspath(udev, path);

		/* usb_device_get_devnode() returns the path to the device node
		   itself in /dev. */
		printf("Device Node Path: %s\n", udev_device_get_devnode(dev));

#if 0
		/* The device pointed to by dev contains information about
		   the hidraw device. In order to get information about the
		   USB device, get the parent device with the
		   subsystem/devtype pair of "usb"/"usb_device". This will
		   be several levels up the tree, but the function will find
		   it.*/
		dev = udev_device_get_parent_with_subsystem_devtype(
		       dev,
		       "usb",
		       "usb_device");
		if (!dev) {
			printf("Unable to find parent usb device.");
			exit(1);
		}
#endif
		/* From here, we can call get_sysattr_value() for each file
		   in the device's /sys entry. The strings passed into these
		   functions (idProduct, idVendor, serial, etc.) correspond
		   directly to the files in the /sys directory which
		   represents the USB device. Note that USB strings are
		   Unicode, UCS2 encoded, but the strings returned from
		   udev_device_get_sysattr_value() are UTF-8 encoded. */
		printf("  VID/PID: %s %s\n",
		        udev_device_get_sysattr_value(dev,"idVendor"),
		        udev_device_get_sysattr_value(dev, "idProduct"));
		printf("  %s\n  %s\n",
		        udev_device_get_sysattr_value(dev,"manufacturer"),
		        udev_device_get_sysattr_value(dev,"product"));
		printf("  serial: %s\n",
		         udev_device_get_sysattr_value(dev, "serial"));
		udev_device_unref(dev);
	}
	/* Free the enumerator object */
	udev_enumerate_unref(enumerate);

	/* Begin polling for udev events. Events occur when devices
	   attached to the system are added, removed, or change state.
	   udev_monitor_receive_device() will return a device
	   object representing the device which changed and what type of
	   change occured.

	   The select() system call is used to ensure that the call to
	   udev_monitor_receive_device() will not block.

	   The monitor was set up earler in this file, and monitoring is
	   already underway.

	   This section will run continuously, calling usleep() at the end
	   of each pass. This is to demonstrate how to use a udev_monitor
	   in a non-blocking way. */
	while (1) {
		/* Set up the call to select(). In this case, select() will
		   only operate on a single file descriptor, the one
		   associated with our udev_monitor. Note that the timeval
		   object is set to 0, which will cause select() to not
		   block. */
		fd_set fds;
		struct timeval tv;
		int ret;

		FD_ZERO(&fds);
		FD_SET(fd, &fds);
		tv.tv_sec = 0;
		tv.tv_usec = 0;

		ret = select(fd+1, &fds, NULL, NULL, &tv);

		/* Check if our file descriptor has received data. */
		if (ret > 0 && FD_ISSET(fd, &fds)) {
			printf("\nselect() says there should be data\n");

			/* Make the call to receive the device.
			   select() ensured that this will not block. */
			dev = udev_monitor_receive_device(mon);
			if (dev) {
				printf("Got Device\n");
				printf("   Node: %s\n", udev_device_get_devnode(dev));
				printf("   Subsystem: %s\n", udev_device_get_subsystem(dev));
				printf("   Devtype: %s\n", udev_device_get_devtype(dev));

				printf("   Action: %s\n", udev_device_get_action(dev));
				udev_device_unref(dev);
			}
			else {
				printf("No Device from receive_device(). An error occured.\n");
			}
		}
		usleep(250*1000);
		printf(".");
		fflush(stdout);
	}


	udev_unref(udev);

	return 0;
}
Beispiel #30
0
static GSList *hw_scan(GSList *options)
{
	int i;
	GSList *devices = NULL;
	const char *conn = NULL;
	const char *serialcomm = NULL;
	GSList *l;
	struct sr_config *src;
	struct udev *udev;

	(void)options;

	for (l = options; l; l = l->next) {
		src = l->data;
		switch (src->key) {
		case SR_CONF_CONN:
			conn = src->value;
			break;
		case SR_CONF_SERIALCOMM:
			serialcomm = src->value;
			break;
		}
	}
	if (!conn)
		conn = SERIALCONN;
	if (serialcomm == NULL)
		serialcomm = SERIALCOMM;

	udev = udev_new();
	if (!udev) {
		sr_err("Failed to initialize udev.");
	}

	struct udev_enumerate *enumerate = udev_enumerate_new(udev);
	udev_enumerate_add_match_subsystem(enumerate, "usb-serial");
	udev_enumerate_scan_devices(enumerate);
	struct udev_list_entry *devs = udev_enumerate_get_list_entry(enumerate);
	struct udev_list_entry *dev_list_entry;
	for (dev_list_entry = devs;
	     dev_list_entry != NULL;
	     dev_list_entry = udev_list_entry_get_next(dev_list_entry)) {
		const char *syspath = udev_list_entry_get_name(dev_list_entry);
		struct udev_device *dev =
		    udev_device_new_from_syspath(udev, syspath);
		const char *sysname = udev_device_get_sysname(dev);
		struct udev_device *parent =
		    udev_device_get_parent_with_subsystem_devtype(dev, "usb",
								  "usb_device");

		if (!parent) {
			sr_err("Unable to find parent usb device for %s",
			       sysname);
			continue;
		}

		const char *idVendor =
		    udev_device_get_sysattr_value(parent, "idVendor");
		const char *idProduct =
		    udev_device_get_sysattr_value(parent, "idProduct");
		if (strcmp(USB_VENDOR, idVendor)
		    || strcmp(USB_PRODUCT, idProduct))
			continue;

		const char *iSerial =
		    udev_device_get_sysattr_value(parent, "serial");
		const char *iProduct =
		    udev_device_get_sysattr_value(parent, "product");

		char path[32];
		snprintf(path, sizeof(path), "/dev/%s", sysname);
		conn = path;

		size_t s = strcspn(iProduct, " ");
		char product[32];
		char manufacturer[32];
		if (s > sizeof(product) ||
		    strlen(iProduct) - s > sizeof(manufacturer)) {
			sr_err("Could not parse iProduct: %s.", iProduct);
			continue;
		}
		strncpy(product, iProduct, s);
		product[s] = 0;
		strcpy(manufacturer, iProduct + s + 1);

		//Create the device context and set its params
		struct dev_context *devc;
		if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) {
			sr_err("Device context malloc failed.");
			return devices;
		}

		if (mso_parse_serial(iSerial, iProduct, devc) != SR_OK) {
			sr_err("Invalid iSerial: %s.", iSerial);
			g_free(devc);
			return devices;
		}

		char hwrev[32];
		sprintf(hwrev, "r%d", devc->hwrev);
		devc->ctlbase1 = 0;
		devc->protocol_trigger.spimode = 0;
		for (i = 0; i < 4; i++) {
			devc->protocol_trigger.word[i] = 0;
			devc->protocol_trigger.mask[i] = 0xff;
		}

		if (!(devc->serial = sr_serial_dev_inst_new(conn, serialcomm))) {
			g_free(devc);
			return devices;
		}

		struct sr_dev_inst *sdi = sr_dev_inst_new(0, SR_ST_INACTIVE,
						manufacturer, product, hwrev);

		if (!sdi) {
			sr_err("Unable to create device instance for %s",
			       sysname);
			sr_dev_inst_free(sdi);
			g_free(devc);
			return devices;
		}

		sdi->driver = di;
		sdi->priv = devc;

		for (i = 0; i < NUM_PROBES; i++) {
			struct sr_probe *probe;
			if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
						   mso19_probe_names[i])))
				return 0;
			sdi->probes = g_slist_append(sdi->probes, probe);
		}

		//Add the driver
		struct drv_context *drvc = di->priv;
		drvc->instances = g_slist_append(drvc->instances, sdi);
		devices = g_slist_append(devices, sdi);
	}

	return devices;
}