[Spice-devel] [PATCH spice-gtk 3/7] usbutil: Add support for getting strings from usb.ids
Marc-André Lureau
marcandre.lureau at gmail.com
Sun Feb 19 06:09:44 PST 2012
ack
On Sun, Feb 19, 2012 at 12:50 AM, Hans de Goede <hdegoede at redhat.com> wrote:
> Unfortunately not all device makers go to the "trouble" of adding device
> identification strings to a device's descriptors. This patch makes spice-gtk
> translate vid/pid into strings if the device lacks the strings.
>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> ---
> configure.ac | 21 ++++++++
> gtk/Makefile.am | 1 +
> gtk/usbutil.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 172 insertions(+), 0 deletions(-)
>
> diff --git a/configure.ac b/configure.ac
> index d8602fd..d2ac883 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -426,6 +426,27 @@ AC_ARG_WITH([usb-acl-helper-dir],
> [ACL_HELPER_DIR="${bindir}/"])
> AC_SUBST([ACL_HELPER_DIR])
>
> +AC_ARG_WITH([usb-ids-path],
> + AC_HELP_STRING([--with-usb-ids-path],
> + [Specify the path to usb.ids @<:@default=auto@:>@]),
> + [USB_IDS="$with_usb_ids_path"],
> + [USB_IDS="auto"])
> +AC_MSG_CHECKING([for usb.ids])
> +if test "x$USB_IDS" = "xauto"; then
> + if test -n "$PKG_CONFIG"; then
> + USB_IDS=$($PKG_CONFIG --variable=usbids usbutils)
> + else
> + USB_IDS=
> + fi
> +fi
> +if test -n "$USB_IDS"; then
> + AC_MSG_RESULT([$USB_IDS])
> + AC_SUBST(USB_IDS)
> + AC_DEFINE(WITH_USBIDS, [1], [Define if compiling with usb.ids support])
> +else
> + AC_MSG_RESULT([not found])
> +fi
> +
> AC_ARG_WITH([coroutine],
> AS_HELP_STRING([--with-coroutine=@<:@ucontext/gthread/winfiber/auto@:>@],
> [use ucontext or GThread for coroutines @<:@default=auto@:>@]),
> diff --git a/gtk/Makefile.am b/gtk/Makefile.am
> index 2ad4494..fd2e477 100644
> --- a/gtk/Makefile.am
> +++ b/gtk/Makefile.am
> @@ -60,6 +60,7 @@ SPICE_COMMON_CPPFLAGS = \
> -DSW_CANVAS_CACHE \
> -DSPICE_GTK_LOCALEDIR=\"${SPICE_GTK_LOCALEDIR}\" \
> -DPNP_IDS=\""$(PNP_IDS)"\"\
> + -DUSB_IDS=\""$(USB_IDS)"\"\
> \
> -I$(COMMON_DIR) \
> -I$(CLIENT_DIR) \
> diff --git a/gtk/usbutil.c b/gtk/usbutil.c
> index 0d1361e..704f973 100644
> --- a/gtk/usbutil.c
> +++ b/gtk/usbutil.c
> @@ -23,6 +23,8 @@
>
> #include <glib-object.h>
> #include <glib/gi18n.h>
> +#include <ctype.h>
> +#include <stdlib.h>
>
> #include "glib-compat.h"
>
> @@ -35,6 +37,27 @@
> #endif
> #include "usbutil.h"
>
> +#ifdef WITH_USBIDS
> +#define VENDOR_NAME_LEN (122 - sizeof(void *))
> +#define PRODUCT_NAME_LEN 126
> +
> +typedef struct _usb_product_info {
> + guint16 product_id;
> + char name[PRODUCT_NAME_LEN];
> +} usb_product_info;
> +
> +typedef struct _usb_vendor_info {
> + usb_product_info *product_info;
> + int product_count;
> + guint16 vendor_id;
> + char name[VENDOR_NAME_LEN];
> +} usb_vendor_info;
> +
> +GStaticMutex usbids_parse_mutex = G_STATIC_MUTEX_INIT;
> +int usbids_vendor_count;
> +usb_vendor_info *usbids_vendor_info;
> +#endif
> +
> G_GNUC_INTERNAL
> const char *spice_usbutil_libusb_strerror(enum libusb_error error_code)
> {
> @@ -98,11 +121,112 @@ static gchar *spice_usbutil_get_sysfs_attribute(int bus, int address,
> }
> #endif
>
> +#ifdef WITH_USBIDS
> +static void spice_usbutil_parse_usbids(void)
> +{
> + gchar *contents, *line, **lines;
> + usb_product_info *product_info;
> + int i, j, id, product_count = 0;
> +
> + g_static_mutex_lock(&usbids_parse_mutex);
> + if (usbids_vendor_count)
> + goto leave;
> +
> + if (!g_file_get_contents(USB_IDS, &contents, NULL, NULL)) {
> + usbids_vendor_count = -1;
> + goto leave;
> + }
> + lines = g_strsplit(contents, "\n", -1);
> +
> + for (i = 0; lines[i]; i++) {
> + if (!isxdigit(lines[i][0]) || !isxdigit(lines[i][1]))
> + continue;
> +
> + for (j = 1; lines[i + j] &&
> + (lines[i + j][0] == '\t' ||
> + lines[i + j][0] == '#' ||
> + lines[i + j][0] == '\0'); j++) {
> + if (lines[i + j][0] == '\t' && isxdigit(lines[i + j][1]))
> + product_count++;
> + }
> + i += j - 1;
> +
> + usbids_vendor_count++;
> + }
> +
> + usbids_vendor_info = g_new(usb_vendor_info, usbids_vendor_count);
> + product_info = g_new(usb_product_info, product_count);
> +
> + usbids_vendor_count = 0;
> + for (i = 0; lines[i]; i++) {
> + line = lines[i];
> +
> + if (!isxdigit(line[0]) || !isxdigit(line[1]))
> + continue;
> +
> + id = strtoul(line, &line, 16);
> + while(isspace(line[0]))
> + line++;
> + usbids_vendor_info[usbids_vendor_count].vendor_id = id;
> + snprintf(usbids_vendor_info[usbids_vendor_count].name,
> + VENDOR_NAME_LEN, "%s", line);
> +
> + product_count = 0;
> + for (j = 1; lines[i + j] &&
> + (lines[i + j][0] == '\t' ||
> + lines[i + j][0] == '#' ||
> + lines[i + j][0] == '\0'); j++) {
> + line = lines[i + j];
> +
> + if (line[0] != '\t' || !isxdigit(line[1]))
> + continue;
> +
> + id = strtoul(line + 1, &line, 16);
> + while(isspace(line[0]))
> + line++;
> + product_info[product_count].product_id = id;
> + snprintf(product_info[product_count].name,
> + PRODUCT_NAME_LEN, "%s", line);
> +
> + product_count++;
> + }
> + i += j - 1;
> +
> + usbids_vendor_info[usbids_vendor_count].product_count = product_count;
> + usbids_vendor_info[usbids_vendor_count].product_info = product_info;
> + product_info += product_count;
> + usbids_vendor_count++;
> + }
> +
> + g_strfreev(lines);
> + g_free(contents);
> +
> +#if 0 /* Testing only */
> + for (i = 0; i < usbids_vendor_count; i++) {
> + printf("%04x %s\n", usbids_vendor_info[i].vendor_id,
> + usbids_vendor_info[i].name);
> + product_info = usbids_vendor_info[i].product_info;
> + for (j = 0; j < usbids_vendor_info[i].product_count; j++) {
> + printf("\t%04x %s\n", product_info[j].product_id,
> + product_info[j].name);
> + }
> + }
> +#endif
> +leave:
> + g_static_mutex_unlock(&usbids_parse_mutex);
> +}
> +#endif
> +
> G_GNUC_INTERNAL
> void spice_usb_util_get_device_strings(int bus, int address,
> int vendor_id, int product_id,
> gchar **manufacturer, gchar **product)
> {
> +#ifdef WITH_USBIDS
> + usb_product_info *product_info;
> + int i, j;
> +#endif
> +
> g_return_if_fail(manufacturer != NULL);
> g_return_if_fail(product != NULL);
>
> @@ -113,6 +237,32 @@ void spice_usb_util_get_device_strings(int bus, int address,
> *manufacturer = spice_usbutil_get_sysfs_attribute(bus, address, "manufacturer");
> *product = spice_usbutil_get_sysfs_attribute(bus, address, "product");
> #endif
> +
> +#ifdef WITH_USBIDS
> + if (!*manufacturer || !*product) {
> + spice_usbutil_parse_usbids();
> +
> + for (i = 0; i < usbids_vendor_count; i++) {
> + if ((int)usbids_vendor_info[i].vendor_id != vendor_id)
> + continue;
> +
> + if (!*manufacturer && usbids_vendor_info[i].name[0])
> + *manufacturer = g_strdup(usbids_vendor_info[i].name);
> +
> + product_info = usbids_vendor_info[i].product_info;
> + for (j = 0; j < usbids_vendor_info[i].product_count; j++) {
> + if ((int)product_info[j].product_id != product_id)
> + continue;
> +
> + if (!*product && product_info[j].name[0])
> + *product = g_strdup(product_info[j].name);
> +
> + break;
> + }
> + break;
> + }
> + }
> +#endif
> if (!*manufacturer)
> *manufacturer = g_strdup(_("USB"));
> if (!*product)
> --
> 1.7.7.5
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
--
Marc-André Lureau
More information about the Spice-devel
mailing list