[LEDE-DEV] [PATCH] usbutils: Update to version 009.

Rosen Penev rosenp at gmail.com
Thu Mar 15 07:41:30 PDT 2018


On Thu, Mar 15, 2018 at 2:26 AM, Karl Palsson <karlp at tweak.net.au> wrote:
>
> Rosen Penev <rosenp at gmail.com> wrote:
>> 4 patches were added to revert the libudev changes as the
>> libudev wrapper in OpenWrt is not good enough.
>
> Personally, I'd like to see substantially better descriptions in
> the patches explaining their purpose. The simple "revert xxxx"
> and the filename doesn't say much, many of it seems unrelated,
> and _none_ of them talk about libudev!
>
To be fair, I just used git format-patch on individual commits. I can
add the original commit message if needed.

usbutils switched to using hwdb which uses udev instead of a usbids file.
> Cheers,
> Karl P
>
>>
>> Signed-off-by: Rosen Penev <rosenp at gmail.com>
>> ---
>>  package/utils/usbutils/Makefile                    |   8 +-
>>  .../patches/010-remove-python-usbids.patch         |  68 ++
>>  .../patches/020-revert-removal-of-usb.ids.patch    | 879 +++++++++++++++++++++
>>  .../usbutils/patches/030-revert-port-to-hwdb.patch | 529 +++++++++++++
>>  .../patches/040-add-back-update-usbids.patch       |  66 ++
>>  5 files changed, 1547 insertions(+), 3 deletions(-)
>>  create mode 100644 package/utils/usbutils/patches/010-remove-python-usbids.patch
>>  create mode 100644 package/utils/usbutils/patches/020-revert-removal-of-usb.ids.patch
>>  create mode 100644 package/utils/usbutils/patches/030-revert-port-to-hwdb.patch
>>  create mode 100644 package/utils/usbutils/patches/040-add-back-update-usbids.patch
>>
>> diff --git a/package/utils/usbutils/Makefile
>> b/package/utils/usbutils/Makefile index 7f798954ae..3fbc4e0b50
>> 100644
>> --- a/package/utils/usbutils/Makefile
>> +++ b/package/utils/usbutils/Makefile
>> @@ -8,15 +8,17 @@
>>  include $(TOPDIR)/rules.mk
>>
>>  PKG_NAME:=usbutils
>> -PKG_VERSION:=007
>> -PKG_RELEASE:=7
>> +PKG_VERSION:=009
>> +PKG_RELEASE:=1
>>
>>  PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
>>  PKG_SOURCE_URL:=@KERNEL/linux/utils/usb/usbutils
>> -PKG_HASH:=7593a01724bbc0fd9fe48e62bc721ceb61c76654f1d7b231b3c65f6dfbbaefa4
>> +PKG_HASH:=8bbff0e54cb5f65a52be4feb9162fc0b022a97eb841b44784f7a89a9ea567160
>>  PKG_LICENSE:=GPL-2.0
>>  PKG_LICENSE_FILES:=COPYING
>>
>> +PKG_FIXUP:=autoreconf
>> +
>>  PKG_BUILD_PARALLEL:=1
>>  PKG_INSTALL:=1
>>
>> diff --git
>> a/package/utils/usbutils/patches/010-remove-python-usbids.patch
>> b/package/utils/usbutils/patches/010-remove-python-usbids.patch
>> new file mode 100644 index 0000000000..19e3cc1dd3
>> --- /dev/null
>> +++ b/package/utils/usbutils/patches/010-remove-python-usbids.patch
>> @@ -0,0 +1,68 @@
>> +From a1c2fd7bbd5b2e26f8f752fd3386a953b3b1ec37 Mon Sep 17
>> 00:00:00 2001 +From: Rosen Penev <rosenp at gmail.com> +Date: Fri,
>> 9 Mar 2018 10:31:09 -0800 +Subject: [PATCH] Revert "substitute
>> usb.id location in lsusb Python script"
>> +
>> +This reverts commit 199756013624bfa497865eb498bf7331eb07ef56.
>> +---
>> + Makefile.am             | 7 +------
>> + lsusb.py.in => lsusb.py | 4 ++--
>> + 3 files changed, 3 insertions(+), 9 deletions(-)
>> + rename lsusb.py.in => lsusb.py (99%)
>> + mode change 100644 => 100755
>> +
>> +diff --git a/Makefile.am b/Makefile.am
>> +index b18ff69..67def60 100644
>> +--- a/Makefile.am
>> ++++ b/Makefile.am
>> +@@ -39,13 +39,9 @@ EXTRA_DIST = \
>> +     lsusb.8.in \
>> +     usb-devices.1.in \
>> +     usb-devices \
>> +-    lsusb.py.in \
>> ++    lsusb.py \
>> +     usbutils.pc.in
>> +
>> +-lsusb.py: $(srcdir)/lsusb.py.in
>> +-    sed 's|VERSION|$(VERSION)|g;s|@usbids@|$(datadir)/usb.ids|g' $< >$@
>> +-    chmod 755 $@
>> +-
>> + lsusb.8: $(srcdir)/lsusb.8.in
>> +     sed 's|VERSION|$(VERSION)|g;s|@usbids@|$(datadir)/usb.ids|g' $< >$@
>> +
>> +@@ -59,7 +55,6 @@ usbutils.pc: $(srcdir)/usbutils.pc.in
>> +     sed 's|@usbids@|$(datadir)/usb.ids|g;s|@VERSION[@]|$(VERSION)|g' $< >$@
>> +
>> + DISTCLEANFILES = \
>> +-    lsusb.py \
>> +     lsusb.8 \
>> +     usb-devices.1 \
>> +     usbutils.pc
>> +diff --git a/lsusb.py.in b/lsusb.py
>> +old mode 100644
>> +new mode 100755
>> +similarity index 99%
>> +rename from lsusb.py.in
>> +rename to lsusb.py
>> +index db2e1e0..aa410fc
>> +--- a/lsusb.py.in
>> ++++ b/lsusb.py
>> +@@ -1,5 +1,5 @@
>> + #!/usr/bin/env python
>> +-# lsusb-VERSION.py
>> ++# lsusb.py
>> + # Displays your USB devices in reasonable form.
>> + # (c) Kurt Garloff <garloff at suse.de>, 2/2009, GPL v2 or v3.
>> + # (c) Kurt Garloff <kurt at garloff.de>, 9/2013, GPL v2 or v3.
>> +@@ -18,7 +18,7 @@ warnsort = False
>> + showeps = False
>> +
>> + prefix = "/sys/bus/usb/devices/"
>> +-usbids = "@usbids@"
>> ++usbids = "/usr/share/usb.ids"
>> +
>> + esc = chr(27)
>> + norm = esc + "[0;0m"
>> +--
>> +2.16.2
>> +
>> diff --git
>> a/package/utils/usbutils/patches/020-revert-removal-of-usb.ids.patch
>> b/package/utils/usbutils/patches/020-revert-removal-of-usb.ids.patch
>> new file mode 100644 index 0000000000..ae38b06a77
>> --- /dev/null
>> +++ b/package/utils/usbutils/patches/020-revert-removal-of-usb.ids.patch
>> @@ -0,0 +1,879 @@
>> +From 2bfca703b324e21aee2fabbe4f998aa663f03a15 Mon Sep 17
>> 00:00:00 2001 +From: Rosen Penev <rosenp at gmail.com> +Date: Fri,
>> 9 Mar 2018 10:31:24 -0800 +Subject: [PATCH] Revert "drop
>> dependency on usb.ids"
>> +
>> +This reverts commit 5d7ea40bc94cbf3069a25beba3146de13bcdcf02.
>> +---
>> + Makefile.am  |    27 +-
>> + configure.ac |    12 +
>> + lsusb.c      |    13 +-
>> + names.c      |   600 +-
>> + names.h      |     2 +-
>> + 5 files changed, 18559 insertions(+), 1775 deletions(-)
>> + delete mode 100644 usb-spec.h
>> + create mode 100644 usb.ids
>> +
>> +diff --git a/Makefile.am b/Makefile.am
>> +index 67def60..31afb20 100644
>> +--- a/Makefile.am
>> ++++ b/Makefile.am
>> +@@ -20,7 +20,6 @@ lsusb_SOURCES = \
>> +     lsusb-t.c \
>> +     list.h \
>> +     names.c names.h \
>> +-    usb-spec.h \
>> +     usbmisc.c usbmisc.h
>> +
>> + lsusb_CPPFLAGS = \
>> +@@ -31,17 +30,41 @@ lsusb_LDADD = \
>> +     $(LIBUSB_LIBS) \
>> +     $(UDEV_LIBS)
>> +
>> ++if HAVE_ZLIB
>> ++lsusb_CPPFLAGS += -DHAVE_LIBZ
>> ++lsusb_LDADD += -lz
>> ++endif
>> ++
>> + man_MANS = \
>> +     lsusb.8 \
>> +     usb-devices.1
>> +
>> + EXTRA_DIST = \
>> ++    usb.ids \
>> ++    update-usbids.sh.in \
>> +     lsusb.8.in \
>> +     usb-devices.1.in \
>> +     usb-devices \
>> +     lsusb.py \
>> +     usbutils.pc.in
>> +
>> ++if INSTALL_USBIDS
>> ++data_DATA += usb.ids
>> ++
>> ++if HAVE_ZLIB
>> ++data_DATA += usb.ids.gz
>> ++endif
>> ++
>> ++sbin_SCRIPTS += update-usbids.sh
>> ++
>> ++usb.ids.gz: $(srcdir)/usb.ids
>> ++    gzip -c -9 $< > $@
>> ++
>> ++update-usbids.sh: $(srcdir)/update-usbids.sh.in
>> ++    sed 's|@usbids@|$(datadir)/usb.ids|g' $< >$@
>> ++    chmod 755 $@
>> ++endif
>> ++
>> + lsusb.8: $(srcdir)/lsusb.8.in
>> +     sed 's|VERSION|$(VERSION)|g;s|@usbids@|$(datadir)/usb.ids|g' $< >$@
>> +
>> +@@ -55,8 +78,10 @@ usbutils.pc: $(srcdir)/usbutils.pc.in
>> +     sed 's|@usbids@|$(datadir)/usb.ids|g;s|@VERSION[@]|$(VERSION)|g' $< >$@
>> +
>> + DISTCLEANFILES = \
>> ++    usb.ids.gz \
>> +     lsusb.8 \
>> +     usb-devices.1 \
>> ++    update-usbids.sh \
>> +     usbutils.pc
>> +
>> + distclean-local:
>> +diff --git a/configure.ac b/configure.ac
>> +index a62748c..89d62f9 100644
>> +--- a/configure.ac
>> ++++ b/configure.ac
>> +@@ -12,6 +12,18 @@ AC_SYS_LARGEFILE
>> + AC_CHECK_HEADERS([byteswap.h])
>> + AC_CHECK_FUNCS([nl_langinfo iconv])
>> +
>> ++AC_ARG_ENABLE(zlib,
>> ++    AS_HELP_STRING(--disable-zlib,disable support for zlib))
>> ++
>> ++HAVE_ZLIB=no
>> ++AS_IF([test "x$enable_zlib" != "xno"],
>> ++    [AC_CHECK_LIB(z, inflateEnd, HAVE_ZLIB=yes)])
>> ++AM_CONDITIONAL(HAVE_ZLIB, [test "$HAVE_ZLIB" = "yes"])
>> ++
>> ++AC_ARG_ENABLE(usbids,
>> ++    AS_HELP_STRING(--disable-usbids, [disable installing usb.ids @<:@default=install@:>@]))
>> ++AM_CONDITIONAL([INSTALL_USBIDS], [test "x$enable_usbids" !=
>> "xno"])
>> ++
>> + PKG_CHECK_MODULES(LIBUSB, libusb-1.0 >= 1.0.9)
>> +
>> + PKG_CHECK_MODULES(UDEV, libudev >= 196)
>> +diff --git a/lsusb.c b/lsusb.c
>> +index f611f2e..969997c 100644
>> +--- a/lsusb.c
>> ++++ b/lsusb.c
>> +@@ -4340,9 +4340,16 @@ int main(int argc, char *argv[])
>> +
>> +
>> +     /* by default, print names as well as numbers */
>> +-    if (names_init() < 0)
>> +-            fprintf(stderr, "unable to initialize usb spec");
>> +-
>> ++    err = names_init(DATADIR "/usb.ids");
>> ++#ifdef HAVE_LIBZ
>> ++    if (err != 0)
>> ++            err = names_init(DATADIR "/usb.ids.gz");
>> ++#endif
>> ++    if (err != 0)
>> ++            fprintf(stderr, "%s: cannot open \"%s\", %s\n",
>> ++                            argv[0],
>> ++                            DATADIR "/usb.ids",
>> ++                            strerror(err));
>> +     status = 0;
>> +
>> +     if (treemode) {
>> +diff --git a/names.c b/names.c
>> +index a151484..f543240 100644
>> +--- a/names.c
>> ++++ b/names.c
>> +@@ -37,13 +37,47 @@
>> +
>> + #include <libudev.h>
>> +
>> +-#include "usb-spec.h"
>> ++#ifdef HAVE_LIBZ
>> ++#include <zlib.h>
>> ++#define     usb_file                        gzFile
>> ++#define     usb_fopen(path, mode)           gzopen(path, mode)
>> ++#define usb_fgets(s, size, stream) gzgets(stream, s, size)
>> ++#define usb_close(f) gzclose(f) ++#else ++#define usb_file
>> FILE * ++#define usb_fopen(path, mode) fopen(path, mode)
>> ++#define usb_fgets(s, size, stream) fgets(s, size, stream)
>> ++#define usb_close(f) fclose(f) ++#endif
>> ++
>> + #include "names.h"
>> +
>> +
>> ++/* ---------------------------------------------------------------------- */
>> ++
>> ++struct audioterminal {
>> ++    struct audioterminal *next;
>> ++    u_int16_t termt;
>> ++    char name[1];
>> ++};
>> ++
>> ++struct videoterminal {
>> ++    struct videoterminal *next;
>> ++    u_int16_t termt;
>> ++    char name[1];
>> ++};
>> ++
>> ++struct genericstrtable {
>> ++    struct genericstrtable *next;
>> ++    unsigned int num;
>> ++    char name[1];
>> ++};
>> ++
>> ++/* ---------------------------------------------------------------------- */
>> ++
>> + #define HASH1  0x10
>> + #define HASH2  0x02
>> +-#define HASHSZ 512
>> ++#define HASHSZ 16
>> +
>> + static unsigned int hashnum(unsigned int num)
>> + {
>> +@@ -59,16 +93,16 @@ static unsigned int hashnum(unsigned int num)
>> +
>> + static struct udev *udev = NULL;
>> + static struct udev_hwdb *hwdb = NULL;
>> +-static struct audioterminal *audioterminals_hash[HASHSZ] = {
>> NULL, }; +-static struct videoterminal
>> *videoterminals_hash[HASHSZ] = { NULL, }; +-static struct
>> genericstrtable *hiddescriptors_hash[HASHSZ] = { NULL, };
>> +-static struct genericstrtable *reports_hash[HASHSZ] = { NULL,
>> }; +-static struct genericstrtable *huts_hash[HASHSZ] = { NULL,
>> }; +-static struct genericstrtable *biass_hash[HASHSZ] = {
>> NULL, }; +-static struct genericstrtable *physdess_hash[HASHSZ]
>> = { NULL, }; +-static struct genericstrtable
>> *hutus_hash[HASHSZ] = { NULL, }; +-static struct
>> genericstrtable *langids_hash[HASHSZ] = { NULL, }; +-static
>> struct genericstrtable *countrycodes_hash[HASHSZ] = { NULL, };
>> ++static struct audioterminal *audioterminals[HASHSZ] = { NULL,
>> }; ++static struct videoterminal *videoterminals[HASHSZ] = {
>> NULL, }; ++static struct genericstrtable
>> *hiddescriptors[HASHSZ] = { NULL, }; ++static struct
>> genericstrtable *reports[HASHSZ] = { NULL, }; ++static struct
>> genericstrtable *huts[HASHSZ] = { NULL, }; ++static struct
>> genericstrtable *biass[HASHSZ] = { NULL, }; ++static struct
>> genericstrtable *physdess[HASHSZ] = { NULL, }; ++static struct
>> genericstrtable *hutus[HASHSZ] = { NULL, }; ++static struct
>> genericstrtable *langids[HASHSZ] = { NULL, }; ++static struct
>> genericstrtable *countrycodes[HASHSZ] = { NULL, };
>> +
>> + /* ---------------------------------------------------------------------- */
>> +
>> +@@ -85,42 +119,42 @@ static const char *names_genericstrtable(struct genericstrtable *t[HASHSZ],
>> +
>> + const char *names_hid(u_int8_t hidd)
>> + {
>> +-    return names_genericstrtable(hiddescriptors_hash, hidd);
>> ++    return names_genericstrtable(hiddescriptors, hidd);
>> + }
>> +
>> + const char *names_reporttag(u_int8_t rt)
>> + {
>> +-    return names_genericstrtable(reports_hash, rt);
>> ++    return names_genericstrtable(reports, rt);
>> + }
>> +
>> + const char *names_huts(unsigned int data)
>> + {
>> +-    return names_genericstrtable(huts_hash, data);
>> ++    return names_genericstrtable(huts, data);
>> + }
>> +
>> + const char *names_hutus(unsigned int data)
>> + {
>> +-    return names_genericstrtable(hutus_hash, data);
>> ++    return names_genericstrtable(hutus, data);
>> + }
>> +
>> + const char *names_langid(u_int16_t langid)
>> + {
>> +-    return names_genericstrtable(langids_hash, langid);
>> ++    return names_genericstrtable(langids, langid);
>> + }
>> +
>> + const char *names_physdes(u_int8_t ph)
>> + {
>> +-    return names_genericstrtable(physdess_hash, ph);
>> ++    return names_genericstrtable(physdess, ph);
>> + }
>> +
>> + const char *names_bias(u_int8_t b)
>> + {
>> +-    return names_genericstrtable(biass_hash, b);
>> ++    return names_genericstrtable(biass, b);
>> + }
>> +
>> + const char *names_countrycode(unsigned int countrycode)
>> + {
>> +-    return names_genericstrtable(countrycodes_hash, countrycode);
>> ++    return names_genericstrtable(countrycodes, countrycode);
>> + }
>> +
>> + static const char *hwdb_get(const char *modalias, const char *key)
>> +@@ -178,7 +212,7 @@ const char *names_audioterminal(u_int16_t termt)
>> + {
>> +     struct audioterminal *at;
>> +
>> +-    at = audioterminals_hash[hashnum(termt)];
>> ++    at = audioterminals[hashnum(termt)];
>> +     for (; at; at = at->next)
>> +             if (at->termt == termt)
>> +                     return at->name;
>> +@@ -189,7 +223,7 @@ const char *names_videoterminal(u_int16_t termt)
>> + {
>> +     struct videoterminal *vt;
>> +
>> +-    vt = videoterminals_hash[hashnum(termt)];
>> ++    vt = videoterminals[hashnum(termt)];
>> +     for (; vt; vt = vt->next)
>> +             if (vt->termt == termt)
>> +                     return vt->name;
>> +@@ -248,189 +282,446 @@ int get_subclass_string(char *buf, size_t size, u_int8_t cls, u_int8_t subcls)
>> +
>> + /* ---------------------------------------------------------------------- */
>> +
>> +-static int hash_audioterminal(struct audioterminal *at)
>> ++static int new_audioterminal(const char *name, u_int16_t
>> termt)
>> + {
>> +-    struct audioterminal *at_old;
>> +-    unsigned int h = hashnum(at->termt);
>> ++    struct audioterminal *at;
>> ++    unsigned int h = hashnum(termt);
>> +
>> +-    for (at_old = audioterminals_hash[h]; at_old; at_old = at_old->next)
>> +-            if (at_old->termt == at->termt)
>> ++    at = audioterminals[h];
>> ++    for (; at; at = at->next)
>> ++            if (at->termt == termt)
>> +                     return -1;
>> +-    at->next = audioterminals_hash[h];
>> +-    audioterminals_hash[h] = at;
>> ++    at = malloc(sizeof(struct audioterminal) + strlen(name));
>> ++    if (!at)
>> ++            return -1;
>> ++    strcpy(at->name, name);
>> ++    at->termt = termt;
>> ++    at->next = audioterminals[h];
>> ++    audioterminals[h] = at;
>> +     return 0;
>> + }
>> +
>> +-static int hash_audioterminals(void)
>> +-{
>> +-    int r = 0, i, k;
>> +-
>> +-    for (i = 0; audioterminals[i].name; i++)
>> +-    {
>> +-            k = hash_audioterminal(&audioterminals[i]);
>> +-            if (k < 0)
>> +-                    r = k;
>> +-    }
>> +-
>> +-    return r;
>> +-}
>> +-
>> +-static int hash_videoterminal(struct videoterminal *vt)
>> ++static int new_videoterminal(const char *name, u_int16_t
>> termt)
>> + {
>> +-    struct videoterminal *vt_old;
>> +-    unsigned int h = hashnum(vt->termt);
>> ++    struct videoterminal *vt;
>> ++    unsigned int h = hashnum(termt);
>> +
>> +-    for (vt_old = videoterminals_hash[h]; vt_old; vt_old = vt_old->next)
>> +-            if (vt_old->termt == vt->termt)
>> ++    vt = videoterminals[h];
>> ++    for (; vt; vt = vt->next)
>> ++            if (vt->termt == termt)
>> +                     return -1;
>> +-    vt->next = videoterminals_hash[h];
>> +-    videoterminals_hash[h] = vt;
>> ++    vt = malloc(sizeof(struct videoterminal) + strlen(name));
>> ++    if (!vt)
>> ++            return -1;
>> ++    strcpy(vt->name, name);
>> ++    vt->termt = termt;
>> ++    vt->next = videoterminals[h];
>> ++    videoterminals[h] = vt;
>> +     return 0;
>> + }
>> +
>> +-static int hash_videoterminals(void)
>> +-{
>> +-    int r = 0, i, k;
>> +-
>> +-    for (i = 0; videoterminals[i].name; i++)
>> +-    {
>> +-            k = hash_videoterminal(&videoterminals[i]);
>> +-            if (k < 0)
>> +-                    r = k;
>> +-    }
>> +-
>> +-    return r;
>> +-}
>> +-
>> +-static int hash_genericstrtable(struct genericstrtable
>> *t[HASHSZ],
>> +-                           struct genericstrtable *g)
>> ++static int new_genericstrtable(struct genericstrtable
>> *t[HASHSZ],
>> ++                           const char *name, unsigned int idx)
>> + {
>> +-    struct genericstrtable *g_old;
>> +-    unsigned int h = hashnum(g->num);
>> ++    struct genericstrtable *g;
>> ++    unsigned int h = hashnum(idx);
>> +
>> +-    for (g_old = t[h]; g_old; g_old = g_old->next)
>> +-            if (g_old->num == g->num)
>> ++    for (g = t[h]; g; g = g->next)
>> ++            if (g->num == idx)
>> +                     return -1;
>> ++    g = malloc(sizeof(struct genericstrtable) + strlen(name));
>> ++    if (!g)
>> ++            return -1;
>> ++    strcpy(g->name, name);
>> ++    g->num = idx;
>> +     g->next = t[h];
>> +     t[h] = g;
>> +     return 0;
>> + }
>> +
>> +-#define HASH_EACH(array, hash) \
>> +-    for (i = 0; array[i].name; i++) { \
>> +-            k = hash_genericstrtable(hash, &array[i]); \
>> +-            if (k < 0) { \
>> +-                    r = k; \
>> +-            }\
>> +-    }
>> +-
>> +-static int hash_tables(void)
>> ++static int new_hid(const char *name, u_int8_t hidd)
>> + {
>> +-    int r = 0, k, i;
>> +-
>> +-    k = hash_audioterminals();
>> +-    if (k < 0)
>> +-            r = k;
>> +-
>> +-    k = hash_videoterminals();
>> +-    if (k < 0)
>> +-            r = k;
>> +-
>> +-    HASH_EACH(hiddescriptors, hiddescriptors_hash);
>> +-
>> +-    HASH_EACH(reports, reports_hash);
>> +-
>> +-    HASH_EACH(huts, huts_hash);
>> ++    return new_genericstrtable(hiddescriptors, name, hidd);
>> ++}
>> +
>> +-    HASH_EACH(hutus, hutus_hash);
>> ++static int new_reporttag(const char *name, u_int8_t rt)
>> ++{
>> ++    return new_genericstrtable(reports, name, rt);
>> ++}
>> +
>> +-    HASH_EACH(langids, langids_hash);
>> ++static int new_huts(const char *name, unsigned int data)
>> ++{
>> ++    return new_genericstrtable(huts, name, data);
>> ++}
>> +
>> +-    HASH_EACH(physdess, physdess_hash);
>> ++static int new_hutus(const char *name, unsigned int data)
>> ++{
>> ++    return new_genericstrtable(hutus, name, data);
>> ++}
>> +
>> +-    HASH_EACH(biass, biass_hash);
>> ++static int new_langid(const char *name, u_int16_t langid)
>> ++{
>> ++    return new_genericstrtable(langids, name, langid);
>> ++}
>> +
>> +-    HASH_EACH(countrycodes, countrycodes_hash);
>> ++static int new_physdes(const char *name, u_int8_t ph)
>> ++{
>> ++    return new_genericstrtable(physdess, name, ph);
>> ++}
>> ++static int new_bias(const char *name, u_int8_t b)
>> ++{
>> ++    return new_genericstrtable(biass, name, b);
>> ++}
>> +
>> +-    return r;
>> ++static int new_countrycode(const char *name, unsigned int
>> countrycode)
>> ++{
>> ++    return new_genericstrtable(countrycodes, name, countrycode);
>> + }
>> +
>> + /* ---------------------------------------------------------------------- */
>> +
>> +-/*
>> +-static void print_tables(void)
>> ++static void free_audioterminal(void)
>> + {
>> ++    struct audioterminal *cur, *tmp;
>> +     int i;
>> +-    struct audioterminal *at;
>> +-    struct videoterminal *vt;
>> +-    struct genericstrtable *li;
>> +-    struct genericstrtable *hu;
>> +-
>> +-
>> +-    printf("--------------------------------------------\n");
>> +-    printf("\t\t Audio Terminals\n");
>> +-    printf("--------------------------------------------\n");
>> +
>> +     for (i = 0; i < HASHSZ; i++) {
>> +-            printf("hash: %d\n", i);
>> +-            at = audioterminals_hash[i];
>> +-            for (; at; at = at->next)
>> +-                    printf("\tentry: %s\n", at->name);
>> ++            cur = audioterminals[i];
>> ++            audioterminals[i] = NULL;
>> ++            while (cur) {
>> ++                    tmp = cur;
>> ++                    cur = cur->next;
>> ++                    free(tmp);
>> ++            }
>> +     }
>> ++    return;
>> ++}
>> +
>> +-    printf("--------------------------------------------\n");
>> +-    printf("\t\t Video Terminals\n");
>> +-    printf("--------------------------------------------\n");
>> ++static void free_videoterminal(void)
>> ++{
>> ++    struct videoterminal *cur, *tmp;
>> ++    int i;
>> +
>> +     for (i = 0; i < HASHSZ; i++) {
>> +-            printf("hash: %d\n", i);
>> +-            vt = videoterminals_hash[i];
>> +-            for (; vt; vt = vt->next)
>> +-                    printf("\tentry: %s\n", vt->name);
>> ++            cur = videoterminals[i];
>> ++            videoterminals[i] = NULL;
>> ++            while (cur) {
>> ++                    tmp = cur;
>> ++                    cur = cur->next;
>> ++                    free(tmp);
>> ++            }
>> +     }
>> ++}
>> +
>> +-    printf("--------------------------------------------\n");
>> +-    printf("\t\t Languages\n");
>> +-    printf("--------------------------------------------\n");
>> ++static void _free_genericstrtable(struct genericstrtable
>> *t[HASHSZ])
>> ++{
>> ++    struct genericstrtable *cur, *tmp;
>> ++    int i;
>> +
>> +     for (i = 0; i < HASHSZ; i++) {
>> +-            li = langids_hash[i];
>> +-            if (li)
>> +-                    printf("hash: %d\n", i);
>> +-            for (; li; li = li->next)
>> +-                    printf("\tid: %x, entry: %s\n", li->num, li->name);
>> ++            cur = t[i];
>> ++            t[i] = NULL;
>> ++            while (cur) {
>> ++                    tmp = cur;
>> ++                    cur = cur->next;
>> ++                    free(tmp);
>> ++            }
>> +     }
>> ++}
>> +
>> +-    printf("--------------------------------------------\n");
>> +-    printf("\t\t Conutry Codes\n");
>> +-    printf("--------------------------------------------\n");
>> ++static void free_genericstrtable(void)
>> ++{
>> ++    _free_genericstrtable(hiddescriptors);
>> ++    _free_genericstrtable(reports);
>> ++    _free_genericstrtable(huts);
>> ++    _free_genericstrtable(biass);
>> ++    _free_genericstrtable(physdess);
>> ++    _free_genericstrtable(hutus);
>> ++    _free_genericstrtable(langids);
>> ++    _free_genericstrtable(countrycodes);
>> ++}
>> +
>> +-    for (i = 0; i < HASHSZ; i++) {
>> +-            hu = countrycodes_hash[i];
>> +-            if (hu)
>> +-                    printf("hash: %d\n", i);
>> +-            for (; hu; hu = hu->next)
>> +-                    printf("\tid: %x, entry: %s\n", hu->num, hu->name);
>> +-    }
>> ++#define DBG(x)
>> +
>> +-    printf("--------------------------------------------\n");
>> ++static void parse(usb_file f)
>> ++{
>> ++    char buf[512], *cp;
>> ++    unsigned int linectr = 0;
>> ++    int lastvendor = -1;
>> ++    int lastclass = -1;
>> ++    int lastsubclass = -1;
>> ++    int lasthut = -1;
>> ++    int lastlang = -1;
>> ++    unsigned int u;
>> ++
>> ++    while (usb_fgets(buf, sizeof(buf), f)) {
>> ++            linectr++;
>> ++            /* remove line ends */
>> ++            cp = strchr(buf, 13);
>> ++            if (cp)
>> ++                    *cp = 0;
>> ++            cp = strchr(buf, 10);
>> ++            if (cp)
>> ++                    *cp = 0;
>> ++            if (buf[0] == '#' || !buf[0])
>> ++                    continue;
>> ++            cp = buf;
>> ++            if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' && buf[3] == 'S' && buf[4] == 'D' &&
>> ++                buf[5] == 'E' && buf[6] == 'S' && /*isspace(buf[7])*/ buf[7] == ' ') {
>> ++                    cp = buf + 8;
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!isxdigit(*cp)) {
>> ++                            fprintf(stderr, "Invalid Physdes type at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    u = strtoul(cp, &cp, 16);
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!*cp) {
>> ++                            fprintf(stderr, "Invalid Physdes type at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    if (new_physdes(cp, u))
>> ++                            fprintf(stderr, "Duplicate Physdes  type spec at line %u terminal type %04x %s\n", linectr, u, cp);
>> ++                    DBG(printf("line %5u physdes type %02x %s\n", linectr, u, cp));
>> ++                    continue;
>> ++
>> ++            }
>> ++            if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' && /*isspace(buf[3])*/ buf[3] == ' ') {
>> ++                    cp = buf + 4;
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!isxdigit(*cp)) {
>> ++                            fprintf(stderr, "Invalid PHY type at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    u = strtoul(cp, &cp, 16);
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!*cp) {
>> ++                            fprintf(stderr, "Invalid PHY type at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    if (new_physdes(cp, u))
>> ++                            fprintf(stderr, "Duplicate PHY type spec at line %u terminal type %04x %s\n", linectr, u, cp);
>> ++                    DBG(printf("line %5u PHY type %02x %s\n", linectr, u, cp));
>> ++                    continue;
>> ++
>> ++            }
>> ++            if (buf[0] == 'B' && buf[1] == 'I' && buf[2] == 'A' && buf[3] == 'S' && /*isspace(buf[4])*/ buf[4] == ' ') {
>> ++                    cp = buf + 5;
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!isxdigit(*cp)) {
>> ++                            fprintf(stderr, "Invalid BIAS type at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    u = strtoul(cp, &cp, 16);
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!*cp) {
>> ++                            fprintf(stderr, "Invalid BIAS type at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    if (new_bias(cp, u))
>> ++                            fprintf(stderr, "Duplicate BIAS  type spec at line %u terminal type %04x %s\n", linectr, u, cp);
>> ++                    DBG(printf("line %5u BIAS type %02x %s\n", linectr, u, cp));
>> ++                    continue;
>> ++
>> ++            }
>> ++            if (buf[0] == 'L' && /*isspace(buf[1])*/ buf[1] == ' ') {
>> ++                    cp =  buf+2;
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!isxdigit(*cp)) {
>> ++                            fprintf(stderr, "Invalid LANGID spec at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    u = strtoul(cp, &cp, 16);
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!*cp) {
>> ++                            fprintf(stderr, "Invalid LANGID spec at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    if (new_langid(cp, u))
>> ++                            fprintf(stderr, "Duplicate LANGID spec at line %u language-id %04x %s\n", linectr, u, cp);
>> ++                    DBG(printf("line %5u LANGID %02x %s\n", linectr, u, cp));
>> ++                    lasthut = lastclass = lastvendor = lastsubclass = -1;
>> ++                    lastlang = u;
>> ++                    continue;
>> ++            }
>> ++            if (buf[0] == 'A' && buf[1] == 'T' && isspace(buf[2])) {
>> ++                    /* audio terminal type spec */
>> ++                    cp = buf+3;
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!isxdigit(*cp)) {
>> ++                            fprintf(stderr, "Invalid audio terminal type at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    u = strtoul(cp, &cp, 16);
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!*cp) {
>> ++                            fprintf(stderr, "Invalid audio terminal type at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    if (new_audioterminal(cp, u))
>> ++                            fprintf(stderr, "Duplicate audio terminal type spec at line %u terminal type %04x %s\n", linectr, u, cp);
>> ++                    DBG(printf("line %5u audio terminal type %02x %s\n", linectr, u, cp));
>> ++                    continue;
>> ++            }
>> ++            if (buf[0] == 'V' && buf[1] == 'T' && isspace(buf[2])) {
>> ++                    /* video terminal type spec */
>> ++                    cp = buf+3;
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!isxdigit(*cp)) {
>> ++                            fprintf(stderr, "Invalid video terminal type at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    u = strtoul(cp, &cp, 16);
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!*cp) {
>> ++                            fprintf(stderr, "Invalid video terminal type at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    if (new_videoterminal(cp, u))
>> ++                            fprintf(stderr, "Duplicate video terminal type spec at line %u terminal type %04x %s\n", linectr, u, cp);
>> ++                    DBG(printf("line %5u video terminal type %02x %s\n", linectr, u, cp));
>> ++                    continue;
>> ++            }
>> ++            if (buf[0] == 'H' && buf[1] == 'C' && buf[2] == 'C' && isspace(buf[3])) {
>> ++                    /* HID Descriptor bCountryCode */
>> ++                    cp =  buf+3;
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!isxdigit(*cp)) {
>> ++                            fprintf(stderr, "Invalid HID country code at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    u = strtoul(cp, &cp, 10);
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!*cp) {
>> ++                            fprintf(stderr, "Invalid HID country code at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    if (new_countrycode(cp, u))
>> ++                            fprintf(stderr, "Duplicate HID country code at line %u country %02u %s\n", linectr, u, cp);
>> ++                    DBG(printf("line %5u keyboard country code %02u %s\n", linectr, u, cp));
>> ++                    continue;
>> ++            }
>> ++            if (buf[0] == '\t' && isxdigit(buf[1])) {
>> ++                    /* product or subclass spec */
>> ++                    u = strtoul(buf+1, &cp, 16);
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!*cp) {
>> ++                            fprintf(stderr, "Invalid product/subclass spec at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    if (lasthut != -1) {
>> ++                            if (new_hutus(cp, (lasthut << 16)+u))
>> ++                                    fprintf(stderr, "Duplicate HUT Usage Spec at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    if (lastlang != -1) {
>> ++                            if (new_langid(cp, lastlang+(u<<10)))
>> ++                                    fprintf(stderr, "Duplicate LANGID Usage Spec at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    fprintf(stderr, "Product/Subclass spec without prior Vendor/Class spec at line %u\n", linectr);
>> ++                    continue;
>> ++            }
>> ++            if (buf[0] == 'H' && buf[1] == 'I' && buf[2] == 'D' && /*isspace(buf[3])*/ buf[3] == ' ') {
>> ++                    cp = buf + 4;
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!isxdigit(*cp)) {
>> ++                            fprintf(stderr, "Invalid HID type at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    u = strtoul(cp, &cp, 16);
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!*cp) {
>> ++                            fprintf(stderr, "Invalid HID type at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    if (new_hid(cp, u))
>> ++                            fprintf(stderr, "Duplicate HID type spec at line %u terminal type %04x %s\n", linectr, u, cp);
>> ++                    DBG(printf("line %5u HID type %02x %s\n", linectr, u, cp));
>> ++                    continue;
>> ++
>> ++            }
>> ++            if (buf[0] == 'H' && buf[1] == 'U' && buf[2] == 'T' && /*isspace(buf[3])*/ buf[3] == ' ') {
>> ++                    cp = buf + 4;
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!isxdigit(*cp)) {
>> ++                            fprintf(stderr, "Invalid HUT type at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    u = strtoul(cp, &cp, 16);
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!*cp) {
>> ++                            fprintf(stderr, "Invalid HUT type at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    if (new_huts(cp, u))
>> ++                            fprintf(stderr, "Duplicate HUT type spec at line %u terminal type %04x %s\n", linectr, u, cp);
>> ++                    lastlang = lastclass = lastvendor = lastsubclass = -1;
>> ++                    lasthut = u;
>> ++                    DBG(printf("line %5u HUT type %02x %s\n", linectr, u, cp));
>> ++                    continue;
>> ++
>> ++            }
>> ++            if (buf[0] == 'R' && buf[1] == ' ') {
>> ++                    cp = buf + 2;
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!isxdigit(*cp)) {
>> ++                            fprintf(stderr, "Invalid Report type at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    u = strtoul(cp, &cp, 16);
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!*cp) {
>> ++                            fprintf(stderr, "Invalid Report type at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    if (new_reporttag(cp, u))
>> ++                            fprintf(stderr, "Duplicate Report type spec at line %u terminal type %04x %s\n", linectr, u, cp);
>> ++                    DBG(printf("line %5u Report type %02x %s\n", linectr, u, cp));
>> ++                    continue;
>> ++
>> ++            }
>> ++            fprintf(stderr, "Unknown line at line %u\n", linectr);
>> ++    }
>> + }
>> +-*/
>> +
>> +-int names_init(void)
>> ++/* ---------------------------------------------------------------------- */
>> ++
>> ++int names_init(char *n)
>> + {
>> +-    int r;
>> ++    usb_file f;
>> ++    int r = 0;
>> +
>> +-    udev = udev_new();
>> +-    if (!udev)
>> +-            r = -1;
>> +-    else {
>> +-            hwdb = udev_hwdb_new(udev);
>> +-            if (!hwdb)
>> +-                    r = -1;
>> +-    }
>> ++    f = usb_fopen(n, "r");
>> ++    if (!f)
>> ++            r = errno;
>> +
>> +-    r = hash_tables();
>> ++    parse(f);
>> ++    usb_close(f);
>> ++
>> ++    udev = udev_new();
>> ++    hwdb = udev_hwdb_new(udev);
>> +
>> +     return r;
>> + }
>> +@@ -439,4 +730,7 @@ void names_exit(void)
>> + {
>> +     hwdb = udev_hwdb_unref(hwdb);
>> +     udev = udev_unref(udev);
>> ++    free_audioterminal();
>> ++    free_videoterminal();
>> ++    free_genericstrtable();
>> + }
>> +diff --git a/names.h b/names.h
>> +index 32e887c..0eba890 100644
>> +--- a/names.h
>> ++++ b/names.h
>> +@@ -49,7 +49,7 @@ extern int get_product_string(char *buf, size_t size, u_int16_t vid, u_int16_t p
>> + extern int get_class_string(char *buf, size_t size, u_int8_t cls);
>> + extern int get_subclass_string(char *buf, size_t size, u_int8_t cls, u_int8_t subcls);
>> +
>> +-extern int names_init(void);
>> ++extern int names_init(char *n);
>> + extern void names_exit(void);
>> +
>> + /* ---------------------------------------------------------------------- */
>> +---
>> +-2.16.2
>> diff --git
>> a/package/utils/usbutils/patches/030-revert-port-to-hwdb.patch
>> b/package/utils/usbutils/patches/030-revert-port-to-hwdb.patch
>> new file mode 100644 index 0000000000..fc41456893
>> --- /dev/null
>> +++ b/package/utils/usbutils/patches/030-revert-port-to-hwdb.patch
>> @@ -0,0 +1,529 @@
>> +From bfb94e20c8ca6eff73e8722165994a45da7cf47c Mon Sep 17
>> 00:00:00 2001 +From: Rosen Penev <rosenp at gmail.com> +Date: Fri,
>> 9 Mar 2018 10:33:52 -0800 +Subject: [PATCH] Revert "lsusb: port
>> to hwdb"
>> +
>> +This reverts commit c6282a7a0e20fbb9c56837f055843635a43ba8b4.
>> +---
>> + Makefile.am  |   5 +-
>> + configure.ac |   2 -
>> + names.c      | 361 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
>> + 3 files changed, 323 insertions(+), 45 deletions(-)
>> +
>> +diff --git a/Makefile.am b/Makefile.am
>> +index 31afb20..60df9a0 100644
>> +--- a/Makefile.am
>> ++++ b/Makefile.am
>> +@@ -23,12 +23,11 @@ lsusb_SOURCES = \
>> +     usbmisc.c usbmisc.h
>> +
>> + lsusb_CPPFLAGS = \
>> +-    $(AM_CPPFLAGS) $(LIBUSB_CFLAGS) $(UDEV_CFLAGS) \
>> ++    $(AM_CPPFLAGS) $(LIBUSB_CFLAGS) \
>> +     -DDATADIR=\"$(datadir)\"
>> +
>> + lsusb_LDADD = \
>> +-    $(LIBUSB_LIBS) \
>> +-    $(UDEV_LIBS)
>> ++    $(LIBUSB_LIBS)
>> +
>> + if HAVE_ZLIB
>> + lsusb_CPPFLAGS += -DHAVE_LIBZ
>> +diff --git a/configure.ac b/configure.ac
>> +index 89d62f9..4b86c9b 100644
>> +--- a/configure.ac
>> ++++ b/configure.ac
>> +@@ -26,8 +26,6 @@ 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 f543240..12cbd60 100644
>> +--- a/names.c
>> ++++ b/names.c
>> +@@ -3,7 +3,6 @@
>> +  *      names.c  --  USB name database manipulation routines
>> +  *
>> +  *      Copyright (C) 1999, 2000  Thomas Sailer (sailer at ife.ee.ethz.ch)
>> +- *      Copyright (C) 2013  Tom Gundersen (teg at jklm.no)
>> +  *
>> +  *      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
>> +@@ -35,8 +34,6 @@
>> + #include <stdio.h>
>> + #include <ctype.h>
>> +
>> +-#include <libudev.h>
>> +-
>> + #ifdef HAVE_LIBZ
>> + #include <zlib.h>
>> + #define     usb_file                        gzFile
>> +@@ -55,6 +52,36 @@
>> +
>> + /* ---------------------------------------------------------------------- */
>> +
>> ++struct vendor {
>> ++    struct vendor *next;
>> ++    u_int16_t vendorid;
>> ++    char name[1];
>> ++};
>> ++
>> ++struct product {
>> ++    struct product *next;
>> ++    u_int16_t vendorid, productid;
>> ++    char name[1];
>> ++};
>> ++
>> ++struct class {
>> ++    struct class *next;
>> ++    u_int8_t classid;
>> ++    char name[1];
>> ++};
>> ++
>> ++struct subclass {
>> ++    struct subclass *next;
>> ++    u_int8_t classid, subclassid;
>> ++    char name[1];
>> ++};
>> ++
>> ++struct protocol {
>> ++    struct protocol *next;
>> ++    u_int8_t classid, subclassid, protocolid;
>> ++    char name[1];
>> ++};
>> ++
>> + struct audioterminal {
>> +     struct audioterminal *next;
>> +     u_int16_t termt;
>> +@@ -91,8 +118,11 @@ 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, }; ++static struct
>> subclass *subclasses[HASHSZ] = { NULL, }; ++static struct
>> protocol *protocols[HASHSZ] = { NULL, };
>> + static struct audioterminal *audioterminals[HASHSZ] = { NULL, };
>> + static struct videoterminal *videoterminals[HASHSZ] = { NULL, };
>> + static struct genericstrtable *hiddescriptors[HASHSZ] = { NULL, };
>> +@@ -157,55 +187,59 @@ 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)
>> + {
>> +-    char modalias[64];
>> ++    struct vendor *v;
>> +
>> +-    sprintf(modalias, "usb:v%04X*", vendorid);
>> +-    return hwdb_get(modalias, "ID_VENDOR_FROM_DATABASE");
>> ++    v = vendors[hashnum(vendorid)];
>> ++    for (; v; v = v->next)
>> ++            if (v->vendorid == vendorid)
>> ++                    return v->name;
>> ++    return NULL;
>> + }
>> +
>> + const char *names_product(u_int16_t vendorid, u_int16_t productid)
>> + {
>> +-    char modalias[64];
>> ++    struct product *p;
>> +
>> +-    sprintf(modalias, "usb:v%04Xp%04X*", vendorid, productid);
>> +-    return hwdb_get(modalias, "ID_MODEL_FROM_DATABASE");
>> ++    p = products[hashnum((vendorid << 16) | productid)];
>> ++    for (; p; p = p->next)
>> ++            if (p->vendorid == vendorid && p->productid == productid)
>> ++                    return p->name;
>> ++    return NULL;
>> + }
>> +
>> + const char *names_class(u_int8_t classid)
>> + {
>> +-    char modalias[64];
>> ++    struct class *c;
>> +
>> +-    sprintf(modalias, "usb:v*p*d*dc%02X*", classid);
>> +-    return hwdb_get(modalias, "ID_USB_CLASS_FROM_DATABASE");
>> ++    c = classes[hashnum(classid)];
>> ++    for (; c; c = c->next)
>> ++            if (c->classid == classid)
>> ++                    return c->name;
>> ++    return NULL;
>> + }
>> +
>> + const char *names_subclass(u_int8_t classid, u_int8_t subclassid)
>> + {
>> +-    char modalias[64];
>> ++    struct subclass *s;
>> +
>> +-    sprintf(modalias, "usb:v*p*d*dc%02Xdsc%02X*", classid, subclassid);
>> +-    return hwdb_get(modalias, "ID_USB_SUBCLASS_FROM_DATABASE");
>> ++    s = subclasses[hashnum((classid << 8) | subclassid)];
>> ++    for (; s; s = s->next)
>> ++            if (s->classid == classid && s->subclassid == subclassid)
>> ++                    return s->name;
>> ++    return NULL;
>> + }
>> +
>> + const char *names_protocol(u_int8_t classid, u_int8_t subclassid, u_int8_t protocolid)
>> + {
>> +-    char modalias[64];
>> ++    struct protocol *p;
>> +
>> +-    sprintf(modalias, "usb:v*p*d*dc%02Xdsc%02Xdp%02X*", classid, subclassid, protocolid);
>> +-    return hwdb_get(modalias, "ID_USB_PROTOCOL_FROM_DATABASE");
>> ++    p = protocols[hashnum((classid << 16) | (subclassid << 8) | protocolid)];
>> ++    for (; p; p = p->next)
>> ++            if (p->classid == classid && p->subclassid == subclassid && p->protocolid == protocolid)
>> ++                    return p->name;
>> ++    return NULL;
>> + }
>> +
>> + const char *names_audioterminal(u_int16_t termt)
>> +@@ -282,6 +316,105 @@ int get_subclass_string(char *buf, size_t size, u_int8_t cls, u_int8_t subcls)
>> +
>> + /* ---------------------------------------------------------------------- */
>> +
>> ++static int new_vendor(const char *name, u_int16_t vendorid)
>> ++{
>> ++    struct vendor *v;
>> ++    unsigned int h = hashnum(vendorid);
>> ++
>> ++    v = vendors[h];
>> ++    for (; v; v = v->next)
>> ++            if (v->vendorid == vendorid)
>> ++                    return -1;
>> ++    v = malloc(sizeof(struct vendor) + strlen(name));
>> ++    if (!v)
>> ++            return -1;
>> ++    strcpy(v->name, name);
>> ++    v->vendorid = vendorid;
>> ++    v->next = vendors[h];
>> ++    vendors[h] = v;
>> ++    return 0;
>> ++}
>> ++
>> ++static int new_product(const char *name, u_int16_t vendorid,
>> u_int16_t productid)
>> ++{
>> ++    struct product *p;
>> ++    unsigned int h = hashnum((vendorid << 16) | productid);
>> ++
>> ++    p = products[h];
>> ++    for (; p; p = p->next)
>> ++            if (p->vendorid == vendorid && p->productid == productid)
>> ++                    return -1;
>> ++    p = malloc(sizeof(struct product) + strlen(name));
>> ++    if (!p)
>> ++            return -1;
>> ++    strcpy(p->name, name);
>> ++    p->vendorid = vendorid;
>> ++    p->productid = productid;
>> ++    p->next = products[h];
>> ++    products[h] = p;
>> ++    return 0;
>> ++}
>> ++
>> ++static int new_class(const char *name, u_int8_t classid)
>> ++{
>> ++    struct class *c;
>> ++    unsigned int h = hashnum(classid);
>> ++
>> ++    c = classes[h];
>> ++    for (; c; c = c->next)
>> ++            if (c->classid == classid)
>> ++                    return -1;
>> ++    c = malloc(sizeof(struct class) + strlen(name));
>> ++    if (!c)
>> ++            return -1;
>> ++    strcpy(c->name, name);
>> ++    c->classid = classid;
>> ++    c->next = classes[h];
>> ++    classes[h] = c;
>> ++    return 0;
>> ++}
>> ++
>> ++static int new_subclass(const char *name, u_int8_t classid,
>> u_int8_t subclassid)
>> ++{
>> ++    struct subclass *s;
>> ++    unsigned int h = hashnum((classid << 8) | subclassid);
>> ++
>> ++    s = subclasses[h];
>> ++    for (; s; s = s->next)
>> ++            if (s->classid == classid && s->subclassid == subclassid)
>> ++                    return -1;
>> ++    s = malloc(sizeof(struct subclass) + strlen(name));
>> ++    if (!s)
>> ++            return -1;
>> ++    strcpy(s->name, name);
>> ++    s->classid = classid;
>> ++    s->subclassid = subclassid;
>> ++    s->next = subclasses[h];
>> ++    subclasses[h] = s;
>> ++    return 0;
>> ++}
>> ++
>> ++static int new_protocol(const char *name, u_int8_t classid,
>> u_int8_t subclassid, u_int8_t protocolid)
>> ++{
>> ++    struct protocol *p;
>> ++    unsigned int h = hashnum((classid << 16) | (subclassid << 8) | protocolid);
>> ++
>> ++    p = protocols[h];
>> ++    for (; p; p = p->next)
>> ++            if (p->classid == classid && p->subclassid == subclassid && p->protocolid == protocolid)
>> ++                    return -1;
>> ++    p = malloc(sizeof(struct protocol) + strlen(name));
>> ++    if (!p)
>> ++            return -1;
>> ++    strcpy(p->name, name);
>> ++    p->classid = classid;
>> ++    p->subclassid = subclassid;
>> ++    p->protocolid = protocolid;
>> ++    p->next = protocols[h];
>> ++    protocols[h] = p;
>> ++    return 0;
>> ++}
>> ++
>> + static int new_audioterminal(const char *name, u_int16_t termt)
>> + {
>> +     struct audioterminal *at;
>> +@@ -380,6 +513,86 @@ static int new_countrycode(const char *name, unsigned int countrycode)
>> +
>> + /* ---------------------------------------------------------------------- */
>> +
>> ++static void free_vendor(void)
>> ++{
>> ++    struct vendor *cur, *tmp;
>> ++    int i;
>> ++
>> ++    for (i = 0; i < HASHSZ; i++) {
>> ++            cur = vendors[i];
>> ++            vendors[i] = NULL;
>> ++            while (cur) {
>> ++                    tmp = cur;
>> ++                    cur = cur->next;
>> ++                    free(tmp);
>> ++            }
>> ++    }
>> ++}
>> ++
>> ++static void free_product(void)
>> ++{
>> ++    struct product *cur, *tmp;
>> ++    int i;
>> ++
>> ++    for (i = 0; i < HASHSZ; i++) {
>> ++            cur = products[i];
>> ++            products[i] = NULL;
>> ++            while (cur) {
>> ++                    tmp = cur;
>> ++                    cur = cur->next;
>> ++                    free(tmp);
>> ++            }
>> ++    }
>> ++}
>> ++
>> ++static void free_class(void)
>> ++{
>> ++    struct class *cur, *tmp;
>> ++    int i;
>> ++
>> ++    for (i = 0; i < HASHSZ; i++) {
>> ++            cur = classes[i];
>> ++            classes[i] = NULL;
>> ++            while (cur) {
>> ++                    tmp = cur;
>> ++                    cur = cur->next;
>> ++                    free(tmp);
>> ++            }
>> ++    }
>> ++}
>> ++
>> ++static void free_subclass(void)
>> ++{
>> ++    struct subclass *cur, *tmp;
>> ++    int i;
>> ++
>> ++    for (i = 0; i < HASHSZ; i++) {
>> ++            cur = subclasses[i];
>> ++            subclasses[i] = NULL;
>> ++            while (cur) {
>> ++                    tmp = cur;
>> ++                    cur = cur->next;
>> ++                    free(tmp);
>> ++            }
>> ++    }
>> ++}
>> ++
>> ++static void free_protocol(void)
>> ++{
>> ++    struct protocol *cur, *tmp;
>> ++    int i;
>> ++
>> ++    for (i = 0; i < HASHSZ; i++) {
>> ++            cur = protocols[i];
>> ++            protocols[i] = NULL;
>> ++            while (cur) {
>> ++                    tmp = cur;
>> ++                    cur = cur->next;
>> ++                    free(tmp);
>> ++            }
>> ++    }
>> ++}
>> ++
>> + static void free_audioterminal(void)
>> + {
>> +     struct audioterminal *cur, *tmp;
>> +@@ -552,6 +765,29 @@ static void parse(usb_file f)
>> +                     lastlang = u;
>> +                     continue;
>> +             }
>> ++            if (buf[0] == 'C' && /*isspace(buf[1])*/ buf[1] == ' ') {
>> ++                    /* class spec */
>> ++                    cp = buf+2;
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!isxdigit(*cp)) {
>> ++                            fprintf(stderr, "Invalid class spec at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    u = strtoul(cp, &cp, 16);
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!*cp) {
>> ++                            fprintf(stderr, "Invalid class spec at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    if (new_class(cp, u))
>> ++                            fprintf(stderr, "Duplicate class spec at line %u class %04x %s\n", linectr, u, cp);
>> ++                    DBG(printf("line %5u class %02x %s\n", linectr, u, cp));
>> ++                    lasthut = lastlang = lastvendor = lastsubclass = -1;
>> ++                    lastclass = u;
>> ++                    continue;
>> ++            }
>> +             if (buf[0] == 'A' && buf[1] == 'T' && isspace(buf[2])) {
>> +                     /* audio terminal type spec */
>> +                     cp = buf+3;
>> +@@ -615,6 +851,22 @@ static void parse(usb_file f)
>> +                     DBG(printf("line %5u keyboard country code %02u %s\n", linectr, u, cp));
>> +                     continue;
>> +             }
>> ++            if (isxdigit(*cp)) {
>> ++                    /* vendor */
>> ++                    u = strtoul(cp, &cp, 16);
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!*cp) {
>> ++                            fprintf(stderr, "Invalid vendor spec at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    if (new_vendor(cp, u))
>> ++                            fprintf(stderr, "Duplicate vendor spec at line %u vendor %04x %s\n", linectr, u, cp);
>> ++                    DBG(printf("line %5u vendor %04x %s\n", linectr, u, cp));
>> ++                    lastvendor = u;
>> ++                    lasthut = lastlang = lastclass = lastsubclass = -1;
>> ++                    continue;
>> ++            }
>> +             if (buf[0] == '\t' && isxdigit(buf[1])) {
>> +                     /* product or subclass spec */
>> +                     u = strtoul(buf+1, &cp, 16);
>> +@@ -624,6 +876,19 @@ static void parse(usb_file f)
>> +                             fprintf(stderr, "Invalid product/subclass spec at line %u\n", linectr);
>> +                             continue;
>> +                     }
>> ++                    if (lastvendor != -1) {
>> ++                            if (new_product(cp, lastvendor, u))
>> ++                                    fprintf(stderr, "Duplicate product spec at line %u product %04x:%04x %s\n", linectr, lastvendor, u, cp);
>> ++                            DBG(printf("line %5u product %04x:%04x %s\n", linectr, lastvendor, u, cp));
>> ++                            continue;
>> ++                    }
>> ++                    if (lastclass != -1) {
>> ++                            if (new_subclass(cp, lastclass, u))
>> ++                                    fprintf(stderr, "Duplicate subclass spec at line %u class %02x:%02x %s\n", linectr, lastclass, u, cp);
>> ++                            DBG(printf("line %5u subclass %02x:%02x %s\n", linectr, lastclass, u, cp));
>> ++                            lastsubclass = u;
>> ++                            continue;
>> ++                    }
>> +                     if (lasthut != -1) {
>> +                             if (new_hutus(cp, (lasthut << 16)+u))
>> +                                     fprintf(stderr, "Duplicate HUT Usage Spec at line %u\n", linectr);
>> +@@ -637,6 +902,24 @@ static void parse(usb_file f)
>> +                     fprintf(stderr, "Product/Subclass spec without prior Vendor/Class spec at line %u\n", linectr);
>> +                     continue;
>> +             }
>> ++            if (buf[0] == '\t' && buf[1] == '\t' && isxdigit(buf[2])) {
>> ++                    /* protocol spec */
>> ++                    u = strtoul(buf+2, &cp, 16);
>> ++                    while (isspace(*cp))
>> ++                            cp++;
>> ++                    if (!*cp) {
>> ++                            fprintf(stderr, "Invalid protocol spec at line %u\n", linectr);
>> ++                            continue;
>> ++                    }
>> ++                    if (lastclass != -1 && lastsubclass != -1) {
>> ++                            if (new_protocol(cp, lastclass, lastsubclass, u))
>> ++                                    fprintf(stderr, "Duplicate protocol spec at line %u class %02x:%02x:%02x %s\n", linectr, lastclass, lastsubclass, u, cp);
>> ++                            DBG(printf("line %5u protocol %02x:%02x:%02x %s\n", linectr, lastclass, lastsubclass, u, cp));
>> ++                            continue;
>> ++                    }
>> ++                    fprintf(stderr, "Protocol spec without prior Class and Subclass spec at line %u\n", linectr);
>> ++                    continue;
>> ++            }
>> +             if (buf[0] == 'H' && buf[1] == 'I' && buf[2] == 'D' && /*isspace(buf[3])*/ buf[3] == ' ') {
>> +                     cp = buf + 4;
>> +                     while (isspace(*cp))
>> +@@ -711,25 +994,23 @@ static void parse(usb_file f)
>> + int names_init(char *n)
>> + {
>> +     usb_file f;
>> +-    int r = 0;
>> +
>> +     f = usb_fopen(n, "r");
>> +     if (!f)
>> +-            r = errno;
>> ++            return errno;
>> +
>> +     parse(f);
>> +     usb_close(f);
>> +-
>> +-    udev = udev_new();
>> +-    hwdb = udev_hwdb_new(udev);
>> +-
>> +-    return r;
>> ++    return 0;
>> + }
>> +
>> + void names_exit(void)
>> + {
>> +-    hwdb = udev_hwdb_unref(hwdb);
>> +-    udev = udev_unref(udev);
>> ++    free_vendor();
>> ++    free_product();
>> ++    free_class();
>> ++    free_subclass();
>> ++    free_protocol();
>> +     free_audioterminal();
>> +     free_videoterminal();
>> +     free_genericstrtable();
>> +--
>> +2.16.2
>> +
>> diff --git
>> a/package/utils/usbutils/patches/040-add-back-update-usbids.patch
>> b/package/utils/usbutils/patches/040-add-back-update-usbids.patch
>> new file mode 100644 index 0000000000..c2df737cfc
>> --- /dev/null
>> +++ b/package/utils/usbutils/patches/040-add-back-update-usbids.patch
>> @@ -0,0 +1,66 @@
>> +From 41ae595f349cd7ceab74f5c92727abf104be164a Mon Sep 17
>> 00:00:00 2001 +From: Rosen Penev <rosenp at gmail.com> +Date: Fri,
>> 9 Mar 2018 13:10:06 -0800 +Subject: [PATCH] Revert "drop unused
>> input file for usb.ids update script"
>> +
>> +This reverts commit 15536b7ab056a960cefe0651a5d50dc558e2f66d.
>> +---
>> + update-usbids.sh.in | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>> + 1 files changed, 47 insertions(+)
>> + create mode 100755 update-usbids.sh.in
>> +
>> +diff --git a/update-usbids.sh.in b/update-usbids.sh.in +new
>> file mode 100755 +index 0000000..4a487ed
>> +--- /dev/null
>> ++++ b/update-usbids.sh.in
>> +@@ -0,0 +1,46 @@
>> ++#!/bin/sh
>> ++
>> ++# see also update-pciids.sh (fancier)
>> ++
>> ++[ "$1" = "-q" ] && quiet="true" || quiet="false"
>> ++
>> ++set -e
>> ++SRC="http://www.linux-usb.org/usb.ids"
>> ++DEST=@usbids@
>> ++
>> ++# if usb.ids is read-only (because the filesystem is read-only),
>> ++# then just skip this whole process.
>> ++if ! touch ${DEST} >&2 >/dev/null ; then
>> ++    ${quiet} || echo "${DEST} is read-only, exiting."
>> ++    exit 0
>> ++fi
>> ++
>> ++if which wget >/dev/null 2>&1 ; then
>> ++    DL="wget -O $DEST.new $SRC"
>> ++    ${quiet} && DL="$DL -q"
>> ++elif which lynx >/dev/null 2>&1 ; then
>> ++    DL="eval lynx -source $SRC >$DEST.new"
>> ++else
>> ++    echo >&2 "update-usbids: cannot find wget nor lynx"
>> ++    exit 1
>> ++fi
>> ++
>> ++if ! $DL ; then
>> ++    echo >&2 "update-usbids: download failed"
>> ++    rm -f $DEST.new
>> ++    exit 1
>> ++fi
>> ++
>> ++if ! grep >/dev/null "^C " $DEST.new ; then
>> ++    echo >&2 "update-usbids: missing class info, probably truncated file"
>> ++    exit 1
>> ++fi
>> ++
>> ++if [ -f $DEST ] ; then
>> ++    mv $DEST $DEST.old
>> ++    # --reference is supported only by chmod from GNU file, so let's ignore any errors
>> ++    chmod -f --reference=$DEST.old $DEST.new 2>/dev/null || true
>> ++fi
>> ++mv $DEST.new $DEST
>> ++
>> ++${quiet} || echo "Done."
>> +--
>> +2.16.2
>> +



More information about the Lede-dev mailing list