[PATCH][usbutils] lsusb: port to hwdb

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Most of the information in usb.ids is now contained in udev's hwdb. First
attempt to query hwdb before falling back on the old file.

This would allow distributions to no longer ship (most of) usb.ids by default,
but rather keep all the usb device information in only one place (the hwdb).

This patch introduces a dependency on libusb >= 196.

Cc: systemd-devel@xxxxxxxxxxxxxxxxxxxxx
---
 Makefile.am  |  5 +++--
 configure.ac |  2 ++
 names.c      | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 1e85a1e..70b9de9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -23,11 +23,12 @@ lsusb_SOURCES = \
 	usbmisc.c usbmisc.h
 
 lsusb_CPPFLAGS = \
-	$(AM_CPPFLAGS) $(LIBUSB_CFLAGS) \
+	$(AM_CPPFLAGS) $(LIBUSB_CFLAGS) $(UDEV_CFLAGS) \
 	-DDATADIR=\"$(datadir)\"
 
 lsusb_LDADD = \
-	$(LIBUSB_LIBS)
+	$(LIBUSB_LIBS) \
+	$(UDEV_LIBS)
 
 if HAVE_ZLIB
 lsusb_CPPFLAGS += -DHAVE_LIBZ
diff --git a/configure.ac b/configure.ac
index adfb4b6..b4b0880 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,6 +26,8 @@ AM_CONDITIONAL([INSTALL_USBIDS], [test "x$enable_usbids" != "xno"])
 
 PKG_CHECK_MODULES(LIBUSB, libusb-1.0 >= 1.0.0)
 
+PKG_CHECK_MODULES(UDEV, libudev >= 196)
+
 AC_CONFIG_HEADERS([config.h])
 AC_CONFIG_FILES([
 	Makefile
diff --git a/names.c b/names.c
index 12cbd60..4b59213 100644
--- a/names.c
+++ b/names.c
@@ -3,6 +3,7 @@
  *      names.c  --  USB name database manipulation routines
  *
  *      Copyright (C) 1999, 2000  Thomas Sailer (sailer@xxxxxxxxxxxxxx)
+ *      Copyright (C) 2013  Tom Gundersen (teg@xxxxxxx)
  *
  *      This program is free software; you can redistribute it and/or modify
  *      it under the terms of the GNU General Public License as published by
@@ -34,6 +35,8 @@
 #include <stdio.h>
 #include <ctype.h>
 
+#include <libudev.h>
+
 #ifdef HAVE_LIBZ
 #include <zlib.h>
 #define 	usb_file			gzFile
@@ -118,6 +121,8 @@ static unsigned int hashnum(unsigned int num)
 
 /* ---------------------------------------------------------------------- */
 
+static struct udev *udev = NULL;
+static struct udev_hwdb *hwdb = NULL;
 static struct vendor *vendors[HASHSZ] = { NULL, };
 static struct product *products[HASHSZ] = { NULL, };
 static struct class *classes[HASHSZ] = { NULL, };
@@ -187,9 +192,27 @@ const char *names_countrycode(unsigned int countrycode)
 	return names_genericstrtable(countrycodes, countrycode);
 }
 
+static const char *hwdb_get(const char *modalias, const char *key)
+{
+	struct udev_list_entry *entry;
+
+	udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(hwdb, modalias, 0))
+		if (strcmp(udev_list_entry_get_name(entry), key) == 0)
+			return udev_list_entry_get_value(entry);
+
+	return NULL;
+}
+
 const char *names_vendor(u_int16_t vendorid)
 {
 	struct vendor *v;
+	char modalias[64];
+	const char *name;
+
+	sprintf(modalias, "usb:v%04X*", vendorid);
+	name = hwdb_get(modalias, "ID_VENDOR_FROM_DATABASE");
+	if (name)
+		return name;
 
 	v = vendors[hashnum(vendorid)];
 	for (; v; v = v->next)
@@ -201,6 +224,13 @@ const char *names_vendor(u_int16_t vendorid)
 const char *names_product(u_int16_t vendorid, u_int16_t productid)
 {
 	struct product *p;
+	char modalias[64];
+	const char *name;
+
+	sprintf(modalias, "usb:v%04Xp%04X*", vendorid, productid);
+	name = hwdb_get(modalias, "ID_MODEL_FROM_DATABASE");
+	if (name)
+		return name;
 
 	p = products[hashnum((vendorid << 16) | productid)];
 	for (; p; p = p->next)
@@ -212,6 +242,13 @@ const char *names_product(u_int16_t vendorid, u_int16_t productid)
 const char *names_class(u_int8_t classid)
 {
 	struct class *c;
+	char modalias[64];
+	const char *name;
+
+	sprintf(modalias, "usb:v*p*d*dc%02X*", classid);
+	name = hwdb_get(modalias, "ID_USB_CLASS_FROM_DATABASE");
+	if (name)
+		return name;
 
 	c = classes[hashnum(classid)];
 	for (; c; c = c->next)
@@ -223,6 +260,13 @@ const char *names_class(u_int8_t classid)
 const char *names_subclass(u_int8_t classid, u_int8_t subclassid)
 {
 	struct subclass *s;
+	char modalias[64];
+	const char *name;
+
+	sprintf(modalias, "usb:v*p*d*dc%02Xdsc%02X*", classid, subclassid);
+	name = hwdb_get(modalias, "ID_USB_SUBCLASS_FROM_DATABASE");
+	if (name)
+		return name;
 
 	s = subclasses[hashnum((classid << 8) | subclassid)];
 	for (; s; s = s->next)
@@ -234,6 +278,13 @@ const char *names_subclass(u_int8_t classid, u_int8_t subclassid)
 const char *names_protocol(u_int8_t classid, u_int8_t subclassid, u_int8_t protocolid)
 {
 	struct protocol *p;
+	char modalias[64];
+	const char *name;
+
+	sprintf(modalias, "usb:v*p*d*dc%02Xdsc%02Xdp%02X*", classid, subclassid, protocolid);
+	name = hwdb_get(modalias, "ID_USB_PROTOCOL_FROM_DATABASE");
+	if (name)
+		return name;
 
 	p = protocols[hashnum((classid << 16) | (subclassid << 8) | protocolid)];
 	for (; p; p = p->next)
@@ -994,18 +1045,25 @@ static void parse(usb_file f)
 int names_init(char *n)
 {
 	usb_file f;
+	int r = 0;
 
 	f = usb_fopen(n, "r");
 	if (!f)
-		return errno;
+		r = errno;
 
 	parse(f);
 	usb_close(f);
-	return 0;
+
+	udev = udev_new();
+	hwdb = udev_hwdb_new(udev);
+
+	return r;
 }
 
 void names_exit(void)
 {
+	hwdb = udev_hwdb_unref(hwdb);
+	udev = udev_unref(udev);
 	free_vendor();
 	free_product();
 	free_class();
-- 
1.8.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux