diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000000..4ecef24b8c23 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +.*.sw? +diff/diff +*.o +*.d +*.a +**/*.o +**/*.d +***/.a +tags +test/got*.diff +test/verify.* +test/arraylist_test/arraylist_test +test/results_test/results_test diff --git a/LICENCE b/LICENCE new file mode 100644 index 000000000000..d908088b90fc --- /dev/null +++ b/LICENCE @@ -0,0 +1,13 @@ + Copyright (c) 2020 Neels Hofmeyr + + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/README b/README new file mode 100644 index 000000000000..4e99e6e3c2e2 --- /dev/null +++ b/README @@ -0,0 +1,26 @@ +This is a collection of diff algorithms, to test various combinations. + +The initial aim was to provide a faster diff implementation for got +(gameoftrees.org) with a BSD license, at the u2k20 OpenBSD hackathon. +A side effect could be improving OpenBSD's /usr/bin/diff utility. + +At the time of writing, this is little more than a playground / benchmark basis +/ diff algorithm analysis platform. What could be done: +- add profiling and test series to rate diff algorithm combinations. +- interface with / merge into got. + +The Myers and Patience Diff algorithm implementations found here are based on +the explanations found in these blog post series: + https://blog.jcoglan.com/2017/02/12/the-myers-diff-algorithm-part-1/ ff. +and + https://blog.jcoglan.com/2017/09/19/the-patience-diff-algorithm/ ff. +-- possibly the single most comprehensive explanations of these algorithms. +Many thanks for this valuable door opener! +The source code itself is not based on the code found in those blogs, but +written from scratch with the knowledge gained. + +Compile: + make -C diff + +Test: + make -C test/ diff --git a/compat/getprogname_linux.c b/compat/getprogname_linux.c new file mode 100644 index 000000000000..0957c6bc106b --- /dev/null +++ b/compat/getprogname_linux.c @@ -0,0 +1,8 @@ +#define _GNU_SOURCE +#include + +const char * +getprogname(void) +{ + return program_invocation_short_name; +} diff --git a/compat/include/stdlib.h b/compat/include/stdlib.h new file mode 100644 index 000000000000..75b18881a7b7 --- /dev/null +++ b/compat/include/stdlib.h @@ -0,0 +1,20 @@ +/* + * stdlib.h compatibility shim + * Public domain + */ + +#include_next + +#ifndef DIFFCOMPAT_STDLIB_H +#define DIFFCOMPAT_STDLIB_H + +#include +#include + +const char * getprogname(void); + +void *reallocarray(void *, size_t, size_t); +void *recallocarray(void *, size_t, size_t, size_t); +int mergesort(void *, size_t, size_t, int (*cmp)(const void *, const void *)); + +#endif diff --git a/compat/include/string.h b/compat/include/string.h new file mode 100644 index 000000000000..75190903aba8 --- /dev/null +++ b/compat/include/string.h @@ -0,0 +1,16 @@ +/* + * string.h compatibility shim + * Public domain + */ + +#include_next + +#ifndef DIFFCOMPAT_STRING_H +#define DIFFCOMPAT_STRING_H + +#include + +size_t strlcpy(char *dst, const char *src, size_t dstsize); +size_t strlcat(char *dst, const char *src, size_t dstsize); + +#endif diff --git a/compat/include/sys/types.h b/compat/include/sys/types.h new file mode 100644 index 000000000000..f580c7c593a8 --- /dev/null +++ b/compat/include/sys/types.h @@ -0,0 +1,15 @@ +/* + * Public domain + * sys/types.h compatibility shim + */ + +#include_next + +#ifndef DIFFCOMPAT_SYS_TYPES_H +#define DIFFCOMPAT_SYS_TYPES_H + +#if !defined(__dead) +#define __dead __attribute__((__noreturn__)) +#endif + +#endif diff --git a/compat/merge.c b/compat/merge.c new file mode 100644 index 000000000000..a5b0d88aa337 --- /dev/null +++ b/compat/merge.c @@ -0,0 +1,338 @@ +/* $OpenBSD: merge.c,v 1.10 2015/06/21 03:20:56 millert Exp $ */ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Peter McIlroy. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Hybrid exponential search/linear search merge sort with hybrid + * natural/pairwise first pass. Requires about .3% more comparisons + * for random data than LSMS with pairwise first pass alone. + * It works for objects as small as two bytes. + */ + +#define NATURAL +#define THRESHOLD 16 /* Best choice for natural merge cut-off. */ + +/* #define NATURAL to get hybrid natural merge. + * (The default is pairwise merging.) + */ + +#include + +#include +#include +#include + +static void setup(u_char *list1, u_char *list2, size_t n, size_t size, + int (*cmp)(const void *, const void *)); +static void insertionsort(u_char *a, size_t n, size_t size, + int (*cmp)(const void *, const void *)); + +#define ISIZE sizeof(int) +#define PSIZE sizeof(u_char *) +#define ICOPY_LIST(src, dst, last) \ + do \ + *(int*)dst = *(int*)src, src += ISIZE, dst += ISIZE; \ + while(src < last) +#define ICOPY_ELT(src, dst, i) \ + do \ + *(int*) dst = *(int*) src, src += ISIZE, dst += ISIZE; \ + while (i -= ISIZE) + +#define CCOPY_LIST(src, dst, last) \ + do \ + *dst++ = *src++; \ + while (src < last) +#define CCOPY_ELT(src, dst, i) \ + do \ + *dst++ = *src++; \ + while (i -= 1) + +/* + * Find the next possible pointer head. (Trickery for forcing an array + * to do double duty as a linked list when objects do not align with word + * boundaries. + */ +/* Assumption: PSIZE is a power of 2. */ +#define EVAL(p) (u_char **) \ + ((u_char *)0 + \ + (((u_char *)p + PSIZE - 1 - (u_char *) 0) & ~(PSIZE - 1))) + +/* + * Arguments are as for qsort. + */ +int +mergesort(void *base, size_t nmemb, size_t size, + int (*cmp)(const void *, const void *)) +{ + int i, sense; + int big, iflag; + u_char *f1, *f2, *t, *b, *tp2, *q, *l1, *l2; + u_char *list2, *list1, *p2, *p, *last, **p1; + + if (size < PSIZE / 2) { /* Pointers must fit into 2 * size. */ + errno = EINVAL; + return (-1); + } + + if (nmemb == 0) + return (0); + + /* + * XXX + * Stupid subtraction for the Cray. + */ + iflag = 0; + if (!(size % ISIZE) && !(((char *)base - (char *)0) % ISIZE)) + iflag = 1; + + if ((list2 = malloc(nmemb * size + PSIZE)) == NULL) + return (-1); + + list1 = base; + setup(list1, list2, nmemb, size, cmp); + last = list2 + nmemb * size; + i = big = 0; + while (*EVAL(list2) != last) { + l2 = list1; + p1 = EVAL(list1); + for (tp2 = p2 = list2; p2 != last; p1 = EVAL(l2)) { + p2 = *EVAL(p2); + f1 = l2; + f2 = l1 = list1 + (p2 - list2); + if (p2 != last) + p2 = *EVAL(p2); + l2 = list1 + (p2 - list2); + while (f1 < l1 && f2 < l2) { + if ((*cmp)(f1, f2) <= 0) { + q = f2; + b = f1, t = l1; + sense = -1; + } else { + q = f1; + b = f2, t = l2; + sense = 0; + } + if (!big) { /* here i = 0 */ + while ((b += size) < t && cmp(q, b) >sense) + if (++i == 6) { + big = 1; + goto EXPONENTIAL; + } + } else { +EXPONENTIAL: for (i = size; ; i <<= 1) + if ((p = (b + i)) >= t) { + if ((p = t - size) > b && + (*cmp)(q, p) <= sense) + t = p; + else + b = p; + break; + } else if ((*cmp)(q, p) <= sense) { + t = p; + if (i == size) + big = 0; + goto FASTCASE; + } else + b = p; + while (t > b+size) { + i = (((t - b) / size) >> 1) * size; + if ((*cmp)(q, p = b + i) <= sense) + t = p; + else + b = p; + } + goto COPY; +FASTCASE: while (i > size) + if ((*cmp)(q, + p = b + (i >>= 1)) <= sense) + t = p; + else + b = p; +COPY: b = t; + } + i = size; + if (q == f1) { + if (iflag) { + ICOPY_LIST(f2, tp2, b); + ICOPY_ELT(f1, tp2, i); + } else { + CCOPY_LIST(f2, tp2, b); + CCOPY_ELT(f1, tp2, i); + } + } else { + if (iflag) { + ICOPY_LIST(f1, tp2, b); + ICOPY_ELT(f2, tp2, i); + } else { + CCOPY_LIST(f1, tp2, b); + CCOPY_ELT(f2, tp2, i); + } + } + } + if (f2 < l2) { + if (iflag) + ICOPY_LIST(f2, tp2, l2); + else + CCOPY_LIST(f2, tp2, l2); + } else if (f1 < l1) { + if (iflag) + ICOPY_LIST(f1, tp2, l1); + else + CCOPY_LIST(f1, tp2, l1); + } + *p1 = l2; + } + tp2 = list1; /* swap list1, list2 */ + list1 = list2; + list2 = tp2; + last = list2 + nmemb*size; + } + if (base == list2) { + memmove(list2, list1, nmemb*size); + list2 = list1; + } + free(list2); + return (0); +} + +#define swap(a, b) { \ + s = b; \ + i = size; \ + do { \ + tmp = *a; *a++ = *s; *s++ = tmp; \ + } while (--i); \ + a -= size; \ + } +#define reverse(bot, top) { \ + s = top; \ + do { \ + i = size; \ + do { \ + tmp = *bot; *bot++ = *s; *s++ = tmp; \ + } while (--i); \ + s -= size2; \ + } while(bot < s); \ +} + +/* + * Optional hybrid natural/pairwise first pass. Eats up list1 in runs of + * increasing order, list2 in a corresponding linked list. Checks for runs + * when THRESHOLD/2 pairs compare with same sense. (Only used when NATURAL + * is defined. Otherwise simple pairwise merging is used.) + */ +void +setup(u_char *list1, u_char *list2, size_t n, size_t size, + int (*cmp)(const void *, const void *)) +{ + int i, length, size2, sense; + u_char tmp, *f1, *f2, *s, *l2, *last, *p2; + + size2 = size*2; + if (n <= 5) { + insertionsort(list1, n, size, cmp); + *EVAL(list2) = (u_char*) list2 + n*size; + return; + } + /* + * Avoid running pointers out of bounds; limit n to evens + * for simplicity. + */ + i = 4 + (n & 1); + insertionsort(list1 + (n - i) * size, i, size, cmp); + last = list1 + size * (n - i); + *EVAL(list2 + (last - list1)) = list2 + n * size; + +#ifdef NATURAL + p2 = list2; + f1 = list1; + sense = (cmp(f1, f1 + size) > 0); + for (; f1 < last; sense = !sense) { + length = 2; + /* Find pairs with same sense. */ + for (f2 = f1 + size2; f2 < last; f2 += size2) { + if ((cmp(f2, f2+ size) > 0) != sense) + break; + length += 2; + } + if (length < THRESHOLD) { /* Pairwise merge */ + do { + p2 = *EVAL(p2) = f1 + size2 - list1 + list2; + if (sense > 0) + swap (f1, f1 + size); + } while ((f1 += size2) < f2); + } else { /* Natural merge */ + l2 = f2; + for (f2 = f1 + size2; f2 < l2; f2 += size2) { + if ((cmp(f2-size, f2) > 0) != sense) { + p2 = *EVAL(p2) = f2 - list1 + list2; + if (sense > 0) + reverse(f1, f2-size); + f1 = f2; + } + } + if (sense > 0) + reverse (f1, f2-size); + f1 = f2; + if (f2 < last || cmp(f2 - size, f2) > 0) + p2 = *EVAL(p2) = f2 - list1 + list2; + else + p2 = *EVAL(p2) = list2 + n*size; + } + } +#else /* pairwise merge only. */ + for (f1 = list1, p2 = list2; f1 < last; f1 += size2) { + p2 = *EVAL(p2) = p2 + size2; + if (cmp (f1, f1 + size) > 0) + swap(f1, f1 + size); + } +#endif /* NATURAL */ +} + +/* + * This is to avoid out-of-bounds addresses in sorting the + * last 4 elements. + */ +static void +insertionsort(u_char *a, size_t n, size_t size, + int (*cmp)(const void *, const void *)) +{ + u_char *ai, *s, *t, *u, tmp; + int i; + + for (ai = a+size; --n >= 1; ai += size) + for (t = ai; t > a; t -= size) { + u = t - size; + if (cmp(u, t) <= 0) + break; + swap(u, t); + } +} diff --git a/compat/reallocarray.c b/compat/reallocarray.c new file mode 100644 index 000000000000..43f0b69158ac --- /dev/null +++ b/compat/reallocarray.c @@ -0,0 +1,38 @@ +/* $OpenBSD: reallocarray.c,v 1.3 2015/09/13 08:31:47 guenther Exp $ */ +/* + * Copyright (c) 2008 Otto Moerbeek + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +/* + * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX + * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW + */ +#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) + +void * +reallocarray(void *optr, size_t nmemb, size_t size) +{ + if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && + nmemb > 0 && SIZE_MAX / nmemb < size) { + errno = ENOMEM; + return NULL; + } + return realloc(optr, size * nmemb); +} diff --git a/compat/recallocarray.c b/compat/recallocarray.c new file mode 100644 index 000000000000..d93abd2da5fd --- /dev/null +++ b/compat/recallocarray.c @@ -0,0 +1,80 @@ +/* $OpenBSD: recallocarray.c,v 1.1 2017/03/06 18:44:21 otto Exp $ */ +/* + * Copyright (c) 2008, 2017 Otto Moerbeek + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +/* + * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX + * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW + */ +#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) + +void * +recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size) +{ + size_t oldsize, newsize; + void *newptr; + + if (ptr == NULL) + return calloc(newnmemb, size); + + if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && + newnmemb > 0 && SIZE_MAX / newnmemb < size) { + errno = ENOMEM; + return NULL; + } + newsize = newnmemb * size; + + if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && + oldnmemb > 0 && SIZE_MAX / oldnmemb < size) { + errno = EINVAL; + return NULL; + } + oldsize = oldnmemb * size; + + /* + * Don't bother too much if we're shrinking just a bit, + * we do not shrink for series of small steps, oh well. + */ + if (newsize <= oldsize) { + size_t d = oldsize - newsize; + + if (d < oldsize / 2 && d < getpagesize()) { + memset((char *)ptr + newsize, 0, d); + return ptr; + } + } + + newptr = malloc(newsize); + if (newptr == NULL) + return NULL; + + if (newsize > oldsize) { + memcpy(newptr, ptr, oldsize); + memset((char *)newptr + oldsize, 0, newsize - oldsize); + } else + memcpy(newptr, ptr, newsize); + + explicit_bzero(ptr, oldsize); + free(ptr); + + return newptr; +} diff --git a/compat/strlcat.c b/compat/strlcat.c new file mode 100644 index 000000000000..c94e90deeeeb --- /dev/null +++ b/compat/strlcat.c @@ -0,0 +1,55 @@ +/* $OpenBSD: strlcat.c,v 1.19 2019/01/25 00:19:25 millert Exp $ */ + +/* + * Copyright (c) 1998, 2015 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +/* + * Appends src to string dst of size dsize (unlike strncat, dsize is the + * full size of dst, not space left). At most dsize-1 characters + * will be copied. Always NUL terminates (unless dsize <= strlen(dst)). + * Returns strlen(src) + MIN(dsize, strlen(initial dst)). + * If retval >= dsize, truncation occurred. + */ +size_t +strlcat(char *dst, const char *src, size_t dsize) +{ + const char *odst = dst; + const char *osrc = src; + size_t n = dsize; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end. */ + while (n-- != 0 && *dst != '\0') + dst++; + dlen = dst - odst; + n = dsize - dlen; + + if (n-- == 0) + return(dlen + strlen(src)); + while (*src != '\0') { + if (n != 0) { + *dst++ = *src; + n--; + } + src++; + } + *dst = '\0'; + + return(dlen + (src - osrc)); /* count does not include NUL */ +} diff --git a/compat/strlcpy.c b/compat/strlcpy.c new file mode 100644 index 000000000000..2fa498c3978b --- /dev/null +++ b/compat/strlcpy.c @@ -0,0 +1,50 @@ +/* $OpenBSD: strlcpy.c,v 1.16 2019/01/25 00:19:25 millert Exp $ */ + +/* + * Copyright (c) 1998, 2015 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +/* + * Copy string src to buffer dst of size dsize. At most dsize-1 + * chars will be copied. Always NUL terminates (unless dsize == 0). + * Returns strlen(src); if retval >= dsize, truncation occurred. + */ +size_t +strlcpy(char *dst, const char *src, size_t dsize) +{ + const char *osrc = src; + size_t nleft = dsize; + + /* Copy as many bytes as will fit. */ + if (nleft != 0) { + while (--nleft != 0) { + if ((*dst++ = *src++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src. */ + if (nleft == 0) { + if (dsize != 0) + *dst = '\0'; /* NUL-terminate dst */ + while (*src++) + ; + } + + return(src - osrc - 1); /* count does not include NUL */ +} diff --git a/diff-version.mk b/diff-version.mk new file mode 100644 index 000000000000..1d14cd7ecfcc --- /dev/null +++ b/diff-version.mk @@ -0,0 +1,8 @@ +DIFF_RELEASE=No +DIFF_VERSION_NUMBER=0.1 + +.if ${DIFF_RELEASE} == Yes +DIFF_VERSION=${DIFF_VERSION_NUMBER} +.else +DIFF_VERSION=${DIFF_VERSION_NUMBER}-current +.endif diff --git a/diff/GNUmakefile b/diff/GNUmakefile new file mode 100644 index 000000000000..63d0b8795665 --- /dev/null +++ b/diff/GNUmakefile @@ -0,0 +1,19 @@ +CFLAGS = -fsanitize=address -fsanitize=undefined -g -O3 +CFLAGS += -Wstrict-prototypes -Wunused-variable -Wuninitialized + +SRCS= diff.c +LIB= ../lib/libdiff.a + +# Compat sources +CFLAGS+= -I$(CURDIR)/../compat/include + +diff: $(SRCS) $(LIB) + gcc $(CFLAGS) -I../include -o $@ $^ + +../lib/libdiff.a: ../lib/*.[hc] ../include/*.h + $(MAKE) -C ../lib + +.PHONY: clean +clean: + rm diff + $(MAKE) -C ../lib clean diff --git a/diff/Makefile b/diff/Makefile new file mode 100644 index 000000000000..4a7f3a9755f5 --- /dev/null +++ b/diff/Makefile @@ -0,0 +1,41 @@ +.PATH:${.CURDIR}/../lib + +.include "../diff-version.mk" + +PROG= diff +SRCS= \ + diff.c \ + diff_atomize_text.c \ + diff_main.c \ + diff_myers.c \ + diff_patience.c \ + diff_output.c \ + diff_output_plain.c \ + diff_output_unidiff.c \ + diff_output_edscript.c \ + ${END} +MAN = ${PROG}.1 + +CPPFLAGS = -I${.CURDIR}/../include -I${.CURDIR}/../lib +#CPPFLAGS += -DDIFF_NO_MMAP + +.if defined(PROFILE) +CFLAGS = -O0 -pg -g +LDFLAGS = -pg -lc_p -lutil_p -lz_p -static +.else +LDFLAGS = -lutil -lz +.endif + +.if ${DIFF_RELEASE} != "Yes" +NOMAN = Yes +.endif + +realinstall: + ${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} \ + -m ${BINMODE} ${PROG} ${BINDIR}/${PROG} + +dist: + mkdir ../diff-${DIFF_VERSION}/diff + cp ${SRCS} ${MAN} ../diff-${DIFF_VERSION}/diff + +.include diff --git a/diff/diff.c b/diff/diff.c new file mode 100644 index 000000000000..eded4163df8d --- /dev/null +++ b/diff/diff.c @@ -0,0 +1,280 @@ +/* Commandline diff utility to test diff implementations. */ +/* + * Copyright (c) 2018 Martin Pieuchot + * Copyright (c) 2020 Neels Hofmeyr + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +enum diffreg_algo { + DIFFREG_ALGO_MYERS_THEN_MYERS_DIVIDE = 0, + DIFFREG_ALGO_MYERS_THEN_PATIENCE = 1, + DIFFREG_ALGO_PATIENCE = 2, + DIFFREG_ALGO_NONE = 3, +}; + +__dead void usage(void); +int diffreg(char *, char *, enum diffreg_algo, bool, bool, bool, + int, bool); +FILE * openfile(const char *, char **, struct stat *); + +__dead void +usage(void) +{ + fprintf(stderr, + "usage: %s [-apPQTwe] [-U n] file1 file2\n" + "\n" + " -a Treat input as ASCII even if binary data is detected\n" + " -p Show function prototypes in hunk headers\n" + " -P Use Patience Diff (slower but often nicer)\n" + " -Q Use forward-Myers for small files, otherwise Patience\n" + " -T Trivial algo: detect similar start and end only\n" + " -w Ignore Whitespace\n" + " -U n Number of Context Lines\n" + " -e Produce ed script output\n" + , getprogname()); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + int ch, rc; + bool force_text = false; + bool ignore_whitespace = false; + bool show_function_prototypes = false; + bool edscript = false; + int context_lines = 3; + enum diffreg_algo algo = DIFFREG_ALGO_MYERS_THEN_MYERS_DIVIDE; + + while ((ch = getopt(argc, argv, "apPQTwU:e")) != -1) { + switch (ch) { + case 'a': + force_text = true; + break; + case 'p': + show_function_prototypes = true; + break; + case 'P': + algo = DIFFREG_ALGO_PATIENCE; + break; + case 'Q': + algo = DIFFREG_ALGO_MYERS_THEN_PATIENCE; + break; + case 'T': + algo = DIFFREG_ALGO_NONE; + break; + case 'w': + ignore_whitespace = true; + break; + case 'U': + context_lines = atoi(optarg); + break; + case 'e': + edscript = true; + break; + default: + usage(); + } + } + + argc -= optind; + argv += optind; + + if (argc != 2) + usage(); + + rc = diffreg(argv[0], argv[1], algo, force_text, ignore_whitespace, + show_function_prototypes, context_lines, edscript); + if (rc != DIFF_RC_OK) { + fprintf(stderr, "diff: %s\n", strerror(rc)); + return 1; + } + return 0; +} + +const struct diff_algo_config myers_then_patience; +const struct diff_algo_config myers_then_myers_divide; +const struct diff_algo_config patience; +const struct diff_algo_config myers_divide; + +const struct diff_algo_config myers_then_patience = (struct diff_algo_config){ + .impl = diff_algo_myers, + .permitted_state_size = 1024 * 1024 * sizeof(int), + .fallback_algo = &patience, +}; + +const struct diff_algo_config myers_then_myers_divide = + (struct diff_algo_config){ + .impl = diff_algo_myers, + .permitted_state_size = 1024 * 1024 * sizeof(int), + .fallback_algo = &myers_divide, +}; + +const struct diff_algo_config patience = (struct diff_algo_config){ + .impl = diff_algo_patience, + /* After subdivision, do Patience again: */ + .inner_algo = &patience, + /* If subdivision failed, do Myers Divide et Impera: */ + .fallback_algo = &myers_then_myers_divide, +}; + +const struct diff_algo_config myers_divide = (struct diff_algo_config){ + .impl = diff_algo_myers_divide, + /* When division succeeded, start from the top: */ + .inner_algo = &myers_then_myers_divide, + /* (fallback_algo = NULL implies diff_algo_none). */ +}; + +const struct diff_algo_config no_algo = (struct diff_algo_config){ + .impl = diff_algo_none, +}; + +/* If the state for a forward-Myers is small enough, use Myers, otherwise first + * do a Myers-divide. */ +const struct diff_config diff_config_myers_then_myers_divide = { + .atomize_func = diff_atomize_text_by_line, + .algo = &myers_then_myers_divide, +}; + +/* If the state for a forward-Myers is small enough, use Myers, otherwise first + * do a Patience. */ +const struct diff_config diff_config_myers_then_patience = { + .atomize_func = diff_atomize_text_by_line, + .algo = &myers_then_patience, +}; + +/* Directly force Patience as a first divider of the source file. */ +const struct diff_config diff_config_patience = { + .atomize_func = diff_atomize_text_by_line, + .algo = &patience, +}; + +/* Directly force Patience as a first divider of the source file. */ +const struct diff_config diff_config_no_algo = { + .atomize_func = diff_atomize_text_by_line, +}; + +int +diffreg(char *file1, char *file2, enum diffreg_algo algo, bool force_text, + bool ignore_whitespace, bool show_function_prototypes, int context_lines, + bool edscript) +{ + char *str1, *str2; + FILE *f1, *f2; + struct stat st1, st2; + struct diff_input_info info = { + .left_path = file1, + .right_path = file2, + }; + struct diff_data left = {}, right = {}; + struct diff_result *result = NULL; + int rc; + const struct diff_config *cfg; + int diff_flags = 0; + + switch (algo) { + default: + case DIFFREG_ALGO_MYERS_THEN_MYERS_DIVIDE: + cfg = &diff_config_myers_then_myers_divide; + break; + case DIFFREG_ALGO_MYERS_THEN_PATIENCE: + cfg = &diff_config_myers_then_patience; + break; + case DIFFREG_ALGO_PATIENCE: + cfg = &diff_config_patience; + break; + case DIFFREG_ALGO_NONE: + cfg = &diff_config_no_algo; + break; + } + + f1 = openfile(file1, &str1, &st1); + f2 = openfile(file2, &str2, &st2); + + if (force_text) + diff_flags |= DIFF_FLAG_FORCE_TEXT_DATA; + if (ignore_whitespace) + diff_flags |= DIFF_FLAG_IGNORE_WHITESPACE; + if (show_function_prototypes) + diff_flags |= DIFF_FLAG_SHOW_PROTOTYPES; + + rc = diff_atomize_file(&left, cfg, f1, str1, st1.st_size, diff_flags); + if (rc) + goto done; + rc = diff_atomize_file(&right, cfg, f2, str2, st2.st_size, diff_flags); + if (rc) + goto done; + + result = diff_main(cfg, &left, &right); +#if 0 + rc = diff_output_plain(stdout, &info, result); +#else + if (edscript) + rc = diff_output_edscript(NULL, stdout, &info, result); + else { + rc = diff_output_unidiff(NULL, stdout, &info, result, + context_lines); + } +#endif +done: + diff_result_free(result); + diff_data_free(&left); + diff_data_free(&right); + if (str1) + munmap(str1, st1.st_size); + if (str2) + munmap(str2, st2.st_size); + fclose(f1); + fclose(f2); + + return rc; +} + +FILE * +openfile(const char *path, char **p, struct stat *st) +{ + FILE *f = NULL; + + f = fopen(path, "r"); + if (f == NULL) + err(2, "%s", path); + + if (fstat(fileno(f), st) == -1) + err(2, "%s", path); + +#ifndef DIFF_NO_MMAP + *p = mmap(NULL, st->st_size, PROT_READ, MAP_PRIVATE, fileno(f), 0); + if (*p == MAP_FAILED) +#endif + *p = NULL; /* fall back on file I/O */ + + return f; +} diff --git a/include/arraylist.h b/include/arraylist.h new file mode 100644 index 000000000000..453b71cedd7f --- /dev/null +++ b/include/arraylist.h @@ -0,0 +1,121 @@ +/* Auto-reallocating array for arbitrary member types. */ +/* + * Copyright (c) 2020 Neels Hofmeyr + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* Usage: + * + * ARRAYLIST(any_type_t) list; + * // OR + * typedef ARRAYLIST(any_type_t) any_type_list_t; + * any_type_list_t list; + * + * // pass the number of (at first unused) members to add on each realloc: + * ARRAYLIST_INIT(list, 128); + * any_type_t *x; + * while (bar) { + * // This enlarges the allocated array as needed; + * // list.head may change due to realloc: + * ARRAYLIST_ADD(x, list); + * if (!x) + * return ENOMEM; + * *x = random_foo_value; + * } + * for (i = 0; i < list.len; i++) + * printf("%s", foo_to_str(list.head[i])); + * ARRAYLIST_FREE(list); + */ +#define ARRAYLIST(MEMBER_TYPE) \ + struct { \ + MEMBER_TYPE *head; \ + MEMBER_TYPE *p; \ + unsigned int len; \ + unsigned int allocated; \ + unsigned int alloc_blocksize; \ + } + +#define ARRAYLIST_INIT(ARRAY_LIST, ALLOC_BLOCKSIZE) do { \ + (ARRAY_LIST).head = NULL; \ + (ARRAY_LIST).len = 0; \ + (ARRAY_LIST).allocated = 0; \ + (ARRAY_LIST).alloc_blocksize = ALLOC_BLOCKSIZE; \ + } while(0) + +#define ARRAYLIST_ADD(NEW_ITEM_P, ARRAY_LIST) do { \ + if ((ARRAY_LIST).len && !(ARRAY_LIST).allocated) { \ + NEW_ITEM_P = NULL; \ + break; \ + } \ + if ((ARRAY_LIST).head == NULL \ + || (ARRAY_LIST).allocated < (ARRAY_LIST).len + 1) { \ + (ARRAY_LIST).p = recallocarray((ARRAY_LIST).head, \ + (ARRAY_LIST).len, \ + (ARRAY_LIST).allocated + \ + ((ARRAY_LIST).allocated ? \ + (ARRAY_LIST).allocated / 2 : \ + (ARRAY_LIST).alloc_blocksize ? \ + (ARRAY_LIST).alloc_blocksize : 8), \ + sizeof(*(ARRAY_LIST).head)); \ + if ((ARRAY_LIST).p == NULL) { \ + NEW_ITEM_P = NULL; \ + break; \ + } \ + (ARRAY_LIST).allocated += \ + (ARRAY_LIST).allocated ? \ + (ARRAY_LIST).allocated / 2 : \ + (ARRAY_LIST).alloc_blocksize ? \ + (ARRAY_LIST).alloc_blocksize : 8, \ + (ARRAY_LIST).head = (ARRAY_LIST).p; \ + (ARRAY_LIST).p = NULL; \ + }; \ + if ((ARRAY_LIST).head == NULL \ + || (ARRAY_LIST).allocated < (ARRAY_LIST).len + 1) { \ + NEW_ITEM_P = NULL; \ + break; \ + } \ + (NEW_ITEM_P) = &(ARRAY_LIST).head[(ARRAY_LIST).len]; \ + (ARRAY_LIST).len++; \ + } while (0) + +#define ARRAYLIST_INSERT(NEW_ITEM_P, ARRAY_LIST, AT_IDX) do { \ + int _at_idx = (AT_IDX); \ + ARRAYLIST_ADD(NEW_ITEM_P, ARRAY_LIST); \ + if ((NEW_ITEM_P) \ + && _at_idx >= 0 \ + && _at_idx < (ARRAY_LIST).len) { \ + memmove(&(ARRAY_LIST).head[_at_idx + 1], \ + &(ARRAY_LIST).head[_at_idx], \ + ((ARRAY_LIST).len - 1 - _at_idx) \ + * sizeof(*(ARRAY_LIST).head)); \ + (NEW_ITEM_P) = &(ARRAY_LIST).head[_at_idx]; \ + }; \ + } while (0) + +#define ARRAYLIST_CLEAR(ARRAY_LIST) \ + (ARRAY_LIST).len = 0 + +#define ARRAYLIST_FREE(ARRAY_LIST) \ + do { \ + if ((ARRAY_LIST).head && (ARRAY_LIST).allocated) \ + free((ARRAY_LIST).head); \ + ARRAYLIST_INIT(ARRAY_LIST, (ARRAY_LIST).alloc_blocksize); \ + } while(0) + +#define ARRAYLIST_FOREACH(ITEM_P, ARRAY_LIST) \ + for ((ITEM_P) = (ARRAY_LIST).head; \ + (ITEM_P) - (ARRAY_LIST).head < (ARRAY_LIST).len; \ + (ITEM_P)++) + +#define ARRAYLIST_IDX(ITEM_P, ARRAY_LIST) ((ITEM_P) - (ARRAY_LIST).head) diff --git a/include/diff_main.h b/include/diff_main.h new file mode 100644 index 000000000000..04a6c6e748c9 --- /dev/null +++ b/include/diff_main.h @@ -0,0 +1,264 @@ +/* Generic infrastructure to implement various diff algorithms. */ +/* + * Copyright (c) 2020 Neels Hofmeyr + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +struct diff_range { + int start; + int end; +}; + +/* List of all possible return codes of a diff invocation. */ +#define DIFF_RC_USE_DIFF_ALGO_FALLBACK -1 +#define DIFF_RC_OK 0 +/* Any positive return values are errno values from sys/errno.h */ + +struct diff_atom { + struct diff_data *root; /* back pointer to root diff data */ + + off_t pos; /* set whether memory-mapped or not */ + const uint8_t *at; /* only set if memory-mapped */ + off_t len; + + /* This hash is just a very cheap speed up for finding *mismatching* + * atoms. When hashes match, we still need to compare entire atoms to + * find out whether they are indeed identical or not. + * Calculated over all atom bytes with diff_atom_hash_update(). */ + unsigned int hash; +}; + +/* Mix another atom_byte into the provided hash value and return the result. + * The hash value passed in for the first byte of the atom must be zero. */ +unsigned int +diff_atom_hash_update(unsigned int hash, unsigned char atom_byte); + +/* Compare two atoms for equality. Return 0 on success, or errno on failure. + * Set cmp to -1, 0, or 1, just like strcmp(). */ +int +diff_atom_cmp(int *cmp, + const struct diff_atom *left, + const struct diff_atom *right); + + +/* The atom's index in the entire file. For atoms divided by lines of text, this + * yields the line number (starting with 0). Also works for diff_data that + * reference only a subsection of a file, always reflecting the global position + * in the file (and not the relative position within the subsection). */ +#define diff_atom_root_idx(DIFF_DATA, ATOM) \ + ((ATOM) && ((ATOM) >= (DIFF_DATA)->root->atoms.head) \ + ? (unsigned int)((ATOM) - ((DIFF_DATA)->root->atoms.head)) \ + : (DIFF_DATA)->root->atoms.len) + +/* The atom's index within DIFF_DATA. For atoms divided by lines of text, this + * yields the line number (starting with 0). */ +#define diff_atom_idx(DIFF_DATA, ATOM) \ + ((ATOM) && ((ATOM) >= (DIFF_DATA)->atoms.head) \ + ? (unsigned int)((ATOM) - ((DIFF_DATA)->atoms.head)) \ + : (DIFF_DATA)->atoms.len) + +#define foreach_diff_atom(ATOM, FIRST_ATOM, COUNT) \ + for ((ATOM) = (FIRST_ATOM); \ + (ATOM) \ + && ((ATOM) >= (FIRST_ATOM)) \ + && ((ATOM) - (FIRST_ATOM) < (COUNT)); \ + (ATOM)++) + +#define diff_data_foreach_atom(ATOM, DIFF_DATA) \ + foreach_diff_atom(ATOM, (DIFF_DATA)->atoms.head, (DIFF_DATA)->atoms.len) + +#define diff_data_foreach_atom_from(FROM, ATOM, DIFF_DATA) \ + for ((ATOM) = (FROM); \ + (ATOM) \ + && ((ATOM) >= (DIFF_DATA)->atoms.head) \ + && ((ATOM) - (DIFF_DATA)->atoms.head < (DIFF_DATA)->atoms.len); \ + (ATOM)++) + +#define diff_data_foreach_atom_backwards_from(FROM, ATOM, DIFF_DATA) \ + for ((ATOM) = (FROM); \ + (ATOM) \ + && ((ATOM) >= (DIFF_DATA)->atoms.head) \ + && ((ATOM) - (DIFF_DATA)->atoms.head >= 0); \ + (ATOM)--) + +/* For each file, there is a "root" struct diff_data referencing the entire + * file, which the atoms are parsed from. In recursion of diff algorithm, there + * may be "child" struct diff_data only referencing a subsection of the file, + * re-using the atoms parsing. For "root" structs, atoms_allocated will be + * nonzero, indicating that the array of atoms is owned by that struct. For + * "child" structs, atoms_allocated == 0, to indicate that the struct is + * referencing a subset of atoms. */ +struct diff_data { + FILE *f; /* if root diff_data and not memory-mapped */ + off_t pos; /* if not memory-mapped */ + const uint8_t *data; /* if memory-mapped */ + off_t len; + + int atomizer_flags; + ARRAYLIST(struct diff_atom) atoms; + struct diff_data *root; + struct diff_data *current; + void *algo_data; + + int diff_flags; + + int err; +}; + +/* Flags set by file atomizer. */ +#define DIFF_ATOMIZER_FOUND_BINARY_DATA 0x00000001 + +/* Flags set by caller of diff_main(). */ +#define DIFF_FLAG_IGNORE_WHITESPACE 0x00000001 +#define DIFF_FLAG_SHOW_PROTOTYPES 0x00000002 +#define DIFF_FLAG_FORCE_TEXT_DATA 0x00000004 + +void diff_data_free(struct diff_data *diff_data); + +struct diff_chunk; +typedef ARRAYLIST(struct diff_chunk) diff_chunk_arraylist_t; + +struct diff_result { + int rc; + + /* + * Pointers to diff data passed in via diff_main. + * Do not free these diff_data before freeing the diff_result struct. + */ + struct diff_data *left; + struct diff_data *right; + + diff_chunk_arraylist_t chunks; +}; + +enum diff_chunk_type { + CHUNK_EMPTY, + CHUNK_PLUS, + CHUNK_MINUS, + CHUNK_SAME, + CHUNK_ERROR, +}; + +enum diff_chunk_type diff_chunk_type(const struct diff_chunk *c); + +struct diff_state; + +/* Signature of a utility function to divide a file into diff atoms. + * An example is diff_atomize_text_by_line() in diff_atomize_text.c. + * + * func_data: context pointer (free to be used by implementation). + * d: struct diff_data with d->data and d->len already set up, and + * d->atoms to be created and d->atomizer_flags to be set up. + */ +typedef int (*diff_atomize_func_t)(void *func_data, struct diff_data *d); + +extern int diff_atomize_text_by_line(void *func_data, struct diff_data *d); + +struct diff_algo_config; +typedef int (*diff_algo_impl_t)( + const struct diff_algo_config *algo_config, struct diff_state *state); + +/* Form a result with all left-side removed and all right-side added, i.e. no + * actual diff algorithm involved. */ +int diff_algo_none(const struct diff_algo_config *algo_config, + struct diff_state *state); + +/* Myers Diff tracing from the start all the way through to the end, requiring + * quadratic amounts of memory. This can fail if the required space surpasses + * algo_config->permitted_state_size. */ +extern int diff_algo_myers(const struct diff_algo_config *algo_config, + struct diff_state *state); + +/* Myers "Divide et Impera": tracing forwards from the start and backwards from + * the end to find a midpoint that divides the problem into smaller chunks. + * Requires only linear amounts of memory. */ +extern int diff_algo_myers_divide( + const struct diff_algo_config *algo_config, struct diff_state *state); + +/* Patience Diff algorithm, which divides a larger diff into smaller chunks. For + * very specific scenarios, it may lead to a complete diff result by itself, but + * needs a fallback algo to solve chunks that don't have common-unique atoms. */ +extern int diff_algo_patience( + const struct diff_algo_config *algo_config, struct diff_state *state); + +/* Diff algorithms to use, possibly nested. For example: + * + * struct diff_algo_config myers, patience, myers_divide; + * + * myers = (struct diff_algo_config){ + * .impl = diff_algo_myers, + * .permitted_state_size = 32 * 1024 * 1024, + * // When too large, do diff_algo_patience: + * .fallback_algo = &patience, + * }; + * + * const struct diff_algo_config patience = (struct diff_algo_config){ + * .impl = diff_algo_patience, + * // After subdivision, do Patience again: + * .inner_algo = &patience, + * // If subdivision failed, do Myers Divide et Impera: + * .fallback_algo = &myers_then_myers_divide, + * }; + * + * const struct diff_algo_config myers_divide = (struct diff_algo_config){ + * .impl = diff_algo_myers_divide, + * // When division succeeded, start from the top: + * .inner_algo = &myers_then_myers_divide, + * // (fallback_algo = NULL implies diff_algo_none). + * }; + * struct diff_config config = { + * .algo = &myers, + * ... + * }; + * diff_main(&config, ...); + */ +struct diff_algo_config { + diff_algo_impl_t impl; + + /* Fail this algo if it would use more than this amount of memory, and + * instead use fallback_algo (diff_algo_myers). permitted_state_size == + * 0 means no limitation. */ + size_t permitted_state_size; + + /* For algorithms that divide into smaller chunks, use this algorithm to + * solve the divided chunks. */ + const struct diff_algo_config *inner_algo; + + /* If the algorithm fails (e.g. diff_algo_myers_if_small needs too large + * state, or diff_algo_patience can't find any common-unique atoms), + * then use this algorithm instead. */ + const struct diff_algo_config *fallback_algo; +}; + +struct diff_config { + diff_atomize_func_t atomize_func; + void *atomize_func_data; + + const struct diff_algo_config *algo; + + /* How deep to step into subdivisions of a source file, a paranoia / + * safety measure to guard against infinite loops through diff + * algorithms. When the maximum recursion is reached, employ + * diff_algo_none (i.e. remove all left atoms and add all right atoms). + */ + unsigned int max_recursion_depth; +}; + +int diff_atomize_file(struct diff_data *d, const struct diff_config *config, + FILE *f, const uint8_t *data, off_t len, int diff_flags); +struct diff_result *diff_main(const struct diff_config *config, + struct diff_data *left, + struct diff_data *right); +void diff_result_free(struct diff_result *result); +int diff_result_contains_printable_chunks(struct diff_result *result); diff --git a/include/diff_output.h b/include/diff_output.h new file mode 100644 index 000000000000..d2568c5a2b50 --- /dev/null +++ b/include/diff_output.h @@ -0,0 +1,112 @@ +/* Diff output generators and invocation shims. */ +/* + * Copyright (c) 2020 Neels Hofmeyr + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +struct diff_input_info { + const char *left_path; + const char *right_path; + + /* Set by caller of diff_output_* functions. */ + int flags; +#define DIFF_INPUT_LEFT_NONEXISTENT 0x00000001 +#define DIFF_INPUT_RIGHT_NONEXISTENT 0x00000002 +}; + +struct diff_output_info { + /* + * Byte offset to each line in the generated output file. + * The total number of lines in the file is line_offsets.len - 1. + * The last offset in this array corresponds to end-of-file. + */ + ARRAYLIST(off_t) line_offsets; + /* + * Type (i.e., context, minus, plus) of each line generated by the diff. + * nb. 0x00 to 0x3b reserved for client-defined line types. + */ + ARRAYLIST(uint8_t) line_types; +#define DIFF_LINE_HUNK 0x3c +#define DIFF_LINE_MINUS 0x3d +#define DIFF_LINE_PLUS 0x3e +#define DIFF_LINE_CONTEXT 0x3f +#define DIFF_LINE_NONE 0x40 /* binary or no EOF newline msg, etc. */ +}; + +void diff_output_info_free(struct diff_output_info *output_info); + +struct diff_chunk_context { + struct diff_range chunk; + struct diff_range left, right; +}; + +int diff_output_plain(struct diff_output_info **output_info, FILE *dest, + const struct diff_input_info *info, + const struct diff_result *result, + int hunk_headers_only); +int diff_output_unidiff(struct diff_output_info **output_info, + FILE *dest, const struct diff_input_info *info, + const struct diff_result *result, + unsigned int context_lines); +int diff_output_edscript(struct diff_output_info **output_info, + FILE *dest, const struct diff_input_info *info, + const struct diff_result *result); +int diff_chunk_get_left_start(const struct diff_chunk *c, + const struct diff_result *r, + int context_lines); +int diff_chunk_get_left_end(const struct diff_chunk *c, + const struct diff_result *r, + int context_lines); +int diff_chunk_get_right_start(const struct diff_chunk *c, + const struct diff_result *r, + int context_lines); +int diff_chunk_get_right_end(const struct diff_chunk *c, + const struct diff_result *r, + int context_lines); +off_t diff_chunk_get_left_start_pos(const struct diff_chunk *c); +off_t diff_chunk_get_right_start_pos(const struct diff_chunk *c); +struct diff_chunk *diff_chunk_get(const struct diff_result *r, int chunk_idx); +int diff_chunk_get_left_count(struct diff_chunk *c); +int diff_chunk_get_right_count(struct diff_chunk *c); +void diff_chunk_context_get(struct diff_chunk_context *cc, + const struct diff_result *r, + int chunk_idx, int context_lines); +void diff_chunk_context_load_change(struct diff_chunk_context *cc, + int *nchunks_used, + struct diff_result *result, + int start_chunk_idx, + int context_lines); + +struct diff_output_unidiff_state; +struct diff_output_unidiff_state *diff_output_unidiff_state_alloc(void); +void diff_output_unidiff_state_reset(struct diff_output_unidiff_state *state); +void diff_output_unidiff_state_free(struct diff_output_unidiff_state *state); +int diff_output_unidiff_chunk(struct diff_output_info **output_info, FILE *dest, + struct diff_output_unidiff_state *state, + const struct diff_input_info *info, + const struct diff_result *result, + const struct diff_chunk_context *cc); +int diff_output_chunk_left_version(struct diff_output_info **output_info, + FILE *dest, + const struct diff_input_info *info, + const struct diff_result *result, + const struct diff_chunk_context *cc); +int diff_output_chunk_right_version(struct diff_output_info **output_info, + FILE *dest, + const struct diff_input_info *info, + const struct diff_result *result, + const struct diff_chunk_context *cc); + +const char *diff_output_get_label_left(const struct diff_input_info *info); +const char *diff_output_get_label_right(const struct diff_input_info *info); diff --git a/lib/GNUmakefile b/lib/GNUmakefile new file mode 100644 index 000000000000..cb35f757e09d --- /dev/null +++ b/lib/GNUmakefile @@ -0,0 +1,32 @@ +SRCS = \ + diff_atomize_text.c \ + diff_main.c \ + diff_myers.c \ + diff_patience.c \ + diff_output.c \ + diff_output_plain.c \ + diff_output_unidiff.c \ + diff_output_edscript.c \ + $(END) + +# Compat sources +VPATH= $(CURDIR)/../compat +SRCS+= getprogname_linux.c reallocarray.c recallocarray.c merge.c \ + strlcat.c +CFLAGS+= -I$(CURDIR)/../compat/include + +OBJS = $(SRCS:.c=.o) + +libdiff.a: $(OBJS) + ar rcs $@ $^ + +CFLAGS += -fsanitize=address -fsanitize=undefined -g -O3 +CFLAGS += -Wstrict-prototypes -Wunused-variable -Wuninitialized + +%.o: %.c ./*.h ../include/*.h + gcc $(CFLAGS) -I../include -o $@ -c $< + +.PHONY: clean +clean: + -rm $(OBJS) + -rm libdiff.a diff --git a/lib/diff_atomize_text.c b/lib/diff_atomize_text.c new file mode 100644 index 000000000000..32023105af94 --- /dev/null +++ b/lib/diff_atomize_text.c @@ -0,0 +1,197 @@ +/* Split source by line breaks, and calculate a simplistic checksum. */ +/* + * Copyright (c) 2020 Neels Hofmeyr + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "diff_internal.h" +#include "diff_debug.h" + +unsigned int +diff_atom_hash_update(unsigned int hash, unsigned char atom_byte) +{ + return hash * 23 + atom_byte; +} + +static int +diff_data_atomize_text_lines_fd(struct diff_data *d) +{ + off_t pos = 0; + const off_t end = pos + d->len; + unsigned int array_size_estimate = d->len / 50; + unsigned int pow2 = 1; + bool ignore_whitespace = (d->diff_flags & DIFF_FLAG_IGNORE_WHITESPACE); + bool embedded_nul = false; + + while (array_size_estimate >>= 1) + pow2++; + + ARRAYLIST_INIT(d->atoms, 1 << pow2); + + if (fseek(d->root->f, 0L, SEEK_SET) == -1) + return errno; + + while (pos < end) { + off_t line_end = pos; + unsigned int hash = 0; + unsigned char buf[512]; + size_t r, i; + struct diff_atom *atom; + int eol = 0; + + while (eol == 0 && line_end < end) { + r = fread(buf, sizeof(char), sizeof(buf), d->root->f); + if (r == 0 && ferror(d->root->f)) + return EIO; + i = 0; + while (eol == 0 && i < r) { + if (buf[i] != '\r' && buf[i] != '\n') { + if (!ignore_whitespace + || !isspace((unsigned char)buf[i])) + hash = diff_atom_hash_update( + hash, buf[i]); + if (buf[i] == '\0') + embedded_nul = true; + line_end++; + } else + eol = buf[i]; + i++; + } + } + + /* When not at the end of data, the line ending char ('\r' or + * '\n') must follow */ + if (line_end < end) + line_end++; + /* If that was an '\r', also pull in any following '\n' */ + if (line_end < end && eol == '\r') { + if (fseeko(d->root->f, line_end, SEEK_SET) == -1) + return errno; + r = fread(buf, sizeof(char), sizeof(buf), d->root->f); + if (r == 0 && ferror(d->root->f)) + return EIO; + if (r > 0 && buf[0] == '\n') + line_end++; + } + + /* Record the found line as diff atom */ + ARRAYLIST_ADD(atom, d->atoms); + if (!atom) + return ENOMEM; + + *atom = (struct diff_atom){ + .root = d, + .pos = pos, + .at = NULL, /* atom data is not memory-mapped */ + .len = line_end - pos, + .hash = hash, + }; + + /* Starting point for next line: */ + pos = line_end; + if (fseeko(d->root->f, pos, SEEK_SET) == -1) + return errno; + } + + /* File are considered binary if they contain embedded '\0' bytes. */ + if (embedded_nul) + d->atomizer_flags |= DIFF_ATOMIZER_FOUND_BINARY_DATA; + + return DIFF_RC_OK; +} + +static int +diff_data_atomize_text_lines_mmap(struct diff_data *d) +{ + const uint8_t *pos = d->data; + const uint8_t *end = pos + d->len; + bool ignore_whitespace = (d->diff_flags & DIFF_FLAG_IGNORE_WHITESPACE); + bool embedded_nul = false; + unsigned int array_size_estimate = d->len / 50; + unsigned int pow2 = 1; + while (array_size_estimate >>= 1) + pow2++; + + ARRAYLIST_INIT(d->atoms, 1 << pow2); + + while (pos < end) { + const uint8_t *line_end = pos; + unsigned int hash = 0; + + while (line_end < end && *line_end != '\r' && *line_end != '\n') { + if (!ignore_whitespace + || !isspace((unsigned char)*line_end)) + hash = diff_atom_hash_update(hash, *line_end); + if (*line_end == '\0') + embedded_nul = true; + line_end++; + } + + /* When not at the end of data, the line ending char ('\r' or + * '\n') must follow */ + if (line_end < end && *line_end == '\r') + line_end++; + if (line_end < end && *line_end == '\n') + line_end++; + + /* Record the found line as diff atom */ + struct diff_atom *atom; + ARRAYLIST_ADD(atom, d->atoms); + if (!atom) + return ENOMEM; + + *atom = (struct diff_atom){ + .root = d, + .pos = (off_t)(pos - d->data), + .at = pos, + .len = line_end - pos, + .hash = hash, + }; + + /* Starting point for next line: */ + pos = line_end; + } + + /* File are considered binary if they contain embedded '\0' bytes. */ + if (embedded_nul) + d->atomizer_flags |= DIFF_ATOMIZER_FOUND_BINARY_DATA; + + return DIFF_RC_OK; +} + +static int +diff_data_atomize_text_lines(struct diff_data *d) +{ + if (d->data == NULL) + return diff_data_atomize_text_lines_fd(d); + else + return diff_data_atomize_text_lines_mmap(d); +} + +int +diff_atomize_text_by_line(void *func_data, struct diff_data *d) +{ + return diff_data_atomize_text_lines(d); +} diff --git a/lib/diff_debug.h b/lib/diff_debug.h new file mode 100644 index 000000000000..4b7ec8090638 --- /dev/null +++ b/lib/diff_debug.h @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2020 Neels Hofmeyr + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define DEBUG 0 + +#if DEBUG +#include +#include +#define print(args...) fprintf(stderr, ##args) +#define debug print +#define debug_dump dump +#define debug_dump_atom dump_atom +#define debug_dump_atoms dump_atoms + +static inline void +print_atom_byte(unsigned char c) { + if (c == '\r') + print("\\r"); + else if (c == '\n') + print("\\n"); + else if ((c < 32 || c >= 127) && (c != '\t')) + print("\\x%02x", c); + else + print("%c", c); +} + +static inline void +dump_atom(const struct diff_data *left, const struct diff_data *right, + const struct diff_atom *atom) +{ + if (!atom) { + print("NULL atom\n"); + return; + } + if (left) + print(" %3u '", diff_atom_root_idx(left, atom)); + + if (atom->at == NULL) { + off_t remain = atom->len; + if (fseek(atom->root->f, atom->pos, SEEK_SET) == -1) + abort(); /* cannot return error */ + while (remain > 0) { + char buf[16]; + size_t r; + int i; + r = fread(buf, 1, MIN(remain, sizeof(buf)), + atom->root->f); + if (r == 0) + break; + remain -= r; + for (i = 0; i < r; i++) + print_atom_byte(buf[i]); + } + } else { + const char *s; + for (s = atom->at; s < (const char*)(atom->at + atom->len); s++) + print_atom_byte(*s); + } + print("'\n"); +} + +static inline void +dump_atoms(const struct diff_data *d, struct diff_atom *atom, + unsigned int count) +{ + if (count > 42) { + dump_atoms(d, atom, 20); + print("[%u lines skipped]\n", count - 20 - 20); + dump_atoms(d, atom + count - 20, 20); + return; + } else { + struct diff_atom *i; + foreach_diff_atom(i, atom, count) { + dump_atom(d, NULL, i); + } + } +} + +static inline void +dump(struct diff_data *d) +{ + dump_atoms(d, d->atoms.head, d->atoms.len); +} + +/* kd is a quadratic space myers matrix from the original Myers algorithm. + * kd_forward and kd_backward are linear slices of a myers matrix from the Myers + * Divide algorithm. + */ +static inline void +dump_myers_graph(const struct diff_data *l, const struct diff_data *r, + int *kd, int *kd_forward, int kd_forward_d, + int *kd_backward, int kd_backward_d) +{ + #define COLOR_YELLOW "\033[1;33m" + #define COLOR_GREEN "\033[1;32m" + #define COLOR_BLUE "\033[1;34m" + #define COLOR_RED "\033[1;31m" + #define COLOR_END "\033[0;m" + int x; + int y; + print(" "); + for (x = 0; x <= l->atoms.len; x++) + print("%2d", x % 100); + print("\n"); + + for (y = 0; y <= r->atoms.len; y++) { + print("%3d ", y); + for (x = 0; x <= l->atoms.len; x++) { + + /* print d advancements from kd, if any. */ + char label = 'o'; + char *color = NULL; + if (kd) { + int max = l->atoms.len + r->atoms.len; + size_t kd_len = max + 1 + max; + int *kd_pos = kd; + int di; +#define xk_to_y(X, K) ((X) - (K)) + for (di = 0; di < max; di++) { + int ki; + for (ki = di; ki >= -di; ki -= 2) { + if (x != kd_pos[ki] + || y != xk_to_y(x, ki)) + continue; + label = '0' + (di % 10); + color = COLOR_YELLOW; + break; + } + if (label != 'o') + break; + kd_pos += kd_len; + } + } + if (kd_forward && kd_forward_d >= 0) { +#define xc_to_y(X, C, DELTA) ((X) - (C) + (DELTA)) + int ki; + for (ki = kd_forward_d; + ki >= -kd_forward_d; + ki -= 2) { + if (x != kd_forward[ki]) + continue; + if (y != xk_to_y(x, ki)) + continue; + label = 'F'; + color = COLOR_GREEN; + break; + } + } + if (kd_backward && kd_backward_d >= 0) { + int delta = (int)r->atoms.len + - (int)l->atoms.len; + int ki; + for (ki = kd_backward_d; + ki >= -kd_backward_d; + ki -= 2) { + if (x != kd_backward[ki]) + continue; + if (y != xc_to_y(x, ki, delta)) + continue; + if (label == 'o') { + label = 'B'; + color = COLOR_BLUE; + } else { + label = 'X'; + color = COLOR_RED; + } + break; + } + } + if (color) + print("%s", color); + print("%c", label); + if (color) + print("%s", COLOR_END); + if (x < l->atoms.len) + print("-"); + } + print("\n"); + if (y == r->atoms.len) + break; + + print(" "); + for (x = 0; x < l->atoms.len; x++) { + bool same; + diff_atom_same(&same, &l->atoms.head[x], + &r->atoms.head[y]); + if (same) + print("|\\"); + else + print("| "); + } + print("|\n"); + } +} + +static inline void +debug_dump_myers_graph(const struct diff_data *l, const struct diff_data *r, + int *kd, int *kd_forward, int kd_forward_d, + int *kd_backward, int kd_backward_d) +{ + if (l->atoms.len > 99 || r->atoms.len > 99) + return; + dump_myers_graph(l, r, kd, kd_forward, kd_forward_d, + kd_backward, kd_backward_d); +} + +#else +#define debug(args...) +#define debug_dump(args...) +#define debug_dump_atom(args...) +#define debug_dump_atoms(args...) +#define debug_dump_myers_graph(args...) +#endif diff --git a/lib/diff_internal.h b/lib/diff_internal.h new file mode 100644 index 000000000000..46bbadf3cb64 --- /dev/null +++ b/lib/diff_internal.h @@ -0,0 +1,157 @@ +/* Generic infrastructure to implement various diff algorithms. */ +/* + * Copyright (c) 2020 Neels Hofmeyr + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MAX +#define MAX(A,B) ((A)>(B)?(A):(B)) +#endif +#ifndef MIN +#define MIN(A,B) ((A)<(B)?(A):(B)) +#endif + +static inline bool +diff_range_empty(const struct diff_range *r) +{ + return r->start == r->end; +} + +static inline bool +diff_ranges_touch(const struct diff_range *a, const struct diff_range *b) +{ + return (a->end >= b->start) && (a->start <= b->end); +} + +static inline void +diff_ranges_merge(struct diff_range *a, const struct diff_range *b) +{ + *a = (struct diff_range){ + .start = MIN(a->start, b->start), + .end = MAX(a->end, b->end), + }; +} + +static inline int +diff_range_len(const struct diff_range *r) +{ + if (!r) + return 0; + return r->end - r->start; +} + +/* Indicate whether two given diff atoms match. */ +int +diff_atom_same(bool *same, + const struct diff_atom *left, + const struct diff_atom *right); + +/* A diff chunk represents a set of atoms on the left and/or a set of atoms on + * the right. + * + * If solved == false: + * The diff algorithm has divided the source file, and this is a chunk that the + * inner_algo should run on next. + * The lines on the left should be diffed against the lines on the right. + * (If there are no left lines or no right lines, it implies solved == true, + * because there is nothing to diff.) + * + * If solved == true: + * If there are only left atoms, it is a chunk removing atoms from the left ("a + * minus chunk"). + * If there are only right atoms, it is a chunk adding atoms from the right ("a + * plus chunk"). + * If there are both left and right lines, it is a chunk of equal content on + * both sides, and left_count == right_count: + * + * - foo } + * - bar }-- diff_chunk{ left_start = &left.atoms.head[0], left_count = 3, + * - baz } right_start = NULL, right_count = 0 } + * moo } + * goo }-- diff_chunk{ left_start = &left.atoms.head[3], left_count = 3, + * zoo } right_start = &right.atoms.head[0], right_count = 3 } + * +loo } + * +roo }-- diff_chunk{ left_start = NULL, left_count = 0, + * +too } right_start = &right.atoms.head[3], right_count = 3 } + * + */ +struct diff_chunk { + bool solved; + struct diff_atom *left_start; + unsigned int left_count; + struct diff_atom *right_start; + unsigned int right_count; +}; + +#define DIFF_RESULT_ALLOC_BLOCKSIZE 128 + +struct diff_chunk_context; + +bool +diff_chunk_context_empty(const struct diff_chunk_context *cc); + +bool +diff_chunk_contexts_touch(const struct diff_chunk_context *cc, + const struct diff_chunk_context *other); + +void +diff_chunk_contexts_merge(struct diff_chunk_context *cc, + const struct diff_chunk_context *other); + +struct diff_state { + /* The final result passed to the original diff caller. */ + struct diff_result *result; + + /* The root diff_data is in result->left,right, these are (possibly) + * subsections of the root data. */ + struct diff_data left; + struct diff_data right; + + unsigned int recursion_depth_left; + + /* Remaining chunks from one diff algorithm pass, if any solved == false + * chunks came up. */ + diff_chunk_arraylist_t temp_result; + + /* State buffer used by Myers algorithm. */ + int *kd_buf; + size_t kd_buf_size; /* in units of sizeof(int), not bytes */ +}; + +struct diff_chunk *diff_state_add_chunk(struct diff_state *state, bool solved, + struct diff_atom *left_start, + unsigned int left_count, + struct diff_atom *right_start, + unsigned int right_count); + +struct diff_output_info; + +int diff_output_lines(struct diff_output_info *output_info, FILE *dest, + const char *prefix, struct diff_atom *start_atom, + unsigned int count); + +int diff_output_trailing_newline_msg(struct diff_output_info *outinfo, + FILE *dest, + const struct diff_chunk *c); +#define DIFF_FUNCTION_CONTEXT_SIZE 55 +int diff_output_match_function_prototype(char *prototype, size_t prototype_size, + int *last_prototype_idx, + const struct diff_result *result, + const struct diff_chunk_context *cc); + +struct diff_output_info *diff_output_info_alloc(void); + +void +diff_data_init_subsection(struct diff_data *d, struct diff_data *parent, + struct diff_atom *from_atom, unsigned int atoms_count); diff --git a/lib/diff_main.c b/lib/diff_main.c new file mode 100644 index 000000000000..e64b1320e553 --- /dev/null +++ b/lib/diff_main.c @@ -0,0 +1,663 @@ +/* Generic infrastructure to implement various diff algorithms (implementation). */ +/* + * Copyright (c) 2020 Neels Hofmeyr + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "diff_internal.h" +#include "diff_debug.h" + +inline enum diff_chunk_type +diff_chunk_type(const struct diff_chunk *chunk) +{ + if (!chunk->left_count && !chunk->right_count) + return CHUNK_EMPTY; + if (!chunk->solved) + return CHUNK_ERROR; + if (!chunk->right_count) + return CHUNK_MINUS; + if (!chunk->left_count) + return CHUNK_PLUS; + if (chunk->left_count != chunk->right_count) + return CHUNK_ERROR; + return CHUNK_SAME; +} + +static int +read_at(FILE *f, off_t at_pos, unsigned char *buf, size_t len) +{ + int r; + if (fseeko(f, at_pos, SEEK_SET) == -1) + return errno; + r = fread(buf, sizeof(char), len, f); + if ((r == 0 || r < len) && ferror(f)) + return EIO; + if (r != len) + return EIO; + return 0; +} + +static int +buf_cmp(const unsigned char *left, size_t left_len, + const unsigned char *right, size_t right_len, + bool ignore_whitespace) +{ + int cmp; + + if (ignore_whitespace) { + int il = 0, ir = 0; + while (il < left_len && ir < right_len) { + unsigned char cl = left[il]; + unsigned char cr = right[ir]; + + if (isspace((unsigned char)cl) && il < left_len) { + il++; + continue; + } + if (isspace((unsigned char)cr) && ir < right_len) { + ir++; + continue; + } + + if (cl > cr) + return 1; + if (cr > cl) + return -1; + il++; + ir++; + } + while (il < left_len) { + unsigned char cl = left[il++]; + if (!isspace((unsigned char)cl)) + return 1; + } + while (ir < right_len) { + unsigned char cr = right[ir++]; + if (!isspace((unsigned char)cr)) + return -1; + } + + return 0; + } + + cmp = memcmp(left, right, MIN(left_len, right_len)); + if (cmp) + return cmp; + if (left_len == right_len) + return 0; + return (left_len > right_len) ? 1 : -1; +} + +int +diff_atom_cmp(int *cmp, + const struct diff_atom *left, + const struct diff_atom *right) +{ + off_t remain_left, remain_right; + int flags = (left->root->diff_flags | right->root->diff_flags); + bool ignore_whitespace = (flags & DIFF_FLAG_IGNORE_WHITESPACE); + + if (!left->len && !right->len) { + *cmp = 0; + return 0; + } + if (!ignore_whitespace) { + if (!right->len) { + *cmp = 1; + return 0; + } + if (!left->len) { + *cmp = -1; + return 0; + } + } + + if (left->at != NULL && right->at != NULL) { + *cmp = buf_cmp(left->at, left->len, right->at, right->len, + ignore_whitespace); + return 0; + } + + remain_left = left->len; + remain_right = right->len; + while (remain_left > 0 || remain_right > 0) { + const size_t chunksz = 8192; + unsigned char buf_left[chunksz], buf_right[chunksz]; + const uint8_t *p_left, *p_right; + off_t n_left, n_right; + ssize_t r; + + if (!remain_right) { + *cmp = 1; + return 0; + } + if (!remain_left) { + *cmp = -1; + return 0; + } + + n_left = MIN(chunksz, remain_left); + n_right = MIN(chunksz, remain_right); + + if (left->at == NULL) { + r = read_at(left->root->f, + left->pos + (left->len - remain_left), + buf_left, n_left); + if (r) { + *cmp = 0; + return r; + } + p_left = buf_left; + } else { + p_left = left->at + (left->len - remain_left); + } + + if (right->at == NULL) { + r = read_at(right->root->f, + right->pos + (right->len - remain_right), + buf_right, n_right); + if (r) { + *cmp = 0; + return r; + } + p_right = buf_right; + } else { + p_right = right->at + (right->len - remain_right); + } + + r = buf_cmp(p_left, n_left, p_right, n_right, + ignore_whitespace); + if (r) { + *cmp = r; + return 0; + } + + remain_left -= n_left; + remain_right -= n_right; + } + + *cmp = 0; + return 0; +} + +int +diff_atom_same(bool *same, + const struct diff_atom *left, + const struct diff_atom *right) +{ + int cmp; + int r; + if (left->hash != right->hash) { + *same = false; + return 0; + } + r = diff_atom_cmp(&cmp, left, right); + if (r) { + *same = true; + return r; + } + *same = (cmp == 0); + return 0; +} + +static struct diff_chunk * +diff_state_add_solved_chunk(struct diff_state *state, + const struct diff_chunk *chunk) +{ + diff_chunk_arraylist_t *result; + struct diff_chunk *new_chunk; + enum diff_chunk_type last_t; + enum diff_chunk_type new_t; + struct diff_chunk *last; + + /* Append to solved chunks; make sure that adjacent chunks of same type are combined, and that a minus chunk + * never directly follows a plus chunk. */ + result = &state->result->chunks; + + last_t = result->len ? diff_chunk_type(&result->head[result->len - 1]) + : CHUNK_EMPTY; + new_t = diff_chunk_type(chunk); + + debug("ADD %s chunk #%u:\n", chunk->solved ? "solved" : "UNSOLVED", + result->len); + debug("L\n"); + debug_dump_atoms(&state->left, chunk->left_start, chunk->left_count); + debug("R\n"); + debug_dump_atoms(&state->right, chunk->right_start, chunk->right_count); + + if (result->len) { + last = &result->head[result->len - 1]; + assert(chunk->left_start + == last->left_start + last->left_count); + assert(chunk->right_start + == last->right_start + last->right_count); + } + + if (new_t == last_t) { + new_chunk = &result->head[result->len - 1]; + new_chunk->left_count += chunk->left_count; + new_chunk->right_count += chunk->right_count; + debug(" - added chunk touches previous one of same type, joined:\n"); + debug("L\n"); + debug_dump_atoms(&state->left, new_chunk->left_start, new_chunk->left_count); + debug("R\n"); + debug_dump_atoms(&state->right, new_chunk->right_start, new_chunk->right_count); + } else if (last_t == CHUNK_PLUS && new_t == CHUNK_MINUS) { + enum diff_chunk_type prev_last_t = + result->len > 1 ? + diff_chunk_type(&result->head[result->len - 2]) + : CHUNK_EMPTY; + /* If a minus-chunk follows a plus-chunk, place it above the plus-chunk-> + * Is the one before that also a minus? combine. */ + if (prev_last_t == CHUNK_MINUS) { + new_chunk = &result->head[result->len - 2]; + new_chunk->left_count += chunk->left_count; + new_chunk->right_count += chunk->right_count; + + debug(" - added minus-chunk follows plus-chunk," + " put before that plus-chunk and joined" + " with preceding minus-chunk:\n"); + debug("L\n"); + debug_dump_atoms(&state->left, new_chunk->left_start, new_chunk->left_count); + debug("R\n"); + debug_dump_atoms(&state->right, new_chunk->right_start, new_chunk->right_count); + } else { + ARRAYLIST_INSERT(new_chunk, *result, result->len - 1); + if (!new_chunk) + return NULL; + *new_chunk = *chunk; + + /* The new minus chunk indicates to which position on + * the right it corresponds, even though it doesn't add + * any lines on the right. By moving above a plus chunk, + * that position on the right has shifted. */ + last = &result->head[result->len - 1]; + new_chunk->right_start = last->right_start; + + debug(" - added minus-chunk follows plus-chunk," + " put before that plus-chunk\n"); + } + + /* That last_t == CHUNK_PLUS indicates to which position on the + * left it corresponds, even though it doesn't add any lines on + * the left. By inserting/extending the prev_last_t == + * CHUNK_MINUS, that position on the left has shifted. */ + last = &result->head[result->len - 1]; + last->left_start = new_chunk->left_start + + new_chunk->left_count; + + } else { + ARRAYLIST_ADD(new_chunk, *result); + if (!new_chunk) + return NULL; + *new_chunk = *chunk; + } + return new_chunk; +} + +/* Even if a left or right side is empty, diff output may need to know the + * position in that file. + * So left_start or right_start must never be NULL -- pass left_count or + * right_count as zero to indicate staying at that position without consuming + * any lines. */ +struct diff_chunk * +diff_state_add_chunk(struct diff_state *state, bool solved, + struct diff_atom *left_start, unsigned int left_count, + struct diff_atom *right_start, unsigned int right_count) +{ + struct diff_chunk *new_chunk; + struct diff_chunk chunk = { + .solved = solved, + .left_start = left_start, + .left_count = left_count, + .right_start = right_start, + .right_count = right_count, + }; + + /* An unsolved chunk means store as intermediate result for later + * re-iteration. + * If there already are intermediate results, that means even a + * following solved chunk needs to go to intermediate results, so that + * it is later put in the final correct position in solved chunks. + */ + if (!solved || state->temp_result.len) { + /* Append to temp_result */ + debug("ADD %s chunk to temp result:\n", + chunk.solved ? "solved" : "UNSOLVED"); + debug("L\n"); + debug_dump_atoms(&state->left, left_start, left_count); + debug("R\n"); + debug_dump_atoms(&state->right, right_start, right_count); + ARRAYLIST_ADD(new_chunk, state->temp_result); + if (!new_chunk) + return NULL; + *new_chunk = chunk; + return new_chunk; + } + + return diff_state_add_solved_chunk(state, &chunk); +} + +static void +diff_data_init_root(struct diff_data *d, FILE *f, const uint8_t *data, + unsigned long long len, int diff_flags) +{ + *d = (struct diff_data){ + .f = f, + .pos = 0, + .data = data, + .len = len, + .root = d, + .diff_flags = diff_flags, + }; +} + +void +diff_data_init_subsection(struct diff_data *d, struct diff_data *parent, + struct diff_atom *from_atom, unsigned int atoms_count) +{ + struct diff_atom *last_atom; + + debug("diff_data %p parent %p from_atom %p atoms_count %u\n", + d, parent, from_atom, atoms_count); + debug(" from_atom "); + debug_dump_atom(parent, NULL, from_atom); + + if (atoms_count == 0) { + *d = (struct diff_data){ + .f = NULL, + .pos = 0, + .data = NULL, + .len = 0, + .root = parent->root, + .atoms.head = NULL, + .atoms.len = atoms_count, + }; + + return; + } + + last_atom = from_atom + atoms_count - 1; + *d = (struct diff_data){ + .f = NULL, + .pos = from_atom->pos, + .data = from_atom->at, + .len = (last_atom->pos + last_atom->len) - from_atom->pos, + .root = parent->root, + .atoms.head = from_atom, + .atoms.len = atoms_count, + }; + + debug("subsection:\n"); + debug_dump(d); +} + +void +diff_data_free(struct diff_data *diff_data) +{ + if (!diff_data) + return; + if (diff_data->atoms.allocated) + ARRAYLIST_FREE(diff_data->atoms); +} + +int +diff_algo_none(const struct diff_algo_config *algo_config, + struct diff_state *state) +{ + debug("\n** %s\n", __func__); + debug("left:\n"); + debug_dump(&state->left); + debug("right:\n"); + debug_dump(&state->right); + debug_dump_myers_graph(&state->left, &state->right, NULL, NULL, 0, NULL, + 0); + + /* Add a chunk of equal lines, if any */ + struct diff_atom *l = state->left.atoms.head; + unsigned int l_len = state->left.atoms.len; + struct diff_atom *r = state->right.atoms.head; + unsigned int r_len = state->right.atoms.len; + unsigned int equal_atoms_start = 0; + unsigned int equal_atoms_end = 0; + unsigned int l_idx = 0; + unsigned int r_idx = 0; + + while (equal_atoms_start < l_len + && equal_atoms_start < r_len) { + int err; + bool same; + err = diff_atom_same(&same, &l[equal_atoms_start], + &r[equal_atoms_start]); + if (err) + return err; + if (!same) + break; + equal_atoms_start++; + } + while (equal_atoms_end < (l_len - equal_atoms_start) + && equal_atoms_end < (r_len - equal_atoms_start)) { + int err; + bool same; + err = diff_atom_same(&same, &l[l_len - 1 - equal_atoms_end], + &r[r_len - 1 - equal_atoms_end]); + if (err) + return err; + if (!same) + break; + equal_atoms_end++; + } + + /* Add a chunk of equal lines at the start */ + if (equal_atoms_start) { + if (!diff_state_add_chunk(state, true, + l, equal_atoms_start, + r, equal_atoms_start)) + return ENOMEM; + l_idx += equal_atoms_start; + r_idx += equal_atoms_start; + } + + /* Add a "minus" chunk with all lines from the left. */ + if (equal_atoms_start + equal_atoms_end < l_len) { + unsigned int add_len = l_len - equal_atoms_start - equal_atoms_end; + if (!diff_state_add_chunk(state, true, + &l[l_idx], add_len, + &r[r_idx], 0)) + return ENOMEM; + l_idx += add_len; + } + + /* Add a "plus" chunk with all lines from the right. */ + if (equal_atoms_start + equal_atoms_end < r_len) { + unsigned int add_len = r_len - equal_atoms_start - equal_atoms_end; + if (!diff_state_add_chunk(state, true, + &l[l_idx], 0, + &r[r_idx], add_len)) + return ENOMEM; + r_idx += add_len; + } + + /* Add a chunk of equal lines at the end */ + if (equal_atoms_end) { + if (!diff_state_add_chunk(state, true, + &l[l_idx], equal_atoms_end, + &r[r_idx], equal_atoms_end)) + return ENOMEM; + } + + return DIFF_RC_OK; +} + +static int +diff_run_algo(const struct diff_algo_config *algo_config, + struct diff_state *state) +{ + int rc; + + if (!algo_config || !algo_config->impl + || !state->recursion_depth_left + || !state->left.atoms.len || !state->right.atoms.len) { + debug("Fall back to diff_algo_none():%s%s%s\n", + (!algo_config || !algo_config->impl) ? " no-cfg" : "", + (!state->recursion_depth_left) ? " max-depth" : "", + (!state->left.atoms.len || !state->right.atoms.len)? + " trivial" : ""); + return diff_algo_none(algo_config, state); + } + + ARRAYLIST_FREE(state->temp_result); + ARRAYLIST_INIT(state->temp_result, DIFF_RESULT_ALLOC_BLOCKSIZE); + rc = algo_config->impl(algo_config, state); + switch (rc) { + case DIFF_RC_USE_DIFF_ALGO_FALLBACK: + debug("Got DIFF_RC_USE_DIFF_ALGO_FALLBACK (%p)\n", + algo_config->fallback_algo); + rc = diff_run_algo(algo_config->fallback_algo, state); + goto return_rc; + + case DIFF_RC_OK: + /* continue below */ + break; + + default: + /* some error happened */ + goto return_rc; + } + + /* Pick up any diff chunks that are still unsolved and feed to + * inner_algo. inner_algo will solve unsolved chunks and append to + * result, and subsequent solved chunks on this level are then appended + * to result afterwards. */ + int i; + for (i = 0; i < state->temp_result.len; i++) { + struct diff_chunk *c = &state->temp_result.head[i]; + if (c->solved) { + diff_state_add_solved_chunk(state, c); + continue; + } + + /* c is an unsolved chunk, feed to inner_algo */ + struct diff_state inner_state = { + .result = state->result, + .recursion_depth_left = state->recursion_depth_left - 1, + .kd_buf = state->kd_buf, + .kd_buf_size = state->kd_buf_size, + }; + diff_data_init_subsection(&inner_state.left, &state->left, + c->left_start, c->left_count); + diff_data_init_subsection(&inner_state.right, &state->right, + c->right_start, c->right_count); + + rc = diff_run_algo(algo_config->inner_algo, &inner_state); + state->kd_buf = inner_state.kd_buf; + state->kd_buf_size = inner_state.kd_buf_size; + if (rc != DIFF_RC_OK) + goto return_rc; + } + + rc = DIFF_RC_OK; +return_rc: + ARRAYLIST_FREE(state->temp_result); + return rc; +} + +int +diff_atomize_file(struct diff_data *d, + const struct diff_config *config, + FILE *f, const uint8_t *data, off_t len, int diff_flags) +{ + if (!config->atomize_func) + return EINVAL; + + diff_data_init_root(d, f, data, len, diff_flags); + + return config->atomize_func(config->atomize_func_data, d); + +} + +struct diff_result * +diff_main(const struct diff_config *config, struct diff_data *left, + struct diff_data *right) +{ + struct diff_result *result = malloc(sizeof(struct diff_result)); + if (!result) + return NULL; + + *result = (struct diff_result){}; + result->left = left; + result->right = right; + + struct diff_state state = { + .result = result, + .recursion_depth_left = config->max_recursion_depth ? + config->max_recursion_depth : UINT_MAX, + .kd_buf = NULL, + .kd_buf_size = 0, + }; + diff_data_init_subsection(&state.left, left, + left->atoms.head, + left->atoms.len); + diff_data_init_subsection(&state.right, right, + right->atoms.head, + right->atoms.len); + + result->rc = diff_run_algo(config->algo, &state); + free(state.kd_buf); + + return result; +} + +void +diff_result_free(struct diff_result *result) +{ + if (!result) + return; + ARRAYLIST_FREE(result->chunks); + free(result); +} + +int +diff_result_contains_printable_chunks(struct diff_result *result) +{ + struct diff_chunk *c; + enum diff_chunk_type t; + int i; + + for (i = 0; i < result->chunks.len; i++) { + c = &result->chunks.head[i]; + t = diff_chunk_type(c); + if (t == CHUNK_MINUS || t == CHUNK_PLUS) + return 1; + } + + return 0; +} diff --git a/lib/diff_myers.c b/lib/diff_myers.c new file mode 100644 index 000000000000..c886d1a28586 --- /dev/null +++ b/lib/diff_myers.c @@ -0,0 +1,1425 @@ +/* Myers diff algorithm implementation, invented by Eugene W. Myers [1]. + * Implementations of both the Myers Divide Et Impera (using linear space) + * and the canonical Myers algorithm (using quadratic space). */ +/* + * Copyright (c) 2020 Neels Hofmeyr + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "diff_internal.h" +#include "diff_debug.h" + +/* Myers' diff algorithm [1] is nicely explained in [2]. + * [1] http://www.xmailserver.org/diff2.pdf + * [2] https://blog.jcoglan.com/2017/02/12/the-myers-diff-algorithm-part-1/ ff. + * + * Myers approaches finding the smallest diff as a graph problem. + * The crux is that the original algorithm requires quadratic amount of memory: + * both sides' lengths added, and that squared. So if we're diffing lines of + * text, two files with 1000 lines each would blow up to a matrix of about + * 2000 * 2000 ints of state, about 16 Mb of RAM to figure out 2 kb of text. + * The solution is using Myers' "divide and conquer" extension algorithm, which + * does the original traversal from both ends of the files to reach a middle + * where these "snakes" touch, hence does not need to backtrace the traversal, + * and so gets away with only keeping a single column of that huge state matrix + * in memory. + */ + +struct diff_box { + unsigned int left_start; + unsigned int left_end; + unsigned int right_start; + unsigned int right_end; +}; + +/* If the two contents of a file are A B C D E and X B C Y, + * the Myers diff graph looks like: + * + * k0 k1 + * \ \ + * k-1 0 1 2 3 4 5 + * \ A B C D E + * 0 o-o-o-o-o-o + * X | | | | | | + * 1 o-o-o-o-o-o + * B | |\| | | | + * 2 o-o-o-o-o-o + * C | | |\| | | + * 3 o-o-o-o-o-o + * Y | | | | | |\ + * 4 o-o-o-o-o-o c1 + * \ \ + * c-1 c0 + * + * Moving right means delete an atom from the left-hand-side, + * Moving down means add an atom from the right-hand-side. + * Diagonals indicate identical atoms on both sides, the challenge is to use as + * many diagonals as possible. + * + * The original Myers algorithm walks all the way from the top left to the + * bottom right, remembers all steps, and then backtraces to find the shortest + * path. However, that requires keeping the entire graph in memory, which needs + * quadratic space. + * + * Myers adds a variant that uses linear space -- note, not linear time, only + * linear space: walk forward and backward, find a meeting point in the middle, + * and recurse on the two separate sections. This is called "divide and + * conquer". + * + * d: the step number, starting with 0, a.k.a. the distance from the starting + * point. + * k: relative index in the state array for the forward scan, indicating on + * which diagonal through the diff graph we currently are. + * c: relative index in the state array for the backward scan, indicating the + * diagonal number from the bottom up. + * + * The "divide and conquer" traversal through the Myers graph looks like this: + * + * | d= 0 1 2 3 2 1 0 + * ----+-------------------------------------------- + * k= | c= + * 4 | 3 + * | + * 3 | 3,0 5,2 2 + * | / \ + * 2 | 2,0 5,3 1 + * | / \ + * 1 | 1,0 4,3 >= 4,3 5,4<-- 0 + * | / / \ / + * 0 | -->0,0 3,3 4,4 -1 + * | \ / / + * -1 | 0,1 1,2 3,4 -2 + * | \ / + * -2 | 0,2 -3 + * | \ + * | 0,3 + * | forward-> <-backward + * + * x,y pairs here are the coordinates in the Myers graph: + * x = atom index in left-side source, y = atom index in the right-side source. + * + * Only one forward column and one backward column are kept in mem, each need at + * most left.len + 1 + right.len items. Note that each d step occupies either + * the even or the odd items of a column: if e.g. the previous column is in the + * odd items, the next column is formed in the even items, without overwriting + * the previous column's results. + * + * Also note that from the diagonal index k and the x coordinate, the y + * coordinate can be derived: + * y = x - k + * Hence the state array only needs to keep the x coordinate, i.e. the position + * in the left-hand file, and the y coordinate, i.e. position in the right-hand + * file, is derived from the index in the state array. + * + * The two traces meet at 4,3, the first step (here found in the forward + * traversal) where a forward position is on or past a backward traced position + * on the same diagonal. + * + * This divides the problem space into: + * + * 0 1 2 3 4 5 + * A B C D E + * 0 o-o-o-o-o + * X | | | | | + * 1 o-o-o-o-o + * B | |\| | | + * 2 o-o-o-o-o + * C | | |\| | + * 3 o-o-o-o-*-o *: forward and backward meet here + * Y | | + * 4 o-o + * + * Doing the same on each section lead to: + * + * 0 1 2 3 4 5 + * A B C D E + * 0 o-o + * X | | + * 1 o-b b: backward d=1 first reaches here (sliding up the snake) + * B \ f: then forward d=2 reaches here (sliding down the snake) + * 2 o As result, the box from b to f is found to be identical; + * C \ leaving a top box from 0,0 to 1,1 and a bottom trivial + * 3 f-o tail 3,3 to 4,3. + * + * 3 o-* + * Y | + * 4 o *: forward and backward meet here + * + * and solving the last top left box gives: + * + * 0 1 2 3 4 5 + * A B C D E -A + * 0 o-o +X + * X | B + * 1 o C + * B \ -D + * 2 o -E + * C \ +Y + * 3 o-o-o + * Y | + * 4 o + * + */ + +#define xk_to_y(X, K) ((X) - (K)) +#define xc_to_y(X, C, DELTA) ((X) - (C) + (DELTA)) +#define k_to_c(K, DELTA) ((K) + (DELTA)) +#define c_to_k(C, DELTA) ((C) - (DELTA)) + +/* Do one forwards step in the "divide and conquer" graph traversal. + * left: the left side to diff. + * right: the right side to diff against. + * kd_forward: the traversal state for forwards traversal, modified by this + * function. + * This is carried over between invocations with increasing d. + * kd_forward points at the center of the state array, allowing + * negative indexes. + * kd_backward: the traversal state for backwards traversal, to find a meeting + * point. + * Since forwards is done first, kd_backward will be valid for d - + * 1, not d. + * kd_backward points at the center of the state array, allowing + * negative indexes. + * d: Step or distance counter, indicating for what value of d the kd_forward + * should be populated. + * For d == 0, kd_forward[0] is initialized, i.e. the first invocation should + * be for d == 0. + * meeting_snake: resulting meeting point, if any. + * Return true when a meeting point has been identified. + */ +static int +diff_divide_myers_forward(bool *found_midpoint, + struct diff_data *left, struct diff_data *right, + int *kd_forward, int *kd_backward, int d, + struct diff_box *meeting_snake) +{ + int delta = (int)right->atoms.len - (int)left->atoms.len; + int k; + int x; + int prev_x; + int prev_y; + int x_before_slide; + *found_midpoint = false; + + for (k = d; k >= -d; k -= 2) { + if (k < -(int)right->atoms.len || k > (int)left->atoms.len) { + /* This diagonal is completely outside of the Myers + * graph, don't calculate it. */ + if (k < 0) { + /* We are traversing negatively, and already + * below the entire graph, nothing will come of + * this. */ + debug(" break\n"); + break; + } + debug(" continue\n"); + continue; + } + if (d == 0) { + /* This is the initializing step. There is no prev_k + * yet, get the initial x from the top left of the Myers + * graph. */ + x = 0; + prev_x = x; + prev_y = xk_to_y(x, k); + } + /* Favoring "-" lines first means favoring moving rightwards in + * the Myers graph. + * For this, all k should derive from k - 1, only the bottom + * most k derive from k + 1: + * + * | d= 0 1 2 + * ----+---------------- + * k= | + * 2 | 2,0 <-- from prev_k = 2 - 1 = 1 + * | / + * 1 | 1,0 + * | / + * 0 | -->0,0 3,3 + * | \\ / + * -1 | 0,1 <-- bottom most for d=1 from + * | \\ prev_k = -1 + 1 = 0 + * -2 | 0,2 <-- bottom most for d=2 from + * prev_k = -2 + 1 = -1 + * + * Except when a k + 1 from a previous run already means a + * further advancement in the graph. + * If k == d, there is no k + 1 and k - 1 is the only option. + * If k < d, use k + 1 in case that yields a larger x. Also use + * k + 1 if k - 1 is outside the graph. + */ + else if (k > -d + && (k == d + || (k - 1 >= -(int)right->atoms.len + && kd_forward[k - 1] >= kd_forward[k + 1]))) { + /* Advance from k - 1. + * From position prev_k, step to the right in the Myers + * graph: x += 1. + */ + int prev_k = k - 1; + prev_x = kd_forward[prev_k]; + prev_y = xk_to_y(prev_x, prev_k); + x = prev_x + 1; + } else { + /* The bottom most one. + * From position prev_k, step to the bottom in the Myers + * graph: y += 1. + * Incrementing y is achieved by decrementing k while + * keeping the same x. + * (since we're deriving y from y = x - k). + */ + int prev_k = k + 1; + prev_x = kd_forward[prev_k]; + prev_y = xk_to_y(prev_x, prev_k); + x = prev_x; + } + + x_before_slide = x; + /* Slide down any snake that we might find here. */ + while (x < left->atoms.len && xk_to_y(x, k) < right->atoms.len) { + bool same; + int r = diff_atom_same(&same, + &left->atoms.head[x], + &right->atoms.head[ + xk_to_y(x, k)]); + if (r) + return r; + if (!same) + break; + x++; + } + kd_forward[k] = x; +#if 0 + if (x_before_slide != x) { + debug(" down %d similar lines\n", x - x_before_slide); + } + +#if DEBUG + { + int fi; + for (fi = d; fi >= k; fi--) { + debug("kd_forward[%d] = (%d, %d)\n", fi, + kd_forward[fi], kd_forward[fi] - fi); + } + } +#endif +#endif + + if (x < 0 || x > left->atoms.len + || xk_to_y(x, k) < 0 || xk_to_y(x, k) > right->atoms.len) + continue; + + /* Figured out a new forwards traversal, see if this has gone + * onto or even past a preceding backwards traversal. + * + * If the delta in length is odd, then d and backwards_d hit the + * same state indexes: + * | d= 0 1 2 1 0 + * ----+---------------- ---------------- + * k= | c= + * 4 | 3 + * | + * 3 | 2 + * | same + * 2 | 2,0====5,3 1 + * | / \ + * 1 | 1,0 5,4<-- 0 + * | / / + * 0 | -->0,0 3,3====4,4 -1 + * | \ / + * -1 | 0,1 -2 + * | \ + * -2 | 0,2 -3 + * | + * + * If the delta is even, they end up off-by-one, i.e. on + * different diagonals: + * + * | d= 0 1 2 1 0 + * ----+---------------- ---------------- + * | c= + * 3 | 3 + * | + * 2 | 2,0 off 2 + * | / \\ + * 1 | 1,0 4,3 1 + * | / // \ + * 0 | -->0,0 3,3 4,4<-- 0 + * | \ / / + * -1 | 0,1 3,4 -1 + * | \ // + * -2 | 0,2 -2 + * | + * + * So in the forward path, we can only match up diagonals when + * the delta is odd. + */ + if ((delta & 1) == 0) + continue; + /* Forwards is done first, so the backwards one was still at + * d - 1. Can't do this for d == 0. */ + int backwards_d = d - 1; + if (backwards_d < 0) + continue; + + /* If both sides have the same length, forward and backward + * start on the same diagonal, meaning the backwards state index + * c == k. + * As soon as the lengths are not the same, the backwards + * traversal starts on a different diagonal, and c = k shifted + * by the difference in length. + */ + int c = k_to_c(k, delta); + + /* When the file sizes are very different, the traversal trees + * start on far distant diagonals. + * They don't necessarily meet straight on. See whether this + * forward value is on a diagonal that is also valid in + * kd_backward[], and match them if so. */ + if (c >= -backwards_d && c <= backwards_d) { + /* Current k is on a diagonal that exists in + * kd_backward[]. If the two x positions have met or + * passed (forward walked onto or past backward), then + * we've found a midpoint / a mid-box. + * + * When forwards and backwards traversals meet, the + * endpoints of the mid-snake are not the two points in + * kd_forward and kd_backward, but rather the section + * that was slid (if any) of the current + * forward/backward traversal only. + * + * For example: + * + * o + * \ + * o + * \ + * o + * \ + * o + * \ + * X o o + * | | | + * o-o-o o + * \| + * M + * \ + * o + * \ + * A o + * | | + * o-o-o + * + * The forward traversal reached M from the top and slid + * downwards to A. The backward traversal already + * reached X, which is not a straight line from M + * anymore, so picking a mid-snake from M to X would + * yield a mistake. + * + * The correct mid-snake is between M and A. M is where + * the forward traversal hit the diagonal that the + * backward traversal has already passed, and A is what + * it reaches when sliding down identical lines. + */ + int backward_x = kd_backward[c]; + if (x >= backward_x) { + if (x_before_slide != x) { + /* met after sliding up a mid-snake */ + *meeting_snake = (struct diff_box){ + .left_start = x_before_slide, + .left_end = x, + .right_start = xc_to_y(x_before_slide, + c, delta), + .right_end = xk_to_y(x, k), + }; + } else { + /* met after a side step, non-identical + * line. Mark that as box divider + * instead. This makes sure that + * myers_divide never returns the same + * box that came as input, avoiding + * "infinite" looping. */ + *meeting_snake = (struct diff_box){ + .left_start = prev_x, + .left_end = x, + .right_start = prev_y, + .right_end = xk_to_y(x, k), + }; + } + debug("HIT x=(%u,%u) - y=(%u,%u)\n", + meeting_snake->left_start, + meeting_snake->right_start, + meeting_snake->left_end, + meeting_snake->right_end); + debug_dump_myers_graph(left, right, NULL, + kd_forward, d, + kd_backward, d-1); + *found_midpoint = true; + return 0; + } + } + } + + return 0; +} + +/* Do one backwards step in the "divide and conquer" graph traversal. + * left: the left side to diff. + * right: the right side to diff against. + * kd_forward: the traversal state for forwards traversal, to find a meeting + * point. + * Since forwards is done first, after this, both kd_forward and + * kd_backward will be valid for d. + * kd_forward points at the center of the state array, allowing + * negative indexes. + * kd_backward: the traversal state for backwards traversal, to find a meeting + * point. + * This is carried over between invocations with increasing d. + * kd_backward points at the center of the state array, allowing + * negative indexes. + * d: Step or distance counter, indicating for what value of d the kd_backward + * should be populated. + * Before the first invocation, kd_backward[0] shall point at the bottom + * right of the Myers graph (left.len, right.len). + * The first invocation will be for d == 1. + * meeting_snake: resulting meeting point, if any. + * Return true when a meeting point has been identified. + */ +static int +diff_divide_myers_backward(bool *found_midpoint, + struct diff_data *left, struct diff_data *right, + int *kd_forward, int *kd_backward, int d, + struct diff_box *meeting_snake) +{ + int delta = (int)right->atoms.len - (int)left->atoms.len; + int c; + int x; + int prev_x; + int prev_y; + int x_before_slide; + + *found_midpoint = false; + + for (c = d; c >= -d; c -= 2) { + if (c < -(int)left->atoms.len || c > (int)right->atoms.len) { + /* This diagonal is completely outside of the Myers + * graph, don't calculate it. */ + if (c < 0) { + /* We are traversing negatively, and already + * below the entire graph, nothing will come of + * this. */ + break; + } + continue; + } + if (d == 0) { + /* This is the initializing step. There is no prev_c + * yet, get the initial x from the bottom right of the + * Myers graph. */ + x = left->atoms.len; + prev_x = x; + prev_y = xc_to_y(x, c, delta); + } + /* Favoring "-" lines first means favoring moving rightwards in + * the Myers graph. + * For this, all c should derive from c - 1, only the bottom + * most c derive from c + 1: + * + * 2 1 0 + * --------------------------------------------------- + * c= + * 3 + * + * from prev_c = c - 1 --> 5,2 2 + * \ + * 5,3 1 + * \ + * 4,3 5,4<-- 0 + * \ / + * bottom most for d=1 from c + 1 --> 4,4 -1 + * / + * bottom most for d=2 --> 3,4 -2 + * + * Except when a c + 1 from a previous run already means a + * further advancement in the graph. + * If c == d, there is no c + 1 and c - 1 is the only option. + * If c < d, use c + 1 in case that yields a larger x. + * Also use c + 1 if c - 1 is outside the graph. + */ + else if (c > -d && (c == d + || (c - 1 >= -(int)right->atoms.len + && kd_backward[c - 1] <= kd_backward[c + 1]))) { + /* A top one. + * From position prev_c, step upwards in the Myers + * graph: y -= 1. + * Decrementing y is achieved by incrementing c while + * keeping the same x. (since we're deriving y from + * y = x - c + delta). + */ + int prev_c = c - 1; + prev_x = kd_backward[prev_c]; + prev_y = xc_to_y(prev_x, prev_c, delta); + x = prev_x; + } else { + /* The bottom most one. + * From position prev_c, step to the left in the Myers + * graph: x -= 1. + */ + int prev_c = c + 1; + prev_x = kd_backward[prev_c]; + prev_y = xc_to_y(prev_x, prev_c, delta); + x = prev_x - 1; + } + + /* Slide up any snake that we might find here (sections of + * identical lines on both sides). */ +#if 0 + debug("c=%d x-1=%d Yb-1=%d-1=%d\n", c, x-1, xc_to_y(x, c, + delta), + xc_to_y(x, c, delta)-1); + if (x > 0) { + debug(" l="); + debug_dump_atom(left, right, &left->atoms.head[x-1]); + } + if (xc_to_y(x, c, delta) > 0) { + debug(" r="); + debug_dump_atom(right, left, + &right->atoms.head[xc_to_y(x, c, delta)-1]); + } +#endif + x_before_slide = x; + while (x > 0 && xc_to_y(x, c, delta) > 0) { + bool same; + int r = diff_atom_same(&same, + &left->atoms.head[x-1], + &right->atoms.head[ + xc_to_y(x, c, delta)-1]); + if (r) + return r; + if (!same) + break; + x--; + } + kd_backward[c] = x; +#if 0 + if (x_before_slide != x) { + debug(" up %d similar lines\n", x_before_slide - x); + } + + if (DEBUG) { + int fi; + for (fi = d; fi >= c; fi--) { + debug("kd_backward[%d] = (%d, %d)\n", + fi, + kd_backward[fi], + kd_backward[fi] - fi + delta); + } + } +#endif + + if (x < 0 || x > left->atoms.len + || xc_to_y(x, c, delta) < 0 + || xc_to_y(x, c, delta) > right->atoms.len) + continue; + + /* Figured out a new backwards traversal, see if this has gone + * onto or even past a preceding forwards traversal. + * + * If the delta in length is even, then d and backwards_d hit + * the same state indexes -- note how this is different from in + * the forwards traversal, because now both d are the same: + * + * | d= 0 1 2 2 1 0 + * ----+---------------- -------------------- + * k= | c= + * 4 | + * | + * 3 | 3 + * | same + * 2 | 2,0====5,2 2 + * | / \ + * 1 | 1,0 5,3 1 + * | / / \ + * 0 | -->0,0 3,3====4,3 5,4<-- 0 + * | \ / / + * -1 | 0,1 4,4 -1 + * | \ + * -2 | 0,2 -2 + * | + * -3 + * If the delta is odd, they end up off-by-one, i.e. on + * different diagonals. + * So in the backward path, we can only match up diagonals when + * the delta is even. + */ + if ((delta & 1) != 0) + continue; + /* Forwards was done first, now both d are the same. */ + int forwards_d = d; + + /* As soon as the lengths are not the same, the + * backwards traversal starts on a different diagonal, + * and c = k shifted by the difference in length. + */ + int k = c_to_k(c, delta); + + /* When the file sizes are very different, the traversal trees + * start on far distant diagonals. + * They don't necessarily meet straight on. See whether this + * backward value is also on a valid diagonal in kd_forward[], + * and match them if so. */ + if (k >= -forwards_d && k <= forwards_d) { + /* Current c is on a diagonal that exists in + * kd_forward[]. If the two x positions have met or + * passed (backward walked onto or past forward), then + * we've found a midpoint / a mid-box. + * + * When forwards and backwards traversals meet, the + * endpoints of the mid-snake are not the two points in + * kd_forward and kd_backward, but rather the section + * that was slid (if any) of the current + * forward/backward traversal only. + * + * For example: + * + * o-o-o + * | | + * o A + * | \ + * o o + * \ + * M + * |\ + * o o-o-o + * | | | + * o o X + * \ + * o + * \ + * o + * \ + * o + * + * The backward traversal reached M from the bottom and + * slid upwards. The forward traversal already reached + * X, which is not a straight line from M anymore, so + * picking a mid-snake from M to X would yield a + * mistake. + * + * The correct mid-snake is between M and A. M is where + * the backward traversal hit the diagonal that the + * forwards traversal has already passed, and A is what + * it reaches when sliding up identical lines. + */ + + int forward_x = kd_forward[k]; + if (forward_x >= x) { + if (x_before_slide != x) { + /* met after sliding down a mid-snake */ + *meeting_snake = (struct diff_box){ + .left_start = x, + .left_end = x_before_slide, + .right_start = xc_to_y(x, c, delta), + .right_end = xk_to_y(x_before_slide, k), + }; + } else { + /* met after a side step, non-identical + * line. Mark that as box divider + * instead. This makes sure that + * myers_divide never returns the same + * box that came as input, avoiding + * "infinite" looping. */ + *meeting_snake = (struct diff_box){ + .left_start = x, + .left_end = prev_x, + .right_start = xc_to_y(x, c, delta), + .right_end = prev_y, + }; + } + debug("HIT x=%u,%u - y=%u,%u\n", + meeting_snake->left_start, + meeting_snake->right_start, + meeting_snake->left_end, + meeting_snake->right_end); + debug_dump_myers_graph(left, right, NULL, + kd_forward, d, + kd_backward, d); + *found_midpoint = true; + return 0; + } + } + } + return 0; +} + +/* Integer square root approximation */ +static int +shift_sqrt(int val) +{ + int i; + for (i = 1; val > 0; val >>= 2) + i <<= 1; + return i; +} + +#define DIFF_EFFORT_MIN 1024 + +/* Myers "Divide et Impera": tracing forwards from the start and backwards from + * the end to find a midpoint that divides the problem into smaller chunks. + * Requires only linear amounts of memory. */ +int +diff_algo_myers_divide(const struct diff_algo_config *algo_config, + struct diff_state *state) +{ + int rc = ENOMEM; + struct diff_data *left = &state->left; + struct diff_data *right = &state->right; + int *kd_buf; + + debug("\n** %s\n", __func__); + debug("left:\n"); + debug_dump(left); + debug("right:\n"); + debug_dump(right); + + /* Allocate two columns of a Myers graph, one for the forward and one + * for the backward traversal. */ + unsigned int max = left->atoms.len + right->atoms.len; + size_t kd_len = max + 1; + size_t kd_buf_size = kd_len << 1; + + if (state->kd_buf_size < kd_buf_size) { + kd_buf = reallocarray(state->kd_buf, kd_buf_size, + sizeof(int)); + if (!kd_buf) + return ENOMEM; + state->kd_buf = kd_buf; + state->kd_buf_size = kd_buf_size; + } else + kd_buf = state->kd_buf; + int i; + for (i = 0; i < kd_buf_size; i++) + kd_buf[i] = -1; + int *kd_forward = kd_buf; + int *kd_backward = kd_buf + kd_len; + int max_effort = shift_sqrt(max/2); + + if (max_effort < DIFF_EFFORT_MIN) + max_effort = DIFF_EFFORT_MIN; + + /* The 'k' axis in Myers spans positive and negative indexes, so point + * the kd to the middle. + * It is then possible to index from -max/2 .. max/2. */ + kd_forward += max/2; + kd_backward += max/2; + + int d; + struct diff_box mid_snake = {}; + bool found_midpoint = false; + for (d = 0; d <= (max/2); d++) { + int r; + r = diff_divide_myers_forward(&found_midpoint, left, right, + kd_forward, kd_backward, d, + &mid_snake); + if (r) + return r; + if (found_midpoint) + break; + r = diff_divide_myers_backward(&found_midpoint, left, right, + kd_forward, kd_backward, d, + &mid_snake); + if (r) + return r; + if (found_midpoint) + break; + + /* Limit the effort spent looking for a mid snake. If files have + * very few lines in common, the effort spent to find nice mid + * snakes is just not worth it, the diff result will still be + * essentially minus everything on the left, plus everything on + * the right, with a few useless matches here and there. */ + if (d > max_effort) { + /* pick the furthest reaching point from + * kd_forward and kd_backward, and use that as a + * midpoint, to not step into another diff algo + * recursion with unchanged box. */ + int delta = (int)right->atoms.len - (int)left->atoms.len; + int x = 0; + int y; + int i; + int best_forward_i = 0; + int best_forward_distance = 0; + int best_backward_i = 0; + int best_backward_distance = 0; + int distance; + int best_forward_x; + int best_forward_y; + int best_backward_x; + int best_backward_y; + + debug("~~~ HIT d = %d > max_effort = %d\n", d, max_effort); + debug_dump_myers_graph(left, right, NULL, + kd_forward, d, + kd_backward, d); + + for (i = d; i >= -d; i -= 2) { + if (i >= -(int)right->atoms.len && i <= (int)left->atoms.len) { + x = kd_forward[i]; + y = xk_to_y(x, i); + distance = x + y; + if (distance > best_forward_distance) { + best_forward_distance = distance; + best_forward_i = i; + } + } + + if (i >= -(int)left->atoms.len && i <= (int)right->atoms.len) { + x = kd_backward[i]; + y = xc_to_y(x, i, delta); + distance = (right->atoms.len - x) + + (left->atoms.len - y); + if (distance >= best_backward_distance) { + best_backward_distance = distance; + best_backward_i = i; + } + } + } + + /* The myers-divide didn't meet in the middle. We just + * figured out the places where the forward path + * advanced the most, and the backward path advanced the + * most. Just divide at whichever one of those two is better. + * + * o-o + * | + * o + * \ + * o + * \ + * F <-- cut here + * + * + * + * or here --> B + * \ + * o + * \ + * o + * | + * o-o + */ + best_forward_x = kd_forward[best_forward_i]; + best_forward_y = xk_to_y(best_forward_x, best_forward_i); + best_backward_x = kd_backward[best_backward_i]; + best_backward_y = xc_to_y(best_backward_x, best_backward_i, delta); + + if (best_forward_distance >= best_backward_distance) { + x = best_forward_x; + y = best_forward_y; + } else { + x = best_backward_x; + y = best_backward_y; + } + + debug("max_effort cut at x=%d y=%d\n", x, y); + if (x < 0 || y < 0 + || x > left->atoms.len || y > right->atoms.len) + break; + + found_midpoint = true; + mid_snake = (struct diff_box){ + .left_start = x, + .left_end = x, + .right_start = y, + .right_end = y, + }; + break; + } + } + + if (!found_midpoint) { + /* Divide and conquer failed to find a meeting point. Use the + * fallback_algo defined in the algo_config (leave this to the + * caller). This is just paranoia/sanity, we normally should + * always find a midpoint. + */ + debug(" no midpoint \n"); + rc = DIFF_RC_USE_DIFF_ALGO_FALLBACK; + goto return_rc; + } else { + debug(" mid snake L: %u to %u of %u R: %u to %u of %u\n", + mid_snake.left_start, mid_snake.left_end, left->atoms.len, + mid_snake.right_start, mid_snake.right_end, + right->atoms.len); + + /* Section before the mid-snake. */ + debug("Section before the mid-snake\n"); + + struct diff_atom *left_atom = &left->atoms.head[0]; + unsigned int left_section_len = mid_snake.left_start; + struct diff_atom *right_atom = &right->atoms.head[0]; + unsigned int right_section_len = mid_snake.right_start; + + if (left_section_len && right_section_len) { + /* Record an unsolved chunk, the caller will apply + * inner_algo() on this chunk. */ + if (!diff_state_add_chunk(state, false, + left_atom, left_section_len, + right_atom, + right_section_len)) + goto return_rc; + } else if (left_section_len && !right_section_len) { + /* Only left atoms and none on the right, they form a + * "minus" chunk, then. */ + if (!diff_state_add_chunk(state, true, + left_atom, left_section_len, + right_atom, 0)) + goto return_rc; + } else if (!left_section_len && right_section_len) { + /* No left atoms, only atoms on the right, they form a + * "plus" chunk, then. */ + if (!diff_state_add_chunk(state, true, + left_atom, 0, + right_atom, + right_section_len)) + goto return_rc; + } + /* else: left_section_len == 0 and right_section_len == 0, i.e. + * nothing before the mid-snake. */ + + if (mid_snake.left_end > mid_snake.left_start + || mid_snake.right_end > mid_snake.right_start) { + /* The midpoint is a section of identical data on both + * sides, or a certain differing line: that section + * immediately becomes a solved chunk. */ + debug("the mid-snake\n"); + if (!diff_state_add_chunk(state, true, + &left->atoms.head[mid_snake.left_start], + mid_snake.left_end - mid_snake.left_start, + &right->atoms.head[mid_snake.right_start], + mid_snake.right_end - mid_snake.right_start)) + goto return_rc; + } + + /* Section after the mid-snake. */ + debug("Section after the mid-snake\n"); + debug(" left_end %u right_end %u\n", + mid_snake.left_end, mid_snake.right_end); + debug(" left_count %u right_count %u\n", + left->atoms.len, right->atoms.len); + left_atom = &left->atoms.head[mid_snake.left_end]; + left_section_len = left->atoms.len - mid_snake.left_end; + right_atom = &right->atoms.head[mid_snake.right_end]; + right_section_len = right->atoms.len - mid_snake.right_end; + + if (left_section_len && right_section_len) { + /* Record an unsolved chunk, the caller will apply + * inner_algo() on this chunk. */ + if (!diff_state_add_chunk(state, false, + left_atom, left_section_len, + right_atom, + right_section_len)) + goto return_rc; + } else if (left_section_len && !right_section_len) { + /* Only left atoms and none on the right, they form a + * "minus" chunk, then. */ + if (!diff_state_add_chunk(state, true, + left_atom, left_section_len, + right_atom, 0)) + goto return_rc; + } else if (!left_section_len && right_section_len) { + /* No left atoms, only atoms on the right, they form a + * "plus" chunk, then. */ + if (!diff_state_add_chunk(state, true, + left_atom, 0, + right_atom, + right_section_len)) + goto return_rc; + } + /* else: left_section_len == 0 and right_section_len == 0, i.e. + * nothing after the mid-snake. */ + } + + rc = DIFF_RC_OK; + +return_rc: + debug("** END %s\n", __func__); + return rc; +} + +/* Myers Diff tracing from the start all the way through to the end, requiring + * quadratic amounts of memory. This can fail if the required space surpasses + * algo_config->permitted_state_size. */ +int +diff_algo_myers(const struct diff_algo_config *algo_config, + struct diff_state *state) +{ + /* do a diff_divide_myers_forward() without a _backward(), so that it + * walks forward across the entire files to reach the end. Keep each + * run's state, and do a final backtrace. */ + int rc = ENOMEM; + struct diff_data *left = &state->left; + struct diff_data *right = &state->right; + int *kd_buf; + + debug("\n** %s\n", __func__); + debug("left:\n"); + debug_dump(left); + debug("right:\n"); + debug_dump(right); + debug_dump_myers_graph(left, right, NULL, NULL, 0, NULL, 0); + + /* Allocate two columns of a Myers graph, one for the forward and one + * for the backward traversal. */ + unsigned int max = left->atoms.len + right->atoms.len; + size_t kd_len = max + 1 + max; + size_t kd_buf_size = kd_len * kd_len; + size_t kd_state_size = kd_buf_size * sizeof(int); + debug("state size: %zu\n", kd_state_size); + if (kd_buf_size < kd_len /* overflow? */ + || (SIZE_MAX / kd_len ) < kd_len + || kd_state_size > algo_config->permitted_state_size) { + debug("state size %zu > permitted_state_size %zu, use fallback_algo\n", + kd_state_size, algo_config->permitted_state_size); + return DIFF_RC_USE_DIFF_ALGO_FALLBACK; + } + + if (state->kd_buf_size < kd_buf_size) { + kd_buf = reallocarray(state->kd_buf, kd_buf_size, + sizeof(int)); + if (!kd_buf) + return ENOMEM; + state->kd_buf = kd_buf; + state->kd_buf_size = kd_buf_size; + } else + kd_buf = state->kd_buf; + + int i; + for (i = 0; i < kd_buf_size; i++) + kd_buf[i] = -1; + + /* The 'k' axis in Myers spans positive and negative indexes, so point + * the kd to the middle. + * It is then possible to index from -max .. max. */ + int *kd_origin = kd_buf + max; + int *kd_column = kd_origin; + + int d; + int backtrack_d = -1; + int backtrack_k = 0; + int k; + int x, y; + for (d = 0; d <= max; d++, kd_column += kd_len) { + debug("-- %s d=%d\n", __func__, d); + + for (k = d; k >= -d; k -= 2) { + if (k < -(int)right->atoms.len + || k > (int)left->atoms.len) { + /* This diagonal is completely outside of the + * Myers graph, don't calculate it. */ + if (k < -(int)right->atoms.len) + debug(" %d k <" + " -(int)right->atoms.len %d\n", + k, -(int)right->atoms.len); + else + debug(" %d k > left->atoms.len %d\n", k, + left->atoms.len); + if (k < 0) { + /* We are traversing negatively, and + * already below the entire graph, + * nothing will come of this. */ + debug(" break\n"); + break; + } + debug(" continue\n"); + continue; + } + + if (d == 0) { + /* This is the initializing step. There is no + * prev_k yet, get the initial x from the top + * left of the Myers graph. */ + x = 0; + } else { + int *kd_prev_column = kd_column - kd_len; + + /* Favoring "-" lines first means favoring + * moving rightwards in the Myers graph. + * For this, all k should derive from k - 1, + * only the bottom most k derive from k + 1: + * + * | d= 0 1 2 + * ----+---------------- + * k= | + * 2 | 2,0 <-- from + * | / prev_k = 2 - 1 = 1 + * 1 | 1,0 + * | / + * 0 | -->0,0 3,3 + * | \\ / + * -1 | 0,1 <-- bottom most for d=1 + * | \\ from prev_k = -1+1 = 0 + * -2 | 0,2 <-- bottom most for + * d=2 from + * prev_k = -2+1 = -1 + * + * Except when a k + 1 from a previous run + * already means a further advancement in the + * graph. + * If k == d, there is no k + 1 and k - 1 is the + * only option. + * If k < d, use k + 1 in case that yields a + * larger x. Also use k + 1 if k - 1 is outside + * the graph. + */ + if (k > -d + && (k == d + || (k - 1 >= -(int)right->atoms.len + && kd_prev_column[k - 1] + >= kd_prev_column[k + 1]))) { + /* Advance from k - 1. + * From position prev_k, step to the + * right in the Myers graph: x += 1. + */ + int prev_k = k - 1; + int prev_x = kd_prev_column[prev_k]; + x = prev_x + 1; + } else { + /* The bottom most one. + * From position prev_k, step to the + * bottom in the Myers graph: y += 1. + * Incrementing y is achieved by + * decrementing k while keeping the same + * x. (since we're deriving y from y = + * x - k). + */ + int prev_k = k + 1; + int prev_x = kd_prev_column[prev_k]; + x = prev_x; + } + } + + /* Slide down any snake that we might find here. */ + while (x < left->atoms.len + && xk_to_y(x, k) < right->atoms.len) { + bool same; + int r = diff_atom_same(&same, + &left->atoms.head[x], + &right->atoms.head[ + xk_to_y(x, k)]); + if (r) + return r; + if (!same) + break; + x++; + } + kd_column[k] = x; + + if (x == left->atoms.len + && xk_to_y(x, k) == right->atoms.len) { + /* Found a path */ + backtrack_d = d; + backtrack_k = k; + debug("Reached the end at d = %d, k = %d\n", + backtrack_d, backtrack_k); + break; + } + } + + if (backtrack_d >= 0) + break; + } + + debug_dump_myers_graph(left, right, kd_origin, NULL, 0, NULL, 0); + + /* backtrack. A matrix spanning from start to end of the file is ready: + * + * | d= 0 1 2 3 4 + * ----+--------------------------------- + * k= | + * 3 | + * | + * 2 | 2,0 + * | / + * 1 | 1,0 4,3 + * | / / \ + * 0 | -->0,0 3,3 4,4 --> backtrack_d = 4, backtrack_k = 0 + * | \ / \ + * -1 | 0,1 3,4 + * | \ + * -2 | 0,2 + * | + * + * From (4,4) backwards, find the previous position that is the largest, and remember it. + * + */ + for (d = backtrack_d, k = backtrack_k; d >= 0; d--) { + x = kd_column[k]; + y = xk_to_y(x, k); + + /* When the best position is identified, remember it for that + * kd_column. + * That kd_column is no longer needed otherwise, so just + * re-purpose kd_column[0] = x and kd_column[1] = y, + * so that there is no need to allocate more memory. + */ + kd_column[0] = x; + kd_column[1] = y; + debug("Backtrack d=%d: xy=(%d, %d)\n", + d, kd_column[0], kd_column[1]); + + /* Don't access memory before kd_buf */ + if (d == 0) + break; + int *kd_prev_column = kd_column - kd_len; + + /* When y == 0, backtracking downwards (k-1) is the only way. + * When x == 0, backtracking upwards (k+1) is the only way. + * + * | d= 0 1 2 3 4 + * ----+--------------------------------- + * k= | + * 3 | + * | ..y == 0 + * 2 | 2,0 + * | / + * 1 | 1,0 4,3 + * | / / \ + * 0 | -->0,0 3,3 4,4 --> backtrack_d = 4, + * | \ / \ backtrack_k = 0 + * -1 | 0,1 3,4 + * | \ + * -2 | 0,2__ + * | x == 0 + */ + if (y == 0 + || (x > 0 + && kd_prev_column[k - 1] >= kd_prev_column[k + 1])) { + k = k - 1; + debug("prev k=k-1=%d x=%d y=%d\n", + k, kd_prev_column[k], + xk_to_y(kd_prev_column[k], k)); + } else { + k = k + 1; + debug("prev k=k+1=%d x=%d y=%d\n", + k, kd_prev_column[k], + xk_to_y(kd_prev_column[k], k)); + } + kd_column = kd_prev_column; + } + + /* Forwards again, this time recording the diff chunks. + * Definitely start from 0,0. kd_column[0] may actually point to the + * bottom of a snake starting at 0,0 */ + x = 0; + y = 0; + + kd_column = kd_origin; + for (d = 0; d <= backtrack_d; d++, kd_column += kd_len) { + int next_x = kd_column[0]; + int next_y = kd_column[1]; + debug("Forward track from xy(%d,%d) to xy(%d,%d)\n", + x, y, next_x, next_y); + + struct diff_atom *left_atom = &left->atoms.head[x]; + int left_section_len = next_x - x; + struct diff_atom *right_atom = &right->atoms.head[y]; + int right_section_len = next_y - y; + + rc = ENOMEM; + if (left_section_len && right_section_len) { + /* This must be a snake slide. + * Snake slides have a straight line leading into them + * (except when starting at (0,0)). Find out whether the + * lead-in is horizontal or vertical: + * + * left + * ----------> + * | + * r| o-o o + * i| \ | + * g| o o + * h| \ \ + * t| o o + * v + * + * If left_section_len > right_section_len, the lead-in + * is horizontal, meaning first remove one atom from the + * left before sliding down the snake. + * If right_section_len > left_section_len, the lead-in + * is vetical, so add one atom from the right before + * sliding down the snake. */ + if (left_section_len == right_section_len + 1) { + if (!diff_state_add_chunk(state, true, + left_atom, 1, + right_atom, 0)) + goto return_rc; + left_atom++; + left_section_len--; + } else if (right_section_len == left_section_len + 1) { + if (!diff_state_add_chunk(state, true, + left_atom, 0, + right_atom, 1)) + goto return_rc; + right_atom++; + right_section_len--; + } else if (left_section_len != right_section_len) { + /* The numbers are making no sense. Should never + * happen. */ + rc = DIFF_RC_USE_DIFF_ALGO_FALLBACK; + goto return_rc; + } + + if (!diff_state_add_chunk(state, true, + left_atom, left_section_len, + right_atom, + right_section_len)) + goto return_rc; + } else if (left_section_len && !right_section_len) { + /* Only left atoms and none on the right, they form a + * "minus" chunk, then. */ + if (!diff_state_add_chunk(state, true, + left_atom, left_section_len, + right_atom, 0)) + goto return_rc; + } else if (!left_section_len && right_section_len) { + /* No left atoms, only atoms on the right, they form a + * "plus" chunk, then. */ + if (!diff_state_add_chunk(state, true, + left_atom, 0, + right_atom, + right_section_len)) + goto return_rc; + } + + x = next_x; + y = next_y; + } + + rc = DIFF_RC_OK; + +return_rc: + debug("** END %s rc=%d\n", __func__, rc); + return rc; +} diff --git a/lib/diff_output.c b/lib/diff_output.c new file mode 100644 index 000000000000..7ac63bb6c433 --- /dev/null +++ b/lib/diff_output.c @@ -0,0 +1,371 @@ +/* Common parts for printing diff output */ +/* + * Copyright (c) 2020 Neels Hofmeyr + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "diff_internal.h" + +static int +get_atom_byte(int *ch, struct diff_atom *atom, off_t off) +{ + off_t cur; + + if (atom->at != NULL) { + *ch = atom->at[off]; + return 0; + } + + cur = ftello(atom->root->f); + if (cur == -1) + return errno; + + if (cur != atom->pos + off && + fseeko(atom->root->f, atom->pos + off, SEEK_SET) == -1) + return errno; + + *ch = fgetc(atom->root->f); + if (*ch == EOF && ferror(atom->root->f)) + return errno; + + return 0; +} + +#define DIFF_OUTPUT_BUF_SIZE 512 + +int +diff_output_lines(struct diff_output_info *outinfo, FILE *dest, + const char *prefix, struct diff_atom *start_atom, + unsigned int count) +{ + struct diff_atom *atom; + off_t outoff = 0, *offp; + uint8_t *typep; + int rc; + + if (outinfo && outinfo->line_offsets.len > 0) { + unsigned int idx = outinfo->line_offsets.len - 1; + outoff = outinfo->line_offsets.head[idx]; + } + + foreach_diff_atom(atom, start_atom, count) { + off_t outlen = 0; + int i, ch, nbuf = 0; + unsigned int len = atom->len; + unsigned char buf[DIFF_OUTPUT_BUF_SIZE + 1 /* '\n' */]; + size_t n; + + n = strlcpy(buf, prefix, sizeof(buf)); + if (n >= DIFF_OUTPUT_BUF_SIZE) /* leave room for '\n' */ + return ENOBUFS; + nbuf += n; + + if (len) { + rc = get_atom_byte(&ch, atom, len - 1); + if (rc) + return rc; + if (ch == '\n') + len--; + } + + for (i = 0; i < len; i++) { + rc = get_atom_byte(&ch, atom, i); + if (rc) + return rc; + if (nbuf >= DIFF_OUTPUT_BUF_SIZE) { + rc = fwrite(buf, 1, nbuf, dest); + if (rc != nbuf) + return errno; + outlen += rc; + nbuf = 0; + } + buf[nbuf++] = ch; + } + buf[nbuf++] = '\n'; + rc = fwrite(buf, 1, nbuf, dest); + if (rc != nbuf) + return errno; + outlen += rc; + if (outinfo) { + ARRAYLIST_ADD(offp, outinfo->line_offsets); + if (offp == NULL) + return ENOMEM; + outoff += outlen; + *offp = outoff; + ARRAYLIST_ADD(typep, outinfo->line_types); + if (typep == NULL) + return ENOMEM; + *typep = *prefix == ' ' ? DIFF_LINE_CONTEXT : + *prefix == '-' ? DIFF_LINE_MINUS : + *prefix == '+' ? DIFF_LINE_PLUS : DIFF_LINE_NONE; + } + } + + return DIFF_RC_OK; +} + +int +diff_output_chunk_left_version(struct diff_output_info **output_info, + FILE *dest, + const struct diff_input_info *info, + const struct diff_result *result, + const struct diff_chunk_context *cc) +{ + int rc, c_idx; + struct diff_output_info *outinfo = NULL; + + if (diff_range_empty(&cc->left)) + return DIFF_RC_OK; + + if (output_info) { + *output_info = diff_output_info_alloc(); + if (*output_info == NULL) + return ENOMEM; + outinfo = *output_info; + } + + /* Write out all chunks on the left side. */ + for (c_idx = cc->chunk.start; c_idx < cc->chunk.end; c_idx++) { + const struct diff_chunk *c = &result->chunks.head[c_idx]; + + if (c->left_count) { + rc = diff_output_lines(outinfo, dest, "", + c->left_start, c->left_count); + if (rc) + return rc; + } + } + + return DIFF_RC_OK; +} + +int +diff_output_chunk_right_version(struct diff_output_info **output_info, + FILE *dest, + const struct diff_input_info *info, + const struct diff_result *result, + const struct diff_chunk_context *cc) +{ + int rc, c_idx; + struct diff_output_info *outinfo = NULL; + + if (diff_range_empty(&cc->right)) + return DIFF_RC_OK; + + if (output_info) { + *output_info = diff_output_info_alloc(); + if (*output_info == NULL) + return ENOMEM; + outinfo = *output_info; + } + + /* Write out all chunks on the right side. */ + for (c_idx = cc->chunk.start; c_idx < cc->chunk.end; c_idx++) { + const struct diff_chunk *c = &result->chunks.head[c_idx]; + + if (c->right_count) { + rc = diff_output_lines(outinfo, dest, "", c->right_start, + c->right_count); + if (rc) + return rc; + } + } + + return DIFF_RC_OK; +} + +int +diff_output_trailing_newline_msg(struct diff_output_info *outinfo, FILE *dest, + const struct diff_chunk *c) +{ + enum diff_chunk_type chunk_type = diff_chunk_type(c); + struct diff_atom *atom, *start_atom; + unsigned int atom_count; + int rc, ch; + off_t outoff = 0, *offp; + uint8_t *typep; + + + if (chunk_type == CHUNK_MINUS || chunk_type == CHUNK_SAME) { + start_atom = c->left_start; + atom_count = c->left_count; + } else if (chunk_type == CHUNK_PLUS) { + start_atom = c->right_start; + atom_count = c->right_count; + } else + return EINVAL; + + /* Locate the last atom. */ + if (atom_count == 0) + return EINVAL; + atom = &start_atom[atom_count - 1]; + + rc = get_atom_byte(&ch, atom, atom->len - 1); + if (rc != DIFF_RC_OK) + return rc; + + if (ch != '\n') { + if (outinfo && outinfo->line_offsets.len > 0) { + unsigned int idx = outinfo->line_offsets.len - 1; + outoff = outinfo->line_offsets.head[idx]; + } + rc = fprintf(dest, "\\ No newline at end of file\n"); + if (rc < 0) + return errno; + if (outinfo) { + ARRAYLIST_ADD(offp, outinfo->line_offsets); + if (offp == NULL) + return ENOMEM; + outoff += rc; + *offp = outoff; + ARRAYLIST_ADD(typep, outinfo->line_types); + if (typep == NULL) + return ENOMEM; + *typep = DIFF_LINE_NONE; + } + } + + return DIFF_RC_OK; +} + +static bool +is_function_prototype(unsigned char ch) +{ + return (isalpha((unsigned char)ch) || ch == '_' || ch == '$'); +} + +#define begins_with(s, pre) (strncmp(s, pre, sizeof(pre)-1) == 0) + +int +diff_output_match_function_prototype(char *prototype, size_t prototype_size, + int *last_prototype_idx, const struct diff_result *result, + const struct diff_chunk_context *cc) +{ + struct diff_atom *start_atom, *atom; + const struct diff_data *data; + unsigned char buf[DIFF_FUNCTION_CONTEXT_SIZE]; + const char *state = NULL; + int rc, i, ch; + + if (result->left->atoms.len > 0 && cc->left.start > 0) { + data = result->left; + start_atom = &data->atoms.head[cc->left.start - 1]; + } else + return DIFF_RC_OK; + + diff_data_foreach_atom_backwards_from(start_atom, atom, data) { + int atom_idx = diff_atom_root_idx(data, atom); + if (atom_idx < *last_prototype_idx) + break; + rc = get_atom_byte(&ch, atom, 0); + if (rc) + return rc; + buf[0] = (unsigned char)ch; + if (!is_function_prototype(buf[0])) + continue; + for (i = 1; i < atom->len && i < sizeof(buf) - 1; i++) { + rc = get_atom_byte(&ch, atom, i); + if (rc) + return rc; + if (ch == '\n') + break; + buf[i] = (unsigned char)ch; + } + buf[i] = '\0'; + if (begins_with(buf, "private:")) { + if (!state) + state = " (private)"; + } else if (begins_with(buf, "protected:")) { + if (!state) + state = " (protected)"; + } else if (begins_with(buf, "public:")) { + if (!state) + state = " (public)"; + } else { + if (state) /* don't care about truncation */ + strlcat(buf, state, sizeof(buf)); + strlcpy(prototype, buf, prototype_size); + break; + } + } + + *last_prototype_idx = diff_atom_root_idx(data, start_atom); + return DIFF_RC_OK; +} + +struct diff_output_info * +diff_output_info_alloc(void) +{ + struct diff_output_info *output_info; + off_t *offp; + uint8_t *typep; + + output_info = malloc(sizeof(*output_info)); + if (output_info != NULL) { + ARRAYLIST_INIT(output_info->line_offsets, 128); + ARRAYLIST_ADD(offp, output_info->line_offsets); + if (offp == NULL) { + diff_output_info_free(output_info); + return NULL; + } + *offp = 0; + ARRAYLIST_INIT(output_info->line_types, 128); + ARRAYLIST_ADD(typep, output_info->line_types); + if (typep == NULL) { + diff_output_info_free(output_info); + return NULL; + } + *typep = DIFF_LINE_NONE; + } + return output_info; +} + +void +diff_output_info_free(struct diff_output_info *output_info) +{ + ARRAYLIST_FREE(output_info->line_offsets); + ARRAYLIST_FREE(output_info->line_types); + free(output_info); +} + +const char * +diff_output_get_label_left(const struct diff_input_info *info) +{ + if (info->flags & DIFF_INPUT_LEFT_NONEXISTENT) + return "/dev/null"; + + return info->left_path ? info->left_path : "a"; +} + +const char * +diff_output_get_label_right(const struct diff_input_info *info) +{ + if (info->flags & DIFF_INPUT_RIGHT_NONEXISTENT) + return "/dev/null"; + + return info->right_path ? info->right_path : "b"; +} diff --git a/lib/diff_output_edscript.c b/lib/diff_output_edscript.c new file mode 100644 index 000000000000..42d4d5b39ef5 --- /dev/null +++ b/lib/diff_output_edscript.c @@ -0,0 +1,190 @@ +/* Produce ed(1) script output from a diff_result. */ +/* + * Copyright (c) 2020 Neels Hofmeyr + * Copyright (c) 2020 Stefan Sperling + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "diff_internal.h" + +static int +output_edscript_chunk(struct diff_output_info *outinfo, + FILE *dest, const struct diff_input_info *info, + const struct diff_result *result, + struct diff_chunk_context *cc) +{ + off_t outoff = 0, *offp; + int left_start, left_len, right_start, right_len; + int rc; + + left_len = cc->left.end - cc->left.start; + if (left_len < 0) + return EINVAL; + else if (result->left->atoms.len == 0) + left_start = 0; + else if (left_len == 0 && cc->left.start > 0) + left_start = cc->left.start; + else if (cc->left.end > 0) + left_start = cc->left.start + 1; + else + left_start = cc->left.start; + + right_len = cc->right.end - cc->right.start; + if (right_len < 0) + return EINVAL; + else if (result->right->atoms.len == 0) + right_start = 0; + else if (right_len == 0 && cc->right.start > 0) + right_start = cc->right.start; + else if (cc->right.end > 0) + right_start = cc->right.start + 1; + else + right_start = cc->right.start; + + if (left_len == 0) { + /* addition */ + if (right_len == 1) { + rc = fprintf(dest, "%da%d\n", left_start, right_start); + } else { + rc = fprintf(dest, "%da%d,%d\n", left_start, + right_start, cc->right.end); + } + } else if (right_len == 0) { + /* deletion */ + if (left_len == 1) { + rc = fprintf(dest, "%dd%d\n", left_start, + right_start); + } else { + rc = fprintf(dest, "%d,%dd%d\n", left_start, + cc->left.end, right_start); + } + } else { + /* change */ + if (left_len == 1 && right_len == 1) { + rc = fprintf(dest, "%dc%d\n", left_start, right_start); + } else if (left_len == 1) { + rc = fprintf(dest, "%dc%d,%d\n", left_start, + right_start, cc->right.end); + } else if (right_len == 1) { + rc = fprintf(dest, "%d,%dc%d\n", left_start, + cc->left.end, right_start); + } else { + rc = fprintf(dest, "%d,%dc%d,%d\n", left_start, + cc->left.end, right_start, cc->right.end); + } + } + if (rc < 0) + return errno; + if (outinfo) { + ARRAYLIST_ADD(offp, outinfo->line_offsets); + if (offp == NULL) + return ENOMEM; + outoff += rc; + *offp = outoff; + } + + return DIFF_RC_OK; +} + +int +diff_output_edscript(struct diff_output_info **output_info, + FILE *dest, const struct diff_input_info *info, + const struct diff_result *result) +{ + struct diff_output_info *outinfo = NULL; + struct diff_chunk_context cc = {}; + int atomizer_flags = (result->left->atomizer_flags| + result->right->atomizer_flags); + int flags = (result->left->root->diff_flags | + result->right->root->diff_flags); + bool force_text = (flags & DIFF_FLAG_FORCE_TEXT_DATA); + bool have_binary = (atomizer_flags & DIFF_ATOMIZER_FOUND_BINARY_DATA); + int i, rc; + + if (!result) + return EINVAL; + if (result->rc != DIFF_RC_OK) + return result->rc; + + if (output_info) { + *output_info = diff_output_info_alloc(); + if (*output_info == NULL) + return ENOMEM; + outinfo = *output_info; + } + + if (have_binary && !force_text) { + for (i = 0; i < result->chunks.len; i++) { + struct diff_chunk *c = &result->chunks.head[i]; + enum diff_chunk_type t = diff_chunk_type(c); + + if (t != CHUNK_MINUS && t != CHUNK_PLUS) + continue; + + fprintf(dest, "Binary files %s and %s differ\n", + diff_output_get_label_left(info), + diff_output_get_label_right(info)); + break; + } + + return DIFF_RC_OK; + } + + for (i = 0; i < result->chunks.len; i++) { + struct diff_chunk *chunk = &result->chunks.head[i]; + enum diff_chunk_type t = diff_chunk_type(chunk); + struct diff_chunk_context next; + + if (t != CHUNK_MINUS && t != CHUNK_PLUS) + continue; + + if (diff_chunk_context_empty(&cc)) { + /* Note down the start point, any number of subsequent + * chunks may be joined up to this chunk by being + * directly adjacent. */ + diff_chunk_context_get(&cc, result, i, 0); + continue; + } + + /* There already is a previous chunk noted down for being + * printed. Does it join up with this one? */ + diff_chunk_context_get(&next, result, i, 0); + + if (diff_chunk_contexts_touch(&cc, &next)) { + /* This next context touches or overlaps the previous + * one, join. */ + diff_chunk_contexts_merge(&cc, &next); + continue; + } + + rc = output_edscript_chunk(outinfo, dest, info, result, &cc); + if (rc != DIFF_RC_OK) + return rc; + cc = next; + } + + if (!diff_chunk_context_empty(&cc)) + return output_edscript_chunk(outinfo, dest, info, result, &cc); + return DIFF_RC_OK; +} diff --git a/lib/diff_output_plain.c b/lib/diff_output_plain.c new file mode 100644 index 000000000000..7b0082bd1b84 --- /dev/null +++ b/lib/diff_output_plain.c @@ -0,0 +1,246 @@ +/* Output all lines of a diff_result. */ +/* + * Copyright (c) 2020 Neels Hofmeyr + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "diff_internal.h" + +static int +output_plain_chunk(struct diff_output_info *outinfo, + FILE *dest, const struct diff_input_info *info, + const struct diff_result *result, + struct diff_chunk_context *cc, off_t *outoff, bool headers_only) +{ + off_t *offp; + int left_start, left_len, right_start, right_len; + int rc; + bool change = false; + + left_len = cc->left.end - cc->left.start; + if (left_len < 0) + return EINVAL; + else if (result->left->atoms.len == 0) + left_start = 0; + else if (left_len == 0 && cc->left.start > 0) + left_start = cc->left.start; + else if (cc->left.end > 0) + left_start = cc->left.start + 1; + else + left_start = cc->left.start; + + right_len = cc->right.end - cc->right.start; + if (right_len < 0) + return EINVAL; + else if (result->right->atoms.len == 0) + right_start = 0; + else if (right_len == 0 && cc->right.start > 0) + right_start = cc->right.start; + else if (cc->right.end > 0) + right_start = cc->right.start + 1; + else + right_start = cc->right.start; + + if (left_len == 0) { + /* addition */ + if (right_len == 1) { + rc = fprintf(dest, "%da%d\n", left_start, right_start); + } else { + rc = fprintf(dest, "%da%d,%d\n", left_start, + right_start, cc->right.end); + } + } else if (right_len == 0) { + /* deletion */ + if (left_len == 1) { + rc = fprintf(dest, "%dd%d\n", left_start, + right_start); + } else { + rc = fprintf(dest, "%d,%dd%d\n", left_start, + cc->left.end, right_start); + } + } else { + /* change */ + change = true; + if (left_len == 1 && right_len == 1) { + rc = fprintf(dest, "%dc%d\n", left_start, right_start); + } else if (left_len == 1) { + rc = fprintf(dest, "%dc%d,%d\n", left_start, + right_start, cc->right.end); + } else if (right_len == 1) { + rc = fprintf(dest, "%d,%dc%d\n", left_start, + cc->left.end, right_start); + } else { + rc = fprintf(dest, "%d,%dc%d,%d\n", left_start, + cc->left.end, right_start, cc->right.end); + } + } + if (rc < 0) + return errno; + if (outinfo) { + ARRAYLIST_ADD(offp, outinfo->line_offsets); + if (offp == NULL) + return ENOMEM; + *outoff += rc; + *offp = *outoff; + } + + /* + * Now write out all the joined chunks. + * + * If the hunk denotes a change, it will come in the form of a deletion + * chunk followed by a addition chunk. Print a marker to break up the + * additions and deletions when this happens. + */ + int c_idx; + for (c_idx = cc->chunk.start; !headers_only && c_idx < cc->chunk.end; + c_idx++) { + const struct diff_chunk *c = &result->chunks.head[c_idx]; + if (c->left_count && !c->right_count) + rc = diff_output_lines(outinfo, dest, + c->solved ? "< " : "?", + c->left_start, c->left_count); + else if (c->right_count && !c->left_count) { + if (change) { + rc = fprintf(dest, "---\n"); + if (rc < 0) + return errno; + if (outinfo) { + ARRAYLIST_ADD(offp, + outinfo->line_offsets); + if (offp == NULL) + return ENOMEM; + *outoff += rc; + *offp = *outoff; + } + } + rc = diff_output_lines(outinfo, dest, + c->solved ? "> " : "?", + c->right_start, c->right_count); + } + if (rc) + return rc; + if (cc->chunk.end == result->chunks.len) { + rc = diff_output_trailing_newline_msg(outinfo, dest, c); + if (rc != DIFF_RC_OK) + return rc; + } + } + + return DIFF_RC_OK; +} + +int +diff_output_plain(struct diff_output_info **output_info, + FILE *dest, const struct diff_input_info *info, + const struct diff_result *result, int hunk_headers_only) +{ + struct diff_output_info *outinfo = NULL; + struct diff_chunk_context cc = {}; + int atomizer_flags = (result->left->atomizer_flags| + result->right->atomizer_flags); + int flags = (result->left->root->diff_flags | + result->right->root->diff_flags); + bool force_text = (flags & DIFF_FLAG_FORCE_TEXT_DATA); + bool have_binary = (atomizer_flags & DIFF_ATOMIZER_FOUND_BINARY_DATA); + int i, rc; + off_t outoff = 0, *offp; + + if (!result) + return EINVAL; + if (result->rc != DIFF_RC_OK) + return result->rc; + + if (output_info) { + *output_info = diff_output_info_alloc(); + if (*output_info == NULL) + return ENOMEM; + outinfo = *output_info; + } + + if (have_binary && !force_text) { + for (i = 0; i < result->chunks.len; i++) { + struct diff_chunk *c = &result->chunks.head[i]; + enum diff_chunk_type t = diff_chunk_type(c); + + if (t != CHUNK_MINUS && t != CHUNK_PLUS) + continue; + + rc = fprintf(dest, "Binary files %s and %s differ\n", + diff_output_get_label_left(info), + diff_output_get_label_right(info)); + if (rc < 0) + return errno; + if (outinfo) { + ARRAYLIST_ADD(offp, outinfo->line_offsets); + if (offp == NULL) + return ENOMEM; + outoff += rc; + *offp = outoff; + } + break; + } + + return DIFF_RC_OK; + } + + for (i = 0; i < result->chunks.len; i++) { + struct diff_chunk *chunk = &result->chunks.head[i]; + enum diff_chunk_type t = diff_chunk_type(chunk); + struct diff_chunk_context next; + + if (t != CHUNK_MINUS && t != CHUNK_PLUS) + continue; + + if (diff_chunk_context_empty(&cc)) { + /* Note down the start point, any number of subsequent + * chunks may be joined up to this chunk by being + * directly adjacent. */ + diff_chunk_context_get(&cc, result, i, 0); + continue; + } + + /* There already is a previous chunk noted down for being + * printed. Does it join up with this one? */ + diff_chunk_context_get(&next, result, i, 0); + + if (diff_chunk_contexts_touch(&cc, &next)) { + /* This next context touches or overlaps the previous + * one, join. */ + diff_chunk_contexts_merge(&cc, &next); + /* When we merge the last chunk we can end up with one + * hanging chunk and have to come back for it after the + * loop */ + continue; + } + rc = output_plain_chunk(outinfo, dest, info, result, &cc, + &outoff, hunk_headers_only); + if (rc != DIFF_RC_OK) + return rc; + cc = next; + } + if (!diff_chunk_context_empty(&cc)) + return output_plain_chunk(outinfo, dest, info, result, &cc, + &outoff, hunk_headers_only); + return DIFF_RC_OK; +} diff --git a/lib/diff_output_unidiff.c b/lib/diff_output_unidiff.c new file mode 100644 index 000000000000..d480a022a9a7 --- /dev/null +++ b/lib/diff_output_unidiff.c @@ -0,0 +1,602 @@ +/* Produce a unidiff output from a diff_result. */ +/* + * Copyright (c) 2020 Neels Hofmeyr + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "diff_internal.h" +#include "diff_debug.h" + +off_t +diff_chunk_get_left_start_pos(const struct diff_chunk *c) +{ + return c->left_start->pos; +} + +off_t +diff_chunk_get_right_start_pos(const struct diff_chunk *c) +{ + return c->right_start->pos; +} + +bool +diff_chunk_context_empty(const struct diff_chunk_context *cc) +{ + return diff_range_empty(&cc->chunk); +} + +int +diff_chunk_get_left_start(const struct diff_chunk *c, + const struct diff_result *r, int context_lines) +{ + int left_start = diff_atom_root_idx(r->left, c->left_start); + return MAX(0, left_start - context_lines); +} + +int +diff_chunk_get_left_end(const struct diff_chunk *c, + const struct diff_result *r, int context_lines) +{ + int left_start = diff_chunk_get_left_start(c, r, 0); + return MIN(r->left->atoms.len, + left_start + c->left_count + context_lines); +} + +int +diff_chunk_get_right_start(const struct diff_chunk *c, + const struct diff_result *r, int context_lines) +{ + int right_start = diff_atom_root_idx(r->right, c->right_start); + return MAX(0, right_start - context_lines); +} + +int +diff_chunk_get_right_end(const struct diff_chunk *c, + const struct diff_result *r, int context_lines) +{ + int right_start = diff_chunk_get_right_start(c, r, 0); + return MIN(r->right->atoms.len, + right_start + c->right_count + context_lines); +} + +struct diff_chunk * +diff_chunk_get(const struct diff_result *r, int chunk_idx) +{ + return &r->chunks.head[chunk_idx]; +} + +int +diff_chunk_get_left_count(struct diff_chunk *c) +{ + return c->left_count; +} + +int +diff_chunk_get_right_count(struct diff_chunk *c) +{ + return c->right_count; +} + +void +diff_chunk_context_get(struct diff_chunk_context *cc, const struct diff_result *r, + int chunk_idx, int context_lines) +{ + const struct diff_chunk *c = &r->chunks.head[chunk_idx]; + int left_start = diff_chunk_get_left_start(c, r, context_lines); + int left_end = diff_chunk_get_left_end(c, r, context_lines); + int right_start = diff_chunk_get_right_start(c, r, context_lines); + int right_end = diff_chunk_get_right_end(c, r, context_lines); + + *cc = (struct diff_chunk_context){ + .chunk = { + .start = chunk_idx, + .end = chunk_idx + 1, + }, + .left = { + .start = left_start, + .end = left_end, + }, + .right = { + .start = right_start, + .end = right_end, + }, + }; +} + +bool +diff_chunk_contexts_touch(const struct diff_chunk_context *cc, + const struct diff_chunk_context *other) +{ + return diff_ranges_touch(&cc->chunk, &other->chunk) + || diff_ranges_touch(&cc->left, &other->left) + || diff_ranges_touch(&cc->right, &other->right); +} + +void +diff_chunk_contexts_merge(struct diff_chunk_context *cc, + const struct diff_chunk_context *other) +{ + diff_ranges_merge(&cc->chunk, &other->chunk); + diff_ranges_merge(&cc->left, &other->left); + diff_ranges_merge(&cc->right, &other->right); +} + +void +diff_chunk_context_load_change(struct diff_chunk_context *cc, + int *nchunks_used, + struct diff_result *result, + int start_chunk_idx, + int context_lines) +{ + int i; + int seen_minus = 0, seen_plus = 0; + + if (nchunks_used) + *nchunks_used = 0; + + for (i = start_chunk_idx; i < result->chunks.len; i++) { + struct diff_chunk *chunk = &result->chunks.head[i]; + enum diff_chunk_type t = diff_chunk_type(chunk); + struct diff_chunk_context next; + + if (t != CHUNK_MINUS && t != CHUNK_PLUS) { + if (nchunks_used) + (*nchunks_used)++; + if (seen_minus || seen_plus) + break; + else + continue; + } else if (t == CHUNK_MINUS) + seen_minus = 1; + else if (t == CHUNK_PLUS) + seen_plus = 1; + + if (diff_chunk_context_empty(cc)) { + /* Note down the start point, any number of subsequent + * chunks may be joined up to this chunk by being + * directly adjacent. */ + diff_chunk_context_get(cc, result, i, context_lines); + if (nchunks_used) + (*nchunks_used)++; + continue; + } + + /* There already is a previous chunk noted down for being + * printed. Does it join up with this one? */ + diff_chunk_context_get(&next, result, i, context_lines); + + if (diff_chunk_contexts_touch(cc, &next)) { + /* This next context touches or overlaps the previous + * one, join. */ + diff_chunk_contexts_merge(cc, &next); + if (nchunks_used) + (*nchunks_used)++; + continue; + } else + break; + } +} + +struct diff_output_unidiff_state { + bool header_printed; + char prototype[DIFF_FUNCTION_CONTEXT_SIZE]; + int last_prototype_idx; +}; + +struct diff_output_unidiff_state * +diff_output_unidiff_state_alloc(void) +{ + struct diff_output_unidiff_state *state; + + state = calloc(1, sizeof(struct diff_output_unidiff_state)); + if (state != NULL) + diff_output_unidiff_state_reset(state); + return state; +} + +void +diff_output_unidiff_state_reset(struct diff_output_unidiff_state *state) +{ + state->header_printed = false; + memset(state->prototype, 0, sizeof(state->prototype)); + state->last_prototype_idx = 0; +} + +void +diff_output_unidiff_state_free(struct diff_output_unidiff_state *state) +{ + free(state); +} + +static int +output_unidiff_chunk(struct diff_output_info *outinfo, FILE *dest, + struct diff_output_unidiff_state *state, + const struct diff_input_info *info, + const struct diff_result *result, + bool print_header, bool show_function_prototypes, + const struct diff_chunk_context *cc) +{ + int rc, left_start, left_len, right_start, right_len; + off_t outoff = 0, *offp; + uint8_t *typep; + + if (diff_range_empty(&cc->left) && diff_range_empty(&cc->right)) + return DIFF_RC_OK; + + if (outinfo && outinfo->line_offsets.len > 0) { + unsigned int idx = outinfo->line_offsets.len - 1; + outoff = outinfo->line_offsets.head[idx]; + } + + if (print_header && !(state->header_printed)) { + rc = fprintf(dest, "--- %s\n", + diff_output_get_label_left(info)); + if (rc < 0) + return errno; + if (outinfo) { + ARRAYLIST_ADD(offp, outinfo->line_offsets); + if (offp == NULL) + return ENOMEM; + outoff += rc; + *offp = outoff; + ARRAYLIST_ADD(typep, outinfo->line_types); + if (typep == NULL) + return ENOMEM; + *typep = DIFF_LINE_MINUS; + } + rc = fprintf(dest, "+++ %s\n", + diff_output_get_label_right(info)); + if (rc < 0) + return errno; + if (outinfo) { + ARRAYLIST_ADD(offp, outinfo->line_offsets); + if (offp == NULL) + return ENOMEM; + outoff += rc; + *offp = outoff; + ARRAYLIST_ADD(typep, outinfo->line_types); + if (typep == NULL) + return ENOMEM; + *typep = DIFF_LINE_PLUS; + } + state->header_printed = true; + } + + left_len = cc->left.end - cc->left.start; + if (result->left->atoms.len == 0) + left_start = 0; + else if (left_len == 0 && cc->left.start > 0) + left_start = cc->left.start; + else + left_start = cc->left.start + 1; + + right_len = cc->right.end - cc->right.start; + if (result->right->atoms.len == 0) + right_start = 0; + else if (right_len == 0 && cc->right.start > 0) + right_start = cc->right.start; + else + right_start = cc->right.start + 1; + + if (show_function_prototypes) { + rc = diff_output_match_function_prototype(state->prototype, + sizeof(state->prototype), &state->last_prototype_idx, + result, cc); + if (rc) + return rc; + } + + if (left_len == 1 && right_len == 1) { + rc = fprintf(dest, "@@ -%d +%d @@%s%s\n", + left_start, right_start, + state->prototype[0] ? " " : "", + state->prototype[0] ? state->prototype : ""); + } else if (left_len == 1 && right_len != 1) { + rc = fprintf(dest, "@@ -%d +%d,%d @@%s%s\n", + left_start, right_start, right_len, + state->prototype[0] ? " " : "", + state->prototype[0] ? state->prototype : ""); + } else if (left_len != 1 && right_len == 1) { + rc = fprintf(dest, "@@ -%d,%d +%d @@%s%s\n", + left_start, left_len, right_start, + state->prototype[0] ? " " : "", + state->prototype[0] ? state->prototype : ""); + } else { + rc = fprintf(dest, "@@ -%d,%d +%d,%d @@%s%s\n", + left_start, left_len, right_start, right_len, + state->prototype[0] ? " " : "", + state->prototype[0] ? state->prototype : ""); + } + if (rc < 0) + return errno; + if (outinfo) { + ARRAYLIST_ADD(offp, outinfo->line_offsets); + if (offp == NULL) + return ENOMEM; + outoff += rc; + *offp = outoff; + ARRAYLIST_ADD(typep, outinfo->line_types); + if (typep == NULL) + return ENOMEM; + *typep = DIFF_LINE_HUNK; + } + + /* Got the absolute line numbers where to start printing, and the index + * of the interesting (non-context) chunk. + * To print context lines above the interesting chunk, nipping on the + * previous chunk index may be necessary. + * It is guaranteed to be only context lines where left == right, so it + * suffices to look on the left. */ + const struct diff_chunk *first_chunk; + int chunk_start_line; + first_chunk = &result->chunks.head[cc->chunk.start]; + chunk_start_line = diff_atom_root_idx(result->left, + first_chunk->left_start); + if (cc->left.start < chunk_start_line) { + rc = diff_output_lines(outinfo, dest, " ", + &result->left->atoms.head[cc->left.start], + chunk_start_line - cc->left.start); + if (rc) + return rc; + } + + /* Now write out all the joined chunks and contexts between them */ + int c_idx; + for (c_idx = cc->chunk.start; c_idx < cc->chunk.end; c_idx++) { + const struct diff_chunk *c = &result->chunks.head[c_idx]; + + if (c->left_count && c->right_count) + rc = diff_output_lines(outinfo, dest, + c->solved ? " " : "?", + c->left_start, c->left_count); + else if (c->left_count && !c->right_count) + rc = diff_output_lines(outinfo, dest, + c->solved ? "-" : "?", + c->left_start, c->left_count); + else if (c->right_count && !c->left_count) + rc = diff_output_lines(outinfo, dest, + c->solved ? "+" : "?", + c->right_start, c->right_count); + if (rc) + return rc; + + if (cc->chunk.end == result->chunks.len) { + rc = diff_output_trailing_newline_msg(outinfo, dest, c); + if (rc != DIFF_RC_OK) + return rc; + } + } + + /* Trailing context? */ + const struct diff_chunk *last_chunk; + int chunk_end_line; + last_chunk = &result->chunks.head[cc->chunk.end - 1]; + chunk_end_line = diff_atom_root_idx(result->left, + last_chunk->left_start + + last_chunk->left_count); + if (cc->left.end > chunk_end_line) { + rc = diff_output_lines(outinfo, dest, " ", + &result->left->atoms.head[chunk_end_line], + cc->left.end - chunk_end_line); + if (rc) + return rc; + + if (cc->left.end == result->left->atoms.len) { + rc = diff_output_trailing_newline_msg(outinfo, dest, + &result->chunks.head[result->chunks.len - 1]); + if (rc != DIFF_RC_OK) + return rc; + } + } + + return DIFF_RC_OK; +} + +int +diff_output_unidiff_chunk(struct diff_output_info **output_info, FILE *dest, + struct diff_output_unidiff_state *state, + const struct diff_input_info *info, + const struct diff_result *result, + const struct diff_chunk_context *cc) +{ + struct diff_output_info *outinfo = NULL; + int flags = (result->left->root->diff_flags | + result->right->root->diff_flags); + bool show_function_prototypes = (flags & DIFF_FLAG_SHOW_PROTOTYPES); + + if (output_info) { + *output_info = diff_output_info_alloc(); + if (*output_info == NULL) + return ENOMEM; + outinfo = *output_info; + } + + return output_unidiff_chunk(outinfo, dest, state, info, + result, false, show_function_prototypes, cc); +} + +int +diff_output_unidiff(struct diff_output_info **output_info, + FILE *dest, const struct diff_input_info *info, + const struct diff_result *result, + unsigned int context_lines) +{ + struct diff_output_unidiff_state *state; + struct diff_chunk_context cc = {}; + struct diff_output_info *outinfo = NULL; + int atomizer_flags = (result->left->atomizer_flags| + result->right->atomizer_flags); + int flags = (result->left->root->diff_flags | + result->right->root->diff_flags); + bool show_function_prototypes = (flags & DIFF_FLAG_SHOW_PROTOTYPES); + bool force_text = (flags & DIFF_FLAG_FORCE_TEXT_DATA); + bool have_binary = (atomizer_flags & DIFF_ATOMIZER_FOUND_BINARY_DATA); + off_t outoff = 0, *offp; + uint8_t *typep; + int rc, i; + + if (!result) + return EINVAL; + if (result->rc != DIFF_RC_OK) + return result->rc; + + if (output_info) { + *output_info = diff_output_info_alloc(); + if (*output_info == NULL) + return ENOMEM; + outinfo = *output_info; + } + + if (have_binary && !force_text) { + for (i = 0; i < result->chunks.len; i++) { + struct diff_chunk *c = &result->chunks.head[i]; + enum diff_chunk_type t = diff_chunk_type(c); + + if (t != CHUNK_MINUS && t != CHUNK_PLUS) + continue; + + if (outinfo && outinfo->line_offsets.len > 0) { + unsigned int idx = + outinfo->line_offsets.len - 1; + outoff = outinfo->line_offsets.head[idx]; + } + + rc = fprintf(dest, "Binary files %s and %s differ\n", + diff_output_get_label_left(info), + diff_output_get_label_right(info)); + if (outinfo) { + ARRAYLIST_ADD(offp, outinfo->line_offsets); + if (offp == NULL) + return ENOMEM; + outoff += rc; + *offp = outoff; + ARRAYLIST_ADD(typep, outinfo->line_types); + if (typep == NULL) + return ENOMEM; + *typep = DIFF_LINE_NONE; + } + break; + } + + return DIFF_RC_OK; + } + + state = diff_output_unidiff_state_alloc(); + if (state == NULL) { + if (output_info) { + diff_output_info_free(*output_info); + *output_info = NULL; + } + return ENOMEM; + } + +#if DEBUG + unsigned int check_left_pos, check_right_pos; + check_left_pos = 0; + check_right_pos = 0; + for (i = 0; i < result->chunks.len; i++) { + struct diff_chunk *c = &result->chunks.head[i]; + enum diff_chunk_type t = diff_chunk_type(c); + + debug("[%d] %s lines L%d R%d @L %d @R %d\n", + i, (t == CHUNK_MINUS ? "minus" : + (t == CHUNK_PLUS ? "plus" : + (t == CHUNK_SAME ? "same" : "?"))), + c->left_count, + c->right_count, + c->left_start ? diff_atom_root_idx(result->left, c->left_start) : -1, + c->right_start ? diff_atom_root_idx(result->right, c->right_start) : -1); + assert(check_left_pos == diff_atom_root_idx(result->left, c->left_start)); + assert(check_right_pos == diff_atom_root_idx(result->right, c->right_start)); + check_left_pos += c->left_count; + check_right_pos += c->right_count; + + } + assert(check_left_pos == result->left->atoms.len); + assert(check_right_pos == result->right->atoms.len); +#endif + + for (i = 0; i < result->chunks.len; i++) { + struct diff_chunk *c = &result->chunks.head[i]; + enum diff_chunk_type t = diff_chunk_type(c); + struct diff_chunk_context next; + + if (t != CHUNK_MINUS && t != CHUNK_PLUS) + continue; + + if (diff_chunk_context_empty(&cc)) { + /* These are the first lines being printed. + * Note down the start point, any number of subsequent + * chunks may be joined up to this unidiff chunk by + * context lines or by being directly adjacent. */ + diff_chunk_context_get(&cc, result, i, context_lines); + debug("new chunk to be printed:" + " chunk %d-%d left %d-%d right %d-%d\n", + cc.chunk.start, cc.chunk.end, + cc.left.start, cc.left.end, + cc.right.start, cc.right.end); + continue; + } + + /* There already is a previous chunk noted down for being + * printed. Does it join up with this one? */ + diff_chunk_context_get(&next, result, i, context_lines); + debug("new chunk to be printed:" + " chunk %d-%d left %d-%d right %d-%d\n", + next.chunk.start, next.chunk.end, + next.left.start, next.left.end, + next.right.start, next.right.end); + + if (diff_chunk_contexts_touch(&cc, &next)) { + /* This next context touches or overlaps the previous + * one, join. */ + diff_chunk_contexts_merge(&cc, &next); + debug("new chunk to be printed touches previous chunk," + " now: left %d-%d right %d-%d\n", + cc.left.start, cc.left.end, + cc.right.start, cc.right.end); + continue; + } + + /* No touching, so the previous context is complete with a gap + * between it and this next one. Print the previous one and + * start fresh here. */ + debug("new chunk to be printed does not touch previous chunk;" + " print left %d-%d right %d-%d\n", + cc.left.start, cc.left.end, cc.right.start, cc.right.end); + output_unidiff_chunk(outinfo, dest, state, info, result, + true, show_function_prototypes, &cc); + cc = next; + debug("new unprinted chunk is left %d-%d right %d-%d\n", + cc.left.start, cc.left.end, cc.right.start, cc.right.end); + } + + if (!diff_chunk_context_empty(&cc)) + output_unidiff_chunk(outinfo, dest, state, info, result, + true, show_function_prototypes, &cc); + diff_output_unidiff_state_free(state); + return DIFF_RC_OK; +} diff --git a/lib/diff_patience.c b/lib/diff_patience.c new file mode 100644 index 000000000000..a06df2c36c9d --- /dev/null +++ b/lib/diff_patience.c @@ -0,0 +1,647 @@ +/* Implementation of the Patience Diff algorithm invented by Bram Cohen: + * Divide a diff problem into smaller chunks by an LCS (Longest Common Sequence) + * of common-unique lines. */ +/* + * Copyright (c) 2020 Neels Hofmeyr + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "diff_internal.h" +#include "diff_debug.h" + +/* Algorithm to find unique lines: + * 0: stupidly iterate atoms + * 1: qsort + * 2: mergesort + */ +#define UNIQUE_STRATEGY 1 + +/* Per-atom state for the Patience Diff algorithm */ +struct atom_patience { +#if UNIQUE_STRATEGY == 0 + bool unique_here; +#endif + bool unique_in_both; + struct diff_atom *pos_in_other; + struct diff_atom *prev_stack; + struct diff_range identical_lines; +}; + +/* A diff_atom has a backpointer to the root diff_data. That points to the + * current diff_data, a possibly smaller section of the root. That current + * diff_data->algo_data is a pointer to an array of struct atom_patience. The + * atom's index in current diff_data gives the index in the atom_patience array. + */ +#define PATIENCE(ATOM) \ + (((struct atom_patience*)((ATOM)->root->current->algo_data))\ + [diff_atom_idx((ATOM)->root->current, ATOM)]) + +#if UNIQUE_STRATEGY == 0 + +/* Stupid iteration and comparison of all atoms */ +static int +diff_atoms_mark_unique(struct diff_data *d, unsigned int *unique_count) +{ + struct diff_atom *i; + unsigned int count = 0; + diff_data_foreach_atom(i, d) { + PATIENCE(i).unique_here = true; + PATIENCE(i).unique_in_both = true; + count++; + } + diff_data_foreach_atom(i, d) { + struct diff_atom *j; + + if (!PATIENCE(i).unique_here) + continue; + + diff_data_foreach_atom_from(i + 1, j, d) { + bool same; + int r = diff_atom_same(&same, i, j); + if (r) + return r; + if (!same) + continue; + if (PATIENCE(i).unique_here) { + PATIENCE(i).unique_here = false; + PATIENCE(i).unique_in_both = false; + count--; + } + PATIENCE(j).unique_here = false; + PATIENCE(j).unique_in_both = false; + count--; + } + } + if (unique_count) + *unique_count = count; + return 0; +} + +/* Mark those lines as PATIENCE(atom).unique_in_both = true that appear exactly + * once in each side. */ +static int +diff_atoms_mark_unique_in_both(struct diff_data *left, struct diff_data *right, + unsigned int *unique_in_both_count) +{ + /* Derive the final unique_in_both count without needing an explicit + * iteration. So this is just some optimiziation to save one iteration + * in the end. */ + unsigned int unique_in_both; + int r; + + r = diff_atoms_mark_unique(left, &unique_in_both); + if (r) + return r; + r = diff_atoms_mark_unique(right, NULL); + if (r) + return r; + + debug("unique_in_both %u\n", unique_in_both); + + struct diff_atom *i; + diff_data_foreach_atom(i, left) { + if (!PATIENCE(i).unique_here) + continue; + struct diff_atom *j; + int found_in_b = 0; + diff_data_foreach_atom(j, right) { + bool same; + int r = diff_atom_same(&same, i, j); + if (r) + return r; + if (!same) + continue; + if (!PATIENCE(j).unique_here) { + found_in_b = 2; /* or more */ + break; + } else { + found_in_b = 1; + PATIENCE(j).pos_in_other = i; + PATIENCE(i).pos_in_other = j; + } + } + + if (found_in_b == 0 || found_in_b > 1) { + PATIENCE(i).unique_in_both = false; + unique_in_both--; + debug("unique_in_both %u (%d) ", unique_in_both, + found_in_b); + debug_dump_atom(left, NULL, i); + } + } + + /* Still need to unmark right[*]->patience.unique_in_both for atoms that + * don't exist in left */ + diff_data_foreach_atom(i, right) { + if (!PATIENCE(i).unique_here + || !PATIENCE(i).unique_in_both) + continue; + struct diff_atom *j; + bool found_in_a = false; + diff_data_foreach_atom(j, left) { + bool same; + int r; + if (!PATIENCE(j).unique_in_both) + continue; + r = diff_atom_same(&same, i, j); + if (r) + return r; + if (!same) + continue; + found_in_a = true; + break; + } + + if (!found_in_a) + PATIENCE(i).unique_in_both = false; + } + + if (unique_in_both_count) + *unique_in_both_count = unique_in_both; + return 0; +} + +#else /* UNIQUE_STRATEGY != 0 */ + +/* Use an optimized sorting algorithm (qsort, mergesort) to find unique lines */ + +static int diff_atoms_compar(const void *_a, const void *_b) +{ + const struct diff_atom *a = *(struct diff_atom**)_a; + const struct diff_atom *b = *(struct diff_atom**)_b; + int cmp; + int rc = 0; + + /* If there's been an error (e.g. I/O error) in a previous compar, we + * have no way to abort the sort but just report the rc and stop + * comparing. Make sure to catch errors on either side. If atoms are + * from more than one diff_data, make sure the error, if any, spreads + * to all of them, so we can cut short all future comparisons. */ + if (a->root->err) + rc = a->root->err; + if (b->root->err) + rc = b->root->err; + if (rc) { + a->root->err = rc; + b->root->err = rc; + /* just return 'equal' to not swap more positions */ + return 0; + } + + /* Sort by the simplistic hash */ + if (a->hash < b->hash) + return -1; + if (a->hash > b->hash) + return 1; + + /* If hashes are the same, the lines may still differ. Do a full cmp. */ + rc = diff_atom_cmp(&cmp, a, b); + + if (rc) { + /* Mark the I/O error so that the caller can find out about it. + * For the case atoms are from more than one diff_data, mark in + * both. */ + a->root->err = rc; + if (a->root != b->root) + b->root->err = rc; + return 0; + } + + return cmp; +} + +/* Sort an array of struct diff_atom* in-place. */ +static int diff_atoms_sort(struct diff_atom *atoms[], + size_t atoms_count) +{ +#if UNIQUE_STRATEGY == 1 + qsort(atoms, atoms_count, sizeof(struct diff_atom*), diff_atoms_compar); +#else + mergesort(atoms, atoms_count, sizeof(struct diff_atom*), + diff_atoms_compar); +#endif + return atoms[0]->root->err; +} + +static int +diff_atoms_mark_unique_in_both(struct diff_data *left, struct diff_data *right, + unsigned int *unique_in_both_count_p) +{ + struct diff_atom *a; + struct diff_atom *b; + struct diff_atom **all_atoms; + unsigned int len = 0; + unsigned int i; + unsigned int unique_in_both_count = 0; + int rc; + + all_atoms = calloc(left->atoms.len + right->atoms.len, + sizeof(struct diff_atom *)); + if (all_atoms == NULL) + return ENOMEM; + + left->err = 0; + right->err = 0; + left->root->err = 0; + right->root->err = 0; + diff_data_foreach_atom(a, left) { + all_atoms[len++] = a; + } + diff_data_foreach_atom(b, right) { + all_atoms[len++] = b; + } + + rc = diff_atoms_sort(all_atoms, len); + if (rc) + goto free_and_exit; + + /* Now we have a sorted array of atom pointers. All similar lines are + * adjacent. Walk through the array and mark those that are unique on + * each side, but exist once in both sources. */ + for (i = 0; i < len; i++) { + bool same; + unsigned int next_differing_i; + unsigned int last_identical_i; + unsigned int j; + unsigned int count_first_side = 1; + unsigned int count_other_side = 0; + a = all_atoms[i]; + debug("a: "); + debug_dump_atom(a->root, NULL, a); + + /* Do as few diff_atom_cmp() as possible: first walk forward + * only using the cheap hash as indicator for differing atoms; + * then walk backwards until hitting an identical atom. */ + for (next_differing_i = i + 1; next_differing_i < len; + next_differing_i++) { + b = all_atoms[next_differing_i]; + if (a->hash != b->hash) + break; + } + for (last_identical_i = next_differing_i - 1; + last_identical_i > i; + last_identical_i--) { + b = all_atoms[last_identical_i]; + rc = diff_atom_same(&same, a, b); + if (rc) + goto free_and_exit; + if (same) + break; + } + next_differing_i = last_identical_i + 1; + + for (j = i+1; j < next_differing_i; j++) { + b = all_atoms[j]; + /* A following atom is the same. See on which side the + * repetition counts. */ + if (a->root == b->root) + count_first_side ++; + else + count_other_side ++; + debug("b: "); + debug_dump_atom(b->root, NULL, b); + debug(" count_first_side=%d count_other_side=%d\n", + count_first_side, count_other_side); + } + + /* Counted a section of similar atoms, put the results back to + * the atoms. */ + if ((count_first_side == 1) + && (count_other_side == 1)) { + b = all_atoms[i+1]; + PATIENCE(a).unique_in_both = true; + PATIENCE(a).pos_in_other = b; + PATIENCE(b).unique_in_both = true; + PATIENCE(b).pos_in_other = a; + unique_in_both_count++; + } + + /* j now points at the first atom after 'a' that is not + * identical to 'a'. j is always > i. */ + i = j - 1; + } + *unique_in_both_count_p = unique_in_both_count; + rc = 0; +free_and_exit: + free(all_atoms); + return rc; +} +#endif /* UNIQUE_STRATEGY != 0 */ + +/* binary search to find the stack to put this atom "card" on. */ +static int +find_target_stack(struct diff_atom *atom, + struct diff_atom **patience_stacks, + unsigned int patience_stacks_count) +{ + unsigned int lo = 0; + unsigned int hi = patience_stacks_count; + while (lo < hi) { + unsigned int mid = (lo + hi) >> 1; + + if (PATIENCE(patience_stacks[mid]).pos_in_other + < PATIENCE(atom).pos_in_other) + lo = mid + 1; + else + hi = mid; + } + return lo; +} + +/* Among the lines that appear exactly once in each side, find the longest + * streak that appear in both files in the same order (with other stuff allowed + * to interleave). Use patience sort for that, as in the Patience Diff + * algorithm. + * See https://bramcohen.livejournal.com/73318.html and, for a much more + * detailed explanation, + * https://blog.jcoglan.com/2017/09/19/the-patience-diff-algorithm/ */ +int +diff_algo_patience(const struct diff_algo_config *algo_config, + struct diff_state *state) +{ + int rc; + struct diff_data *left = &state->left; + struct diff_data *right = &state->right; + struct atom_patience *atom_patience_left = + calloc(left->atoms.len, sizeof(struct atom_patience)); + struct atom_patience *atom_patience_right = + calloc(right->atoms.len, sizeof(struct atom_patience)); + unsigned int unique_in_both_count; + struct diff_atom **lcs = NULL; + + debug("\n** %s\n", __func__); + + left->root->current = left; + right->root->current = right; + left->algo_data = atom_patience_left; + right->algo_data = atom_patience_right; + + /* Find those lines that appear exactly once in 'left' and exactly once + * in 'right'. */ + rc = diff_atoms_mark_unique_in_both(left, right, &unique_in_both_count); + if (rc) + goto free_and_exit; + + debug("unique_in_both_count %u\n", unique_in_both_count); + debug("left:\n"); + debug_dump(left); + debug("right:\n"); + debug_dump(right); + + if (!unique_in_both_count) { + /* Cannot apply Patience, tell the caller to use fallback_algo + * instead. */ + rc = DIFF_RC_USE_DIFF_ALGO_FALLBACK; + goto free_and_exit; + } + + rc = ENOMEM; + + /* An array of Longest Common Sequence is the result of the below + * subscope: */ + unsigned int lcs_count = 0; + struct diff_atom *lcs_tail = NULL; + + { + /* This subscope marks the lifetime of the atom_pointers + * allocation */ + + /* One chunk of storage for atom pointers */ + struct diff_atom **atom_pointers; + atom_pointers = recallocarray(NULL, 0, unique_in_both_count * 2, + sizeof(struct diff_atom*)); + if (atom_pointers == NULL) + return ENOMEM; + /* Half for the list of atoms that still need to be put on + * stacks */ + struct diff_atom **uniques = atom_pointers; + + /* Half for the patience sort state's "card stacks" -- we + * remember only each stack's topmost "card" */ + struct diff_atom **patience_stacks; + patience_stacks = atom_pointers + unique_in_both_count; + unsigned int patience_stacks_count = 0; + + /* Take all common, unique items from 'left' ... */ + + struct diff_atom *atom; + struct diff_atom **uniques_end = uniques; + diff_data_foreach_atom(atom, left) { + if (!PATIENCE(atom).unique_in_both) + continue; + *uniques_end = atom; + uniques_end++; + } + + /* ...and sort them to the order found in 'right'. + * The idea is to find the leftmost stack that has a higher line + * number and add it to the stack's top. + * If there is no such stack, open a new one on the right. The + * line number is derived from the atom*, which are array items + * and hence reflect the relative position in the source file. + * So we got the common-uniques from 'left' and sort them + * according to PATIENCE(atom).pos_in_other. */ + unsigned int i; + for (i = 0; i < unique_in_both_count; i++) { + atom = uniques[i]; + unsigned int target_stack; + target_stack = find_target_stack(atom, patience_stacks, + patience_stacks_count); + assert(target_stack <= patience_stacks_count); + patience_stacks[target_stack] = atom; + if (target_stack == patience_stacks_count) + patience_stacks_count++; + + /* Record a back reference to the next stack on the + * left, which will form the final longest sequence + * later. */ + PATIENCE(atom).prev_stack = target_stack ? + patience_stacks[target_stack - 1] : NULL; + + { + int xx; + for (xx = 0; xx < patience_stacks_count; xx++) { + debug(" %s%d", + (xx == target_stack) ? ">" : "", + diff_atom_idx(right, + PATIENCE(patience_stacks[xx]).pos_in_other)); + } + debug("\n"); + } + } + + /* backtrace through prev_stack references to form the final + * longest common sequence */ + lcs_tail = patience_stacks[patience_stacks_count - 1]; + lcs_count = patience_stacks_count; + + /* uniques and patience_stacks are no longer needed. + * Backpointers are in PATIENCE(atom).prev_stack */ + free(atom_pointers); + } + + lcs = recallocarray(NULL, 0, lcs_count, sizeof(struct diff_atom*)); + struct diff_atom **lcs_backtrace_pos = &lcs[lcs_count - 1]; + struct diff_atom *atom; + for (atom = lcs_tail; atom; atom = PATIENCE(atom).prev_stack, lcs_backtrace_pos--) { + assert(lcs_backtrace_pos >= lcs); + *lcs_backtrace_pos = atom; + } + + unsigned int i; + if (DEBUG) { + debug("\npatience LCS:\n"); + for (i = 0; i < lcs_count; i++) { + debug("\n L "); debug_dump_atom(left, right, lcs[i]); + debug(" R "); debug_dump_atom(right, left, + PATIENCE(lcs[i]).pos_in_other); + } + } + + + /* TODO: For each common-unique line found (now listed in lcs), swallow + * lines upwards and downwards that are identical on each side. Requires + * a way to represent atoms being glued to adjacent atoms. */ + + debug("\ntraverse LCS, possibly recursing:\n"); + + /* Now we have pinned positions in both files at which it makes sense to + * divide the diff problem into smaller chunks. Go into the next round: + * look at each section in turn, trying to again find common-unique + * lines in those smaller sections. As soon as no more are found, the + * remaining smaller sections are solved by Myers. */ + /* left_pos and right_pos are indexes in left/right->atoms.head until + * which the atoms are already handled (added to result chunks). */ + unsigned int left_pos = 0; + unsigned int right_pos = 0; + for (i = 0; i <= lcs_count; i++) { + struct diff_atom *atom; + struct diff_atom *atom_r; + /* left_idx and right_idx are indexes of the start of this + * section of identical lines on both sides. + * left_pos marks the index of the first still unhandled line, + * left_idx is the start of an identical section some way + * further down, and this loop adds an unsolved chunk of + * [left_pos..left_idx[ and a solved chunk of + * [left_idx..identical_lines.end[. */ + unsigned int left_idx; + unsigned int right_idx; + + debug("iteration %u of %u left_pos %u right_pos %u\n", + i, lcs_count, left_pos, right_pos); + + if (i < lcs_count) { + atom = lcs[i]; + atom_r = PATIENCE(atom).pos_in_other; + debug("lcs[%u] = left[%u] = right[%u]\n", i, + diff_atom_idx(left, atom), diff_atom_idx(right, atom_r)); + left_idx = diff_atom_idx(left, atom); + right_idx = diff_atom_idx(right, atom_r); + } else { + /* There are no more identical lines until the end of + * left and right. */ + atom = NULL; + atom_r = NULL; + left_idx = left->atoms.len; + right_idx = right->atoms.len; + } + + /* 'atom' (if not NULL) now marks an atom that matches on both + * sides according to patience-diff (a common-unique identical + * atom in both files). + * Handle the section before and the atom itself; the section + * after will be handled by the next loop iteration -- note that + * i loops to last element + 1 ("i <= lcs_count"), so that there + * will be another final iteration to pick up the last remaining + * items after the last LCS atom. + */ + + debug("iteration %u left_pos %u left_idx %u" + " right_pos %u right_idx %u\n", + i, left_pos, left_idx, right_pos, right_idx); + + /* Section before the matching atom */ + struct diff_atom *left_atom = &left->atoms.head[left_pos]; + unsigned int left_section_len = left_idx - left_pos; + + struct diff_atom *right_atom = &(right->atoms.head[right_pos]); + unsigned int right_section_len = right_idx - right_pos; + + if (left_section_len && right_section_len) { + /* Record an unsolved chunk, the caller will apply + * inner_algo() on this chunk. */ + if (!diff_state_add_chunk(state, false, + left_atom, left_section_len, + right_atom, + right_section_len)) + goto free_and_exit; + } else if (left_section_len && !right_section_len) { + /* Only left atoms and none on the right, they form a + * "minus" chunk, then. */ + if (!diff_state_add_chunk(state, true, + left_atom, left_section_len, + right_atom, 0)) + goto free_and_exit; + } else if (!left_section_len && right_section_len) { + /* No left atoms, only atoms on the right, they form a + * "plus" chunk, then. */ + if (!diff_state_add_chunk(state, true, + left_atom, 0, + right_atom, right_section_len)) + goto free_and_exit; + } + /* else: left_section_len == 0 and right_section_len == 0, i.e. + * nothing here. */ + + /* The atom found to match on both sides forms a chunk of equals + * on each side. In the very last iteration of this loop, there + * is no matching atom, we were just cleaning out the remaining + * lines. */ + if (atom) { + void *ok; + ok = diff_state_add_chunk(state, true, + atom, 1, + PATIENCE(atom).pos_in_other, 1); + if (!ok) + goto free_and_exit; + } + left_pos = left_idx + 1; + right_pos = right_idx + 1; + debug("end of iteration %u left_pos %u left_idx %u" + " right_pos %u right_idx %u\n", + i, left_pos, left_idx, right_pos, right_idx); + } + debug("** END %s\n", __func__); + + rc = DIFF_RC_OK; + +free_and_exit: + left->root->current = NULL; + right->root->current = NULL; + free(atom_patience_left); + free(atom_patience_right); + if (lcs) + free(lcs); + return rc; +} diff --git a/man/diff.1 b/man/diff.1 new file mode 100644 index 000000000000..b4a9acb0cdc7 --- /dev/null +++ b/man/diff.1 @@ -0,0 +1,47 @@ +.\" $OpenBSD$ +.\" +.\" Copyright (c) 2018 Martin Pieuchot +.\" Copyright (c) 2020 Neels Hofmeyr +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: August 28 2017 $ +.Dt DIFF 1 +.Os +.Sh NAME +.Nm diff +.Nd compare files +.Sh SYNOPSIS +.Nm diff +.Ar file1 file2 +.Sh DESCRIPTION +The +.Nm +utility compares the contents of +.Ar file1 +and +.Ar file2 +line by line. +.Sh EXIT STATUS +The +.Nm +utility exits with one of the following values: +.Pp +.Bl -tag -width Ds -offset indent -compact +.It 0 +No differences were found. +.It 1 +Differences were found. +.It >1 +An error occurred. +.El diff --git a/test/GNUmakefile b/test/GNUmakefile new file mode 100644 index 000000000000..c88d884448ed --- /dev/null +++ b/test/GNUmakefile @@ -0,0 +1,11 @@ +.PHONY: test verify clean +test: verify clean + +# verify_all.sh runs 'make' on sub-directories containing C tests +verify: + ./verify_all.sh +clean: + -rm verify.* + -$(MAKE) -C ../lib clean + -$(MAKE) -C arraylist_test clean + -$(MAKE) -C results_test clean diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 000000000000..f42511784ccd --- /dev/null +++ b/test/Makefile @@ -0,0 +1,12 @@ +.PHONY: test verify clean + +test: verify clean + +# verify_all.sh runs 'make' on sub-directories containing C tests +verify: + ./verify_all.sh + +clean: + -rm verify.* + make -C arraylist_test clean + make -C results_test clean diff --git a/test/README b/test/README new file mode 100644 index 000000000000..60764f106146 --- /dev/null +++ b/test/README @@ -0,0 +1,7 @@ +The test produces a diff, which is successful if it is able to reconstruct the +original source files from it. It is not tested whether diff output is optimal +or beautiful. + +Since different diff algorithms can produce different diff outputs, the +expect*.diff files are merely provided for reference and are not part of the +tests. diff --git a/test/arraylist_test.c b/test/arraylist_test.c new file mode 100644 index 000000000000..da5542e8d629 --- /dev/null +++ b/test/arraylist_test.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include + +void test_basic(void) +{ + int *p; + ARRAYLIST(int) list; + ARRAYLIST_INIT(list, 2); + +#define dump() do {\ + printf("(%d items)\n", list.len); \ + ARRAYLIST_FOREACH(p, list) \ + printf("[%lu] %d\n", \ + (unsigned long)ARRAYLIST_IDX(p, list), *p); \ + printf("\n"); \ + } while(0) + + dump(); + + ARRAYLIST_ADD(p, list); + *p = 100; + dump(); + + ARRAYLIST_ADD(p, list); + *p = 101; + dump(); + + ARRAYLIST_ADD(p, list); + *p = 102; + dump(); + +#define insert_test(AT) do {\ + printf("insert at [" #AT "]:\n"); \ + ARRAYLIST_INSERT(p, list, AT); \ + *p = AT; \ + dump(); \ + } while(0) + + insert_test(list.len - 1); + insert_test(1); + insert_test(0); + insert_test(6); + insert_test(123); + insert_test(-42); + + printf("clear:\n"); + ARRAYLIST_CLEAR(list); + dump(); + + ARRAYLIST_FREE(list); +} + +int main(void) +{ + test_basic(); +} diff --git a/test/arraylist_test/GNUmakefile b/test/arraylist_test/GNUmakefile new file mode 100644 index 000000000000..9f781ee997b3 --- /dev/null +++ b/test/arraylist_test/GNUmakefile @@ -0,0 +1,20 @@ +.PHONY: regress clean + +CFLAGS = -fsanitize=address -fsanitize=undefined -g -O3 +CFLAGS += -Wstrict-prototypes -Wunused-variable -Wuninitialized + +CFLAGS+= -I$(CURDIR)/../../compat/include \ + -I$(CURDIR)/../../include \ + -I$(CURDIR)/../../lib + +$(CURDIR)/arraylist_test: $(CURDIR)/../arraylist_test.c $(CURDIR)/../../lib/libdiff.a + gcc $(CFLAGS) -o $@ $^ + +$(CURDIR)/../../lib/libdiff.a: $(CURDIR)/../../lib/*.[hc] $(CURDIR)/../../include/*.h + $(MAKE) -C $(CURDIR)/../../lib + +regress: $(CURDIR)/arraylist_test + $(CURDIR)/arraylist_test + +clean: + -rm $(CURDIR)/arraylist_test diff --git a/test/arraylist_test/Makefile b/test/arraylist_test/Makefile new file mode 100644 index 000000000000..f088f4767c92 --- /dev/null +++ b/test/arraylist_test/Makefile @@ -0,0 +1,11 @@ +.PATH:${.CURDIR}/../../lib +.PATH:${.CURDIR}/.. + +PROG = arraylist_test +SRCS = arraylist_test.c + +CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib + +NOMAN = yes + +.include diff --git a/test/expect.arraylist_test b/test/expect.arraylist_test new file mode 100644 index 000000000000..6b255ecbe78e --- /dev/null +++ b/test/expect.arraylist_test @@ -0,0 +1,76 @@ +==== run-regress-arraylist_test ==== +(0 items) + +(1 items) +[0] 100 + +(2 items) +[0] 100 +[1] 101 + +(3 items) +[0] 100 +[1] 101 +[2] 102 + +insert at [list.len - 1]: +(4 items) +[0] 100 +[1] 101 +[2] 3 +[3] 102 + +insert at [1]: +(5 items) +[0] 100 +[1] 1 +[2] 101 +[3] 3 +[4] 102 + +insert at [0]: +(6 items) +[0] 0 +[1] 100 +[2] 1 +[3] 101 +[4] 3 +[5] 102 + +insert at [6]: +(7 items) +[0] 0 +[1] 100 +[2] 1 +[3] 101 +[4] 3 +[5] 102 +[6] 6 + +insert at [123]: +(8 items) +[0] 0 +[1] 100 +[2] 1 +[3] 101 +[4] 3 +[5] 102 +[6] 6 +[7] 123 + +insert at [-42]: +(9 items) +[0] 0 +[1] 100 +[2] 1 +[3] 101 +[4] 3 +[5] 102 +[6] 6 +[7] 123 +[8] -42 + +clear: +(0 items) + + diff --git a/test/expect.results_test b/test/expect.results_test new file mode 100644 index 000000000000..93755ac42bd2 --- /dev/null +++ b/test/expect.results_test @@ -0,0 +1,14 @@ +==== run-regress-results_test ==== + +--- test_minus_after_plus() +[0] same lines L2 R2 @L 0 @R 0 +[1] minus lines L3 R0 @L 2 @R 2 +[2] plus lines L0 R3 @L 5 @R 2 +[3] same lines L2 R2 @L 5 @R 5 + +--- test_plus_after_plus() +[0] same lines L2 R2 @L 0 @R 0 +[1] minus lines L3 R0 @L 2 @R 2 +[2] plus lines L0 R3 @L 5 @R 2 +[3] same lines L2 R2 @L 5 @R 5 + diff --git a/test/expect001.diff b/test/expect001.diff new file mode 100644 index 000000000000..7dd803c57dde --- /dev/null +++ b/test/expect001.diff @@ -0,0 +1,12 @@ +--- test001.left.txt ++++ test001.right.txt +@@ -1,7 +1,6 @@ +-A +-B + C ++B + A + B +-B + A ++C diff --git a/test/expect002.diff b/test/expect002.diff new file mode 100644 index 000000000000..d6c64921df76 --- /dev/null +++ b/test/expect002.diff @@ -0,0 +1,16 @@ +--- test002.left.txt ++++ test002.right.txt +@@ -1,10 +1,9 @@ +-A +-B + C ++B + A + B +-B + A ++C + X +-Y + Z ++Q diff --git a/test/expect003.diff b/test/expect003.diff new file mode 100644 index 000000000000..1694445da790 --- /dev/null +++ b/test/expect003.diff @@ -0,0 +1,10 @@ +--- test003.left.txt ++++ test003.right.txt +@@ -1,5 +1,4 @@ +-a ++x + b + c +-d +-e ++y diff --git a/test/expect004.diff b/test/expect004.diff new file mode 100644 index 000000000000..061a76ad650b --- /dev/null +++ b/test/expect004.diff @@ -0,0 +1,24 @@ +--- test004.left.txt ++++ test004.right.txt +@@ -1,3 +1,10 @@ ++int Chunk_bounds_check(Chunk *chunk, size_t start, size_t n) ++{ ++ if (chunk == NULL) return 0; ++ ++ return start <= chunk->length && n <= chunk->length - start; ++} ++ + void Chunk_copy(Chunk *src, size_t src_start, Chunk *dst, size_t dst_start, size_t n) + { + if (!Chunk_bounds_check(src, src_start, n)) return; +@@ -5,10 +12,3 @@ + + memcpy(dst->data + dst_start, src->data + src_start, n); + } +- +-int Chunk_bounds_check(Chunk *chunk, size_t start, size_t n) +-{ +- if (chunk == NULL) return 0; +- +- return start <= chunk->length && n <= chunk->length - start; +-} diff --git a/test/expect005.diff b/test/expect005.diff new file mode 100644 index 000000000000..9ce014a67eb6 --- /dev/null +++ b/test/expect005.diff @@ -0,0 +1,12 @@ +--- test005.left.txt ++++ test005.right.txt +@@ -1,7 +1,7 @@ ++The Slits ++Gil Scott Heron + David Axelrod + Electric Prunes +-Gil Scott Heron +-The Slits + Faust + The Sonics + The Sonics diff --git a/test/expect006.diff b/test/expect006.diff new file mode 100644 index 000000000000..70233e0337e1 --- /dev/null +++ b/test/expect006.diff @@ -0,0 +1,24 @@ +--- test006.left.txt ++++ test006.right.txt +@@ -3,7 +3,7 @@ + + It is important to specify the year of the copyright. Additional years + should be separated by a comma, e.g. +- Copyright (c) 2003, 2004 ++ Copyright (c) 2003, 2004, 2005 + + If you add extra text to the body of the license, be careful not to + add further restrictions. +@@ -11,7 +11,6 @@ + /* + * Copyright (c) CCYY YOUR NAME HERE + * +- * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * +@@ -23,3 +22,4 @@ + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ ++An extra line diff --git a/test/expect007.diff b/test/expect007.diff new file mode 100644 index 000000000000..a6a06181d840 --- /dev/null +++ b/test/expect007.diff @@ -0,0 +1,5 @@ +--- test007.left.txt ++++ test007.right.txt +@@ -1 +1 @@ +-x ++abcdx diff --git a/test/expect008.diff b/test/expect008.diff new file mode 100644 index 000000000000..c4dc6791528b --- /dev/null +++ b/test/expect008.diff @@ -0,0 +1,9 @@ +--- test008.left.txt ++++ test008.right.txt +@@ -1 +1,6 @@ + x ++a ++b ++c ++d ++x diff --git a/test/expect009.diff b/test/expect009.diff new file mode 100644 index 000000000000..c2dae93ed893 --- /dev/null +++ b/test/expect009.diff @@ -0,0 +1,13 @@ +--- test009.left.txt ++++ test009.right.txt +@@ -1,3 +1,10 @@ + x + a + b ++c ++d ++e ++f ++x ++a ++b diff --git a/test/expect010.diff b/test/expect010.diff new file mode 100644 index 000000000000..868a057dec4d --- /dev/null +++ b/test/expect010.diff @@ -0,0 +1,19 @@ +--- test010.left.txt ++++ test010.right.txt +@@ -1,4 +1,4 @@ +-/* $OpenBSD: usbdevs_data.h,v 1.715 2020/01/20 07:09:11 jsg Exp $ */ ++/* $OpenBSD$ */ + + /* + * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. +@@ -10979,6 +10979,10 @@ + }, + { + USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8192EU, ++ "RTL8192EU", ++ }, ++ { ++ USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8192EU_2, + "RTL8192EU", + }, + { diff --git a/test/expect011.diff b/test/expect011.diff new file mode 100644 index 000000000000..7ad8f311b3e6 --- /dev/null +++ b/test/expect011.diff @@ -0,0 +1,19 @@ +--- test011.left.txt ++++ test011.right.txt +@@ -1,4 +1,4 @@ +-/* $OpenBSD: usbdevs_data.h,v 1.715 2020/01/20 07:09:11 jsg Exp $ */ ++/* $OpenBSD$ */ + + /* + * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. +@@ -375,6 +375,10 @@ + }, + { + USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8192EU, ++ "RTL8192EU", ++ }, ++ { ++ USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8192EU_2, + "RTL8192EU", + }, + { diff --git a/test/expect012.diff b/test/expect012.diff new file mode 100644 index 000000000000..e9a704b8c534 --- /dev/null +++ b/test/expect012.diff @@ -0,0 +1,21 @@ +--- test012.left.txt ++++ test012.right.txt +@@ -1,4 +1,4 @@ +-1 left ++1 right + 2 + 3 + 4 +@@ -17,6 +17,12 @@ + 17 + 18 + 19 ++14 ++15 ++16 right ++17 ++18 ++19 + 20 + 21 + 22 diff --git a/test/expect013.diff b/test/expect013.diff new file mode 100644 index 000000000000..139970c971d6 --- /dev/null +++ b/test/expect013.diff @@ -0,0 +1,10 @@ +--- test013.left-w.txt ++++ test013.right-w.txt +@@ -3,5 +3,5 @@ + C + D + E +-F +-G ++F x ++y G diff --git a/test/expect014.diff b/test/expect014.diff new file mode 100644 index 000000000000..43af317b26f1 --- /dev/null +++ b/test/expect014.diff @@ -0,0 +1,4 @@ +--- test014.left.txt ++++ test014.right.txt +@@ -0,0 +1 @@ ++A diff --git a/test/expect015.diff b/test/expect015.diff new file mode 100644 index 000000000000..fd5d0482ba38 --- /dev/null +++ b/test/expect015.diff @@ -0,0 +1,4 @@ +--- test015.left.txt ++++ test015.right.txt +@@ -1 +0,0 @@ +-A diff --git a/test/expect016.diff b/test/expect016.diff new file mode 100644 index 000000000000..17299d578095 --- /dev/null +++ b/test/expect016.diff @@ -0,0 +1,30 @@ +--- test016.left.txt ++++ test016.right.txt +@@ -254,7 +254,7 @@ + const char *uri, *dirname; + char *proto, *host, *port, *repo_name, *server_path; + char *default_destdir = NULL, *id_str = NULL; +- const char *repo_path; ++ const char *repo_path, *remote_repo_path; + struct got_repository *repo = NULL; + struct got_pathlist_head refs, symrefs, wanted_branches, wanted_refs; + struct got_pathlist_entry *pe; +@@ -275,6 +275,9 @@ + goto done; + } + got_path_strip_trailing_slashes(server_path); ++ remote_repo_path = server_path; ++ while (remote_repo_path[0] == '/') ++ remote_repo_path++; + if (asprintf(&gotconfig, + "remote \"%s\" {\n" + "\tserver %s\n" +@@ -285,7 +288,7 @@ + "}\n", + GOT_FETCH_DEFAULT_REMOTE_NAME, host, proto, + port ? "\tport " : "", port ? port : "", port ? "\n" : "", +- server_path, ++ remote_repo_path, + mirror_references ? "\tmirror-references yes\n" : "") == -1) { + error = got_error_from_errno("asprintf"); + goto done; diff --git a/test/expect018.diff b/test/expect018.diff new file mode 100644 index 000000000000..c948e6210e5c --- /dev/null +++ b/test/expect018.diff @@ -0,0 +1,16 @@ +--- test018.left-T.txt ++++ test018.right-T.txt +@@ -1,7 +1,6 @@ +-A +-B +-C +-A +-B +-B +-A ++C ++B ++A ++B ++A ++C diff --git a/test/expect019.diff b/test/expect019.diff new file mode 100644 index 000000000000..ee242a032fca --- /dev/null +++ b/test/expect019.diff @@ -0,0 +1,204 @@ +--- test019.left.txt ++++ test019.right.txt +@@ -40,8 +40,23 @@ + #include "got_lib_object.h" + + static const struct got_error * +-diff_blobs(struct got_diffreg_result **resultp, +-struct got_blob_object *blob1, struct got_blob_object *blob2, ++add_line_offset(off_t **line_offsets, size_t *nlines, off_t off) ++{ ++ off_t *p; ++ ++ p = reallocarray(*line_offsets, *nlines + 1, sizeof(off_t)); ++ if (p == NULL) ++ return got_error_from_errno("reallocarray"); ++ *line_offsets = p; ++ (*line_offsets)[*nlines] = off; ++ (*nlines)++; ++ return NULL; ++} ++ ++static const struct got_error * ++diff_blobs(off_t **line_offsets, size_t *nlines, ++ struct got_diffreg_result **resultp, struct got_blob_object *blob1, ++ struct got_blob_object *blob2, + const char *label1, const char *label2, mode_t mode1, mode_t mode2, + int diff_context, int ignore_whitespace, FILE *outfile) + { +@@ -52,7 +67,12 @@ + char *idstr1 = NULL, *idstr2 = NULL; + size_t size1, size2; + struct got_diffreg_result *result; ++ off_t outoff = 0; ++ int n; + ++ if (line_offsets && *line_offsets && *nlines > 0) ++ outoff = (*line_offsets)[*nlines - 1]; ++ + if (resultp) + *resultp = NULL; + +@@ -116,10 +136,32 @@ + goto done; + } + } +- fprintf(outfile, "blob - %s%s\n", idstr1, ++ n = fprintf(outfile, "blob - %s%s\n", idstr1, + modestr1 ? modestr1 : ""); +- fprintf(outfile, "blob + %s%s\n", idstr2, ++ if (n < 0) { ++ err = got_error_from_errno("fprintf"); ++ goto done; ++ } ++ outoff += n; ++ if (line_offsets) { ++ err = add_line_offset(line_offsets, nlines, outoff); ++ if (err) ++ goto done; ++ } ++ ++ n = fprintf(outfile, "blob + %s%s\n", idstr2, + modestr2 ? modestr2 : ""); ++ if (n < 0) { ++ err = got_error_from_errno("fprintf"); ++ goto done; ++ } ++ outoff += n; ++ if (line_offsets) { ++ err = add_line_offset(line_offsets, nlines, outoff); ++ if (err) ++ goto done; ++ } ++ + free(modestr1); + free(modestr2); + } +@@ -129,7 +171,7 @@ + goto done; + + if (outfile) { +- err = got_diffreg_output(NULL, NULL, result, f1, f2, ++ err = got_diffreg_output(line_offsets, nlines, result, f1, f2, + label1 ? label1 : idstr1, + label2 ? label2 : idstr2, + GOT_DIFF_OUTPUT_UNIDIFF, diff_context, outfile); +@@ -158,21 +200,21 @@ + struct got_object_id *id2, const char *label1, const char *label2, + mode_t mode1, mode_t mode2, struct got_repository *repo) + { +- const struct got_error *err; + struct got_diff_blob_output_unidiff_arg *a = arg; + +- err = diff_blobs(NULL, blob1, blob2, label1, label2, mode1, mode2, +- a->diff_context, a->ignore_whitespace, a->outfile); +- return err; ++ return diff_blobs(&a->line_offsets, &a->nlines, NULL, ++ blob1, blob2, label1, label2, mode1, mode2, a->diff_context, ++ a->ignore_whitespace, a->outfile); + } + + const struct got_error * +-got_diff_blob(struct got_blob_object *blob1, struct got_blob_object *blob2, ++got_diff_blob(off_t **line_offsets, size_t *nlines, ++ struct got_blob_object *blob1, struct got_blob_object *blob2, + const char *label1, const char *label2, int diff_context, + int ignore_whitespace, FILE *outfile) + { +- return diff_blobs(NULL, blob1, blob2, label1, label2, 0, 0, diff_context, +- ignore_whitespace, outfile); ++ return diff_blobs(line_offsets, nlines, NULL, blob1, blob2, ++ label1, label2, 0, 0, diff_context, ignore_whitespace, outfile); + } + + static const struct got_error * +@@ -259,7 +301,8 @@ + { + const struct got_error *err = NULL; + +- err = diff_blobs(result, blob1, blob2, NULL, NULL, 0, 0, 3, 0, NULL); ++ err = diff_blobs(NULL, NULL, result, blob1, blob2, ++ NULL, NULL, 0, 0, 3, 0, NULL); + if (err) { + got_diffreg_result_free(*result); + *result = NULL; +@@ -702,7 +745,8 @@ + } + + const struct got_error * +-got_diff_objects_as_blobs(struct got_object_id *id1, struct got_object_id *id2, ++got_diff_objects_as_blobs(off_t **line_offsets, size_t *nlines, ++ struct got_object_id *id1, struct got_object_id *id2, + const char *label1, const char *label2, int diff_context, + int ignore_whitespace, struct got_repository *repo, FILE *outfile) + { +@@ -722,8 +766,8 @@ + if (err) + goto done; + } +- err = got_diff_blob(blob1, blob2, label1, label2, diff_context, +- ignore_whitespace, outfile); ++ err = got_diff_blob(line_offsets, nlines, blob1, blob2, ++ label1, label2, diff_context, ignore_whitespace, outfile); + done: + if (blob1) + got_object_blob_close(blob1); +@@ -733,13 +777,15 @@ + } + + const struct got_error * +-got_diff_objects_as_trees(struct got_object_id *id1, struct got_object_id *id2, ++got_diff_objects_as_trees(off_t **line_offsets, size_t *nlines, ++ struct got_object_id *id1, struct got_object_id *id2, + char *label1, char *label2, int diff_context, int ignore_whitespace, + struct got_repository *repo, FILE *outfile) + { + const struct got_error *err; + struct got_tree_object *tree1 = NULL, *tree2 = NULL; + struct got_diff_blob_output_unidiff_arg arg; ++ int want_lineoffsets = (line_offsets != NULL && *line_offsets != NULL); + + if (id1 == NULL && id2 == NULL) + return got_error(GOT_ERR_NO_OBJ); +@@ -757,8 +803,20 @@ + arg.diff_context = diff_context; + arg.ignore_whitespace = ignore_whitespace; + arg.outfile = outfile; ++ if (want_lineoffsets) { ++ arg.line_offsets = *line_offsets; ++ arg.nlines = *nlines; ++ } else { ++ arg.line_offsets = NULL; ++ arg.nlines = 0; ++ } + err = got_diff_tree(tree1, tree2, label1, label2, repo, + got_diff_blob_output_unidiff, &arg, 1); ++ ++ if (want_lineoffsets) { ++ *line_offsets = arg.line_offsets; /* was likely re-allocated */ ++ *nlines = arg.nlines; ++ } + done: + if (tree1) + got_object_tree_close(tree1); +@@ -768,8 +826,9 @@ + } + + const struct got_error * +-got_diff_objects_as_commits(struct got_object_id *id1, +- struct got_object_id *id2, int diff_context, int ignore_whitespace, ++got_diff_objects_as_commits(off_t **line_offsets, size_t *nlines, ++ struct got_object_id *id1, struct got_object_id *id2, ++ int diff_context, int ignore_whitespace, + struct got_repository *repo, FILE *outfile) + { + const struct got_error *err; +@@ -788,7 +847,7 @@ + if (err) + goto done; + +- err = got_diff_objects_as_trees( ++ err = got_diff_objects_as_trees(line_offsets, nlines, + commit1 ? got_object_commit_get_tree_id(commit1) : NULL, + got_object_commit_get_tree_id(commit2), "", "", diff_context, + ignore_whitespace, repo, outfile); diff --git a/test/expect021.diff b/test/expect021.diff new file mode 100644 index 000000000000..076ccd4d4a2d --- /dev/null +++ b/test/expect021.diff @@ -0,0 +1,868 @@ +--- test021.left.txt ++++ test021.right.txt +@@ -1,4 +1,4 @@ +-/* $OpenBSD: softraid_crypto.c,v 1.91 2013/03/31 15:44:52 jsing Exp $ */ ++/* $OpenBSD: softraid_crypto.c,v 1.139 2020/07/13 00:06:22 kn Exp $ */ + /* + * Copyright (c) 2007 Marco Peereboom + * Copyright (c) 2008 Hans-Joerg Hoexer +@@ -25,7 +25,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -34,6 +33,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -42,7 +42,6 @@ + #include + + #include +-#include + #include + #include + #include +@@ -54,7 +53,6 @@ + #include + + #include +-#include + + /* + * The per-I/O data that we need to preallocate. We cannot afford to allow I/O +@@ -62,18 +60,15 @@ + * because we assert that only one ccb per WU will ever be active. + */ + struct sr_crypto_wu { +- TAILQ_ENTRY(sr_crypto_wu) cr_link; ++ struct sr_workunit cr_wu; /* Must be first. */ + struct uio cr_uio; + struct iovec cr_iov; + struct cryptop *cr_crp; +- struct cryptodesc *cr_descs; +- struct sr_workunit *cr_wu; + void *cr_dmabuf; + }; + + +-struct sr_crypto_wu *sr_crypto_wu_get(struct sr_workunit *, int); +-void sr_crypto_wu_put(struct sr_crypto_wu *); ++struct sr_crypto_wu *sr_crypto_prepare(struct sr_workunit *, int); + int sr_crypto_create_keys(struct sr_discipline *); + int sr_crypto_get_kdf(struct bioc_createraid *, + struct sr_discipline *); +@@ -92,12 +87,11 @@ + struct bioc_discipline *); + int sr_crypto_meta_opt_handler(struct sr_discipline *, + struct sr_meta_opt_hdr *); +-int sr_crypto_write(struct cryptop *); ++void sr_crypto_write(struct cryptop *); + int sr_crypto_rw(struct sr_workunit *); +-int sr_crypto_rw2(struct sr_workunit *, struct sr_crypto_wu *); ++int sr_crypto_dev_rw(struct sr_workunit *, struct sr_crypto_wu *); + void sr_crypto_done(struct sr_workunit *); +-int sr_crypto_read(struct cryptop *); +-void sr_crypto_finish_io(struct sr_workunit *); ++void sr_crypto_read(struct cryptop *); + void sr_crypto_calculate_check_hmac_sha1(u_int8_t *, int, + u_int8_t *, int, u_char *); + void sr_crypto_hotplug(struct sr_discipline *, struct disk *, int); +@@ -113,6 +107,7 @@ + int i; + + /* Fill out discipline members. */ ++ sd->sd_wu_size = sizeof(struct sr_crypto_wu); + sd->sd_type = SR_MD_CRYPTO; + strlcpy(sd->sd_name, "CRYPTO", sizeof(sd->sd_name)); + sd->sd_capabilities = SR_CAP_SYSTEM_DISK | SR_CAP_AUTO_ASSEMBLE; +@@ -143,8 +138,14 @@ + sr_error(sd->sd_sc, "%s requires exactly one chunk", + sd->sd_name); + goto done; +- } ++ } + ++ if (coerced_size > SR_CRYPTO_MAXSIZE) { ++ sr_error(sd->sd_sc, "%s exceeds maximum size (%lli > %llu)", ++ sd->sd_name, coerced_size, SR_CRYPTO_MAXSIZE); ++ goto done; ++ } ++ + /* Create crypto optional metadata. */ + omi = malloc(sizeof(struct sr_meta_opt_item), M_DEVBUF, + M_WAITOK | M_ZERO); +@@ -208,7 +209,7 @@ + + if (data != NULL) { + /* Kernel already has mask key. */ +- bcopy(data, sd->mds.mdd_crypto.scr_maskkey, ++ memcpy(sd->mds.mdd_crypto.scr_maskkey, data, + sizeof(sd->mds.mdd_crypto.scr_maskkey)); + } else if (bc->bc_key_disk != NODEV) { + /* Read the mask key from the key disk. */ +@@ -248,117 +249,69 @@ + } + + struct sr_crypto_wu * +-sr_crypto_wu_get(struct sr_workunit *wu, int encrypt) ++sr_crypto_prepare(struct sr_workunit *wu, int encrypt) + { + struct scsi_xfer *xs = wu->swu_xs; + struct sr_discipline *sd = wu->swu_dis; + struct sr_crypto_wu *crwu; + struct cryptodesc *crd; + int flags, i, n; +- daddr64_t blk = 0; ++ daddr_t blkno; + u_int keyndx; + +- DNPRINTF(SR_D_DIS, "%s: sr_crypto_wu_get wu: %p encrypt: %d\n", ++ DNPRINTF(SR_D_DIS, "%s: sr_crypto_prepare wu %p encrypt %d\n", + DEVNAME(sd->sd_sc), wu, encrypt); + +- mtx_enter(&sd->mds.mdd_crypto.scr_mutex); +- if ((crwu = TAILQ_FIRST(&sd->mds.mdd_crypto.scr_wus)) != NULL) +- TAILQ_REMOVE(&sd->mds.mdd_crypto.scr_wus, crwu, cr_link); +- mtx_leave(&sd->mds.mdd_crypto.scr_mutex); +- if (crwu == NULL) +- panic("sr_crypto_wu_get: out of wus"); +- ++ crwu = (struct sr_crypto_wu *)wu; + crwu->cr_uio.uio_iovcnt = 1; + crwu->cr_uio.uio_iov->iov_len = xs->datalen; + if (xs->flags & SCSI_DATA_OUT) { + crwu->cr_uio.uio_iov->iov_base = crwu->cr_dmabuf; +- bcopy(xs->data, crwu->cr_uio.uio_iov->iov_base, xs->datalen); ++ memcpy(crwu->cr_uio.uio_iov->iov_base, xs->data, xs->datalen); + } else + crwu->cr_uio.uio_iov->iov_base = xs->data; + +- if (xs->cmdlen == 10) +- blk = _4btol(((struct scsi_rw_big *)xs->cmd)->addr); +- else if (xs->cmdlen == 16) +- blk = _8btol(((struct scsi_rw_16 *)xs->cmd)->addr); +- else if (xs->cmdlen == 6) +- blk = _3btol(((struct scsi_rw *)xs->cmd)->addr); +- ++ blkno = wu->swu_blk_start; + n = xs->datalen >> DEV_BSHIFT; + + /* + * We preallocated enough crypto descs for up to MAXPHYS of I/O. +- * Since there may be less than that we need to tweak the linked list ++ * Since there may be less than that we need to tweak the amount + * of crypto desc structures to be just long enough for our needs. + */ +- crd = crwu->cr_descs; +- for (i = 0; i < ((MAXPHYS >> DEV_BSHIFT) - n); i++) { +- crd = crd->crd_next; +- KASSERT(crd); +- } +- crwu->cr_crp->crp_desc = crd; ++ KASSERT(crwu->cr_crp->crp_ndescalloc >= n); ++ crwu->cr_crp->crp_ndesc = n; + flags = (encrypt ? CRD_F_ENCRYPT : 0) | + CRD_F_IV_PRESENT | CRD_F_IV_EXPLICIT; + +- /* Select crypto session based on block number */ +- keyndx = blk >> SR_CRYPTO_KEY_BLKSHIFT; +- if (keyndx >= SR_CRYPTO_MAXKEYS) +- goto unwind; ++ /* ++ * Select crypto session based on block number. ++ * ++ * XXX - this does not handle the case where the read/write spans ++ * across a different key blocks (e.g. 0.5TB boundary). Currently ++ * this is already broken by the use of scr_key[0] below. ++ */ ++ keyndx = blkno >> SR_CRYPTO_KEY_BLKSHIFT; + crwu->cr_crp->crp_sid = sd->mds.mdd_crypto.scr_sid[keyndx]; +- if (crwu->cr_crp->crp_sid == (u_int64_t)-1) +- goto unwind; + ++ crwu->cr_crp->crp_opaque = crwu; + crwu->cr_crp->crp_ilen = xs->datalen; + crwu->cr_crp->crp_alloctype = M_DEVBUF; ++ crwu->cr_crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_NOQUEUE; + crwu->cr_crp->crp_buf = &crwu->cr_uio; +- for (i = 0, crd = crwu->cr_crp->crp_desc; crd; +- i++, blk++, crd = crd->crd_next) { ++ for (i = 0; i < crwu->cr_crp->crp_ndesc; i++, blkno++) { ++ crd = &crwu->cr_crp->crp_desc[i]; + crd->crd_skip = i << DEV_BSHIFT; + crd->crd_len = DEV_BSIZE; + crd->crd_inject = 0; + crd->crd_flags = flags; +- crd->crd_alg = CRYPTO_AES_XTS; +- +- switch (sd->mds.mdd_crypto.scr_meta->scm_alg) { +- case SR_CRYPTOA_AES_XTS_128: +- crd->crd_klen = 256; +- break; +- case SR_CRYPTOA_AES_XTS_256: +- crd->crd_klen = 512; +- break; +- default: +- goto unwind; +- } ++ crd->crd_alg = sd->mds.mdd_crypto.scr_alg; ++ crd->crd_klen = sd->mds.mdd_crypto.scr_klen; + crd->crd_key = sd->mds.mdd_crypto.scr_key[0]; +- bcopy(&blk, crd->crd_iv, sizeof(blk)); ++ memcpy(crd->crd_iv, &blkno, sizeof(blkno)); + } +- crwu->cr_wu = wu; +- crwu->cr_crp->crp_opaque = crwu; + + return (crwu); +- +-unwind: +- /* steal the descriptors back from the cryptop */ +- crwu->cr_crp->crp_desc = NULL; +- +- return (NULL); +-} +- +-void +-sr_crypto_wu_put(struct sr_crypto_wu *crwu) +-{ +- struct cryptop *crp = crwu->cr_crp; +- struct sr_workunit *wu = crwu->cr_wu; +- struct sr_discipline *sd = wu->swu_dis; +- +- DNPRINTF(SR_D_DIS, "%s: sr_crypto_wu_put crwu: %p\n", +- DEVNAME(wu->swu_dis->sd_sc), crwu); +- +- /* steal the descriptors back from the cryptop */ +- crp->crp_desc = NULL; +- +- mtx_enter(&sd->mds.mdd_crypto.scr_mutex); +- TAILQ_INSERT_TAIL(&sd->mds.mdd_crypto.scr_wus, crwu, cr_link); +- mtx_leave(&sd->mds.mdd_crypto.scr_mutex); + } + + int +@@ -386,9 +339,8 @@ + if (sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint) < + kdfinfo->genkdf.len) + goto out; +- bcopy(&kdfinfo->genkdf, +- sd->mds.mdd_crypto.scr_meta->scm_kdfhint, +- kdfinfo->genkdf.len); ++ memcpy(sd->mds.mdd_crypto.scr_meta->scm_kdfhint, ++ &kdfinfo->genkdf, kdfinfo->genkdf.len); + } + + /* copy mask key to run-time meta data */ +@@ -396,7 +348,7 @@ + if (sizeof(sd->mds.mdd_crypto.scr_maskkey) < + sizeof(kdfinfo->maskkey)) + goto out; +- bcopy(&kdfinfo->maskkey, sd->mds.mdd_crypto.scr_maskkey, ++ memcpy(sd->mds.mdd_crypto.scr_maskkey, &kdfinfo->maskkey, + sizeof(kdfinfo->maskkey)); + } + +@@ -404,7 +356,7 @@ + rv = 0; + out: + explicit_bzero(kdfinfo, bc->bc_opaque_size); +- free(kdfinfo, M_DEVBUF); ++ free(kdfinfo, M_DEVBUF, bc->bc_opaque_size); + + return (rv); + } +@@ -424,7 +376,7 @@ + rv = 0; + break; + default: +- DNPRINTF(SR_D_DIS, "%s: unsupported encryption algorithm %u\n", ++ DNPRINTF(SR_D_DIS, "%s: unsupported encryption algorithm %d\n", + "softraid", alg); + rv = -1; + goto out; +@@ -450,7 +402,7 @@ + rv = 0; + break; + default: +- DNPRINTF(SR_D_DIS, "%s: unsupported encryption algorithm %u\n", ++ DNPRINTF(SR_D_DIS, "%s: unsupported encryption algorithm %d\n", + "softraid", alg); + rv = -1; + goto out; +@@ -615,6 +567,17 @@ + sr_error(sd->sd_sc, "incorrect key or passphrase"); + rv = EPERM; + goto out; ++ } ++ ++ /* Copy new KDF hint to metadata, if supplied. */ ++ if (kdfinfo2->flags & SR_CRYPTOKDF_HINT) { ++ if (kdfinfo2->genkdf.len > ++ sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint)) ++ goto out; ++ explicit_bzero(sd->mds.mdd_crypto.scr_meta->scm_kdfhint, ++ sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint)); ++ memcpy(sd->mds.mdd_crypto.scr_meta->scm_kdfhint, ++ &kdfinfo2->genkdf, kdfinfo2->genkdf.len); + } + + /* Mask the disk keys. */ +@@ -630,7 +593,7 @@ + sizeof(sd->mds.mdd_crypto.scr_key), check_digest); + + /* Copy new encrypted key and HMAC to metadata. */ +- bcopy(check_digest, sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac, ++ memcpy(sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac, check_digest, + sizeof(sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac)); + + rv = 0; /* Success */ +@@ -638,7 +601,7 @@ + out: + if (p) { + explicit_bzero(p, ksz); +- free(p, M_DEVBUF); ++ free(p, M_DEVBUF, ksz); + } + + explicit_bzero(check_digest, sizeof(check_digest)); +@@ -686,7 +649,7 @@ + DNPRINTF(SR_D_META,"%s: sr_crypto_create_key_disk cannot " + "open %s\n", DEVNAME(sc), devname); + vput(vn); +- goto fail; ++ goto done; + } + open = 1; /* close dev on error */ + +@@ -696,19 +659,12 @@ + FREAD, NOCRED, curproc)) { + DNPRINTF(SR_D_META, "%s: sr_crypto_create_key_disk ioctl " + "failed\n", DEVNAME(sc)); +- VOP_CLOSE(vn, FREAD | FWRITE, NOCRED, curproc); +- vput(vn); +- goto fail; ++ goto done; + } +- if (label.d_secsize != DEV_BSIZE) { +- sr_error(sc, "%s has unsupported sector size (%d)", +- devname, label.d_secsize); +- goto fail; +- } + if (label.d_partitions[part].p_fstype != FS_RAID) { +- sr_error(sc, "%s partition not of type RAID (%d)\n", ++ sr_error(sc, "%s partition not of type RAID (%d)", + devname, label.d_partitions[part].p_fstype); +- goto fail; ++ goto done; + } + + /* +@@ -728,7 +684,7 @@ + km->scmi.scm_size = 0; + km->scmi.scm_coerced_size = 0; + strlcpy(km->scmi.scm_devname, devname, sizeof(km->scmi.scm_devname)); +- bcopy(&sd->sd_meta->ssdi.ssd_uuid, &km->scmi.scm_uuid, ++ memcpy(&km->scmi.scm_uuid, &sd->sd_meta->ssdi.ssd_uuid, + sizeof(struct sr_uuid)); + + sr_checksum(sc, km, &km->scm_checksum, +@@ -745,7 +701,7 @@ + sm->ssdi.ssd_version = SR_META_VERSION; + sm->ssd_ondisk = 0; + sm->ssdi.ssd_vol_flags = 0; +- bcopy(&sd->sd_meta->ssdi.ssd_uuid, &sm->ssdi.ssd_uuid, ++ memcpy(&sm->ssdi.ssd_uuid, &sd->sd_meta->ssdi.ssd_uuid, + sizeof(struct sr_uuid)); + sm->ssdi.ssd_chunk_no = 1; + sm->ssdi.ssd_volid = SR_KEYDISK_VOLID; +@@ -785,7 +741,7 @@ + omi->omi_som->som_type = SR_OPT_KEYDISK; + omi->omi_som->som_length = sizeof(struct sr_meta_keydisk); + skm = (struct sr_meta_keydisk *)omi->omi_som; +- bcopy(sd->mds.mdd_crypto.scr_maskkey, &skm->skm_maskkey, ++ memcpy(&skm->skm_maskkey, sd->mds.mdd_crypto.scr_maskkey, + sizeof(skm->skm_maskkey)); + SLIST_INSERT_HEAD(&fakesd->sd_meta_opt, omi, omi_link); + fakesd->sd_meta->ssdi.ssd_opt_no++; +@@ -799,19 +755,16 @@ + goto done; + + fail: +- if (key_disk) +- free(key_disk, M_DEVBUF); ++ free(key_disk, M_DEVBUF, sizeof(struct sr_chunk)); + key_disk = NULL; + + done: +- if (omi) +- free(omi, M_DEVBUF); ++ free(omi, M_DEVBUF, sizeof(struct sr_meta_opt_item)); + if (fakesd && fakesd->sd_vol.sv_chunks) +- free(fakesd->sd_vol.sv_chunks, M_DEVBUF); +- if (fakesd) +- free(fakesd, M_DEVBUF); +- if (sm) +- free(sm, M_DEVBUF); ++ free(fakesd->sd_vol.sv_chunks, M_DEVBUF, ++ sizeof(struct sr_chunk *)); ++ free(fakesd, M_DEVBUF, sizeof(struct sr_discipline)); ++ free(sm, M_DEVBUF, sizeof(struct sr_metadata)); + if (open) { + VOP_CLOSE(vn, FREAD | FWRITE, NOCRED, curproc); + vput(vn); +@@ -855,7 +808,7 @@ + sr_error(sc, "cannot open key disk %s", devname); + goto done; + } +- if (VOP_OPEN(vn, FREAD | FWRITE, NOCRED, curproc)) { ++ if (VOP_OPEN(vn, FREAD, NOCRED, curproc)) { + DNPRINTF(SR_D_META,"%s: sr_crypto_read_key_disk cannot " + "open %s\n", DEVNAME(sc), devname); + vput(vn); +@@ -869,17 +822,10 @@ + NOCRED, curproc)) { + DNPRINTF(SR_D_META, "%s: sr_crypto_read_key_disk ioctl " + "failed\n", DEVNAME(sc)); +- VOP_CLOSE(vn, FREAD | FWRITE, NOCRED, curproc); +- vput(vn); + goto done; + } +- if (label.d_secsize != DEV_BSIZE) { +- sr_error(sc, "%s has unsupported sector size (%d)", +- devname, label.d_secsize); +- goto done; +- } + if (label.d_partitions[part].p_fstype != FS_RAID) { +- sr_error(sc, "%s partition not of type RAID (%d)\n", ++ sr_error(sc, "%s partition not of type RAID (%d)", + devname, label.d_partitions[part].p_fstype); + goto done; + } +@@ -887,7 +833,7 @@ + /* + * Read and validate key disk metadata. + */ +- sm = malloc(SR_META_SIZE * 512, M_DEVBUF, M_WAITOK | M_ZERO); ++ sm = malloc(SR_META_SIZE * DEV_BSIZE, M_DEVBUF, M_WAITOK | M_ZERO); + if (sr_meta_native_read(sd, dev, sm, NULL)) { + sr_error(sc, "native bootprobe could not read native metadata"); + goto done; +@@ -911,7 +857,7 @@ + key_disk->src_vn = vn; + key_disk->src_size = 0; + +- bcopy((struct sr_meta_chunk *)(sm + 1), &key_disk->src_meta, ++ memcpy(&key_disk->src_meta, (struct sr_meta_chunk *)(sm + 1), + sizeof(key_disk->src_meta)); + + /* Read mask key from optional metadata. */ +@@ -920,13 +866,12 @@ + omh = omi->omi_som; + if (omh->som_type == SR_OPT_KEYDISK) { + skm = (struct sr_meta_keydisk *)omh; +- bcopy(&skm->skm_maskkey, +- sd->mds.mdd_crypto.scr_maskkey, ++ memcpy(sd->mds.mdd_crypto.scr_maskkey, &skm->skm_maskkey, + sizeof(sd->mds.mdd_crypto.scr_maskkey)); + } else if (omh->som_type == SR_OPT_CRYPTO) { + /* Original keydisk format with key in crypto area. */ +- bcopy(omh + sizeof(struct sr_meta_opt_hdr), +- sd->mds.mdd_crypto.scr_maskkey, ++ memcpy(sd->mds.mdd_crypto.scr_maskkey, ++ omh + sizeof(struct sr_meta_opt_hdr), + sizeof(sd->mds.mdd_crypto.scr_maskkey)); + } + } +@@ -934,15 +879,13 @@ + open = 0; + + done: +- for (omi = SLIST_FIRST(&som); omi != SLIST_END(&som); omi = omi_next) { ++ for (omi = SLIST_FIRST(&som); omi != NULL; omi = omi_next) { + omi_next = SLIST_NEXT(omi, omi_link); +- if (omi->omi_som) +- free(omi->omi_som, M_DEVBUF); +- free(omi, M_DEVBUF); ++ free(omi->omi_som, M_DEVBUF, 0); ++ free(omi, M_DEVBUF, sizeof(struct sr_meta_opt_item)); + } + +- if (sm) +- free(sm, M_DEVBUF); ++ free(sm, M_DEVBUF, SR_META_SIZE * DEV_BSIZE); + + if (vn && open) { + VOP_CLOSE(vn, FREAD, NOCRED, curproc); +@@ -950,18 +893,45 @@ + } + + return key_disk; ++} ++ ++static void ++sr_crypto_free_sessions(struct sr_discipline *sd) ++{ ++ u_int i; ++ ++ for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) { ++ if (sd->mds.mdd_crypto.scr_sid[i] != (u_int64_t)-1) { ++ crypto_freesession(sd->mds.mdd_crypto.scr_sid[i]); ++ sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1; ++ } ++ } + } + + int + sr_crypto_alloc_resources(struct sr_discipline *sd) + { +- struct cryptoini cri; ++ struct sr_workunit *wu; + struct sr_crypto_wu *crwu; ++ struct cryptoini cri; + u_int num_keys, i; + + DNPRINTF(SR_D_DIS, "%s: sr_crypto_alloc_resources\n", + DEVNAME(sd->sd_sc)); + ++ sd->mds.mdd_crypto.scr_alg = CRYPTO_AES_XTS; ++ switch (sd->mds.mdd_crypto.scr_meta->scm_alg) { ++ case SR_CRYPTOA_AES_XTS_128: ++ sd->mds.mdd_crypto.scr_klen = 256; ++ break; ++ case SR_CRYPTOA_AES_XTS_256: ++ sd->mds.mdd_crypto.scr_klen = 512; ++ break; ++ default: ++ sr_error(sd->sd_sc, "unknown crypto algorithm"); ++ return (EINVAL); ++ } ++ + for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) + sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1; + +@@ -979,61 +949,34 @@ + } + + /* +- * For each wu allocate the uio, iovec and crypto structures. +- * these have to be allocated now because during runtime we can't +- * fail an allocation without failing the io (which can cause real ++ * For each work unit allocate the uio, iovec and crypto structures. ++ * These have to be allocated now because during runtime we cannot ++ * fail an allocation without failing the I/O (which can cause real + * problems). + */ +- mtx_init(&sd->mds.mdd_crypto.scr_mutex, IPL_BIO); +- TAILQ_INIT(&sd->mds.mdd_crypto.scr_wus); +- for (i = 0; i < sd->sd_max_wu; i++) { +- crwu = malloc(sizeof(*crwu), M_DEVBUF, +- M_WAITOK | M_ZERO | M_CANFAIL); +- if (crwu == NULL) +- return (ENOMEM); +- /* put it on the list now so if we fail it'll be freed */ +- mtx_enter(&sd->mds.mdd_crypto.scr_mutex); +- TAILQ_INSERT_TAIL(&sd->mds.mdd_crypto.scr_wus, crwu, cr_link); +- mtx_leave(&sd->mds.mdd_crypto.scr_mutex); +- ++ TAILQ_FOREACH(wu, &sd->sd_wu, swu_next) { ++ crwu = (struct sr_crypto_wu *)wu; + crwu->cr_uio.uio_iov = &crwu->cr_iov; + crwu->cr_dmabuf = dma_alloc(MAXPHYS, PR_WAITOK); + crwu->cr_crp = crypto_getreq(MAXPHYS >> DEV_BSHIFT); + if (crwu->cr_crp == NULL) + return (ENOMEM); +- /* steal the list of cryptodescs */ +- crwu->cr_descs = crwu->cr_crp->crp_desc; +- crwu->cr_crp->crp_desc = NULL; + } + +- bzero(&cri, sizeof(cri)); +- cri.cri_alg = CRYPTO_AES_XTS; +- switch (sd->mds.mdd_crypto.scr_meta->scm_alg) { +- case SR_CRYPTOA_AES_XTS_128: +- cri.cri_klen = 256; +- break; +- case SR_CRYPTOA_AES_XTS_256: +- cri.cri_klen = 512; +- break; +- default: +- return (EINVAL); +- } ++ memset(&cri, 0, sizeof(cri)); ++ cri.cri_alg = sd->mds.mdd_crypto.scr_alg; ++ cri.cri_klen = sd->mds.mdd_crypto.scr_klen; + +- /* Allocate a session for every 2^SR_CRYPTO_KEY_BLKSHIFT blocks */ +- num_keys = sd->sd_meta->ssdi.ssd_size >> SR_CRYPTO_KEY_BLKSHIFT; +- if (num_keys >= SR_CRYPTO_MAXKEYS) ++ /* Allocate a session for every 2^SR_CRYPTO_KEY_BLKSHIFT blocks. */ ++ num_keys = ((sd->sd_meta->ssdi.ssd_size - 1) >> ++ SR_CRYPTO_KEY_BLKSHIFT) + 1; ++ if (num_keys > SR_CRYPTO_MAXKEYS) + return (EFBIG); +- for (i = 0; i <= num_keys; i++) { ++ for (i = 0; i < num_keys; i++) { + cri.cri_key = sd->mds.mdd_crypto.scr_key[i]; + if (crypto_newsession(&sd->mds.mdd_crypto.scr_sid[i], + &cri, 0) != 0) { +- for (i = 0; +- sd->mds.mdd_crypto.scr_sid[i] != (u_int64_t)-1; +- i++) { +- crypto_freesession( +- sd->mds.mdd_crypto.scr_sid[i]); +- sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1; +- } ++ sr_crypto_free_sessions(sd); + return (EINVAL); + } + } +@@ -1046,39 +989,30 @@ + void + sr_crypto_free_resources(struct sr_discipline *sd) + { ++ struct sr_workunit *wu; + struct sr_crypto_wu *crwu; +- u_int i; + + DNPRINTF(SR_D_DIS, "%s: sr_crypto_free_resources\n", + DEVNAME(sd->sd_sc)); + + if (sd->mds.mdd_crypto.key_disk != NULL) { +- explicit_bzero(sd->mds.mdd_crypto.key_disk, sizeof +- sd->mds.mdd_crypto.key_disk); +- free(sd->mds.mdd_crypto.key_disk, M_DEVBUF); ++ explicit_bzero(sd->mds.mdd_crypto.key_disk, ++ sizeof(*sd->mds.mdd_crypto.key_disk)); ++ free(sd->mds.mdd_crypto.key_disk, M_DEVBUF, ++ sizeof(*sd->mds.mdd_crypto.key_disk)); + } + + sr_hotplug_unregister(sd, sr_crypto_hotplug); + +- for (i = 0; sd->mds.mdd_crypto.scr_sid[i] != (u_int64_t)-1; i++) { +- crypto_freesession(sd->mds.mdd_crypto.scr_sid[i]); +- sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1; +- } ++ sr_crypto_free_sessions(sd); + +- mtx_enter(&sd->mds.mdd_crypto.scr_mutex); +- while ((crwu = TAILQ_FIRST(&sd->mds.mdd_crypto.scr_wus)) != NULL) { +- TAILQ_REMOVE(&sd->mds.mdd_crypto.scr_wus, crwu, cr_link); +- +- if (crwu->cr_dmabuf != NULL) ++ TAILQ_FOREACH(wu, &sd->sd_wu, swu_next) { ++ crwu = (struct sr_crypto_wu *)wu; ++ if (crwu->cr_dmabuf) + dma_free(crwu->cr_dmabuf, MAXPHYS); +- if (crwu->cr_crp) { +- /* twiddle cryptoreq back */ +- crwu->cr_crp->crp_desc = crwu->cr_descs; ++ if (crwu->cr_crp) + crypto_freereq(crwu->cr_crp); +- } +- free(crwu, M_DEVBUF); + } +- mtx_leave(&sd->mds.mdd_crypto.scr_mutex); + + sr_wu_free(sd); + sr_ccb_free(sd); +@@ -1165,65 +1099,60 @@ + sr_crypto_rw(struct sr_workunit *wu) + { + struct sr_crypto_wu *crwu; +- int s, rv = 0; ++ daddr_t blkno; ++ int rv = 0; + +- DNPRINTF(SR_D_DIS, "%s: sr_crypto_rw wu: %p\n", ++ DNPRINTF(SR_D_DIS, "%s: sr_crypto_rw wu %p\n", + DEVNAME(wu->swu_dis->sd_sc), wu); + +- if (wu->swu_xs->flags & SCSI_DATA_OUT) { +- crwu = sr_crypto_wu_get(wu, 1); +- if (crwu == NULL) +- return (1); ++ if (sr_validate_io(wu, &blkno, "sr_crypto_rw")) ++ return (1); ++ ++ if (wu->swu_xs->flags & SCSI_DATA_OUT) { ++ crwu = sr_crypto_prepare(wu, 1); + crwu->cr_crp->crp_callback = sr_crypto_write; +- s = splvm(); +- if (crypto_invoke(crwu->cr_crp)) +- rv = 1; +- else ++ rv = crypto_dispatch(crwu->cr_crp); ++ if (rv == 0) + rv = crwu->cr_crp->crp_etype; +- splx(s); + } else +- rv = sr_crypto_rw2(wu, NULL); ++ rv = sr_crypto_dev_rw(wu, NULL); + + return (rv); + } + +-int ++void + sr_crypto_write(struct cryptop *crp) + { + struct sr_crypto_wu *crwu = crp->crp_opaque; +- struct sr_workunit *wu = crwu->cr_wu; ++ struct sr_workunit *wu = &crwu->cr_wu; + int s; + +- DNPRINTF(SR_D_INTR, "%s: sr_crypto_write: wu %x xs: %x\n", ++ DNPRINTF(SR_D_INTR, "%s: sr_crypto_write: wu %p xs: %p\n", + DEVNAME(wu->swu_dis->sd_sc), wu, wu->swu_xs); + + if (crp->crp_etype) { + /* fail io */ + wu->swu_xs->error = XS_DRIVER_STUFFUP; + s = splbio(); +- sr_crypto_finish_io(wu); ++ sr_scsi_done(wu->swu_dis, wu->swu_xs); + splx(s); + } + +- return (sr_crypto_rw2(wu, crwu)); ++ sr_crypto_dev_rw(wu, crwu); + } + + int +-sr_crypto_rw2(struct sr_workunit *wu, struct sr_crypto_wu *crwu) ++sr_crypto_dev_rw(struct sr_workunit *wu, struct sr_crypto_wu *crwu) + { + struct sr_discipline *sd = wu->swu_dis; + struct scsi_xfer *xs = wu->swu_xs; + struct sr_ccb *ccb; + struct uio *uio; +- int s; +- daddr64_t blk; ++ daddr_t blkno; + +- if (sr_validate_io(wu, &blk, "sr_crypto_rw2")) +- goto bad; ++ blkno = wu->swu_blk_start; + +- blk += sd->sd_meta->ssd_data_offset; +- +- ccb = sr_ccb_rw(sd, 0, blk, xs->datalen, xs->data, xs->flags, 0); ++ ccb = sr_ccb_rw(sd, 0, blkno, xs->datalen, xs->data, xs->flags, 0); + if (!ccb) { + /* should never happen but handle more gracefully */ + printf("%s: %s: too many ccbs queued\n", +@@ -1236,17 +1165,10 @@ + ccb->ccb_opaque = crwu; + } + sr_wu_enqueue_ccb(wu, ccb); ++ sr_schedule_wu(wu); + +- s = splbio(); +- +- if (sr_check_io_collision(wu)) +- goto queued; +- +- sr_raid_startwu(wu); +- +-queued: +- splx(s); + return (0); ++ + bad: + /* wu is unwound by sr_wu_put */ + if (crwu) +@@ -1259,77 +1181,39 @@ + { + struct scsi_xfer *xs = wu->swu_xs; + struct sr_crypto_wu *crwu; +- struct sr_ccb *ccb; + int s; + + /* If this was a successful read, initiate decryption of the data. */ + if (ISSET(xs->flags, SCSI_DATA_IN) && xs->error == XS_NOERROR) { +- /* only fails on implementation error */ +- crwu = sr_crypto_wu_get(wu, 0); +- if (crwu == NULL) +- panic("sr_crypto_intr: no wu"); ++ crwu = sr_crypto_prepare(wu, 0); + crwu->cr_crp->crp_callback = sr_crypto_read; +- ccb = TAILQ_FIRST(&wu->swu_ccb); +- if (ccb == NULL) +- panic("sr_crypto_done: no ccbs on workunit"); +- ccb->ccb_opaque = crwu; +- DNPRINTF(SR_D_INTR, "%s: sr_crypto_intr: crypto_invoke %p\n", ++ DNPRINTF(SR_D_INTR, "%s: sr_crypto_done: crypto_dispatch %p\n", + DEVNAME(wu->swu_dis->sd_sc), crwu->cr_crp); +- s = splvm(); +- crypto_invoke(crwu->cr_crp); +- splx(s); ++ crypto_dispatch(crwu->cr_crp); + return; + } + + s = splbio(); +- sr_crypto_finish_io(wu); ++ sr_scsi_done(wu->swu_dis, wu->swu_xs); + splx(s); + } + + void +-sr_crypto_finish_io(struct sr_workunit *wu) +-{ +- struct sr_discipline *sd = wu->swu_dis; +- struct scsi_xfer *xs = wu->swu_xs; +- struct sr_ccb *ccb; +-#ifdef SR_DEBUG +- struct sr_softc *sc = sd->sd_sc; +-#endif /* SR_DEBUG */ +- +- splassert(IPL_BIO); +- +- DNPRINTF(SR_D_INTR, "%s: sr_crypto_finish_io: wu %x xs: %x\n", +- DEVNAME(sc), wu, xs); +- +- if (wu->swu_cb_active == 1) +- panic("%s: sr_crypto_finish_io", DEVNAME(sd->sd_sc)); +- TAILQ_FOREACH(ccb, &wu->swu_ccb, ccb_link) { +- if (ccb->ccb_opaque == NULL) +- continue; +- sr_crypto_wu_put(ccb->ccb_opaque); +- } +- +- sr_scsi_done(sd, xs); +-} +- +-int + sr_crypto_read(struct cryptop *crp) + { + struct sr_crypto_wu *crwu = crp->crp_opaque; +- struct sr_workunit *wu = crwu->cr_wu; ++ struct sr_workunit *wu = &crwu->cr_wu; + int s; + +- DNPRINTF(SR_D_INTR, "%s: sr_crypto_read: wu %x xs: %x\n", ++ DNPRINTF(SR_D_INTR, "%s: sr_crypto_read: wu %p xs: %p\n", + DEVNAME(wu->swu_dis->sd_sc), wu, wu->swu_xs); + + if (crp->crp_etype) + wu->swu_xs->error = XS_DRIVER_STUFFUP; + + s = splbio(); +- sr_crypto_finish_io(wu); ++ sr_scsi_done(wu->swu_dis, wu->swu_xs); + splx(s); +- +- return (0); + } + + void diff --git a/test/expect101.diff b/test/expect101.diff new file mode 100644 index 000000000000..eca02621faf8 --- /dev/null +++ b/test/expect101.diff @@ -0,0 +1,12 @@ +--- test101.left-P.txt ++++ test101.right-P.txt +@@ -1,7 +1,6 @@ +-A +-B + C ++B + A + B +-B + A ++C diff --git a/test/expect102.diff b/test/expect102.diff new file mode 100644 index 000000000000..58ec6b7744c8 --- /dev/null +++ b/test/expect102.diff @@ -0,0 +1,16 @@ +--- test102.left-P.txt ++++ test102.right-P.txt +@@ -1,10 +1,9 @@ +-A +-B + C ++B + A + B +-B + A ++C + X +-Y + Z ++Q diff --git a/test/expect103.diff b/test/expect103.diff new file mode 100644 index 000000000000..dae017d8028e --- /dev/null +++ b/test/expect103.diff @@ -0,0 +1,10 @@ +--- test103.left-P.txt ++++ test103.right-P.txt +@@ -1,5 +1,4 @@ +-a ++x + b + c +-d +-e ++y diff --git a/test/expect104.diff b/test/expect104.diff new file mode 100644 index 000000000000..c48183f5fa9c --- /dev/null +++ b/test/expect104.diff @@ -0,0 +1,24 @@ +--- test104.left-P.txt ++++ test104.right-P.txt +@@ -1,3 +1,10 @@ ++int Chunk_bounds_check(Chunk *chunk, size_t start, size_t n) ++{ ++ if (chunk == NULL) return 0; ++ ++ return start <= chunk->length && n <= chunk->length - start; ++} ++ + void Chunk_copy(Chunk *src, size_t src_start, Chunk *dst, size_t dst_start, size_t n) + { + if (!Chunk_bounds_check(src, src_start, n)) return; +@@ -5,10 +12,3 @@ + + memcpy(dst->data + dst_start, src->data + src_start, n); + } +- +-int Chunk_bounds_check(Chunk *chunk, size_t start, size_t n) +-{ +- if (chunk == NULL) return 0; +- +- return start <= chunk->length && n <= chunk->length - start; +-} diff --git a/test/expect105.diff b/test/expect105.diff new file mode 100644 index 000000000000..82d3b52ee97e --- /dev/null +++ b/test/expect105.diff @@ -0,0 +1,12 @@ +--- test105.left-P.txt ++++ test105.right-P.txt +@@ -1,7 +1,7 @@ ++The Slits ++Gil Scott Heron + David Axelrod + Electric Prunes +-Gil Scott Heron +-The Slits + Faust + The Sonics + The Sonics diff --git a/test/expect106.diff b/test/expect106.diff new file mode 100644 index 000000000000..c48cf3199188 --- /dev/null +++ b/test/expect106.diff @@ -0,0 +1,24 @@ +--- test106.left-P.txt ++++ test106.right-P.txt +@@ -3,7 +3,7 @@ + + It is important to specify the year of the copyright. Additional years + should be separated by a comma, e.g. +- Copyright (c) 2003, 2004 ++ Copyright (c) 2003, 2004, 2005 + + If you add extra text to the body of the license, be careful not to + add further restrictions. +@@ -11,7 +11,6 @@ + /* + * Copyright (c) CCYY YOUR NAME HERE + * +- * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * +@@ -23,3 +22,4 @@ + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ ++An extra line diff --git a/test/expect107.diff b/test/expect107.diff new file mode 100644 index 000000000000..f658b89fd21e --- /dev/null +++ b/test/expect107.diff @@ -0,0 +1,5 @@ +--- test107.left-P.txt ++++ test107.right-P.txt +@@ -1 +1 @@ +-x ++abcdx diff --git a/test/expect108.diff b/test/expect108.diff new file mode 100644 index 000000000000..a9b93e784e4e --- /dev/null +++ b/test/expect108.diff @@ -0,0 +1,9 @@ +--- test108.left-P.txt ++++ test108.right-P.txt +@@ -1 +1,6 @@ + x ++a ++b ++c ++d ++x diff --git a/test/expect109.diff b/test/expect109.diff new file mode 100644 index 000000000000..ee94eff22a3e --- /dev/null +++ b/test/expect109.diff @@ -0,0 +1,13 @@ +--- test109.left-P.txt ++++ test109.right-P.txt +@@ -1,3 +1,10 @@ + x + a + b ++c ++d ++e ++f ++x ++a ++b diff --git a/test/expect110.diff b/test/expect110.diff new file mode 100644 index 000000000000..40e1d155b0f2 --- /dev/null +++ b/test/expect110.diff @@ -0,0 +1,19 @@ +--- test110.left-P.txt ++++ test110.right-P.txt +@@ -1,4 +1,4 @@ +-/* $OpenBSD: usbdevs_data.h,v 1.715 2020/01/20 07:09:11 jsg Exp $ */ ++/* $OpenBSD$ */ + + /* + * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. +@@ -10982,6 +10982,10 @@ + "RTL8192EU", + }, + { ++ USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8192EU_2, ++ "RTL8192EU", ++ }, ++ { + USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8188EUS, + "RTL8188EUS", + }, diff --git a/test/expect111.diff b/test/expect111.diff new file mode 100644 index 000000000000..dd53220bf3cc --- /dev/null +++ b/test/expect111.diff @@ -0,0 +1,19 @@ +--- test111.left-P.txt ++++ test111.right-P.txt +@@ -1,4 +1,4 @@ +-/* $OpenBSD: usbdevs_data.h,v 1.715 2020/01/20 07:09:11 jsg Exp $ */ ++/* $OpenBSD$ */ + + /* + * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. +@@ -378,6 +378,10 @@ + "RTL8192EU", + }, + { ++ USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8192EU_2, ++ "RTL8192EU", ++ }, ++ { + USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8188EUS, + "RTL8188EUS", + }, diff --git a/test/expect112.diff b/test/expect112.diff new file mode 100644 index 000000000000..680fe1ac37c5 --- /dev/null +++ b/test/expect112.diff @@ -0,0 +1,21 @@ +--- test112.left-P.txt ++++ test112.right-P.txt +@@ -1,4 +1,4 @@ +-1 left ++1 right + 2 + 3 + 4 +@@ -17,6 +17,12 @@ + 17 + 18 + 19 ++14 ++15 ++16 right ++17 ++18 ++19 + 20 + 21 + 22 diff --git a/test/expect113.diff b/test/expect113.diff new file mode 100644 index 000000000000..882171f0cbb5 --- /dev/null +++ b/test/expect113.diff @@ -0,0 +1,10 @@ +--- test113.left-Pw.txt ++++ test113.right-Pw.txt +@@ -3,5 +3,5 @@ + C + D + E +-F +-G ++F x ++y G diff --git a/test/expect114.diff b/test/expect114.diff new file mode 100644 index 000000000000..538b475acd17 --- /dev/null +++ b/test/expect114.diff @@ -0,0 +1,4 @@ +--- test114.left-P.txt ++++ test114.right-P.txt +@@ -0,0 +1 @@ ++A diff --git a/test/expect115.diff b/test/expect115.diff new file mode 100644 index 000000000000..64d4f35f2582 --- /dev/null +++ b/test/expect115.diff @@ -0,0 +1,4 @@ +--- test115.left-P.txt ++++ test115.right-P.txt +@@ -1 +0,0 @@ +-A diff --git a/test/expect116.diff b/test/expect116.diff new file mode 100644 index 000000000000..35c3a14b2f70 --- /dev/null +++ b/test/expect116.diff @@ -0,0 +1,30 @@ +--- test116.left-P.txt ++++ test116.right-P.txt +@@ -254,7 +254,7 @@ + const char *uri, *dirname; + char *proto, *host, *port, *repo_name, *server_path; + char *default_destdir = NULL, *id_str = NULL; +- const char *repo_path; ++ const char *repo_path, *remote_repo_path; + struct got_repository *repo = NULL; + struct got_pathlist_head refs, symrefs, wanted_branches, wanted_refs; + struct got_pathlist_entry *pe; +@@ -275,6 +275,9 @@ + goto done; + } + got_path_strip_trailing_slashes(server_path); ++ remote_repo_path = server_path; ++ while (remote_repo_path[0] == '/') ++ remote_repo_path++; + if (asprintf(&gotconfig, + "remote \"%s\" {\n" + "\tserver %s\n" +@@ -285,7 +288,7 @@ + "}\n", + GOT_FETCH_DEFAULT_REMOTE_NAME, host, proto, + port ? "\tport " : "", port ? port : "", port ? "\n" : "", +- server_path, ++ remote_repo_path, + mirror_references ? "\tmirror-references yes\n" : "") == -1) { + error = got_error_from_errno("asprintf"); + goto done; diff --git a/test/expect117.diff b/test/expect117.diff new file mode 100644 index 000000000000..63df381db814 --- /dev/null +++ b/test/expect117.diff @@ -0,0 +1,64 @@ +--- test117.left-P.txt ++++ test117.right-P.txt +@@ -65,6 +65,8 @@ + struct sr_crypto_kdfinfo *, struct sr_crypto_kdfinfo *); + int sr_crypto_create(struct sr_discipline *, + struct bioc_createraid *, int, int64_t); ++int sr_crypto_init(struct sr_discipline *, ++ struct bioc_createraid *); + int sr_crypto_assemble(struct sr_discipline *, + struct bioc_createraid *, int, void *); + int sr_crypto_alloc_resources(struct sr_discipline *); +@@ -117,18 +119,34 @@ + sr_crypto_create(struct sr_discipline *sd, struct bioc_createraid *bc, + int no_chunk, int64_t coerced_size) + { +- struct sr_meta_opt_item *omi; +- int rv = EINVAL; ++ int rv = EINVAL; + + if (no_chunk != 1) { + sr_error(sd->sd_sc, "%s requires exactly one chunk", + sd->sd_name); +- goto done; ++ return (rv); + } + +- if (coerced_size > SR_CRYPTO_MAXSIZE) { ++ sd->sd_meta->ssdi.ssd_size = coerced_size; ++ ++ rv = sr_crypto_init(sd, bc); ++ if (rv) ++ return (rv); ++ ++ sd->sd_max_ccb_per_wu = no_chunk; ++ return (0); ++} ++ ++int ++sr_crypto_init(struct sr_discipline *sd, struct bioc_createraid *bc) ++{ ++ struct sr_meta_opt_item *omi; ++ int rv = EINVAL; ++ ++ if (sd->sd_meta->ssdi.ssd_size > SR_CRYPTO_MAXSIZE) { + sr_error(sd->sd_sc, "%s exceeds maximum size (%lli > %llu)", +- sd->sd_name, coerced_size, SR_CRYPTO_MAXSIZE); ++ sd->sd_name, sd->sd_meta->ssdi.ssd_size, ++ SR_CRYPTO_MAXSIZE); + goto done; + } + +@@ -170,12 +188,8 @@ + if (!(bc->bc_flags & BIOC_SCNOAUTOASSEMBLE) && bc->bc_key_disk == NODEV) + goto done; + +- sd->sd_meta->ssdi.ssd_size = coerced_size; +- + sr_crypto_create_keys(sd); + +- sd->sd_max_ccb_per_wu = no_chunk; +- + rv = 0; + done: + return (rv); diff --git a/test/expect123.diff b/test/expect123.diff new file mode 100644 index 000000000000..77d05518ee95 --- /dev/null +++ b/test/expect123.diff @@ -0,0 +1 @@ +0a1 diff --git a/test/expect124.diff b/test/expect124.diff new file mode 100644 index 000000000000..82713c206aff --- /dev/null +++ b/test/expect124.diff @@ -0,0 +1,9 @@ +--- test124.left-p.txt ++++ test124.right-p.txt +@@ -11,5 +11,5 @@ doSomethingThenPrintHello(int test) + + struct testfile * + return_test(int test) { +- return NULL; ++ return test*2; + } diff --git a/test/expect125.diff b/test/expect125.diff new file mode 100644 index 000000000000..dc9ca80aa498 --- /dev/null +++ b/test/expect125.diff @@ -0,0 +1,12 @@ +--- test125.left.txt ++++ test125.right.txt +@@ -1,7 +1,7 @@ + This is a test + of missing trailing new lines + in context +-this line has a change ++this line has the change + this is the same + this is too + and this one +\ No newline at end of file diff --git a/test/expect126.diff b/test/expect126.diff new file mode 100644 index 000000000000..ddf0066b6822 --- /dev/null +++ b/test/expect126.diff @@ -0,0 +1,28 @@ +--- test126.left.txt ++++ test126.right.txt +@@ -1,4 +1,4 @@ +-/* $OpenBSD: a_time_tm.c,v 1.15 2018/04/25 11:48:21 tb Exp $ */ ++/* $OpenBSD: a_time_tm.c,v 1.16 2020/12/16 18:35:59 tb Exp $ */ + /* + * Copyright (c) 2015 Bob Beck + * +@@ -108,10 +108,9 @@ + return (-1); + + lt = tm; +- if (lt == NULL) { +- memset(<m, 0, sizeof(ltm)); ++ if (lt == NULL) + lt = <m; +- } ++ memset(lt, 0, sizeof(*lt)); + + /* Timezone is required and must be GMT (Zulu). */ + if (bytes[len - 1] != 'Z') +@@ -168,4 +167,4 @@ + } + + return (type); +-} ++} +\ No newline at end of file diff --git a/test/results_test.c b/test/results_test.c new file mode 100644 index 000000000000..02856a39c249 --- /dev/null +++ b/test/results_test.c @@ -0,0 +1,178 @@ +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +void test_minus_after_plus(void) +{ + struct diff_result *result = malloc(sizeof(struct diff_result)); + struct diff_data d_left, d_right; + char *left_data = "a\nb\nc\nd\ne\nm\nn\n"; + char *right_data = "a\nb\nj\nk\nl\nm\nn\n"; + int i; + + printf("\n--- %s()\n", __func__); + + d_left = (struct diff_data){ + .data = left_data, + .len = strlen(left_data), + .root = &d_left, + }; + d_right = (struct diff_data){ + .data = right_data, + .len = strlen(right_data), + .root = &d_right, + }; + *result = (struct diff_result) { + .left = &d_left, + .right = &d_right, + }; + + diff_atomize_text_by_line(NULL, result->left); + diff_atomize_text_by_line(NULL, result->right); + + struct diff_state state = { + .result = result, + .recursion_depth_left = 32, + }; + diff_data_init_subsection(&state.left, result->left, + result->left->atoms.head, + result->left->atoms.len); + diff_data_init_subsection(&state.right, result->right, + result->right->atoms.head, + result->right->atoms.len); + + /* "same" section */ + diff_state_add_chunk(&state, true, + &state.left.atoms.head[0], 2, + &state.right.atoms.head[0], 2); + + /* "plus" section */ + diff_state_add_chunk(&state, true, + &state.left.atoms.head[2], 0, + &state.right.atoms.head[2], 3); + + /* "minus" section */ + diff_state_add_chunk(&state, true, + &state.left.atoms.head[2], 3, + &state.right.atoms.head[5], 0); + + /* "same" section */ + diff_state_add_chunk(&state, true, + &state.left.atoms.head[5], 2, + &state.right.atoms.head[5], 2); + + for (i = 0; i < result->chunks.len; i++) { + struct diff_chunk *c = &result->chunks.head[i]; + enum diff_chunk_type t = diff_chunk_type(c); + + printf("[%d] %s lines L%d R%d @L %lld @R %lld\n", + i, (t == CHUNK_MINUS ? "minus" : + (t == CHUNK_PLUS ? "plus" : + (t == CHUNK_SAME ? "same" : "?"))), + c->left_count, + c->right_count, + (long long)(c->left_start ? diff_atom_root_idx(result->left, c->left_start) : -1LL), + (long long)(c->right_start ? diff_atom_root_idx(result->right, c->right_start) : -1LL)); + } + + diff_result_free(result); + diff_data_free(&d_left); + diff_data_free(&d_right); +} + +void test_plus_after_plus(void) +{ + struct diff_result *result = malloc(sizeof(struct diff_result)); + struct diff_data d_left, d_right; + char *left_data = "a\nb\nc\nd\ne\nm\nn\n"; + char *right_data = "a\nb\nj\nk\nl\nm\nn\n"; + struct diff_chunk *c; + + printf("\n--- %s()\n", __func__); + + d_left = (struct diff_data){ + .data = left_data, + .len = strlen(left_data), + .root = &d_left, + }; + d_right = (struct diff_data){ + .data = right_data, + .len = strlen(right_data), + .root = &d_right, + }; + *result = (struct diff_result) { + .left = &d_left, + .right = &d_right, + }; + + diff_atomize_text_by_line(NULL, result->left); + diff_atomize_text_by_line(NULL, result->right); + + struct diff_state state = { + .result = result, + .recursion_depth_left = 32, + }; + diff_data_init_subsection(&state.left, result->left, + result->left->atoms.head, + result->left->atoms.len); + diff_data_init_subsection(&state.right, result->right, + result->right->atoms.head, + result->right->atoms.len); + + /* "same" section */ + diff_state_add_chunk(&state, true, + &state.left.atoms.head[0], 2, + &state.right.atoms.head[0], 2); + + /* "minus" section */ + diff_state_add_chunk(&state, true, + &state.left.atoms.head[2], 3, + &state.right.atoms.head[2], 0); + + /* "plus" section */ + diff_state_add_chunk(&state, true, + &state.left.atoms.head[5], 0, + &state.right.atoms.head[2], 1); + /* "plus" section */ + diff_state_add_chunk(&state, true, + &state.left.atoms.head[5], 0, + &state.right.atoms.head[3], 2); + + /* "same" section */ + diff_state_add_chunk(&state, true, + &state.left.atoms.head[5], 2, + &state.right.atoms.head[5], 2); + + ARRAYLIST_FOREACH(c, result->chunks) { + enum diff_chunk_type t = diff_chunk_type(c); + + printf("[%lu] %s lines L%d R%d @L %lld @R %lld\n", + (unsigned long)ARRAYLIST_IDX(c, result->chunks), + (t == CHUNK_MINUS ? "minus" : + (t == CHUNK_PLUS ? "plus" : + (t == CHUNK_SAME ? "same" : "?"))), + c->left_count, + c->right_count, + (long long)(c->left_start ? diff_atom_root_idx(result->left, c->left_start) : -1LL), + (long long)(c->right_start ? diff_atom_root_idx(result->right, c->right_start) : -1LL)); + } + + diff_result_free(result); + diff_data_free(&d_left); + diff_data_free(&d_right); +} + +int main(void) +{ + test_minus_after_plus(); + test_plus_after_plus(); + return 0; +} diff --git a/test/results_test/GNUmakefile b/test/results_test/GNUmakefile new file mode 100644 index 000000000000..f5b14b1f6648 --- /dev/null +++ b/test/results_test/GNUmakefile @@ -0,0 +1,20 @@ +.PHONY: regress clean + +CFLAGS = -fsanitize=address -fsanitize=undefined -g -O3 +CFLAGS += -Wstrict-prototypes -Wunused-variable -Wuninitialized + +CFLAGS+= -I$(CURDIR)/../../compat/include \ + -I$(CURDIR)/../../include \ + -I$(CURDIR)/../../lib + +$(CURDIR)/results_test: $(CURDIR)/../results_test.c $(CURDIR)/../../lib/libdiff.a + gcc $(CFLAGS) -o $@ $^ + +$(CURDIR)/../../lib/libdiff.a: $(CURDIR)/../../lib/*.[hc] $(CURDIR)/../../include/*.h + $(MAKE) -C $(CURDIR)/../../lib + +regress: $(CURDIR)/results_test + $(CURDIR)/results_test + +clean: + -rm $(CURDIR)/results_test diff --git a/test/results_test/Makefile b/test/results_test/Makefile new file mode 100644 index 000000000000..4cb496ada0aa --- /dev/null +++ b/test/results_test/Makefile @@ -0,0 +1,11 @@ +.PATH:${.CURDIR}/../../lib +.PATH:${.CURDIR}/.. + +PROG = results_test +SRCS = results_test.c diff_atomize_text.c diff_main.c + +CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib + +NOMAN = yes + +.include diff --git a/test/test001.left.txt b/test/test001.left.txt new file mode 100644 index 000000000000..fd113b0f7150 --- /dev/null +++ b/test/test001.left.txt @@ -0,0 +1,7 @@ +A +B +C +A +B +B +A diff --git a/test/test001.right.txt b/test/test001.right.txt new file mode 100644 index 000000000000..0075e6d23de0 --- /dev/null +++ b/test/test001.right.txt @@ -0,0 +1,6 @@ +C +B +A +B +A +C diff --git a/test/test002.left.txt b/test/test002.left.txt new file mode 100644 index 000000000000..de77f56f2d47 --- /dev/null +++ b/test/test002.left.txt @@ -0,0 +1,10 @@ +A +B +C +A +B +B +A +X +Y +Z diff --git a/test/test002.right.txt b/test/test002.right.txt new file mode 100644 index 000000000000..a9b4b8b851dd --- /dev/null +++ b/test/test002.right.txt @@ -0,0 +1,9 @@ +C +B +A +B +A +C +X +Z +Q diff --git a/test/test003.left.txt b/test/test003.left.txt new file mode 100644 index 000000000000..940532533944 --- /dev/null +++ b/test/test003.left.txt @@ -0,0 +1,5 @@ +a +b +c +d +e diff --git a/test/test003.right.txt b/test/test003.right.txt new file mode 100644 index 000000000000..d9f266e14574 --- /dev/null +++ b/test/test003.right.txt @@ -0,0 +1,4 @@ +x +b +c +y diff --git a/test/test004.left.txt b/test/test004.left.txt new file mode 100644 index 000000000000..72d95cf6331a --- /dev/null +++ b/test/test004.left.txt @@ -0,0 +1,14 @@ +void Chunk_copy(Chunk *src, size_t src_start, Chunk *dst, size_t dst_start, size_t n) +{ + if (!Chunk_bounds_check(src, src_start, n)) return; + if (!Chunk_bounds_check(dst, dst_start, n)) return; + + memcpy(dst->data + dst_start, src->data + src_start, n); +} + +int Chunk_bounds_check(Chunk *chunk, size_t start, size_t n) +{ + if (chunk == NULL) return 0; + + return start <= chunk->length && n <= chunk->length - start; +} diff --git a/test/test004.right.txt b/test/test004.right.txt new file mode 100644 index 000000000000..cfe8f2ed6be0 --- /dev/null +++ b/test/test004.right.txt @@ -0,0 +1,14 @@ +int Chunk_bounds_check(Chunk *chunk, size_t start, size_t n) +{ + if (chunk == NULL) return 0; + + return start <= chunk->length && n <= chunk->length - start; +} + +void Chunk_copy(Chunk *src, size_t src_start, Chunk *dst, size_t dst_start, size_t n) +{ + if (!Chunk_bounds_check(src, src_start, n)) return; + if (!Chunk_bounds_check(dst, dst_start, n)) return; + + memcpy(dst->data + dst_start, src->data + src_start, n); +} diff --git a/test/test005.left.txt b/test/test005.left.txt new file mode 100644 index 000000000000..b77fc41c4c87 --- /dev/null +++ b/test/test005.left.txt @@ -0,0 +1,7 @@ +David Axelrod +Electric Prunes +Gil Scott Heron +The Slits +Faust +The Sonics +The Sonics diff --git a/test/test005.right.txt b/test/test005.right.txt new file mode 100644 index 000000000000..2480cecfba48 --- /dev/null +++ b/test/test005.right.txt @@ -0,0 +1,7 @@ +The Slits +Gil Scott Heron +David Axelrod +Electric Prunes +Faust +The Sonics +The Sonics diff --git a/test/test006.left.txt b/test/test006.left.txt new file mode 100644 index 000000000000..e01fce04d5ef --- /dev/null +++ b/test/test006.left.txt @@ -0,0 +1,25 @@ +Below is an example license to be used for new code in OpenBSD, +modeled after the ISC license. + +It is important to specify the year of the copyright. Additional years +should be separated by a comma, e.g. + Copyright (c) 2003, 2004 + +If you add extra text to the body of the license, be careful not to +add further restrictions. + +/* + * Copyright (c) CCYY YOUR NAME HERE + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/test/test006.right.txt b/test/test006.right.txt new file mode 100644 index 000000000000..40a0f253dd2e --- /dev/null +++ b/test/test006.right.txt @@ -0,0 +1,25 @@ +Below is an example license to be used for new code in OpenBSD, +modeled after the ISC license. + +It is important to specify the year of the copyright. Additional years +should be separated by a comma, e.g. + Copyright (c) 2003, 2004, 2005 + +If you add extra text to the body of the license, be careful not to +add further restrictions. + +/* + * Copyright (c) CCYY YOUR NAME HERE + * + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +An extra line diff --git a/test/test007.left.txt b/test/test007.left.txt new file mode 100644 index 000000000000..587be6b4c3f9 --- /dev/null +++ b/test/test007.left.txt @@ -0,0 +1 @@ +x diff --git a/test/test007.right.txt b/test/test007.right.txt new file mode 100644 index 000000000000..47b0ccb04734 --- /dev/null +++ b/test/test007.right.txt @@ -0,0 +1 @@ +abcdx diff --git a/test/test008.left.txt b/test/test008.left.txt new file mode 100644 index 000000000000..587be6b4c3f9 --- /dev/null +++ b/test/test008.left.txt @@ -0,0 +1 @@ +x diff --git a/test/test008.right.txt b/test/test008.right.txt new file mode 100644 index 000000000000..70b67eef4500 --- /dev/null +++ b/test/test008.right.txt @@ -0,0 +1,6 @@ +x +a +b +c +d +x diff --git a/test/test009.left.txt b/test/test009.left.txt new file mode 100644 index 000000000000..e4e5238f8e5d --- /dev/null +++ b/test/test009.left.txt @@ -0,0 +1,3 @@ +x +a +b diff --git a/test/test009.right.txt b/test/test009.right.txt new file mode 100644 index 000000000000..3a4386800dba --- /dev/null +++ b/test/test009.right.txt @@ -0,0 +1,10 @@ +x +a +b +c +d +e +f +x +a +b diff --git a/test/test010.left.txt b/test/test010.left.txt new file mode 100644 index 000000000000..f68ae6a8ceaa --- /dev/null +++ b/test/test010.left.txt @@ -0,0 +1,14197 @@ +/* $OpenBSD: usbdevs_data.h,v 1.715 2020/01/20 07:09:11 jsg Exp $ */ + +/* + * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. + * + * generated from: + * OpenBSD: usbdevs,v 1.709 2020/01/20 07:08:20 jsg Exp + */ +/* $NetBSD: usbdevs,v 1.322 2003/05/10 17:47:14 hamajima Exp $ */ + +/* + * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Lennart Augustsson (lennart@augustsson.net) at + * Carlstedt Research & Technology. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Descriptions of known vendors and devices ("products"). + */ +struct usb_known_vendor { + u_int16_t vendor; + char *vendorname; +}; + +struct usb_known_product { + u_int16_t vendor; + u_int16_t product; + char *productname; +}; + +const struct usb_known_product usb_known_products[] = { + { + USB_VENDOR_3COM, USB_PRODUCT_3COM_HOMECONN, + "HomeConnect", + }, + { + USB_VENDOR_3COM, USB_PRODUCT_3COM_3CREB96, + "Bluetooth", + }, + { + USB_VENDOR_3COM, USB_PRODUCT_3COM_3C19250, + "3C19250 Ethernet", + }, + { + USB_VENDOR_3COM, USB_PRODUCT_3COM_3CRSHEW696, + "3CRSHEW696", + }, + { + USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460, + "HomeConnect 3C460", + }, + { + USB_VENDOR_3COM, USB_PRODUCT_3COM_USR56K, + "U.S.Robotics 56000", + }, + { + USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460B, + "HomeConnect 3C460B", + }, + { + USB_VENDOR_3COM2, USB_PRODUCT_3COM2_3CRUSB10075, + "3CRUSB10075", + }, + { + USB_VENDOR_3COM3, USB_PRODUCT_3COM3_AR5523_1, + "AR5523", + }, + { + USB_VENDOR_3COM3, USB_PRODUCT_3COM3_AR5523_2, + "AR5523", + }, + { + USB_VENDOR_3COM3, USB_PRODUCT_3COM3_AR5523_3, + "AR5523", + }, + { + USB_VENDOR_3COMUSR, USB_PRODUCT_3COMUSR_OFFICECONN, + "3Com OfficeConnect Analog Modem", + }, + { + USB_VENDOR_3COMUSR, USB_PRODUCT_3COMUSR_USRISDN, + "3Com U.S. Robotics Pro ISDN TA", + }, + { + USB_VENDOR_3COMUSR, USB_PRODUCT_3COMUSR_HOMECONN, + "3Com HomeConnect", + }, + { + USB_VENDOR_3COMUSR, USB_PRODUCT_3COMUSR_USR56K, + "U.S.Robotics 56000", + }, + { + USB_VENDOR_ABBOTT, USB_PRODUCT_ABBOTT_STEREO_PLUG, + "Stereo Plug Cable", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX1, + "XX1", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX2, + "XX2", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2770, + "RT2770", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2870, + "RT2870", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT3070, + "RT3070", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT3071, + "RT3071", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT3072, + "RT3072", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_URE450, + "URE450 Ethernet", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UFE1000, + "UFE1000 Fast Ethernet", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_DSB650TX_PNA, + "1/10/100 Ethernet", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX4, + "XX4", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX5, + "XX5", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX6, + "XX6", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX7, + "XX7", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_LCS8138TX, + "LCS-8138TX", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX8, + "XX8", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX9, + "XX9", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UF200, + "UF200 Ethernet", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_WL54, + "WL54", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8188EU, + "RTL8188EU", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8188CU_1, + "RTL8188CU", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8188CU_2, + "RTL8188CU", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX10, + "XX10", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_BWU613, + "BWU613", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_HWU54DM, + "HWU54DM", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_2, + "RT2573", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_3, + "RT2573", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_4, + "RT2573", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_WUG2700, + "WUG2700", + }, + { + USB_VENDOR_ABOCOM2, USB_PRODUCT_ABOCOM2_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_USB320_EC, + "USB320-EC Ethernet", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_2664W, + "2664W", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_111, + "T-Sinus 111 WLAN", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SMCWUSBG, + "SMCWUSB-G", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SMCWUSBTG2, + "SMCWUSBT-G2", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SMCWUSBTG2_NF, + "SMCWUSBT-G2", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_PRISM_GT, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SS1001, + "SpeedStream Ethernet", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070, + "RT3070", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT2770, + "RT2770", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT2870_3, + "RT2870", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT2870_5, + "RT2870", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_4, + "RT3070", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT2870_4, + "RT2870", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_1, + "RT3070", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_2, + "RT3070", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_6, + "RT3070", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_AR9280, + "AR9280+AR7010", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RTL8192SU, + "RTL8192SU", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_3, + "RT3070", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_5, + "RT3070", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_ZD1211B, + "ZD1211B", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_WN4501H_LF_IR, + "WN4501H-LF-IR", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_WUS201, + "WUS-201", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_WN7512, + "WN7512", + }, + { + USB_VENDOR_ACEECA, USB_PRODUCT_ACEECA_MEZ1000, + "MEZ1000 RDA", + }, + { + USB_VENDOR_ACERCM, USB_PRODUCT_ACERCM_EP1427X2, + "EP-1427X-2 Ethernet", + }, + { + USB_VENDOR_ACERLABS, USB_PRODUCT_ACERLABS_M5632, + "USB 2.0 Data Link", + }, + { + USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_C310U, + "Acerscan C310U", + }, + { + USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_320U, + "Acerscan 320U", + }, + { + USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_640U, + "Acerscan 640U", + }, + { + USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_620U, + "Acerscan 620U", + }, + { + USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ATAPI, + "ATA/ATAPI", + }, + { + USB_VENDOR_ACERP, USB_PRODUCT_ACERP_AWL300, + "AWL300", + }, + { + USB_VENDOR_ACERP, USB_PRODUCT_ACERP_AWL400, + "AWL400", + }, + { + USB_VENDOR_ACERW, USB_PRODUCT_ACERW_WARPLINK, + "Warplink", + }, + { + USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_PRISM_25, + "Prism2.5 WLAN", + }, + { + USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_PRISM_25A, + "Prism2.5 WLAN A", + }, + { + USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_AR9287, + "AR9287+AR7010", + }, + { + USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_FREELAN, + "ROPEX FreeLan 802.11b", + }, + { + USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_802UAT1, + "802UAT1", + }, + { + USB_VENDOR_ACTISYS, USB_PRODUCT_ACTISYS_IR2000U, + "ACT-IR2000U FIR", + }, + { + USB_VENDOR_ACTIVEWIRE, USB_PRODUCT_ACTIVEWIRE_IOBOARD, + "I/O Board", + }, + { + USB_VENDOR_ACTIVEWIRE, USB_PRODUCT_ACTIVEWIRE_IOBOARD_FW1, + "I/O Board, rev. 1", + }, + { + USB_VENDOR_ADAPTEC, USB_PRODUCT_ADAPTEC_AWN8020, + "AWN-8020 WLAN", + }, + { + USB_VENDOR_ADDONICS2, USB_PRODUCT_ADDONICS2_205, + "Cable 205", + }, + { + USB_VENDOR_ADDTRON, USB_PRODUCT_ADDTRON_AWU120, + "AWU-120", + }, + { + USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_4, + "AN986A Ethernet", + }, + { + USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUS, + "AN986 Ethernet", + }, + { + USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII, + "AN8511 Ethernet", + }, + { + USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_2, + "AN8513 Ethernet", + }, + { + USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_3, + "AN8515 Ethernet", + }, + { + USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BT, + "UBS-10BT Ethernet", + }, + { + USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BTX, + "UBS-10BT Ethernet", + }, + { + USB_VENDOR_AEI, USB_PRODUCT_AEI_FASTETHERNET, + "Fast Ethernet", + }, + { + USB_VENDOR_AGATE, USB_PRODUCT_AGATE_QDRIVE, + "Q-Drive", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1212U, + "SnapScan 1212U", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1236U, + "SnapScan 1236U", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANTOUCH, + "SnapScan Touch", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1212U2, + "SnapScan 1212U", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE40, + "SnapScan e40", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE50, + "SnapScan e50", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE20, + "SnapScan e20", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE25, + "SnapScan e25", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE26, + "SnapScan e26", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE52, + "SnapScan e52", + }, + { + USB_VENDOR_AINCOMM, USB_PRODUCT_AINCOMM_AWU2000B, + "AWU2000B", + }, + { + USB_VENDOR_AIRPRIME, USB_PRODUCT_AIRPRIME_PC5220, + "CDMA Wireless EVDO card", + }, + { + USB_VENDOR_AIRPRIME, USB_PRODUCT_AIRPRIME_AIRCARD_313U, + "Aircard 313U", + }, + { + USB_VENDOR_AIRTIES, USB_PRODUCT_AIRTIES_RT3070_2, + "RT3070", + }, + { + USB_VENDOR_AIRTIES, USB_PRODUCT_AIRTIES_RT3070, + "RT3070", + }, + { + USB_VENDOR_AKS, USB_PRODUCT_AKS_USBHASP, + "USB-HASP 0.06", + }, + { + USB_VENDOR_ALCATEL, USB_PRODUCT_ALCATEL_OT535, + "One Touch 535/735", + }, + { + USB_VENDOR_ALCATELT, USB_PRODUCT_ALCATELT_ST120G, + "SpeedTouch 120g", + }, + { + USB_VENDOR_ALCATELT, USB_PRODUCT_ALCATELT_ST121G, + "SpeedTouch 121g", + }, + { + USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_MA_KBD_HUB, + "MacAlly Kbd Hub", + }, + { + USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_AU9814, + "AU9814 Hub", + }, + { + USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_SM_KBD, + "MicroConnectors/StrongMan", + }, + { + USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_NEC_KBD_HUB, + "NEC Kbd Hub", + }, + { + USB_VENDOR_ALCOR2, USB_PRODUCT_ALCOR2_KBD_HUB, + "Kbd Hub", + }, + { + USB_VENDOR_ALLIEDTELESYN, USB_PRODUCT_ALLIEDTELESYN_ATUSB100, + "AT-USB100", + }, + { + USB_VENDOR_ALLWIN, USB_PRODUCT_ALLWIN_RT2070, + "RT2070", + }, + { + USB_VENDOR_ALLWIN, USB_PRODUCT_ALLWIN_RT2770, + "RT2770", + }, + { + USB_VENDOR_ALLWIN, USB_PRODUCT_ALLWIN_RT2870, + "RT2870", + }, + { + USB_VENDOR_ALLWIN, USB_PRODUCT_ALLWIN_RT3070, + "RT3070", + }, + { + USB_VENDOR_ALLWIN, USB_PRODUCT_ALLWIN_RT3071, + "RT3071", + }, + { + USB_VENDOR_ALLWIN, USB_PRODUCT_ALLWIN_RT3072, + "RT3072", + }, + { + USB_VENDOR_ALLWIN, USB_PRODUCT_ALLWIN_RT3572, + "RT3572", + }, + { + USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ADA70, + "ADA70 Speakers", + }, + { + USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ASC495, + "ASC495 Speakers", + }, + { + USB_VENDOR_ALTI2, USB_PRODUCT_ALTI2_NEPTUNE3, + "Neptune 3", + }, + { + USB_VENDOR_AMBIT, USB_PRODUCT_AMBIT_WLAN, + "WLAN", + }, + { + USB_VENDOR_AMBIT, USB_PRODUCT_AMBIT_NTL_250, + "NTL 250 cable modem", + }, + { + USB_VENDOR_AMIGO, USB_PRODUCT_AMIGO_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_AMIGO, USB_PRODUCT_AMIGO_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_AMIT, USB_PRODUCT_AMIT_CGWLUSB2GO, + "CG-WLUSB2GO", + }, + { + USB_VENDOR_AMIT, USB_PRODUCT_AMIT_CGWLUSB2GNR, + "CG-WLUSB2GNR", + }, + { + USB_VENDOR_AMIT, USB_PRODUCT_AMIT_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_AMIT2, USB_PRODUCT_AMIT2_RT2870, + "RT2870", + }, + { + USB_VENDOR_ANALOG, USB_PRODUCT_ANALOG_EAGLEI, + "Eagle I", + }, + { + USB_VENDOR_ANALOG, USB_PRODUCT_ANALOG_EAGLEI_NF, + "Eagle I", + }, + { + USB_VENDOR_ANALOG, USB_PRODUCT_ANALOG_EAGLEII, + "Eagle II", + }, + { + USB_VENDOR_ANALOG, USB_PRODUCT_ANALOG_EAGLEII_NF, + "Eagle II", + }, + { + USB_VENDOR_ANALOG, USB_PRODUCT_ANALOG_EAGLEIIC, + "Eagle IIC", + }, + { + USB_VENDOR_ANALOG, USB_PRODUCT_ANALOG_EAGLEIIC_NF, + "Eagle IIC", + }, + { + USB_VENDOR_ANALOG, USB_PRODUCT_ANALOG_EAGLEIII, + "Eagle III", + }, + { + USB_VENDOR_ANALOG, USB_PRODUCT_ANALOG_EAGLEIII_NF, + "Eagle III", + }, + { + USB_VENDOR_ANALOGDEVICES, USB_PRODUCT_ANALOGDEVICES_GNICE, + "gnICE", + }, + { + USB_VENDOR_ANALOGDEVICES, USB_PRODUCT_ANALOGDEVICES_GNICEPLUS, + "gnICE+", + }, + { + USB_VENDOR_ANCHOR, USB_PRODUCT_ANCHOR_SERIAL, + "Serial", + }, + { + USB_VENDOR_ANCHOR, USB_PRODUCT_ANCHOR_EZUSB, + "EZUSB", + }, + { + USB_VENDOR_ANCHOR, USB_PRODUCT_ANCHOR_EZLINK, + "EZLINK", + }, + { + USB_VENDOR_ANYDATA, USB_PRODUCT_ANYDATA_A2502, + "NTT DoCoMo A2502", + }, + { + USB_VENDOR_ANYDATA, USB_PRODUCT_ANYDATA_ADU_E100H, + "ADU-E100H", + }, + { + USB_VENDOR_ANYDATA, USB_PRODUCT_ANYDATA_ADU_500A, + "ADU-500A", + }, + { + USB_VENDOR_AOX, USB_PRODUCT_AOX_USB101, + "Ethernet", + }, + { + USB_VENDOR_APC, USB_PRODUCT_APC_UPS, + "UPS", + }, + { + USB_VENDOR_APC, USB_PRODUCT_APC_UPS5G, + "5G UPS", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_FOUNTAIN_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_FOUNTAIN_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_GEYSER_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_GEYSER_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING2_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING2_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING2_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING3_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING3_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING3_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4A_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4A_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4A_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6A_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6A_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6A_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5A_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5A_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5A_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7A_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7A_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7A_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING9_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING9_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING9_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING8_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING8_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING8_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_OPTMOUSE, + "Optical mouse", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_BLUETOOTH_HCI, + "HID-proxy", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_SPEAKERS, + "Speakers", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE, + "iPhone", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPOD_TOUCH, + "iPod Touch", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_3G, + "iPhone 3G", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPOD_TOUCH_2G, + "iPod Touch 2G", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_3GS, + "iPhone 3GS", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_4_GSM, + "iPhone 4 GSM", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPOD_TOUCH_3G, + "iPod Touch 3G", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPAD, + "iPad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_4_CDMA, + "iPhone 4 CDMA", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPOD_TOUCH_4G, + "iPod Touch 4G", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPAD2, + "iPad 2", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_4S, + "iPhone 4S", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_6, + "iPhone 6", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_ETHERNET, + "Ethernet A1277", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_BLUETOOTH2, + "Bluetooth", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_BLUETOOTH, + "Bluetooth", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_ISIGHT_1, + "iSight", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_ISIGHT, + "iSight", + }, + { + USB_VENDOR_ARANEUS, USB_PRODUCT_ARANEUS_ALEA, + "True Random Number Generator", + }, + { + USB_VENDOR_ARDUINO, USB_PRODUCT_ARDUINO_LEONARDO, + "Leonardo", + }, + { + USB_VENDOR_ARKMICRO, USB_PRODUCT_ARKMICRO_ARK3116, + "ARK3116 Serial", + }, + { + USB_VENDOR_ARUBA, USB_PRODUCT_ARUBA_CP210X, + "CP210x Serial", + }, + { + USB_VENDOR_ASAHIOPTICAL, USB_PRODUCT_ASAHIOPTICAL_OPTIO230, + "PENTAX Optio230", + }, + { + USB_VENDOR_ASANTE, USB_PRODUCT_ASANTE_EA, + "Ethernet", + }, + { + USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88172, + "USB 2.0 10/100 Ethernet controller", + }, + { + USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88178, + "AX88178", + }, + { + USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88179, + "AX88179", + }, + { + USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772, + "AX88772", + }, + { + USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772A, + "AX88772A", + }, + { + USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772B, + "AX88772B", + }, + { + USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772B_1, + "AX88772B", + }, + { + USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_WLL013I, + "WLL013 (Intersil)", + }, + { + USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_WLL013, + "WLL013", + }, + { + USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_VOYAGER1010, + "Voyager 1010", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2570, + "RT2570", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2570_2, + "RT2570", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_WL159G, + "WL-159g", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_A9T_WIFI, + "A9T wireless", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_P5B_WIFI, + "P5B wireless", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_1, + "RT2573", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_2, + "RT2573", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2870_3, + "RT2870", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2870_4, + "RT2870", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2870_5, + "RT2870", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_USBN13, + "USB-N13", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_USBN10, + "USB-N10", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT3070_1, + "RT3070", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RTL8192SU_1, + "RTL8192SU", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_USBN53, + "USB-N53", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_USBN66, + "USB-N66", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RTL8192CU_2, + "RTL8192CU", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RTL8192CU_3, + "RTL8192CU", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_MYPAL_A730, + "MyPal A730", + }, + { + USB_VENDOR_ASUS2, USB_PRODUCT_ASUS2_USBN11, + "USB-N11", + }, + { + USB_VENDOR_ASUSTEK, USB_PRODUCT_ASUSTEK_WL140, + "WL-140", + }, + { + USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC1284, + "Parallel", + }, + { + USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC10T, + "10Mbps Ethernet", + }, + { + USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC110T, + "UC-110T Ethernet", + }, + { + USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC232A, + "UC232A Serial", + }, + { + USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC210T, + "UC210T Ethernet", + }, + { + USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC2324, + "UC2324 Serial", + }, + { + USB_VENDOR_ATEN, USB_PRODUCT_ATEN_DSB650C, + "DSB-650C", + }, + { + USB_VENDOR_ATHEROS, USB_PRODUCT_ATHEROS_AR5523, + "AR5523", + }, + { + USB_VENDOR_ATHEROS, USB_PRODUCT_ATHEROS_AR5523_NF, + "AR5523", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR5523_1, + "AR5523", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR5523_1_NF, + "AR5523", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR5523_2, + "AR5523", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR5523_2_NF, + "AR5523", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR5523_3, + "AR5523", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR5523_3_NF, + "AR5523", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_TG121N, + "TG121N", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_WN821NV2, + "WN821NV2", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9271_1, + "AR9271", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_3CRUSBN275, + "3CRUSBN275", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_WN612, + "WN612", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR3011, + "AR3011", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9280, + "AR9280+AR7010", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9287, + "AR9287+AR7010", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9170, + "AR9170", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9271_2, + "AR9271", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9271_3, + "AR9271", + }, + { + USB_VENDOR_ATI2, USB_PRODUCT_ATI2_205, + "USB Cable 205", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_STK541, + "STK541 Zigbee", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_UHB124, + "UHB124 hub", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_WN210, + "W-Buddie WN210", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_DWL900AP, + "DWL-900AP Wireless access point", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT91_CDC_ACM, + "AT91 CDC ACM", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503I1, + "AT76C503 (Intersil 3861 Radio)", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503I2, + "AT76C503 (Intersil 3863 Radio)", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503RFMD, + "AT76C503 (RFMD Radio)", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505RFMD, + "AT76C505 (RFMD Radio)", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505RFMD2958, + "AT76C505 (RFMD 2958 Radio)", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505A, + "AT76C505A (RFMD 2958 Radio)", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505AS, + "AT76C505AS (RFMD 2958 Radio)", + }, + { + USB_VENDOR_AUDIOTECHNICA, USB_PRODUCT_AUDIOTECHNICA_ATCHA4USB, + "ATC-HA4USB USB headphone", + }, + { + USB_VENDOR_AVAGO, USB_PRODUCT_AVAGO_MOUSE, + "Mouse", + }, + { + USB_VENDOR_AVANCELOGIC, USB_PRODUCT_AVANCELOGIC_USBAUDIO, + "USB Audio Speaker", + }, + { + USB_VENDOR_AVERATEC, USB_PRODUCT_AVERATEC_USBWLAN, + "WLAN", + }, + { + USB_VENDOR_AVISION, USB_PRODUCT_AVISION_1200U, + "1200U", + }, + { + USB_VENDOR_AVM, USB_PRODUCT_AVM_FRITZWLAN, + "FRITZ!WLAN N", + }, + { + USB_VENDOR_AXESSTEL, USB_PRODUCT_AXESSTEL_DATAMODEM, + "Data Modem", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RT3070_1, + "RT3070", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RT3070_2, + "RT3070", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RT3070_3, + "RT3070", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_1, + "RTL8192SU", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RT3070_4, + "RT3070", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_2, + "RTL8192SU", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_3, + "RTL8192SU", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_4, + "RTL8192SU", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RT3070_5, + "RT3070", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_5, + "RTL8192SU", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_1, + "AR9271", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_2, + "AR9271", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_3, + "AR9271", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_4, + "AR9271", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_5, + "AR9271", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_6, + "AR9271", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8188CU, + "RTL8188CU", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8188CE_1, + "RTL8188CE", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8188CE_2, + "RTL8188CE", + }, + { + USB_VENDOR_BALTECH, USB_PRODUCT_BALTECH_CARDREADER, + "Card reader", + }, + { + USB_VENDOR_BAYER, USB_PRODUCT_BAYER_CONTOUR, + "Ascensia Contour", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_USOTL4, + "USOTL4 RS-422/485", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_USTL4, + "USTL4 RS-422/485", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_USO9ML2, + "USO9ML2 RS-232", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_USOPTL4, + "USOPTL4 RS-422/485", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_USPTL4, + "USPTL4 RS-422/485", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_USO9ML2DR2, + "USO9ML2DR-2 RS-232", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_USO9ML2DR, + "USO9ML2DR RS-232", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_USOPTL4DR2, + "USOPTL4DR-2 RS-422/485", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_USOPTL4DR, + "USOPTL4DR RS-422/485", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_485USB9F2W, + "485USB9F-2W RS-422/485", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_485USB9F4W, + "485USB9F-4W RS-422/485", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_232USB9M, + "232USB9M RS-232", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_485USBTB_2W, + "485USBTB-2W RS-422/485", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_485USBTB_4W, + "485USBTB-4W RS-422/485", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_TTL5USB9M, + "TTL5USB9M", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_TTL3USB9M, + "TTL3USB9M", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_ZZ_PROG1, + "ZZ Programmer", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D6050, + "F5D6050 802.11b Wireless adapter", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_FBT001V, + "Bluetooth", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F8T003V, + "Bluetooth", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_FBT003V, + "Bluetooth", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U103, + "F5U103 Serial", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U109, + "F5U109 Serial", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_SCSI, + "SCSI", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D5050, + "F5D5050 Ethernet", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U234, + "F5U234 USB 2.0 4-Port Hub", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U237, + "F5U237 USB 2.0 7-Port Hub", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U257, + "F5U257 Serial", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6H375, + "F6H375 UPS", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U409, + "F5U409 Serial", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C550AVR, + "F6C550-AVR UPS", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C1250EITWRK, + "F6C1250EITW-RK UPS", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C1500EITWRK, + "F6C1500EITW-RK UPS", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C900, + "F6C900 UPS", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C100, + "F6C100 UPS", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C120, + "F6C120 UPS", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C800, + "F6C800 UPS", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F9L1004V1, + "F9L1004V1", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C1100, + "F6C1100/1200 UPS", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8188CU, + "RTL8188CU", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F9L1103, + "F9L1103 Wireless Adapter", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8188CUS, + "RTL8188CUS", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U120, + "F5U120-PC Hub", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F7D2102, + "F7D2102", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192CU_1, + "RTL8192CU", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_ZD1211B, + "ZD1211B", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D5055, + "F5D5055", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050, + "F5D7050 54g USB Network Adapter", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050A, + "F5D705A 54g USB Network Adapter", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050C, + "F5D705C 54g USB Network Adapter", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050E, + "F5D705E 54g USB Network Adapter", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D8053V3, + "F5D8053 v3", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192SU_1, + "RTL8192SU", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D8055, + "F5D8055", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D8055V2, + "F5D8055 v2", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192SU_2, + "RTL8192SU", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D9050V3, + "F5D9050 ver 3", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D9050C, + "F5D9050C", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6D4050V1, + "F6D4050 ver 1", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6D4050V2, + "F6D4050 ver 2", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192SU_3, + "RTL8192SU", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F7D1101V2, + "F7D1101 v2", + }, + { + USB_VENDOR_BELKIN2, USB_PRODUCT_BELKIN2_F5U002, + "F5U002 Parallel", + }, + { + USB_VENDOR_BEWAN, USB_PRODUCT_BEWAN_BWIFI_USB54AR, + "BWIFI-USB54AR", + }, + { + USB_VENDOR_BEWAN, USB_PRODUCT_BEWAN_RT3070, + "RT3070", + }, + { + USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB100, + "USB100N 10/100 Ethernet", + }, + { + USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBLP100, + "USB100LP", + }, + { + USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBEL100, + "USB100EL", + }, + { + USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBE100, + "USBE100", + }, + { + USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB2AR, + "USB2AR Ethernet", + }, + { + USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCMFW, + "BCMFW", + }, + { + USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM2033, + "BCM2033", + }, + { + USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM2033NF, + "BCM2033 (no fw)", + }, + { + USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM43236, + "BCM43236", + }, + { + USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM43143, + "BCM43143", + }, + { + USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM43242, + "BCM43242", + }, + { + USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM43569, + "BCM43569", + }, + { + USB_VENDOR_BROTHER, USB_PRODUCT_BROTHER_HL1050, + "HL-1050 laser printer", + }, + { + USB_VENDOR_BROTHER, USB_PRODUCT_BROTHER_MFC210C, + "MFC 210C", + }, + { + USB_VENDOR_BTC, USB_PRODUCT_BTC_BTC7932, + "Keyboard/Mouse", + }, + { + USB_VENDOR_BWCT, USB_PRODUCT_BWCT_6CHCONSER, + "6ch ConSer", + }, + { + USB_VENDOR_CACE, USB_PRODUCT_CACE_AIRPCAPNX, + "AirPcap Nx", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_N656U, + "CANOSCAN N656U", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_N1220U, + "CANOSCAN N1220U", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_N670U, + "CANOSCAN N670U", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_N1240U, + "CANOSCAN N1240U", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_LIDE60, + "CANOSCAN LiDE60", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_S10, + "PowerShot S10", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_S20, + "PowerShot S20", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_S100_US, + "PowerShot S100", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_S100_EU, + "PowerShot S100", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_G1, + "PowerShot G1", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_A20, + "PowerShot A20", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_A540, + "PowerShot A540", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_SX100, + "PowerShot SX100", + }, + { + USB_VENDOR_CASIO, USB_PRODUCT_CASIO_QV, + "QV", + }, + { + USB_VENDOR_CASIO, USB_PRODUCT_CASIO_BE300, + "BE-300 PDA", + }, + { + USB_VENDOR_CASIO, USB_PRODUCT_CASIO_NAMELAND, + "CASIO Nameland EZ-USB", + }, + { + USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE, + "Netmate Ethernet", + }, + { + USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE2, + "Netmate2 Ethernet", + }, + { + USB_VENDOR_CATC, USB_PRODUCT_CATC_CHIEF, + "USB Chief Bus & Protocol Analyzer", + }, + { + USB_VENDOR_CATC, USB_PRODUCT_CATC_ANDROMEDA, + "Andromeda hub", + }, + { + USB_VENDOR_CCYU, USB_PRODUCT_CCYU_EASYDISK, + "EasyDisk Portable", + }, + { + USB_VENDOR_CHENSOURCE, USB_PRODUCT_CHENSOURCE_CM12402, + "CM12402 Eagle IR Cam", + }, + { + USB_VENDOR_CHERRY, USB_PRODUCT_CHERRY_MY3000KBD, + "My3000 keyboard", + }, + { + USB_VENDOR_CHERRY, USB_PRODUCT_CHERRY_MY3000HUB, + "My3000 hub", + }, + { + USB_VENDOR_CHIC, USB_PRODUCT_CHIC_MOUSE1, + "mouse", + }, + { + USB_VENDOR_CHIC, USB_PRODUCT_CHIC_CYPRESS, + "Cypress", + }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_KB8933, + "KB-8933 keyboard", + }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_CAMERA, + "Integrated Camera", + }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_1, + "RTL8188CUS", + }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_2, + "RTL8188CUS", + }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_3, + "RTL8188CUS", + }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_4, + "RTL8188CUS", + }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_5, + "RTL8188CUS", + }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_6, + "RTL8188CUS", + }, + { + USB_VENDOR_CHPRODUCTS, USB_PRODUCT_CHPRODUCTS_PROTHROTTLE, + "Pro Throttle", + }, + { + USB_VENDOR_CHPRODUCTS, USB_PRODUCT_CHPRODUCTS_PROPEDALS, + "Pro Pedals", + }, + { + USB_VENDOR_CHPRODUCTS, USB_PRODUCT_CHPRODUCTS_FIGHTERSTICK, + "Fighterstick", + }, + { + USB_VENDOR_CHPRODUCTS, USB_PRODUCT_CHPRODUCTS_FLIGHTYOKE, + "Flight Sim Yoke", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GV2, + "WUSB54G v2", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54AG, + "WUSB54AG", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54G, + "RT2570", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GP, + "RT2570", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_USB200MV2, + "USB200M v2", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_HU200TS, + "HU200-TS", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GC, + "WUSB54GC", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GR, + "WUSB54GR", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSBF54G, + "WUSBF54G", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB200, + "WUSB200", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_AE1000, + "AE1000", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_AM10, + "AM10", + }, + { + USB_VENDOR_CISCOLINKSYS2, USB_PRODUCT_CISCOLINKSYS2_RT3070, + "RT3070", + }, + { + USB_VENDOR_CISCOLINKSYS3, USB_PRODUCT_CISCOLINKSYS3_RT3070, + "RT3070", + }, + { + USB_VENDOR_CLIPSAL, USB_PRODUCT_CLIPSAL_560884, + "560884 C-Bus Switch", + }, + { + USB_VENDOR_CLIPSAL, USB_PRODUCT_CLIPSAL_5500PACA, + "5500PACA C-Bus Controller", + }, + { + USB_VENDOR_CLIPSAL, USB_PRODUCT_CLIPSAL_5800PC, + "5800PC C-Bus Wireless", + }, + { + USB_VENDOR_CLIPSAL, USB_PRODUCT_CLIPSAL_5500PCU, + "5500PCU C-Bus", + }, + { + USB_VENDOR_CLIPSAL, USB_PRODUCT_CLIPSAL_5000CT2, + "5000CT2 C-Bus Touch Screen", + }, + { + USB_VENDOR_CLIPSAL, USB_PRODUCT_CLIPSAL_C5000CT2, + "C5000CT2 C-Bus Touch Screen", + }, + { + USB_VENDOR_CLIPSAL, USB_PRODUCT_CLIPSAL_L51XX, + "L51xx C-Bus Dimmer", + }, + { + USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CNU510, + "CDMA Technologies USB modem", + }, + { + USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CM5100P, + "CM-5100P EVDO", + }, + { + USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CCU550, + "CCU-550 EVDO", + }, + { + USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CNU550PRO, + "CNU-550pro EVDO", + }, + { + USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CGU628, + "CGU-628", + }, + { + USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CNU680, + "CNU-680", + }, + { + USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CGU628_DISK, + "CGU-628 disk mode", + }, + { + USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQPOCKETPC, + "iPAQ PocketPC", + }, + { + USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_A1500, + "A1500", + }, + { + USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQWLAN, + "iPAQ WLAN", + }, + { + USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_W100, + "W100", + }, + { + USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_W200, + "WLAN MultiPort W200", + }, + { + USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_PJB100, + "Personal Jukebox PJB100", + }, + { + USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQLINUX, + "iPAQ Linux", + }, + { + USB_VENDOR_COMPARE, USB_PRODUCT_COMPARE_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_PRISM_GT, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_C11U, + "C11U", + }, + { + USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_WL210, + "WL-210", + }, + { + USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_AR5523_1, + "AR5523", + }, + { + USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_AR5523_1_NF, + "AR5523", + }, + { + USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_AR5523_2, + "AR5523", + }, + { + USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_AR5523_2_NF, + "AR5523", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RTL8192SU_1, + "RTL8192SU", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RTL8192SU_2, + "RTL8192SU", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RTL8192SU_3, + "RTL8192SU", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_C54RU, + "C54RU WLAN", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT3070_1, + "RT3070", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_7, + "RT2870", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT3070_2, + "RT3070", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_8, + "RT2870", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_C54RU2, + "C54RU", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_3, + "RT2870", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2573, + "RT2573M", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_VIGORN61, + "VIGORN61", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_5, + "RT2870", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_6, + "RT2870", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT3070_3, + "RT3070", + }, + { + USB_VENDOR_CONCORDCAMERA, USB_PRODUCT_CONCORDCAMERA_EYE_Q_3X, + "Eye Q 3x", + }, + { + USB_VENDOR_CONNECTIX, USB_PRODUCT_CONNECTIX_QUICKCAM, + "QuickCam", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_ETHER_USB_T, + "Ether USB-T", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TX, + "FEther USB-TX", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_WLAN_USB_USB_11, + "WirelessLAN USB-11", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXS, + "FEther USB-TXS", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_WLANUSB, + "Wireless LAN Stick-11", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB2_TX, + "FEther USB2-TX", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_WLUSB_11_KEY, + "ULUSB-11 Key", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB2GL, + "CG-WLUSB2GL", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB2GPX, + "CG-WLUSB2GPX", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_RT2870_3, + "RT2870", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_RT3070, + "RT3070", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB300GNM, + "CG-WLUSB300GNM", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB300N, + "CG-WLUSB300N", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_RTL8192SU, + "RTL8192SU", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_WLUSB_11_STICK, + "WLAN USB Stick 11", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXC, + "FEther USB-TXC", + }, + { + USB_VENDOR_CORSAIR, USB_PRODUCT_CORSAIR_CP210X, + "CP210X", + }, + { + USB_VENDOR_CREATIVE, USB_PRODUCT_CREATIVE_NOMAD_II, + "Nomad II", + }, + { + USB_VENDOR_CREATIVE, USB_PRODUCT_CREATIVE_EMU0202, + "E-Mu 0202", + }, + { + USB_VENDOR_CREATIVE, USB_PRODUCT_CREATIVE_NOMAD_IIMG, + "Nomad II MG", + }, + { + USB_VENDOR_CREATIVE, USB_PRODUCT_CREATIVE_NOMAD, + "Nomad", + }, + { + USB_VENDOR_CREATIVE2, USB_PRODUCT_CREATIVE2_VOIP_BLASTER, + "Voip Blaster", + }, + { + USB_VENDOR_CSR, USB_PRODUCT_CSR_BLUETOOTH, + "Bluetooth", + }, + { + USB_VENDOR_CSR, USB_PRODUCT_CSR_BLUECORE, + "BlueCore", + }, + { + USB_VENDOR_CTC, USB_PRODUCT_CTC_CW6622, + "CW6622", + }, + { + USB_VENDOR_CTX, USB_PRODUCT_CTX_EX1300, + "Ex1300 hub", + }, + { + USB_VENDOR_CYBERPOWER, USB_PRODUCT_CYBERPOWER_UPS, + "UPS", + }, + { + USB_VENDOR_CYBERPOWER, USB_PRODUCT_CYBERPOWER_1500, + "1500 UPS", + }, + { + USB_VENDOR_CYBERPOWER, USB_PRODUCT_CYBERPOWER_OR2200, + "OR2200 UPS", + }, + { + USB_VENDOR_CYBERTAN, USB_PRODUCT_CYBERTAN_GIGASET108, + "Siemens Gigaset 108", + }, + { + USB_VENDOR_CYBERTAN, USB_PRODUCT_CYBERTAN_TG54USB, + "TG54USB", + }, + { + USB_VENDOR_CYBERTAN, USB_PRODUCT_CYBERTAN_ZD1211B, + "ZD1211B", + }, + { + USB_VENDOR_CYBERTAN, USB_PRODUCT_CYBERTAN_RT2870, + "RT2870", + }, + { + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_MOUSE, + "mouse", + }, + { + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_THERMO, + "thermometer", + }, + { + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_KBDHUB, + "Keyboard/Hub", + }, + { + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_FMRADIO, + "FM Radio", + }, + { + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_USBRS232, + "RS232", + }, + { + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_HUB2, + "USB2 Hub", + }, + { + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_LPRDK, + "CY4636 LP RDK Bridge", + }, + { + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_SISPM_OLD, + "Sispm - old version", + }, + { + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_SISPM, + "Sispm", + }, + { + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_SISPM_FLASH, + "Sispm - flash", + }, + { + USB_VENDOR_DAISY, USB_PRODUCT_DAISY_DMC, + "PhotoClip", + }, + { + USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_USB_FOB_IBUTTON, + "USB-FOB/iBUTTON", + }, + { + USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502, + "J-6502 speakers", + }, + { + USB_VENDOR_DATAAPEX, USB_PRODUCT_DATAAPEX_MULTICOM, + "MultiCom", + }, + { + USB_VENDOR_DAVICOM, USB_PRODUCT_DAVICOM_WK668, + "HenTong WK-668", + }, + { + USB_VENDOR_DAVICOM, USB_PRODUCT_DAVICOM_DM9601, + "DM9601", + }, + { + USB_VENDOR_DELL, USB_PRODUCT_DELL_AXIM, + "Axim X51v", + }, + { + USB_VENDOR_DELL, USB_PRODUCT_DELL_BC02, + "Bluetooth", + }, + { + USB_VENDOR_DELL, USB_PRODUCT_DELL_TM1180, + "TrueMobile 1180 WLAN", + }, + { + USB_VENDOR_DELL, USB_PRODUCT_DELL_PRISM_GT_1, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_DELL, USB_PRODUCT_DELL_BLUETOOTH350, + "Bluetooth", + }, + { + USB_VENDOR_DELL, USB_PRODUCT_DELL_PRISM_GT_2, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_DELL, USB_PRODUCT_DELL_W5500, + "W5500 HSDPA", + }, + { + USB_VENDOR_DELL, USB_PRODUCT_DELL_U740, + "Dell U740 CDMA", + }, + { + USB_VENDOR_DELL, USB_PRODUCT_DELL_EU870D, + "EU870D HSDPA", + }, + { + USB_VENDOR_DELL, USB_PRODUCT_DELL_DW700, + "DW700 GPS", + }, + { + USB_VENDOR_DELL2, USB_PRODUCT_DELL2_UPS, + "UPS", + }, + { + USB_VENDOR_DELORME, USB_PRODUCT_DELORME_EMUSB, + "Earthmate GPS", + }, + { + USB_VENDOR_DELORME, USB_PRODUCT_DELORME_EMLT20, + "Earthmate LT20", + }, + { + USB_VENDOR_DIAMOND, USB_PRODUCT_DIAMOND_RIO500USB, + "Rio 500", + }, + { + USB_VENDOR_DIAMOND2, USB_PRODUCT_DIAMOND2_SUPRAEXPRESS56K, + "Supra Express 56K", + }, + { + USB_VENDOR_DIAMOND2, USB_PRODUCT_DIAMOND2_SUPRA2890, + "SupraMax 2890 56K", + }, + { + USB_VENDOR_DIAMOND2, USB_PRODUCT_DIAMOND2_RIO600USB, + "Rio 600", + }, + { + USB_VENDOR_DIAMOND2, USB_PRODUCT_DIAMOND2_RIO800USB, + "Rio 800", + }, + { + USB_VENDOR_DIAMOND2, USB_PRODUCT_DIAMOND2_PSAPLAY120, + "Nike psa[play 120", + }, + { + USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_WL200U, + "WL-200U", + }, + { + USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_CHUSB611G, + "CHUSB 611G", + }, + { + USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_WL240U, + "WL-240U", + }, + { + USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_XH1153, + "XH1153 802.11b", + }, + { + USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_RT2573, + "RT2573", + }, + { + USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_CWD854F, + "C-Net CWD-854 rev F", + }, + { + USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_RTL8187, + "RTL8187", + }, + { + USB_VENDOR_DIGI, USB_PRODUCT_DIGI_ACCELEPORT2, + "AccelePort 2", + }, + { + USB_VENDOR_DIGI, USB_PRODUCT_DIGI_ACCELEPORT4, + "AccelePort 4", + }, + { + USB_VENDOR_DIGI, USB_PRODUCT_DIGI_ACCELEPORT8, + "AccelePort 8", + }, + { + USB_VENDOR_DIGIANSWER, USB_PRODUCT_DIGIANSWER_ZIGBEE802154, + "ZigBee", + }, + { + USB_VENDOR_DIGITALSTREAM, USB_PRODUCT_DIGITALSTREAM_PS2, + "PS/2 Active", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_GUC2020, + "IOGEAR DVI GUC2020", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_LD220, + "Samsung LD220", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_POLARIS2, + "Polaris2 USB dock", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_VCUD60, + "Rextron DVI", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_CONV, + "StarTech CONV-USB2DVI", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_DLDVI, + "DisplayLink DVI", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_VGA10, + "CMP-USBVGA10", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_WSDVI, + "WS Tech DVI", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_EC008, + "EasyCAP008 DVI", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_LCD4300U, + "LCD-4300U", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_LCD8000U, + "LCD-8000U", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_HPDOCK, + "HP USB Docking", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_NL571, + "HP USB DVI", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_M01061, + "Lenovo DVI", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_NBDOCK, + "VideoHome NBdock1920", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_SWDVI, + "SUNWEIT DVI", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_LUM70, + "Lilliput UM-70", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_LT1421, + "Lenovo ThinkVision LT1421", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_UM7X0, + "nanovision MiMo", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100, + "10/100 Ethernet", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100C1, + "DUB-E100 rev C1", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX4, + "10/100 Ethernet", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWL120E, + "DWL-120 rev E", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA130C, + "DWA-130 rev C", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8192CU_1, + "RTL8192CU", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8188CU, + "RTL8188CU", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8192CU_2, + "RTL8192CU", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8192CU_3, + "RTL8192CU", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8192CU_4, + "RTL8192CU", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA131B, + "DWA-131 rev B", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA125D1, + "DWA-125 rev D1", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA123D1, + "DWA-123 rev D1", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA137A1, + "DWA-137 rev A1", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA131E1, + "DWA-131 rev E1", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA182D1, + "DWA-182 rev D1", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA171C1, + "DWA-171 rev C1", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWL122, + "DWL-122", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLG120, + "DWL-G120", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWL120F, + "DWL-120 rev F", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLG122A2, + "DWL-G122 rev A2", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLAG132, + "DWL-AG132", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLAG132_NF, + "DWL-AG132", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLG132, + "DWL-G132", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLG132_NF, + "DWL-G132", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLAG122, + "DWL-AG122", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLAG122_NF, + "DWL-AG122", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RT2570, + "RT2570", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100B1, + "DUB-E100 rev B1", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RT2870, + "RT2870", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RT3072, + "RT3072", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA140B3, + "DWA-140 rev B3", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA160B2, + "DWA-160 rev B2", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA127, + "DWA-127", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA125B2, + "DWA-125 rev B2", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA162, + "DWA-162 Wireless Adapter", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA140D1, + "DWA-140 rev D1", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA130F1, + "DWA-130 rev F1", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650C, + "10Mbps Ethernet", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX1, + "10/100 Ethernet", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX, + "10/100 Ethernet", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX_PNA, + "1/10/100 Ethernet", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX3, + "10/100 Ethernet", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX2, + "10/100 Ethernet", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUB1312, + "DUB-1312", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650, + "10/100 Ethernet", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RTL8192SU_1, + "RTL8192SU", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RTL8192SU_2, + "RTL8192SU", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA131A1, + "DWA-131 A1", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_WUA2340, + "WUA-2340", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_WUA2340_NF, + "WUA-2340", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA160A2, + "DWA-160 A2", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA130D1, + "DWA-130 rev D1", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_AR9271, + "AR9271", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWLG122C1, + "DWL-G122 rev C1", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_WUA1340, + "WUA-1340", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA111, + "DWA-111", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA110, + "DWA-110", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT3072, + "RT3072", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT3072_1, + "RT3072", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT3070_1, + "RT3070", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT3070_2, + "RT3070", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT3070_3, + "RT3070", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA160A1, + "DWA-160 A1", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA130, + "DWA-130", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT3070_4, + "RT3070", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT3070_5, + "RT3070", + }, + { + USB_VENDOR_DLINK3, USB_PRODUCT_DLINK3_KVM221, + "KVM-221", + }, + { + USB_VENDOR_DMI, USB_PRODUCT_DMI_SA2_0, + "Storage Adapter", + }, + { + USB_VENDOR_DOMAIN, USB_PRODUCT_DOMAIN_ROCKCHIP, + "RockChip Media Player", + }, + { + USB_VENDOR_DRAYTEK, USB_PRODUCT_DRAYTEK_VIGOR550, + "Vigor550", + }, + { + USB_VENDOR_DRAYTEK, USB_PRODUCT_DRAYTEK_VIGOR600, + "Vigor600", + }, + { + USB_VENDOR_DREAMCHEEKY, USB_PRODUCT_DREAMCHEEKY_ROCKETBABY, + "Missile Launcher", + }, + { + USB_VENDOR_DREAMLINK, USB_PRODUCT_DREAMLINK_ULMB1, + "USB LED Message Board v1.0", + }, + { + USB_VENDOR_DRESDENELEC, USB_PRODUCT_DRESDENELEC_STB, + "Sensor Terminal", + }, + { + USB_VENDOR_DRESDENELEC, USB_PRODUCT_DRESDENELEC_WHT, + "Wireless Terminal", + }, + { + USB_VENDOR_DVICO, USB_PRODUCT_DVICO_RT3070, + "RT3070", + }, + { + USB_VENDOR_DYNASTREAM, USB_PRODUCT_DYNASTREAM_ANTDEVBOARD, + "ANT dev board", + }, + { + USB_VENDOR_DYNASTREAM, USB_PRODUCT_DYNASTREAM_ANT2USB, + "ANT2USB", + }, + { + USB_VENDOR_DYNASTREAM, USB_PRODUCT_DYNASTREAM_ANTDEVBOARD2, + "ANT dev board", + }, + { + USB_VENDOR_DYNASTREAM, USB_PRODUCT_DYNASTREAM_ANTUSB2, + "ANTUSB-2 Stick", + }, + { + USB_VENDOR_DYNASTREAM, USB_PRODUCT_DYNASTREAM_ANTUSBM, + "ANTUSB-m Stick", + }, + { + USB_VENDOR_EASYDISK, USB_PRODUCT_EASYDISK_EASYDISK, + "Flash Disk", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7318, + "EW-7318", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RTL8192SU_1, + "RTL8192SU", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RTL8192SU_2, + "RTL8192SU", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7618, + "EW-7618", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RTL8192SU_3, + "RTL8192SU", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7717, + "EW-7717", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7718, + "EW-7718", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7722UTN, + "EW-7722UTn", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7811UN, + "EW-7811Un", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7611ULB, + "EW-7611ULB", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7822ULC, + "EW-7822ULC", + }, + { + USB_VENDOR_EGALAX, USB_PRODUCT_EGALAX_TPANEL, + "Touch Panel", + }, + { + USB_VENDOR_EGALAX, USB_PRODUCT_EGALAX_TPANEL2, + "Touch Panel", + }, + { + USB_VENDOR_EGALAX2, USB_PRODUCT_EGALAX2_TPANEL, + "Touch Panel", + }, + { + USB_VENDOR_EICON, USB_PRODUCT_EICON_DIVA852, + "Diva 852 ISDN TA", + }, + { + USB_VENDOR_EIZO, USB_PRODUCT_EIZO_HUB, + "hub", + }, + { + USB_VENDOR_EIZO, USB_PRODUCT_EIZO_MONITOR, + "monitor", + }, + { + USB_VENDOR_ELAN, USB_PRODUCT_ELAN_BARCODE, + "Barcode Scanner", + }, + { + USB_VENDOR_ELCON, USB_PRODUCT_ELCON_PLAN, + "Goldpfeil P-LAN", + }, + { + USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_MOUSE29UO, + "29UO", + }, + { + USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX0, + "LD-USB/TX", + }, + { + USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX1, + "LD-USB/TX", + }, + { + USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBLTX, + "LD-USBL/TX", + }, + { + USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_WDC150SU2M, + "WDC-150SU2M", + }, + { + USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX2, + "LD-USB/TX", + }, + { + USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSB20, + "LD-USB20", + }, + { + USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_UCSGT, + "UC-SGT Serial", + }, + { + USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_UCSGT0, + "UC-SGT0 Serial", + }, + { + USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX3, + "LD-USB/TX", + }, + { + USB_VENDOR_ELEKTOR, USB_PRODUCT_ELEKTOR_FT323R, + "FT323R", + }, + { + USB_VENDOR_ELSA, USB_PRODUCT_ELSA_MODEM1, + "ELSA", + }, + { + USB_VENDOR_ELSA, USB_PRODUCT_ELSA_USB2ETHERNET, + "Microlink USB2Ethernet", + }, + { + USB_VENDOR_ELV, USB_PRODUCT_ELV_USBI2C, + "USB-I2C", + }, + { + USB_VENDOR_EMPIA, USB_PRODUCT_EMPIA_EEEPC701_VIDEO, + "EeePC701 camera", + }, + { + USB_VENDOR_ENCORE, USB_PRODUCT_ENCORE_RT3070_1, + "RT3070", + }, + { + USB_VENDOR_ENCORE, USB_PRODUCT_ENCORE_RT3070_2, + "RT3070", + }, + { + USB_VENDOR_ENCORE, USB_PRODUCT_ENCORE_RT3070_3, + "RT3070", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_1S, + "1S serial", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_2S, + "2S serial", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_1S25, + "1S25 serial", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_4S, + "4S serial", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_E45, + "E45 Ethernet", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_CENTRONICS, + "Centronics", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_XX1, + "Ethernet", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_1S9, + "1S9 serial", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_EZUSB, + "EZ-USB", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_2U4S, + "2U4S serial", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_XX2, + "Ethernet", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_PRINTER1, + "USB Printer", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_PRINTER2, + "ISD Smart Cable for Mac", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_PRINTER3, + "ISD Smart Cable", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_PRINTER5, + "USB Printer", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_636, + "Perfection 636U / 636Photo", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_610, + "Perfection 610", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1200, + "Perfection 1200U / 1200Photo", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1600, + "Expression 1600", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1640, + "Perfection 1640SU", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1240, + "Perfection 1240U / 1240Photo", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_640U, + "Perfection 640U", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1650, + "Perfection 1650", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_GT9700F, + "GT-9700F", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_2400, + "Perfection 2400", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1260, + "Perfection 1260", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1660, + "Perfection 1660", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1670, + "Perfection 1670", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_CX5400, + "CX5400", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_CX3650, + "Stylus CX3650", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX3800, + "Stylus DX3800", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX5000, + "Stylus DX5000", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX6000, + "Stylus DX6000", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX4000, + "Stylus DX4000", + }, + { + USB_VENDOR_ETEK, USB_PRODUCT_ETEK_1COM, + "Serial", + }, + { + USB_VENDOR_EVOLUTION, USB_PRODUCT_EVOLUTION_ER1, + "ER1 Control Module", + }, + { + USB_VENDOR_EVOLUTION, USB_PRODUCT_EVOLUTION_RCM4_1, + "RCM4 interface", + }, + { + USB_VENDOR_EVOLUTION, USB_PRODUCT_EVOLUTION_RCM4_2, + "RCM4 interface", + }, + { + USB_VENDOR_EXAR, USB_PRODUCT_EXAR_XR21V1410, + "XR21V1410", + }, + { + USB_VENDOR_EXTENDED, USB_PRODUCT_EXTENDED_XTNDACCESS, + "XTNDAccess IrDA", + }, + { + USB_VENDOR_FALCOM, USB_PRODUCT_FALCOM_TWIST, + "Twist", + }, + { + USB_VENDOR_FALCOM, USB_PRODUCT_FALCOM_SAMBA, + "Samba", + }, + { + USB_VENDOR_FEIXUN, USB_PRODUCT_FEIXUN_RTL8188CU, + "RTL8188CU", + }, + { + USB_VENDOR_FEIXUN, USB_PRODUCT_FEIXUN_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_FESTO, USB_PRODUCT_FESTO_CPX_USB, + "CPX-USB", + }, + { + USB_VENDOR_FESTO, USB_PRODUCT_FESTO_CMSP, + "CMSP", + }, + { + USB_VENDOR_FIBERLINE, USB_PRODUCT_FIBERLINE_WL430U, + "WL-430U", + }, + { + USB_VENDOR_FOSSIL, USB_PRODUCT_FOSSIL_WRISTPDA, + "Wrist PDA", + }, + { + USB_VENDOR_FOXCONN, USB_PRODUCT_FOXCONN_TCOM_TC_300, + "T-Com TC 300", + }, + { + USB_VENDOR_FOXCONN, USB_PRODUCT_FOXCONN_PIRELLI_DP_L10, + "Pirelli DP-L10", + }, + { + USB_VENDOR_FREECOM, USB_PRODUCT_FREECOM_DVD, + "Connector for DVD drive", + }, + { + USB_VENDOR_FSC, USB_PRODUCT_FSC_E5400, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_FT232_1, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_8U232AM, + "8U232AM Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_8U232AM4, + "8U232AM Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_FT232_3, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_FT232_4, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_FT232_5, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_FT232_6, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_2232C, + "2232C Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_FT4232H, + "FT4232H", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_FTX, + "FTX", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PS2KBDMS, + "PS/2 Keyboard/Mouse", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_8U100AX, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MJS_SIRIUS_PC_2, + "MJS Sirius To PC Interface", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_OPENRD, + "OpenRD JTAGKey", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CANDAPTER, + "CANdapter", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_NXTCAM, + "Mindstorms NXTCam", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_OOCDLINK, + "OOCDlink", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LM3S_DEVEL, + "LM3S Devel", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LM3S_EVAL, + "LM3S Eval", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_TURTELIZER_JTAG, + "JTAG/RS-232", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_OPENDCC, + "OpenDCC", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_OPENDCC_SNIFFER, + "OpenDCC Sniffer", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_OPENDCC_THROTTLE, + "OpenDCC Throttle", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_OPENDCC_GATEWAY, + "OpenDCC Gateway", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LOCOBUFFER, + "RR-CirKits LocoBuffer", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_DMX4ALL, + "DMX4ALL DMX interface", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ASK_RDR4X7_1, + "ASK RDR 4X7", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ASK_RDR4X7_2, + "ASK RDR 4X7", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ASK_RDR4X7_3, + "ASK RDR 4X7", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ASK_RDR4X7_4, + "ASK RDR 4X7", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ASK_RDR4X7_5, + "ASK RDR 4X7", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ASK_RDR4X7_6, + "ASK RDR 4X7", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ASK_RDR4X7_7, + "ASK RDR 4X7", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ASK_RDR4X7_8, + "ASK RDR 4X7", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MJS_SIRIUS_PC_1, + "MJS Sirius To PC Interface", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CHAMELEON, + "uChameleon", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_OPENPORT_13M, + "OpenPort 1.3 Mitsubishi", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_OPENPORT_13S, + "OpenPort 1.3 Subaru", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_OPENPORT_13U, + "OpenPort 1.3 Universal", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_2232L, + "2232L Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SCS_0, + "Radio Modem", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SCS_1, + "Radio Modem", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SCS_2, + "Radio Modem", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SCS_3, + "Radio Modem", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SCS_4, + "Radio Modem", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SCS_5, + "Radio Modem", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SCS_6, + "Radio Modem", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SCS_7, + "Radio Modem", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IPLUS, + "iPlus", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IPLUS2, + "iPlus", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_XSENS_1, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_XSENS_2, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_XSENS_3, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_XSENS_4, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_XSENS_5, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_XSENS_6, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_XSENS_7, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_XSENS_8, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GAMMASCOUT, + "Gamma Scout Online", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_JTAGCABLEII, + "Propox JTAG", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_WESTREX_777, + "Westrex 777", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_WESTREX_8900F, + "Westrex 8900F", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ACG_HFDUAL, + "HF Dual ISO Reader", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ARTEMIS, + "CCD camera", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ATK16, + "ATK-16 Camera", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ATK16HR, + "ATK-16HR Camera", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ATK16C, + "ATK-16C Camera", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ATK16HRC, + "ATK-16HRC Camera", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ATK16IC, + "ATK-16IC Camera", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_USR, + "USR", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_MSM1, + "Mini-Sound-Modul", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_KL100, + "KL 100", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_WS550, + "WS 550", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_WS888, + "WS 888", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_TWS550, + "WS 550", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_FEM, + "Funk Energie Monitor", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_YEI_SC31, + "ServoCenter3.1", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_FHZ1300PC, + "FHZ 1300 PC", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_WS500, + "WS 500", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_HS485, + "RS-485", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_UMS100, + "UMS 100", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_TFD128, + "TFD 128", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_FM3RX, + "FM3 RX", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_WS777, + "WS 777", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_EM1010PC, + "EM 1010 PC", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_CSI8, + "CSI 8", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_EM1000DL, + "EM 1000 DL", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_PCK100, + "PCK 100", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_RFP500, + "RFP 500", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_FS20SIG, + "FS 20 SIG", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_UTP8, + "UTP 8", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_WS300PC, + "WS 300 PC", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_WS444PC, + "WS 444 PC", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_FISCO, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ECO_PRO, + "EVER Eco Pro UPS", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ACTROBOTS, + "Active Robots comms", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PYRAMID, + "Pyramid Display", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_UNICOM, + "Unicom III", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_1, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_2, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_3, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_4, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_5, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_6, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_7, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_8, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_EISCOU, + "Expert ISDN", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_UOPTBR, + "RS232 OptoBridge", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_DCF, + "Expert mouseCLOCK USB II", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MSF, + "Expert mouseCLOCK USB II MSF", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_HBG, + "Expert mouseCLOCK USB II HBG", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_9, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_A, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_B, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ECLO_1WIRE, + "1-Wire", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_TNCX, + "TNC-X packet-radio", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_TERATRONIK_VCP, + "VCP", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_TERATRONIK_D2XX, + "D2XX", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_REU_TINY, + "RigExpert Tiny", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_HO870, + "HO870", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_HO820, + "HO820", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_232BM, + "FT232BM Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MHAM_KW, + "KW", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MHAM_YS, + "YS", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MHAM_Y6, + "Y6", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MHAM_Y8, + "Y8", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MHAM_IC, + "IC", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MHAM_DB9, + "DB9", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MHAM_RS232, + "RS232", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MHAM_Y9, + "Y9", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_DGQG, + "DGQG", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_DUSB, + "DUSB", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_UAD8, + "UAD 8", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_UAD7, + "UAD 7", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_USI2, + "USI 2", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_T1100, + "T 1100", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_PCD200, + "PCD 200", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_ULA200, + "ULA 200", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_ALC8500, + "ALC 8500 Expert", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_FHZ1000PC, + "FHZ 1000 PC", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PERLE_UP, + "UltraPort", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SPROG_II, + "Sprog II", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PIEGROUP_IR, + "Infrared", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ACTZWAVE, + "HomePro ZWave", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GALAXY_1, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GALAXY_2, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_COASTAL_TNCX, + "Coastal ChipWorks TNC-X", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LINX_MASTER2, + "Master Development 2.0", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LINX_1, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LINX_2, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LINX_3, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_OCEANIC, + "Oceanic instrument", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SUUNTO, + "Suunto Sports", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_USBUIRT, + "USB-UIRT", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_USBX_707, + "USBX-707", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CCS_ICDU20, + "ICD-U20", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CCS_ICDU40, + "ICD-U40", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CCS_MACHX, + "MACH-X", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CCS_LOAD_N_GO, + "LOAD N GO", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CCS_ICDU64, + "ICDU64", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CCS_PRIME8, + "PRIME8", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ITM_TOUCH, + "ITM Touchscreen", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_USBSERIAL, + "Matrix Orbital USB Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_MX200, + "Matrix Orbital MX200 Series LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_MTXO, + "Matrix Orbital LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_LK202_24, + "Matrix Orbital LK202-24 LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_LK204_24, + "Matrix Orbital LK204-24 LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MATRIX_2, + "Matrix Orbital LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MATRIX_3, + "Matrix Orbital LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_RELAIS, + "Relais", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_TIRA1, + "Tira-1", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PCDJ_DAC2, + "DAC-2", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ACCESSO, + "Accesso reader", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_THORLABS, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_UR100, + "UR 100", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_CLI7000, + "CLI 7000", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_UM100, + "UM 100", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_UO100, + "UO 100", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_PPS7330, + "PPS 7330", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_TFM100, + "TFM 100", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_UDF77, + "UDF 77", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_UIO88, + "UIO 88", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_R2000KU_RNG, + "R2000KU RNG", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_BCS_SE923, + "BCS SE923", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_FT232RL, + "FT232RL", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_CFA_632, + "Crystalfontz CFA-632 LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_CFA_634, + "Crystalfontz CFA-634 LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_CFA_547, + "Crystalfontz CFA-547 LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_CFA_633, + "Crystalfontz CFA-633 LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_CFA_631, + "Crystalfontz CFA-631 LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_CFA_635, + "Crystalfontz CFA-635 LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_CFA_640, + "Crystalfontz CFA-640 LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_CFA_642, + "Crystalfontz CFA-642 LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IRTRANS, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PROTEGO_1, + "Protego", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PROTEGO_R200, + "R200-USB TRNG", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PROTEGO_3, + "Protego", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PROTEGO_4, + "Protego", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SEMC_DSS20, + "SEMC DSS-20 SyncStation", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CANVIEW, + "CANview", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_VNHC, + "Modem", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_AMC232, + "AMC-232USB0", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_TTUSB, + "TT-USB", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IBS_US485, + "US485", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IBS_PICPRO, + "PIC-Programmer", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IBS_PCMCIA, + "PCMCIA SRAM-cards reader", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IBS_PK1, + "Particel counter PK1", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IBS_RS232MON, + "RS232", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IBS_APP70, + "APP 70 dust monitoring", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IBS_PEDO, + "IBS PEDO-Modem", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IBS_1, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CANUSB, + "CANUSB", + }, + { + USB_VENDOR_FUJIPHOTO, USB_PRODUCT_FUJIPHOTO_MASS0100, + "Mass Storage", + }, + { + USB_VENDOR_FUJITSU, USB_PRODUCT_FUJITSU_AH_F401U, + "AH-F401U Air H device", + }, + { + USB_VENDOR_FUJITSUCOMP, USB_PRODUCT_FUJITSUCOMP_KEYBOARD6, + "Type 6 Keyboard", + }, + { + USB_VENDOR_FUJITSUCOMP, USB_PRODUCT_FUJITSUCOMP_KEYBOARD7, + "Type 7 Keyboard", + }, + { + USB_VENDOR_FUJITSUCOMP, USB_PRODUCT_FUJITSUCOMP_MOUSE, + "Type 6 Mouse", + }, + { + USB_VENDOR_FUJITSUCOMP, USB_PRODUCT_FUJITSUCOMP_FX5204PS, + "Smart Power Strip FX-5204PS", + }, + { + USB_VENDOR_FUJITSUCOMP, USB_PRODUCT_FUJITSUCOMP_FX5251WB, + "Base Station FX-5251WB", + }, + { + USB_VENDOR_FUJITSUCOMP, USB_PRODUCT_FUJITSUCOMP_VIRTETH, + "Virtual Eth Device", + }, + { + USB_VENDOR_FUSHICAI, USB_PRODUCT_FUSHICAI_USBTV007, + "Fushicai Audio-Video Grabber", + }, + { + USB_VENDOR_GARMIN, USB_PRODUCT_GARMIN_GPSMAP60CSX, + "GPSmap 60Csx", + }, + { + USB_VENDOR_GARMIN, USB_PRODUCT_GARMIN_IQUE3600, + "Ique 3600", + }, + { + USB_VENDOR_GARMIN, USB_PRODUCT_GARMIN_DAKOTA20, + "Dakota 20", + }, + { + USB_VENDOR_GARMIN, USB_PRODUCT_GARMIN_GPSMAP62S, + "GPSmap 62s", + }, + { + USB_VENDOR_GCTSEMICON, USB_PRODUCT_GCTSEMICON_INSTALL, + "GDM720x MASS storage mode", + }, + { + USB_VENDOR_GEMPLUS, USB_PRODUCT_GEMPLUS_PROXPU, + "Prox-PU/CU", + }, + { + USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL620USB_A, + "GL620USB-A GeneLink USB-USB Bridge", + }, + { + USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GENELINK, + "GeneLink Host-Host Bridge", + }, + { + USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL650, + "GL650 Hub", + }, + { + USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB, + "GL641USB CompactFlash", + }, + { + USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNBR402W, + "GN-BR402W", + }, + { + USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWLBM101, + "GN-WLBM101", + }, + { + USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWBKG, + "GN-WBKG", + }, + { + USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWB01GS, + "GN-WB01GS", + }, + { + USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWI05GS, + "GN-WI05GS", + }, + { + USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWB31N, + "GN-WB31N", + }, + { + USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWB32L, + "GN-WB32L", + }, + { + USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_WLAN, + "WLAN", + }, + { + USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_SMCWUSBTG, + "SMCWUSBT-G", + }, + { + USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_SMCWUSBTG_NF, + "SMCWUSBT-G", + }, + { + USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_AR5523, + "AR5523", + }, + { + USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_AR5523_NF, + "AR5523", + }, + { + USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_RT2573, + "RT2573", + }, + { + USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_RT3070_1, + "RT3070", + }, + { + USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_RT3070_2, + "RT3070", + }, + { + USB_VENDOR_GLOBALSUN, USB_PRODUCT_GLOBALSUN_AR5523_1, + "AR5523", + }, + { + USB_VENDOR_GLOBALSUN, USB_PRODUCT_GLOBALSUN_AR5523_1_NF, + "AR5523", + }, + { + USB_VENDOR_GLOBALSUN, USB_PRODUCT_GLOBALSUN_AR5523_2, + "AR5523", + }, + { + USB_VENDOR_GLOBALSUN, USB_PRODUCT_GLOBALSUN_AR5523_2_NF, + "AR5523", + }, + { + USB_VENDOR_GLOBESPAN, USB_PRODUCT_GLOBESPAN_PRISM_GT_1, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_GLOBESPAN, USB_PRODUCT_GLOBESPAN_PRISM_GT_2, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_GMATE, USB_PRODUCT_GMATE_YP3X00, + "YP3X00 PDA", + }, + { + USB_VENDOR_GNOTOMETRICS, USB_PRODUCT_GNOTOMETRICS_AURICAL, + "Aurical", + }, + { + USB_VENDOR_GOHUBS, USB_PRODUCT_GOHUBS_GOCOM232, + "GoCOM232 Serial converter", + }, + { + USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_GWUSB2E, + "GWUSB2E", + }, + { + USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_RT2573, + "RT2573", + }, + { + USB_VENDOR_GRAVIS, USB_PRODUCT_GRAVIS_GAMEPADPRO, + "GamePad Pro", + }, + { + USB_VENDOR_GREENHOUSE, USB_PRODUCT_GREENHOUSE_KANA21, + "CF-writer/MP3 Player", + }, + { + USB_VENDOR_GRIFFIN, USB_PRODUCT_GRIFFIN_IMATE, + "iMate, ADB adapter", + }, + { + USB_VENDOR_GUDE, USB_PRODUCT_GUDE_DCF, + "Expert mouseCLOCK USB", + }, + { + USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_DALEADER, + "DA Leader", + }, + { + USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254, + "HWGUSB2-54 WLAN", + }, + { + USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254LB, + "HWGUSB2-54-LB", + }, + { + USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254V2AP, + "HWGUSB2-54V2-AP", + }, + { + USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWNU300, + "HWNU-300", + }, + { + USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWNUM300, + "HWNUm-300", + }, + { + USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUN54, + "HWGUn-54", + }, + { + USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWNUP150, + "HWNUP-150", + }, + { + USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_GUNZE, USB_PRODUCT_GUNZE_TOUCHPANEL, + "Gunze USB Touch Panel", + }, + { + USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FGSM, + "FlashGate SmartMedia", + }, + { + USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FGCF, + "FlashGate CompactFlash", + }, + { + USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FG, + "FlashGate", + }, + { + USB_VENDOR_HAL, USB_PRODUCT_HAL_IMR001, + "Crossam2+USB IR commander", + }, + { + USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_VISOR, + "Handspring Visor", + }, + { + USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO, + "Handspring Treo", + }, + { + USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO600, + "Handspring Treo 600", + }, + { + USB_VENDOR_HAUPPAUGE, USB_PRODUCT_HAUPPAUGE_WINTV_USB_FM, + "WinTV FM", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_HWUN2, + "HWUN2", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_HWDN2, + "HWDN2", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RT2870_3, + "RT2870", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RTL8192SU_1, + "RTL8192SU", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RTL8192SU_2, + "RTL8192SU", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RT2870_4, + "RT2870", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RT2870_5, + "RT2870", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RTL8192CU_2, + "RTL8192CU", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_UF100, + "10/100 Ethernet", + }, + { + USB_VENDOR_HIROSE, USB_PRODUCT_HIROSE_USB100, + "USB-100", + }, + { + USB_VENDOR_HITACHI, USB_PRODUCT_HITACHI_DZMV100A, + "DVD-CAM DZ-MV100A Camcorder", + }, + { + USB_VENDOR_HOLTEK, USB_PRODUCT_HOLTEK_MOUSE, + "Mouse", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_895C, + "DeskJet 895C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_4100C, + "Scanjet 4100C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_S20, + "Photosmart S20", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_880C, + "DeskJet 880C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_4200C, + "ScanJet 4200C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_CDWRITERPLUS, + "CD-Writer Plus", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_KBDHUB, + "Multimedia Keyboard Hub", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_HN210W, + "HN210W", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_HPX9GP, + "HP-x9G+", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_6200C, + "ScanJet 6200C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_S20B, + "PhotoSmart S20", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_815C, + "DeskJet 815C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_3300C, + "ScanJet 3300C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_CDW8200, + "CD-Writer Plus 8200e", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_1220C, + "DeskJet 1220C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_810C, + "DeskJet 810C/812C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_4300C, + "Scanjet 4300C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_CD4E, + "CD-Writer+ CD-4e", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_G85XI, + "OfficeJet G85xi", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_1200, + "LaserJet 1200", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_5200C, + "Scanjet 5200C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_830C, + "DeskJet 830C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_3400CSE, + "ScanJet 3400cse", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_885C, + "DeskJet 885C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_1000, + "LaserJet 1000", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_6300C, + "Scanjet 6300C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_840C, + "DeskJet 840c", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_2200C, + "ScanJet 2200C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_5300C, + "Scanjet 5300C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_816C, + "DeskJet 816C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_970CSE, + "Deskjet 970Cse", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_5400C, + "Scanjet 5400C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_2215, + "iPAQ 22xx/Jornada 548", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_959C, + "Deskjet 959C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_568J, + "Jornada 568", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_930C, + "DeskJet 930c", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_1005, + "LaserJet 1005", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_P2000U, + "Inkjet P-2000U", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_HS2300, + "HS2300", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_T750, + "T750 UPS", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_T1000, + "T1000 UPS", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_T1500, + "T1500 UPS", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_RT2200, + "R/T2200 UPS", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_R1500G2, + "R1500 G2 UPS", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_T750G2, + "T750 G2 UPS", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_640C, + "DeskJet 640c", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_1020, + "LaserJet 1020", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_P1100, + "Photosmart P1100", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_LD220, + "LD220", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_1018, + "LaserJet 1018", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_HN210E, + "HN210E Ethernet", + }, + { + USB_VENDOR_HP2, USB_PRODUCT_HP2_C500, + "PhotoSmart C500", + }, + { + USB_VENDOR_HP3, USB_PRODUCT_HP3_RTL8188CU, + "RTL8188CU", + }, + { + USB_VENDOR_HTC, USB_PRODUCT_HTC_PPC6700MODEM, + "PPC6700 Modem", + }, + { + USB_VENDOR_HTC, USB_PRODUCT_HTC_SMARTPHONE, + "SmartPhone", + }, + { + USB_VENDOR_HTC, USB_PRODUCT_HTC_ANDROID, + "Android phone", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E618, + "HUAWEI Mobile E618", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E220, + "HUAWEI Mobile Modem", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_MOBILE, + "HUAWEI Mobile Modem", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_EM770W, + "HUAWEI Mobile Modem", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E1750, + "HUAWEI Mobile Modem", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E180, + "HUAWEI Mobile E180", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E510, + "HUAWEI Mobile E510", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E181, + "HUAWEI Mobile E181", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E1752, + "HUAWEI Mobile Modem", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E182, + "HUAWEI Mobile Modem", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E3372, + "HUAWEI Mobile Modem", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E161, + "HUAWEI Mobile Modem", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_K3765, + "HUAWEI Mobile K3765", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E1820, + "HUAWEI Mobile Modem", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_K4511, + "HUAWEI Mobile Modem K4511", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_K4510, + "HUAWEI Mobile Modem", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_K3772, + "HUAWEI Mobile K3772", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E353_INIT, + "HUAWEI Mobile E353 Initial", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E392_INIT, + "HUAWEI Mobile E392 Initial", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_K3765_INIT, + "HUAWEI Mobile K3765 Initial", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_K3772_INIT, + "HUAWEI Mobile K3772 Initial", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_MU609, + "HUAWEI Mobile ME906", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E173S, + "HUAWEI Mobile E173s", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E173S_INIT, + "HUAWEI Mobile E173s Initial", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E303, + "HUAWEI Mobile E303", + }, + { + USB_VENDOR_HUAWEI3COM, USB_PRODUCT_HUAWEI3COM_WUB320G, + "Aolynk WUB320g", + }, + { + USB_VENDOR_HUMAX, USB_PRODUCT_HUMAX_PVRSMART, + "PVR-SMART", + }, + { + USB_VENDOR_HYUNDAI, USB_PRODUCT_HYUNDAI_PC5740, + "PC5740 EVDO", + }, + { + USB_VENDOR_HYUNDAI, USB_PRODUCT_HYUNDAI_UM175, + "UM175 EVDO", + }, + { + USB_VENDOR_IBM, USB_PRODUCT_IBM_OPTTRAVELMOUSE, + "Optical", + }, + { + USB_VENDOR_IBM, USB_PRODUCT_IBM_OPTWHEELMOUSE, + "Wheel", + }, + { + USB_VENDOR_IBM, USB_PRODUCT_IBM_USBCDROMDRIVE, + "CD-ROM", + }, + { + USB_VENDOR_IBM, USB_PRODUCT_IBM_THINKPADHUB, + "Hub", + }, + { + USB_VENDOR_ICOM, USB_PRODUCT_ICOM_ID1, + "ID-1", + }, + { + USB_VENDOR_ICOM, USB_PRODUCT_ICOM_RP2C1, + "ID-RP2C service 1", + }, + { + USB_VENDOR_ICOM, USB_PRODUCT_ICOM_RP2C2, + "ID-RP2C service 2", + }, + { + USB_VENDOR_ICOM, USB_PRODUCT_ICOM_RP2D, + "ID-RP2D", + }, + { + USB_VENDOR_ICOM, USB_PRODUCT_ICOM_RP2VT, + "ID-RP2V service T", + }, + { + USB_VENDOR_ICOM, USB_PRODUCT_ICOM_RP2VR, + "ID-RP2V service R", + }, + { + USB_VENDOR_ICOM, USB_PRODUCT_ICOM_RP4000VT, + "ID-RP4000V service T", + }, + { + USB_VENDOR_ICOM, USB_PRODUCT_ICOM_RP4000VR, + "ID-RP4000V service R", + }, + { + USB_VENDOR_ICOM, USB_PRODUCT_ICOM_RP2000VT, + "ID-RP2000V service T", + }, + { + USB_VENDOR_ICOM, USB_PRODUCT_ICOM_RP2000VR, + "ID-RP2000V service R", + }, + { + USB_VENDOR_IDOWELL, USB_PRODUCT_IDOWELL_IDOWELL, + "UPS", + }, + { + USB_VENDOR_IDQUANTIQUE, USB_PRODUCT_IDQUANTIQUE_QUANTISUSB, + "Quantis USB", + }, + { + USB_VENDOR_IDTECH, USB_PRODUCT_IDTECH_SERIAL, + "Serial", + }, + { + USB_VENDOR_IIYAMA, USB_PRODUCT_IIYAMA_HUB, + "Hub", + }, + { + USB_VENDOR_IMATION, USB_PRODUCT_IMATION_FLASHGO, + "Flash Go!", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4, + "EdgePort/4 RS232", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_HUBPORT7, + "Hubport/7", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_RAPIDPORT4, + "Rapidport/4", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4T, + "Edgeport/4 RS232", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT2, + "Edgeport/2 RS232", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4I, + "Edgeport/4 RS422", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT2I, + "Edgeport/2 RS422/RS485", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_HUBPORT4, + "Hubport/4", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT8HAND, + "Hand-built Edgeport/8", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_MULTIMODEM, + "MultiTech version of RP/4", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORTPPORT, + "Edgeport/(4)21 Parallel", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT421, + "Edgeport/421 Hub+RS232+Parallel", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT21, + "Edgeport/21 RS232+Parallel", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT8DC, + "1/2 Edgeport/8", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT8, + "Edgeport/8", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT2DIN, + "Edgeport/2 RS232/DIN", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4DIN, + "Edgeport/4 RS232/DIN", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT16DC, + "1/2 Edgeport/16", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORTCOMP, + "Edgeport Compatible", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT8I, + "Edgeport/8 RS422", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_WATCHPORTH, + "WatchPort/H", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_MT4X56USB, + "OEM device", + }, + { + USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_F5U002, + "Parallel", + }, + { + USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ATAPI, + "ATAPI", + }, + { + USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_IDEUSB2, + "USB2 Storage", + }, + { + USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ISD110, + "IDE ISD110", + }, + { + USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ISD105, + "IDE ISD105", + }, + { + USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_DRIVEV2, + "Portable USB Harddrive V2", + }, + { + USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_DRIVEV2_5, + "Portable USB Harddrive V2", + }, + { + USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_USBCABLE, + "USB cable", + }, + { + USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ADAPTERV2, + "USB Storage Adapter V2", + }, + { + USB_VENDOR_INTEL, USB_PRODUCT_INTEL_EASYPC_CAMERA, + "EasyPC", + }, + { + USB_VENDOR_INTEL, USB_PRODUCT_INTEL_AP310, + "AP310 AnyPoint II", + }, + { + USB_VENDOR_INTEL, USB_PRODUCT_INTEL_I2011B, + "Wireless 2011B", + }, + { + USB_VENDOR_INTEL, USB_PRODUCT_INTEL_TESTBOARD, + "82930 test board", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_RMH_1, + "Rate Matching Hub", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_RMH_2, + "Rate Matching Hub", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_BLUETOOTH3, + "Bluetooth", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_BLUETOOTH, + "Bluetooth", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_BLUETOOTH2, + "Bluetooth", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_RMH_3, + "Rate Matching Hub", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_RMH_5, + "Rate Matching Hub", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_RMH_7, + "Rate Matching Hub", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_RMH_4, + "Rate Matching Hub", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_RMH_6, + "Rate Matching Hub", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_RMH_8, + "Rate Matching Hub", + }, + { + USB_VENDOR_INTERBIO, USB_PRODUCT_INTERBIO_IOBOARD, + "IO Board", + }, + { + USB_VENDOR_INTERBIO, USB_PRODUCT_INTERBIO_MINIIOBOARD, + "Mini IO Board", + }, + { + USB_VENDOR_INTERBIO, USB_PRODUCT_INTERBIO_MINIIOBOARD2, + "Mini IO Board", + }, + { + USB_VENDOR_INTERSIL, USB_PRODUCT_INTERSIL_PRISM_GT, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_INTERSIL, USB_PRODUCT_INTERSIL_PRISM_2X, + "Prism2.x WLAN", + }, + { + USB_VENDOR_INTREPIDCS, USB_PRODUCT_INTREPIDCS_VALUECAN, + "ValueCAN", + }, + { + USB_VENDOR_INTREPIDCS, USB_PRODUCT_INTREPIDCS_NEOVI, + "NeoVI Blue", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBSSMRW, + "USB-SSMRW SD-card", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBSDRW, + "USB-SDRW SD-card", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETT, + "USB ET/T", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETTX, + "USB ET/TX", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETTXS, + "USB ET/TX-S", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBWNB11A, + "USB WN-B11", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBWNB11, + "USB Airport WN-B11", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBWNG54US, + "USB WN-G54/US", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBWNG54US_NF, + "USB WN-G54/US", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_ETXUS2, + "ETX-US2", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_ETGUS2, + "ETG-US2", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_FT232R, + "FT232R", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_WNGDNUS2, + "WN-GDN/US2", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_RT3072_1, + "RT3072", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_RT3072_2, + "RT3072", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_RT3072_3, + "RT3072", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_RT3072_4, + "RT3072", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_WNG150UM, + "WN-G150UM", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBRSAQ, + "RSAQ1 Serial", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBRSAQ5, + "RSAQ5 Serial", + }, + { + USB_VENDOR_IODATA2, USB_PRODUCT_IODATA2_USB2SC, + "USB2.0-SCSI Bridge USB2-SC", + }, + { + USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP100, + "Zip 100", + }, + { + USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP250, + "Zip 250", + }, + { + USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP250_2, + "Zip 250", + }, + { + USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_CDRW, + "CDRW 9602", + }, + { + USB_VENDOR_IRIVER, USB_PRODUCT_IRIVER_IFP_1XX, + "iFP-1xx", + }, + { + USB_VENDOR_IRIVER, USB_PRODUCT_IRIVER_IFP_3XX, + "iFP-3xx", + }, + { + USB_VENDOR_IRIVER, USB_PRODUCT_IRIVER_IFP_5XX, + "iFP-5xx", + }, + { + USB_VENDOR_ISSC, USB_PRODUCT_ISSC_KYBT100, + "KY-BT100 Bluetooth", + }, + { + USB_VENDOR_ITEGNO, USB_PRODUCT_ITEGNO_WM1080A, + "WM1080A", + }, + { + USB_VENDOR_JABLOTRON, USB_PRODUCT_JABLOTRON_PC60B, + "PC-60B", + }, + { + USB_VENDOR_JATON, USB_PRODUCT_JATON_EDA, + "Ethernet", + }, + { + USB_VENDOR_JENOPTIK, USB_PRODUCT_JENOPTIK_JD350, + "JD 350", + }, + { + USB_VENDOR_JETI, USB_PRODUCT_JETI_SPC1201, + "SPECBOS 1201", + }, + { + USB_VENDOR_JRC, USB_PRODUCT_JRC_AH_J3001V_J3002V, + "AirH\"PHONE AH-J3001V/J3002V", + }, + { + USB_VENDOR_JVC, USB_PRODUCT_JVC_MP_PRX1, + "MP-PRX1", + }, + { + USB_VENDOR_JVC, USB_PRODUCT_JVC_MP_XP7250_WL, + "MP-XP7250 Builtin WLAN", + }, + { + USB_VENDOR_KAMSTRUP, USB_PRODUCT_KAMSTRUP_OPTICALEYE, + "Optical Eye/3-wire", + }, + { + USB_VENDOR_KAMSTRUP, USB_PRODUCT_KAMSTRUP_MBUS_250D, + "M-Bus Master MultiPort 250D", + }, + { + USB_VENDOR_KAWATSU, USB_PRODUCT_KAWATSU_MH4000P, + "MiniHub 4000P", + }, + { + USB_VENDOR_KAWATSU, USB_PRODUCT_KAWATSU_KC180, + "KC-180 IrDA", + }, + { + USB_VENDOR_KEISOKUGIKEN, USB_PRODUCT_KEISOKUGIKEN_USBDAQ, + "HKS-0200 USBDAQ", + }, + { + USB_VENDOR_KENSINGTON, USB_PRODUCT_KENSINGTON_ORBIT, + "Orbit trackball", + }, + { + USB_VENDOR_KENSINGTON, USB_PRODUCT_KENSINGTON_TURBOBALL, + "TurboBall", + }, + { + USB_VENDOR_KENSINGTON, USB_PRODUCT_KENSINGTON_ORBIT_MAC, + "Orbit trackball for Mac", + }, + { + USB_VENDOR_KENSINGTON, USB_PRODUCT_KENSINGTON_BT_EDR, + "Bluetooth", + }, + { + USB_VENDOR_KENSINGTON, USB_PRODUCT_KENSINGTON_VIDEOCAM_VGA, + "VideoCAM VGA", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA28_NF, + "USA-28 serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA28X_NF, + "USA-28X serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19_NF, + "USA-19 serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA18_NF, + "USA-18 serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA18X_NF, + "USA-18X serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19W_NF, + "USA-19W serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19, + "USA-19 serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19W, + "USA-19W serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA49W_NF, + "USA-49W serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA49W, + "USA-49W serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19QI_NF, + "USA-19QI serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19QI, + "USA-19QI serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19Q_NF, + "USA-19Q serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19Q, + "USA-19Q serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA28, + "USA-28 serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA28XXB, + "USA-28X/XB serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA18, + "USA-18 serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA18X, + "USA-18X serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA28XB_NF, + "USA-28XB serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA28XA_NF, + "USA-28XB serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA28XA, + "USA-28XA serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA18XA_NF, + "USA-18XA serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA18XA, + "USA-18XA serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19QW_NF, + "USA-19WQ serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19QW, + "USA-19WQ serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19HS, + "USA-19HS serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_UIA10, + "UIA-10 remote control", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_UIA11, + "UIA-11 remote control", + }, + { + USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_XX1, + "Ethernet", + }, + { + USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_KNU101TX, + "KNU101TX Ethernet", + }, + { + USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BT, + "10BT Ethernet", + }, + { + USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BTN, + "10BT Ethernet", + }, + { + USB_VENDOR_KOBIL, USB_PRODUCT_KOBIL_B1, + "Konverter for B1", + }, + { + USB_VENDOR_KOBIL, USB_PRODUCT_KOBIL_KAAN, + "Konverter for KAAN", + }, + { + USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC220, + "Digital Science DC220", + }, + { + USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC260, + "Digital Science DC260", + }, + { + USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC265, + "Digital Science DC265", + }, + { + USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC290, + "Digital Science DC290", + }, + { + USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC240, + "Digital Science DC240", + }, + { + USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC280, + "Digital Science DC280", + }, + { + USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DX4900, + "EasyShare DX4900", + }, + { + USB_VENDOR_KONICA, USB_PRODUCT_KONICA_CAMERA, + "Camera", + }, + { + USB_VENDOR_KYE, USB_PRODUCT_KYE_NICHE, + "Niche mouse", + }, + { + USB_VENDOR_KYE, USB_PRODUCT_KYE_NETSCROLL, + "Genius NetScroll mouse", + }, + { + USB_VENDOR_KYE, USB_PRODUCT_KYE_FLIGHT2000, + "Flight 2000 joystick", + }, + { + USB_VENDOR_KYE, USB_PRODUCT_KYE_VIVIDPRO, + "ColorPage Vivid-Pro", + }, + { + USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_AHK3001V, + "AH-K3001V", + }, + { + USB_VENDOR_KYOCERA2, USB_PRODUCT_KYOCERA2_KPC650, + "KPC650 EVDO", + }, + { + USB_VENDOR_LACIE, USB_PRODUCT_LACIE_HD, + "Hard Disk", + }, + { + USB_VENDOR_LACIE, USB_PRODUCT_LACIE_CDRW, + "CD R/W", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M121, + "Model 121", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M218A, + "Model 218A", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M219, + "Model 219", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M233, + "Model 233", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M235, + "Model 235", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M335, + "Model 335", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M336, + "Model 336", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M350, + "Model 350", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M371, + "Model 371", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M411, + "Model 411", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M425, + "Model 425", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M455A, + "Model 455A", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M475A, + "Model 475A", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M465, + "Model 465", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M625A, + "Model 625A", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M642A, + "Model 642A", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M648, + "Model 648", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M737, + "Model 737", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M776, + "Model 776", + }, + { + USB_VENDOR_LARSENBRUSGAARD, USB_PRODUCT_LARSENBRUSGAARD_ALTITRACK, + "AltiTrack", + }, + { + USB_VENDOR_LEADTEK, USB_PRODUCT_LEADTEK_9531, + "9531 GPS", + }, + { + USB_VENDOR_LENOVO, USB_PRODUCT_LENOVO_AX88179, + "AX88179", + }, + { + USB_VENDOR_LENOVO, USB_PRODUCT_LENOVO_DOCK_ETHERNET, + "USB-C Dock Ethernet", + }, + { + USB_VENDOR_LENOVO, USB_PRODUCT_LENOVO_ETHERNET, + "USB 2.0 Ethernet", + }, + { + USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_JUMPSHOT, + "jumpSHOT CompactFlash", + }, + { + USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_2662WAR, + "2662W-AR", + }, + { + USB_VENDOR_LEXMARK, USB_PRODUCT_LEXMARK_S2450, + "Optra S 2450", + }, + { + USB_VENDOR_LIEBERT, USB_PRODUCT_LIEBERT_UPS, + "UPS", + }, + { + USB_VENDOR_LIEBERT2, USB_PRODUCT_LIEBERT2_PSA, + "PowerSure PSA UPS", + }, + { + USB_VENDOR_LINKINSTRUMENTS, USB_PRODUCT_LINKINSTRUMENTS_MSO19, + "Link Instruments MSO-19", + }, + { + USB_VENDOR_LINKINSTRUMENTS, USB_PRODUCT_LINKINSTRUMENTS_MSO28, + "Link Instruments MSO-28", + }, + { + USB_VENDOR_LINKINSTRUMENTS, USB_PRODUCT_LINKINSTRUMENTS_MSO28_2, + "Link Instruments MSO-28", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_MAUSB2, + "Camedia MAUSB-2", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TX1, + "USB10TX", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_HG20F9, + "HG20F9 Ethernet", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T, + "USB10T Ethernet", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100TX, + "USB100TX Ethernet", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100H1, + "USB100H1 Ethernet/HPNA", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TA, + "USB10TA Ethernet", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_WUSB11, + "WUSB11 802.11b", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_WUSB11_25, + "WUSB11 802.11b v2.5", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_WUSB12_11, + "WUSB12 802.11b v1.1", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TX2, + "USB10TX", + }, + { + USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_NWU11B, + "NWU11B", + }, + { + USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_USB200M, + "USB 2.0 10/100 Ethernet controller", + }, + { + USB_VENDOR_LINKSYS3, USB_PRODUCT_LINKSYS3_WUSB11V28, + "WUSB11 v2.8", + }, + { + USB_VENDOR_LINKSYS3, USB_PRODUCT_LINKSYS3_WUSB11V30, + "WUSB11 v3.0", + }, + { + USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_USB1000, + "USB1000", + }, + { + USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB100, + "WUSB100", + }, + { + USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB600N, + "WUSB600N", + }, + { + USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB54GCV2, + "WUSB54GC v2", + }, + { + USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB54GCV3, + "WUSB54GC v3", + }, + { + USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_RT3070, + "RT3070", + }, + { + USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB600NV2, + "WUSB600N v2", + }, + { + USB_VENDOR_LITEON, USB_PRODUCT_LITEON_AR9271, + "AR9271", + }, + { + USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LAN_GTJU2, + "LAN-GTJ/U2", + }, + { + USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LANTX, + "LAN-TX", + }, + { + USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_RTL8187, + "RTL8187", + }, + { + USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_RT2870_3, + "RT2870", + }, + { + USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LANW300NU2, + "LAN-W300N/U2", + }, + { + USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LANW150NU2, + "LAN-W150N/U2", + }, + { + USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LANW300NU2S, + "LAN-W300N/U2S", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_M2452, + "M2452 keyboard", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_M4848, + "M4848 mouse", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_PAGESCAN, + "PageScan", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMWEB, + "QuickCam Web", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WEBCAMC200, + "Webcam C200", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WEBCAMC250, + "Webcam C250", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WEBCAMC500, + "Webcam C500", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRO, + "QuickCam Pro", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WEBCAMC210, + "Webcam C210", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WEBCAMC310, + "Webcam C310", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_HDPROC910, + "HD Pro Webcam C910", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WEBCAMC270, + "Webcam C270", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMEXP, + "QuickCam Express", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAM, + "QuickCam", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMNBDLX, + "QuickCam Notebook Deluxe", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRO3K, + "QuickCam Pro 3000", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMNBPRO_1, + "QuickCam Notebook Pro", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRO4K, + "QuickCam Pro 4000", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMZOOM, + "QuickCam Zoom", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMFUSION_1, + "QuickCam Fusion", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMORBITMP_1, + "QuickCam Orbit MP", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMNBPRO, + "QuickCam Notebook Pro", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRO5K_1, + "QuickCam Pro 5000", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMOEM_1, + "QuickCam OEM", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMOEM_2, + "QuickCam OEM", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMULTVIS, + "QuickCam Ultra Vision", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMFUSION_2, + "QuickCam Fusion", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMNBPRO_2, + "QuickCam Notebook Pro", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMORBITMP_2, + "QuickCam Orbit MP", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRO5K_2, + "QuickCam Pro 5000", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRO9K, + "QuickCam Pro 9000", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRONB, + "QuickCam Pro Notebook", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMCOMMDLX, + "QuickCam Communicate Deluxe", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMORBITAF, + "QuickCam Orbit AF", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMCOMMMP, + "QuickCam Communicate MP", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAME3500P, + "QuickCam E 3500 Plus", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMDLXNB, + "QuickCam Deluxe Notebook", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_N43, + "N43", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_N48, + "N48 mouse", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_MBA47, + "M-BA47 mouse", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WMMOUSE, + "WingMan Gaming Mouse", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_BD58, + "BD58 mouse", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_UN58A, + "iFeel Mouse", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WMPAD, + "WingMan GamePad Extreme", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WMRPAD, + "WingMan RumblePad", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WMJOY, + "WingMan Force joystick", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WMFFGP, + "WingMan Formula Force GP (GT-Force)", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_ITOUCH, + "iTouch Keyboard", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_BB13, + "USB-PS/2 Trackball", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_BB18, + "TrackMan Wheel", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_RK53, + "Cordless mouse", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_RB6, + "Cordless keyboard", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_CDO, + "Cordless Desktop Optical", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRO2, + "QuickCam Pro", + }, + { + USB_VENDOR_LONGCHEER, USB_PRODUCT_LONGCHEER_D21LCMASS, + "Emobile D21LC Mass only mode", + }, + { + USB_VENDOR_LONGCHEER, USB_PRODUCT_LONGCHEER_D21LC, + "Emobile D21LC", + }, + { + USB_VENDOR_LONGCHEER, USB_PRODUCT_LONGCHEER_510FU, + "IIJmobile 510FU", + }, + { + USB_VENDOR_LONGCHEER, USB_PRODUCT_LONGCHEER_510FUMASS, + "IIJmobile 510FU Mass only mode", + }, + { + USB_VENDOR_LUCENT, USB_PRODUCT_LUCENT_EVALKIT, + "USS-720 evaluation kit", + }, + { + USB_VENDOR_MACALLY, USB_PRODUCT_MACALLY_MOUSE1, + "mouse", + }, + { + USB_VENDOR_MARVELL, USB_PRODUCT_MARVELL_SHEEVAPLUG, + "SheevaPlug", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0100, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0101, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0102, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0103, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0104, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0105, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0106, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0107, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0108, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0109, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_010A, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_010B, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_010C, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_010D, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_010E, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_010F, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0110, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0111, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0112, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0113, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0114, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0115, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0116, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0117, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0118, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0119, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_011A, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_011B, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_011C, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_011D, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_011E, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_011F, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0120, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0121, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0122, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0123, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0124, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0125, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0126, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0127, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0128, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0129, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_012A, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_012B, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_012C, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_012D, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_012E, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_012F, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0130, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0131, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0132, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0133, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0134, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0135, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0136, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0137, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0138, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0139, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_013A, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_013B, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_013C, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_013D, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_013E, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_013F, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0140, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0141, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0142, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0143, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0144, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0145, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0146, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0147, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0148, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0149, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_014A, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_014B, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_014C, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_014D, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_014E, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_014F, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0150, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0151, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0152, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0153, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0154, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0155, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0156, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0157, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0158, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0159, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_015A, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_015B, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_015C, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_015D, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_015E, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_015F, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0160, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0161, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0162, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0163, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0164, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0165, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0166, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0167, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0168, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0169, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_016A, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_016B, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_016C, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_016D, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_016E, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_016F, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0170, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0171, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0172, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0173, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0174, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0175, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0176, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0177, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0178, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0179, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_017A, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_017B, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_017C, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_017D, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_017E, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_017F, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0180, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0181, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0182, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0183, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0184, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0185, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0186, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0187, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0188, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0189, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_018A, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_018B, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_018C, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_018D, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_018E, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_018F, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0190, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0191, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0192, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0193, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0194, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0195, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0196, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0197, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0198, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0199, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_019A, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_019B, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_019C, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_019D, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_019E, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_019F, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01A0, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01A1, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01A2, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01A3, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01A4, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01A5, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01A6, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01A7, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01A8, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01A9, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01AA, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01AB, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01AC, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01AD, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01AE, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01AF, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01B0, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01B1, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01B2, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01B3, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01B4, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01B5, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01B6, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01B7, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01B8, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01B9, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01BA, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01BB, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01BC, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01BD, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01BE, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01BF, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01C0, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01C1, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01C2, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01C3, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01C4, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01C5, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01C6, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01C7, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01C8, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01C9, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01CA, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01CB, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01CC, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01CD, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01CE, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01CF, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01D0, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01D1, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01D2, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01D3, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01D4, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01D5, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01D6, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01D7, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01D8, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01D9, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01DA, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01DB, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01DC, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01DD, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01DE, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01DF, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01E0, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01E1, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01E2, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01E3, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01E4, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01E5, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01E6, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01E7, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01E8, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01E9, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01EA, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01EB, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01EC, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01ED, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01EE, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01EF, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01F0, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01F1, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01F2, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01F3, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01F4, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01F5, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01F6, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01F7, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01F8, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01F9, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01FA, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01FB, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01FC, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01FD, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01FE, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01FF, + "LCD", + }, + { + USB_VENDOR_MCT, USB_PRODUCT_MCT_HUB0100, + "Hub", + }, + { + USB_VENDOR_MCT, USB_PRODUCT_MCT_DU_H3SP_USB232, + "D-Link DU-H3SP BAY Hub", + }, + { + USB_VENDOR_MCT, USB_PRODUCT_MCT_USB232, + "RS232", + }, + { + USB_VENDOR_MCT, USB_PRODUCT_MCT_SITECOM_USB232, + "Sitecom RS232", + }, + { + USB_VENDOR_MCT, USB_PRODUCT_MCT_ML_4500, + "ML-4500", + }, + { + USB_VENDOR_MDS, USB_PRODUCT_MDS_ISDBT, + "MDS ISDB-T tuner", + }, + { + USB_VENDOR_MECANIQUE, USB_PRODUCT_MECANIQUE_WISPY, + "MetaGeek Wi-Spy", + }, + { + USB_VENDOR_MECANIQUE, USB_PRODUCT_MECANIQUE_TELLSTICK, + "Telldus Tellstick", + }, + { + USB_VENDOR_MEDIATEK, USB_PRODUCT_MEDIATEK_UMASS, + "USB MSM installer", + }, + { + USB_VENDOR_MEDIATEK, USB_PRODUCT_MEDIATEK_DC_4COM, + "UMTS USB modem", + }, + { + USB_VENDOR_MEI, USB_PRODUCT_MEI_CASHFLOW_SC, + "Cashflow-SC", + }, + { + USB_VENDOR_MEI, USB_PRODUCT_MEI_S2000, + "Series 2000", + }, + { + USB_VENDOR_MEINBERG, USB_PRODUCT_MEINBERG_USB5131, + "USB 5131 DCF77 - Radio Clock", + }, + { + USB_VENDOR_MEINBERG, USB_PRODUCT_MEINBERG_DCF600USB, + "DCF600USB - Radio Clock", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX1, + "LUA-TX Ethernet", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX5, + "LUA-TX Ethernet", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUA2TX5, + "LUA2-TX Ethernet", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAKTX, + "LUA-KTX Ethernet", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_S11, + "WLI-USB-S11", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_MCRSM2, + "MCR-SM2 SmartMedia", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_DUBPXXG, + "USB-IDE Bridge: DUB-PxxG", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KS11G, + "WLI-USB-KS11G wlan", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2KTX, + "LUA-U2-KTX Ethernet", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KB11, + "WLI-USB-KB11 WLAN", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54YB, + "WLI-U2-KG54-YB WLAN", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54, + "WLI-U2-KG54 WLAN", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54AI, + "WLI-U2-KG54-AI WLAN", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2GT, + "LUA-U2-GT Ethernet", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_NINWIFI, + "Nintendo Wi-Fi", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIU2KAMG54, + "WLI-U2-KAMG54", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIU2KAMG54_NF, + "WLI-U2-KAMG54", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_PCOPRS1, + "PC-OP-RS1 RemoteStation", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HP, + "WLI-U2-SG54HP", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_G54HP, + "WLI-U2-G54HP", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54L, + "WLI-U2-KG54L", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCG300N, + "WLI-UC-G300N", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HG, + "WLI-U2-SG54HG", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCAG300N, + "WLI-UC-AG300N", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCGNHP, + "WLI-UC-GNHP", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCGN, + "WLI-UC-GN", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCG301N, + "WLI-UC-G301N", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCGNM, + "WLI-UC-GNM", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCGNM2, + "WLI-UC-GNM2", + }, + { + USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY24I, + "Wi-Spy 2.4i", + }, + { + USB_VENDOR_METRICOM, USB_PRODUCT_METRICOM_RICOCHET_GS, + "Ricochet GS", + }, + { + USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS1, + "UPS", + }, + { + USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS2, + "UPS", + }, + { + USB_VENDOR_MICROCHIP, USB_PRODUCT_MICROCHIP_USBLCD20X2, + "USB-LCD-20x2", + }, + { + USB_VENDOR_MICROCHIP, USB_PRODUCT_MICROCHIP_USBLCD256X64, + "USB-LCD-256x64", + }, + { + USB_VENDOR_MICRODIA, USB_PRODUCT_MICRODIA_YUREX, + "YUREX", + }, + { + USB_VENDOR_MICRODIA, USB_PRODUCT_MICRODIA_CAM_1, + "CAM_1", + }, + { + USB_VENDOR_MICRODIA, USB_PRODUCT_MICRODIA_TEMPER, + "TEMPer sensor", + }, + { + USB_VENDOR_MICRODIA, USB_PRODUCT_MICRODIA_TEMPERHUM, + "TEMPerHUM sensor", + }, + { + USB_VENDOR_MICRONET, USB_PRODUCT_MICRONET_SP128AR, + "SP128AR EtherFast", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_SIDEPREC, + "SideWinder Precision Pro", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_INTELLIMOUSE, + "IntelliMouse", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_NATURALKBD, + "Natural", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_DDS80, + "Digital Sound System 80", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_SIDEWINDER, + "Sidewinder Precision Racing Wheel", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_INETPRO, + "Internet Keyboard Pro", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_TBEXPLORER, + "Trackball Explorer", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_INTELLIEYE, + "IntelliEye mouse", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_INETPRO2, + "Internet Keyboard Pro", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_MN510, + "MN510 Wireless", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_700WX, + "Palm 700WX", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_MN110, + "10/100 Ethernet", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLINTELLIMOUSE, + "Wireless Optical IntelliMouse", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLNOTEBOOK, + "Wireless Optical Mouse (Model 1023)", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLNOTEBOOK3, + "Wireless Optical Mouse 3000 (Model 1049)", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLNOTEBOOK2, + "Wireless Optical Mouse 3000 (Model 1056)", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_XBOX360_CONTROLLER, + "XBOX 360 Controller", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_XBOX360, + "XBOX 360 WLAN", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLMOBILEMOUSE3500, + "Wireless Mobile Mouse 3500", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_LIFECAM, + "Microsoft LifeCam", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLARCMOUSE, + "Wireless Arc Mouse (Model 1350)", + }, + { + USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIDB25, + "SCSI-DB25", + }, + { + USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIHD50, + "SCSI-HD50", + }, + { + USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_DPCM, + "CameraMate", + }, + { + USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_FREECOM, + "Freecom IDE", + }, + { + USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_336CX, + "Phantom 336CX - C3", + }, + { + USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_X6U, + "ScanMaker X6 - X6U", + }, + { + USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_C6, + "Phantom C6", + }, + { + USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_336CX2, + "Phantom 336CX - C3", + }, + { + USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6USL, + "ScanMaker V6USL", + }, + { + USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6USL2, + "ScanMaker V6USL", + }, + { + USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6UL, + "ScanMaker V6UL", + }, + { + USB_VENDOR_MIDIMAN, USB_PRODUCT_MIDIMAN_MIDISPORT2X2, + "Midisport 2x2", + }, + { + USB_VENDOR_MINDSATWORK, USB_PRODUCT_MINDSATWORK_DW, + "Digital Wallet", + }, + { + USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_S304, + "Dimage S304", + }, + { + USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_X, + "Dimage X", + }, + { + USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_DIMAGE7I, + "Dimage 7i", + }, + { + USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_DIMAGEA1, + "Dimage A1", + }, + { + USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_CDRRW, + "CD-R/RW Drive", + }, + { + USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_MOUSE, + "Mouse", + }, + { + USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_BLUETOOTH, + "Bluetooth", + }, + { + USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_FDD, + "FDD", + }, + { + USB_VENDOR_MOBILEACTION, USB_PRODUCT_MOBILEACTION_MA620, + "MA-620 IrDA", + }, + { + USB_VENDOR_MOBILITY, USB_PRODUCT_MOBILITY_ED200H, + "EasiDock 200 Serial", + }, + { + USB_VENDOR_MOBILITY, USB_PRODUCT_MOBILITY_EA, + "Ethernet", + }, + { + USB_VENDOR_MOBILITY, USB_PRODUCT_MOBILITY_EASIDOCK, + "EasiDock Ethernet", + }, + { + USB_VENDOR_MODACOM, USB_PRODUCT_MODACOM_MWIMAX, + "MODACOM Mobile wimax adaptor", + }, + { + USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7703, + "MCS7703 Serial", + }, + { + USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7715, + "MCS7715 Serial Parallel", + }, + { + USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7730, + "MCS7730 Ethernet", + }, + { + USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7810, + "MCS7810 Serial", + }, + { + USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7820, + "MCS7820 Serial", + }, + { + USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7830, + "MCS7830 Ethernet", + }, + { + USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7832, + "MCS7832 Ethernet", + }, + { + USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7840, + "MCS7840 Serial", + }, + { + USB_VENDOR_MOTOROLA, USB_PRODUCT_MOTOROLA_MC141555, + "MC141555 hub controller", + }, + { + USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_T720C, + "T720c", + }, + { + USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_V360, + "V360", + }, + { + USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN, + "USBLAN", + }, + { + USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN2, + "USBLAN", + }, + { + USB_VENDOR_MOTOROLA3, USB_PRODUCT_MOTOROLA3_SB4100, + "SB4100 Cable Modem", + }, + { + USB_VENDOR_MOTOROLA3, USB_PRODUCT_MOTOROLA3_SB5100, + "SB5100 Cable Modem", + }, + { + USB_VENDOR_MOTOROLA4, USB_PRODUCT_MOTOROLA4_RT2770, + "RT2770", + }, + { + USB_VENDOR_MOTOROLA4, USB_PRODUCT_MOTOROLA4_RT3070, + "RT3070", + }, + { + USB_VENDOR_MOXA, USB_PRODUCT_MOXA_UPORT1110, + "UPort 1110", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_WLAN, + "WLAN", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_BLUETOOTH, + "Bluetooth", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_1, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_2, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_8, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_3, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_9, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570, + "RT2570", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570_2, + "RT2570", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570_3, + "RT2570", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_1, + "RT2573", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_2, + "RT2573", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_4, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_5, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_10, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_12, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_13, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_6, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_11, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_14, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_15, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_7, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_3, + "RT2573", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_4, + "RT2573", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_AX88772A, + "AX88772A", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_BLUETOOTH_2, + "Bluetooth", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_BLUETOOTH_3, + "Bluetooth", + }, + { + USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY, + "DiskOnKey", + }, + { + USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY2, + "DiskOnKey", + }, + { + USB_VENDOR_MULTITECH, USB_PRODUCT_MULTITECH_ATLAS, + "MT5634ZBA modem", + }, + { + USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200CU, + "1200 CU", + }, + { + USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_600CU, + "600 CU", + }, + { + USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200USB, + "1200", + }, + { + USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200UB, + "1200 UB", + }, + { + USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200USBPLUS, + "1200 Plus", + }, + { + USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200CUPLUS, + "1200 CU Plus", + }, + { + USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_BEARPAW1200F, + "BearPaw 1200F", + }, + { + USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_600USB, + "600", + }, + { + USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_MDC800, + "MDC-800", + }, + { + USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_DV2000, + "DV2000", + }, + { + USB_VENDOR_MUSTEK2, USB_PRODUCT_MUSTEK2_PM800, + "PowerMust 800", + }, + { + USB_VENDOR_NATIONAL, USB_PRODUCT_NATIONAL_BEARPAW1200, + "BearPaw 1200", + }, + { + USB_VENDOR_NATIONAL, USB_PRODUCT_NATIONAL_BEARPAW2400, + "BearPaw 2400", + }, + { + USB_VENDOR_NEC, USB_PRODUCT_NEC_HUB, + "hub", + }, + { + USB_VENDOR_NEC, USB_PRODUCT_NEC_WL300NUG, + "WL300NU-G", + }, + { + USB_VENDOR_NEC, USB_PRODUCT_NEC_USB2EXTEND, + "Repeater", + }, + { + USB_VENDOR_NEC, USB_PRODUCT_NEC_HUB_B, + "hub", + }, + { + USB_VENDOR_NEC, USB_PRODUCT_NEC_HUB_C, + "hub", + }, + { + USB_VENDOR_NEC, USB_PRODUCT_NEC_PICTY760, + "Picty760", + }, + { + USB_VENDOR_NEC, USB_PRODUCT_NEC_PICTY900, + "Picty900", + }, + { + USB_VENDOR_NEC, USB_PRODUCT_NEC_PICTY920, + "Picty920", + }, + { + USB_VENDOR_NEC, USB_PRODUCT_NEC_PICTY800, + "Picty800", + }, + { + USB_VENDOR_NEC2, USB_PRODUCT_NEC2_HUB2_0, + "USB2.0 Hub", + }, + { + USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND3050, + "6-in-1 Flash Device Controller", + }, + { + USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND3260, + "8-in-1 Flash Device Controller", + }, + { + USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND5010, + "Multi-format Flash Controller", + }, + { + USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_TURBOCONNECT, + "Turbo-Connect", + }, + { + USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_CLIK40, + "Clik! 40", + }, + { + USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_ETHERNETGADGET, + "EthernetGadget", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101, + "Ethernet", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101X, + "Ethernet", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA101, + "10/100 Ethernet", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA120, + "USB 2.0 Fast Ethernet", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_M7100, + "M7100", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_MA111NA, + "802.11b", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_MA111V2, + "802.11b V2", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WG111V2_2, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WG111V3, + "WG111v3", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WG111U, + "WG111U", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WG111U_NF, + "WG111U", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WG111V2, + "WG111v2", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WN111V2, + "WN111V2", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNDA3100, + "WNDA3100", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNDA3200, + "WNDA3200", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1100, + "WNA1100", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1000, + "WNA1000", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1000M, + "WNA1000M", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1000MV2, + "WNA1000Mv2", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_N300MA, + "N300MA", + }, + { + USB_VENDOR_NETGEAR2, USB_PRODUCT_NETGEAR2_MA101, + "MA101", + }, + { + USB_VENDOR_NETGEAR2, USB_PRODUCT_NETGEAR2_MA101B, + "MA101 Rev B", + }, + { + USB_VENDOR_NETGEAR3, USB_PRODUCT_NETGEAR3_WG111T, + "WG111T", + }, + { + USB_VENDOR_NETGEAR3, USB_PRODUCT_NETGEAR3_WG111T_NF, + "WG111T", + }, + { + USB_VENDOR_NETGEAR3, USB_PRODUCT_NETGEAR3_WG111T_1, + "WG111T", + }, + { + USB_VENDOR_NETGEAR3, USB_PRODUCT_NETGEAR3_WPN111, + "WPN111", + }, + { + USB_VENDOR_NETGEAR3, USB_PRODUCT_NETGEAR3_WPN111_NF, + "WPN111", + }, + { + USB_VENDOR_NETGEAR4, USB_PRODUCT_NETGEAR4_RTL8188CU, + "RTL8188CU", + }, + { + USB_VENDOR_NETWEEN, USB_PRODUCT_NETWEEN_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_NHJ, USB_PRODUCT_NHJ_CAM2, + "Camera", + }, + { + USB_VENDOR_NI, USB_PRODUCT_NI_GPIB_USB_A, + "GPIB-USB-A", + }, + { + USB_VENDOR_NIKON, USB_PRODUCT_NIKON_E990, + "E990", + }, + { + USB_VENDOR_NIKON, USB_PRODUCT_NIKON_E880, + "E880", + }, + { + USB_VENDOR_NIKON, USB_PRODUCT_NIKON_E885, + "E885", + }, + { + USB_VENDOR_NOKIA, USB_PRODUCT_NOKIA_CA42, + "CA-42 Serial", + }, + { + USB_VENDOR_NOKIA2, USB_PRODUCT_NOKIA2_CS15UMASS, + "Internet Stick CS-15 (umass mode)", + }, + { + USB_VENDOR_NOKIA2, USB_PRODUCT_NOKIA2_CS15, + "Internet Stick CS-15", + }, + { + USB_VENDOR_NORITAKE, USB_PRODUCT_NORITAKE_COMEMO, + "Noritake COMEMO", + }, + { + USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_NV902W, + "NV-902W", + }, + { + USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_RT2573, + "RT2573", + }, + { + USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_RTL8188CU, + "RTL8188CU", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_EXPRESSCARD, + "ExpressCard 3G", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MERLINV620, + "V620", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MERLINV740, + "V740", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V720, + "V720", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MERLINU740, + "U740", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MERLINU740_2, + "U740", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U870, + "U870", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_XU870, + "XU870", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_X950D, + "X950D", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ES620, + "ES620 CDMA", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U720, + "U720", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_EU870D, + "EU870D", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U727, + "U727", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MC950D, + "MC950D HSUPA", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MERLINX950D, + "X950D", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ZEROCD2, + "ZeroCD", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MC760CD, + "MC760 CD", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U760, + "U760", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MC760, + "MC760", + }, + { + USB_VENDOR_NOVATEL1, USB_PRODUCT_NOVATEL1_FLEXPACKGPS, + "NovAtel FlexPack GPS", + }, + { + USB_VENDOR_O2MICRO, USB_PRODUCT_O2MICRO_OZ776HUB, + "OZ776 Hub", + }, + { + USB_VENDOR_OCT, USB_PRODUCT_OCT_USBTOETHER, + "Ethernet", + }, + { + USB_VENDOR_OCT, USB_PRODUCT_OCT_US2308, + "Serial", + }, + { + USB_VENDOR_OLIMEX, USB_PRODUCT_OLIMEX_OPENOCD_JTAG, + "OpenOCD JTAG", + }, + { + USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1, + "C-1", + }, + { + USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C700, + "C-700 Ultra Zoom", + }, + { + USB_VENDOR_OMNIVISION, USB_PRODUCT_OMNIVISION_OV511, + "OV511", + }, + { + USB_VENDOR_OMNIVISION, USB_PRODUCT_OMNIVISION_OV511PLUS, + "OV511+", + }, + { + USB_VENDOR_OMRON, USB_PRODUCT_OMRON_BX50F, + "BX50F UPS", + }, + { + USB_VENDOR_OMRON, USB_PRODUCT_OMRON_BX35F, + "BX35F UPS", + }, + { + USB_VENDOR_OMRON, USB_PRODUCT_OMRON_BY35S, + "BY35S UPS", + }, + { + USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MD2, + "disk", + }, + { + USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MDCFEB, + "MDCFE-B CF", + }, + { + USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_SIIGMS, + "Memory Stick+CF", + }, + { + USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_DATAFAB3, + "Datafab-based", + }, + { + USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_DATAFAB4, + "Datafab-based", + }, + { + USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_PNYCFSM, + "PNY/Datafab CF+SM", + }, + { + USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_STECHCFSM, + "Simple Tech/Datafab CF+SM", + }, + { + USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_LC1, + "CF + SM Combo (LC1)", + }, + { + USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MD1II, + "Datafab MD1-II PC-Card", + }, + { + USB_VENDOR_ONSPEC2, USB_PRODUCT_ONSPEC2_8IN2, + "8In2", + }, + { + USB_VENDOR_OPENMOKO, USB_PRODUCT_OPENMOKO_N1793D, + "Neo1973 Debug", + }, + { + USB_VENDOR_OPENMOKO2, USB_PRODUCT_OPENMOKO2_ONERNG, + "Moonbase Otago OneRNG", + }, + { + USB_VENDOR_OPENMOKO2, USB_PRODUCT_OPENMOKO2_CHAOSKEY, + "Altusmetrum ChaosKey 1.0", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_VODAFONEMC3G, + "Vodafone Mobile Connect 3G", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GFUSION, + "GlobeTrotter 3G FUSION", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GQUAD, + "GlobeTrotter 3G QUAD", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GQUADPLUS, + "GlobeTrotter 3G QUAD PLUS", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTMAX36, + "GlobeTrotter MAX 3.6/7.2", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GPLUS, + "GlobeTrotter 3G PLUS", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_SCORPION, + "GlobeTrotter HSDPA Modem", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GSICON72, + "GlobeSurfer iCON 7.2", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_ICON225, + "iCON 225", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTHSUPA380E, + "GlobeTrotter HSUPA 380E", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_ICON322, + "iCON 322", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_ICON505, + "iCON 505", + }, + { + USB_VENDOR_OQO, USB_PRODUCT_OQO_WIFI01, + "model 01 WiFi", + }, + { + USB_VENDOR_OQO, USB_PRODUCT_OQO_BT01, + "model 01 Bluetooth", + }, + { + USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01PLUS, + "model 01+ Ethernet", + }, + { + USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01, + "model 01 Ethernet", + }, + { + USB_VENDOR_OREGONSCI, USB_PRODUCT_OREGONSCI_OWL_CM160, + "OWL CM-160", + }, + { + USB_VENDOR_OTI, USB_PRODUCT_OTI_SOLID, + "Solid state disk", + }, + { + USB_VENDOR_OTI, USB_PRODUCT_OTI_DKU5, + "DKU-5 Serial", + }, + { + USB_VENDOR_OVISLINK, USB_PRODUCT_OVISLINK_RT3071, + "RT3071", + }, + { + USB_VENDOR_OVISLINK, USB_PRODUCT_OVISLINK_RT3072, + "RT3072", + }, + { + USB_VENDOR_OWEN, USB_PRODUCT_OWEN_AC4, + "AC4 USB-RS485", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_M500, + "Palm m500", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_M505, + "Palm m505", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_M515, + "Palm m515", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_I705, + "Palm i705", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_Z, + "Palm Tungsten Z", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_M125, + "Palm m125", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_M130, + "Palm m130", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_T, + "Palm Tungsten T", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE_31, + "Palm Zire 31", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE, + "Palm Zire", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_SERIAL, + "USB Serial Adaptor", + }, + { + USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_LS120, + "LS-120", + }, + { + USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_SDCAAE, + "MultiMediaCard", + }, + { + USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_TYTP50P6S, + "TY-TP50P6-S 50in Touch Panel", + }, + { + USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_N5HBZ0000055, + "UB94", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_SB485_1, + "SB485 USB-485/422", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_AP485_1, + "AP485 USB-RS485", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_SB422_1, + "SB422 USB-RS422", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_SB485_2, + "SB485 USB-485/422", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_AP485_2, + "AP485 USB-RS485", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_SB422_2, + "SB422 USB-RS422", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_SB485S, + "SB485S USB-485/422", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_SB485C, + "SB485C USB-485/422", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_SERIAL, + "Serial", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_LEC, + "Serial", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_SB232, + "SB232 USB-RS232", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_TMU, + "TMU Thermometer", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_IRAMP, + "IRAmp Duplex", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_DRAK5, + "DRAK5", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_QUIDO88, + "QUIDO USB 8/8", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_QUIDO44, + "QUIDO USB 4/4", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_QUIDO22, + "QUIDO USB 2/2", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_QUIDO101, + "QUIDO USB 10/1", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_QUIDO303, + "QUIDO USB 30/3", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_QUIDO603, + "QUIDO USB 60(100)/3", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_QUIDO216, + "QUIDO USB 2/16", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_QUIDO332, + "QUIDO USB 3/32", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_DRAK6, + "DRAK6 USB", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_STAVOVY, + "UPS-USB Stavovy", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_MUC, + "MU Controller", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_SIMUKEY, + "SimuKey", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_AD4USB, + "AD4USB", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_GOLIATH_MUX, + "GOLIATH MUX", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_GOLIATH_MSR, + "GOLIATH MSR", + }, + { + USB_VENDOR_PARA, USB_PRODUCT_PARA_RT3070, + "RT3070", + }, + { + USB_VENDOR_PEGATRON, USB_PRODUCT_PEGATRON_RT2870, + "RT2870", + }, + { + USB_VENDOR_PEGATRON, USB_PRODUCT_PEGATRON_RT3070, + "RT3070", + }, + { + USB_VENDOR_PEGATRON, USB_PRODUCT_PEGATRON_RT3070_2, + "RT3070", + }, + { + USB_VENDOR_PEGATRON, USB_PRODUCT_PEGATRON_RT3070_3, + "RT3070", + }, + { + USB_VENDOR_PEGATRON, USB_PRODUCT_PEGATRON_RT3072, + "RT3072", + }, + { + USB_VENDOR_PEN, USB_PRODUCT_PEN_USBREADER, + "6 in 1", + }, + { + USB_VENDOR_PEN, USB_PRODUCT_PEN_MOBILEDRIVE, + "3 in 1", + }, + { + USB_VENDOR_PEN, USB_PRODUCT_PEN_USBDISK, + "Disk", + }, + { + USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_SERIAL1, + "Serial Converter", + }, + { + USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET, + "Ethernet", + }, + { + USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET3, + "At-Home Ethernet", + }, + { + USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET2, + "Ethernet", + }, + { + USB_VENDOR_PHEENET, USB_PRODUCT_PHEENET_WM168B, + "WM-168b", + }, + { + USB_VENDOR_PHEENET, USB_PRODUCT_PHEENET_WL503IA, + "WL-503IA", + }, + { + USB_VENDOR_PHEENET, USB_PRODUCT_PHEENET_GWU513, + "GWU513", + }, + { + USB_VENDOR_PHIDGETS, USB_PRODUCT_PHIDGETS_2X2, + "2x2 Interface Kit", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_DSS350, + "DSS 350 Digital Speaker System", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_DSS, + "DSS XXX Digital Speaker System", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_HUB, + "hub", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_PCA645VC, + "PCA645VC", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_PCA646VC, + "PCA646VC", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_PCVC675K, + "PCVC675K Vesta", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_PCVC680K, + "PCVC680K Vesta Pro", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_PCVC690K, + "PCVC690K Vesta Pro Scan Camera", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_PCVC730K, + "PCVC730K ToUCam Fun", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_PCVC740K, + "PCVC740K ToUCam Pro PC", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_PCVC750K, + "PCVC750K ToUCam Pro Scan", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_DSS150, + "DSS 150 Digital Speaker System", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_ACE1001, + "AKTAKOM ACE-1001", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_CPWUA054, + "CPWUA054", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_SNU6500, + "SNU6500", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_SNU6500_NF, + "SNU6500", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_SNU5600, + "SNU5600", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_SNU5630NS05, + "SNU5630NS/05", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_DIVAUSB, + "DIVA mp3 player", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_RT2870, + "RT2870", + }, + { + USB_VENDOR_PHILIPSSEMI, USB_PRODUCT_PHILIPSSEMI_HUB1122, + "hub", + }, + { + USB_VENDOR_PIENGINEERING, USB_PRODUCT_PIENGINEERING_PS2USB, + "PS2 to Mac", + }, + { + USB_VENDOR_PIENGINEERING, USB_PRODUCT_PIENGINEERING_XKEYS, + "Xkeys Programmable Keyboard", + }, + { + USB_VENDOR_PILOTECH, USB_PRODUCT_PILOTECH_CRW600, + "CRW-600 6-in-1", + }, + { + USB_VENDOR_PLANEX, USB_PRODUCT_PLANEX_GW_US11H, + "GW-US11H WLAN", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CUS, + "RTL8188CUS", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US11S, + "GW-US11S WLAN", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_3, + "RTL8188CU", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US54GXS, + "GW-US54GXS WLAN", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US300, + "GW-US300", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54HP, + "GW-US54HP", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS300MINIS, + "GW-US300MiniS", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RT3070, + "RT3070", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSNANO, + "GW-USNano", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSMICRO300, + "GW-USMicro300", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_1, + "RTL8188CU", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_4, + "RTL8188CU", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54MINI2, + "GW-US54Mini2", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54SG, + "GW-US54SG", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54GZL, + "GW-US54GZL", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54GD, + "GW-US54GD", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSMM, + "GW-USMM", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RT2870, + "RT2870", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSMICRON, + "GW-USMicroN", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSMICRON2W, + "GW-USMicroN2W", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_2, + "RTL8188CU", + }, + { + USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GWUS54GZ, + "GW-US54GZ", + }, + { + USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GU1000T, + "GU-1000T", + }, + { + USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GWUS54MINI, + "GW-US54Mini", + }, + { + USB_VENDOR_PLANEX4, USB_PRODUCT_PLANEX4_GWUS54ZGL, + "GW-US54ZGL", + }, + { + USB_VENDOR_PLANEX4, USB_PRODUCT_PLANEX4_ZD1211B, + "ZD1211B", + }, + { + USB_VENDOR_PLANTRONICS, USB_PRODUCT_PLANTRONICS_HEADSET, + "DSP-400 Headset", + }, + { + USB_VENDOR_PLX, USB_PRODUCT_PLX_TESTBOARD, + "test board", + }, + { + USB_VENDOR_PLX, USB_PRODUCT_PLX_CA42, + "CA-42 Serial", + }, + { + USB_VENDOR_PORTGEAR, USB_PRODUCT_PORTGEAR_EA8, + "Ethernet", + }, + { + USB_VENDOR_PORTGEAR, USB_PRODUCT_PORTGEAR_EA9, + "Ethernet", + }, + { + USB_VENDOR_PORTSMITH, USB_PRODUCT_PORTSMITH_EEA, + "Express Ethernet", + }, + { + USB_VENDOR_POSIFLEX, USB_PRODUCT_POSIFLEX_PP7000_1, + "PP7000 series printer", + }, + { + USB_VENDOR_POSIFLEX, USB_PRODUCT_POSIFLEX_PP7000_2, + "PP7000 series printer", + }, + { + USB_VENDOR_PQI, USB_PRODUCT_PQI_TRAVELFLASH, + "Travel Flash Drive", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2X300, + "G2-200", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E300, + "G2E-300", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2300, + "G2-300", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E3002, + "G2E-300", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_9600, + "Colorado 9600", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_600U, + "Colorado 600u", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_6200, + "Visioneer 6200", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_19200, + "Colorado 19200", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_1200U, + "Colorado 1200u", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G600, + "G2-600", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_636I, + "ReadyScan 636i", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2600, + "G2-600", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E600, + "G2E-600", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_COMFORT, + "Comfort", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_MOUSEINABOX, + "Mouse-in-a-Box", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_PCGAUMS1, + "Sony PCGA-UMS1", + }, + { + USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2301, + "PL2301 Host-Host", + }, + { + USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2302, + "PL2302 Host-Host", + }, + { + USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_RSAQ2, + "PL2303 Serial", + }, + { + USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303BENQ, + "PL2303 Serial", + }, + { + USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303, + "PL2303 Serial", + }, + { + USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2305, + "Parallel printer", + }, + { + USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_ATAPI4, + "ATAPI-4 Bridge Controller", + }, + { + USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2501, + "PL2501 Host-Host", + }, + { + USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303X, + "PL2303 Serial", + }, + { + USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303X2, + "PL2303 Serial", + }, + { + USB_VENDOR_PROLIFIC2, USB_PRODUCT_PROLIFIC2_PL2303, + "PL2303 Serial", + }, + { + USB_VENDOR_PUTERCOM, USB_PRODUCT_PUTERCOM_UPA100, + "USB-1284 BRIDGE", + }, + { + USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573, + "RT2573", + }, + { + USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573_2, + "RT2573", + }, + { + USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573_3, + "RT2573", + }, + { + USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2870, + "RT2870", + }, + { + USB_VENDOR_QTRONIX, USB_PRODUCT_QTRONIX_980N, + "Scorpion-980N", + }, + { + USB_VENDOR_QUALCOMM, USB_PRODUCT_QUALCOMM_MSM_DRIVER, + "MSM driver", + }, + { + USB_VENDOR_QUALCOMM, USB_PRODUCT_QUALCOMM_MSM_MODEM, + "CDMA MSM modem", + }, + { + USB_VENDOR_QUALCOMM, USB_PRODUCT_QUALCOMM_MSM_HSDPA2, + "HSDPA MSM", + }, + { + USB_VENDOR_QUALCOMM, USB_PRODUCT_QUALCOMM_MSM_HSDPA, + "HSDPA MSM", + }, + { + USB_VENDOR_QUALCOMM, USB_PRODUCT_QUALCOMM_MSM_HSDPA3, + "HSDPA MSM", + }, + { + USB_VENDOR_QUALCOMM, USB_PRODUCT_QUALCOMM_MSM_DRIVER2, + "MSM driver", + }, + { + USB_VENDOR_QUALCOMM2, USB_PRODUCT_QUALCOMM2_MSM_PHONE, + "CDMA MSM phone", + }, + { + USB_VENDOR_QUANTA, USB_PRODUCT_QUANTA_RT3070, + "RT3070", + }, + { + USB_VENDOR_QUANTA2, USB_PRODUCT_QUANTA2_UMASS, + "Quanta USB MSM (umass mode)", + }, + { + USB_VENDOR_QUANTA2, USB_PRODUCT_QUANTA2_Q101, + "Quanta Q101 HSDPA USB modem", + }, + { + USB_VENDOR_QUICKSHOT, USB_PRODUCT_QUICKSHOT_STRIKEPAD, + "USB StrikePad", + }, + { + USB_VENDOR_RADIOSHACK, USB_PRODUCT_RADIOSHACK_PL2303, + "PL2303 Serial", + }, + { + USB_VENDOR_RAINBOW, USB_PRODUCT_RAINBOW_IKEY2000, + "i-Key 2000", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570, + "RT2570", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2070, + "RT2070", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570_2, + "RT2570", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573, + "RT2573", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2671, + "RT2671", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2770, + "RT2770", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2870, + "RT2870", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT3070, + "RT3070", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT3071, + "RT3071", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT3072, + "RT3072", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT3370, + "RT3370", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT3572, + "RT3572", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT3573, + "RT3573", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT5370, + "RT5370", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT5572, + "RT5572", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_MT7601, + "MT7601", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT8070, + "RT8070", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570_3, + "RT2570", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573_2, + "RT2573", + }, + { + USB_VENDOR_RATOC, USB_PRODUCT_RATOC_REXUSB60, + "USB serial REX-USB60", + }, + { + USB_VENDOR_RATOC, USB_PRODUCT_RATOC_REXUSB60F, + "REX-USB60F", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188ETV, + "RTL8188ETV", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CTV, + "RTL8188CTV", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188RU_2, + "RTL8188RU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_4, + "RTL8188CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8150, + "RTL8150", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8151, + "RTL8151 PNA", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8152, + "RTL8152", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8153, + "RTL8153", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8156, + "RTL8156", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CE_0, + "RTL8188CE", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8171, + "RTL8171", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8172, + "RTL8172", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8173, + "RTL8173", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8174, + "RTL8174", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_0, + "RTL8188CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8191CU, + "RTL8191CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188EU, + "RTL8188EU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_1, + "RTL8188CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_2, + "RTL8188CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192CE, + "RTL8192CE", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188RU, + "RTL8188RU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CE_1, + "RTL8188CE", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188RU_3, + "RTL8188RU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192CE_VAU, + "RTL8192CE", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8187, + "RTL8187", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8187B_0, + "RTL8187B", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CUS, + "RTL8188CUS", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192EU, + "RTL8192EU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_3, + "RTL8188CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192U, + "RTL8192U", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8187B_1, + "RTL8187B", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8187B_2, + "RTL8187B", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_5, + "RTL8188CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8712, + "RTL8712", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8713, + "RTL8713", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_COMBO, + "RTL8188CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8723BU, + "RTL8723BU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192SU, + "RTL8192SU", + }, + { + USB_VENDOR_RENESAS, USB_PRODUCT_RENESAS_RX610, + "RX610 RX-Stick", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC2, + "VGP-VCC2 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC3, + "VGP-VCC3 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC2_2, + "VGP-VCC2 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC2_3, + "VGP-VCC2 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC5, + "VGP-VCC5 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC4, + "VGP-VCC4 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC4_2, + "VGP-VCC4 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC6, + "VGP-VCC6 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC7, + "VGP-VCC7 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC8, + "VGP-VCC8 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC9, + "VGP-VCC9 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VPGVCCX, + "VGP-VCCX Camera", + }, + { + USB_VENDOR_RIM, USB_PRODUCT_RIM_BLACKBERRY, + "BlackBerry", + }, + { + USB_VENDOR_RIM, USB_PRODUCT_RIM_PEARL_DUAL, + "RIM Mass Storage Device", + }, + { + USB_VENDOR_RIM, USB_PRODUCT_RIM_PEARL, + "BlackBerry pearl", + }, + { + USB_VENDOR_ROCKFIRE, USB_PRODUCT_ROCKFIRE_GAMEPAD, + "Gamepad 203USB", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_UA100, + "UA-100 Audio I/F", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_UM4, + "UM-4 MIDI I/F", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_SC8850, + "SC-8850 MIDI Synth", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_U8, + "U-8 Audio I/F", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_UM2, + "UM-2 MIDI I/F", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_SC8820, + "SC-8820 MIDI Synth", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_PC300, + "PC-300 MIDI Keyboard", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_UM1, + "UM-1 MIDI I/F", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_SK500, + "SK-500 MIDI Keyboard", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_SCD70, + "SC-D70 MIDI Synth", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_UM880N, + "UM-880 MIDI I/F", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_SD90, + "SD-90 MIDI Synth", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_UM550, + "UM-550 MIDI I/F", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_SD20, + "SD-20 MIDI Synth", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_SD80, + "SD-80 MIDI Synth", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_UA700, + "UA-700 Audio I/F", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_UMONE, + "UM-ONE MIDI I/F", + }, + { + USB_VENDOR_RTSYSTEMS, USB_PRODUCT_RTSYSTEMS_CT57B, + "CT57B Radio Cable", + }, + { + USB_VENDOR_SACOM, USB_PRODUCT_SACOM_USB485BL, + "USB-485-BL", + }, + { + USB_VENDOR_SAGEM, USB_PRODUCT_SAGEM_SERIAL, + "Serial", + }, + { + USB_VENDOR_SAGEM, USB_PRODUCT_SAGEM_XG760A, + "XG-760A", + }, + { + USB_VENDOR_SAGEM, USB_PRODUCT_SAGEM_XG76NA, + "XG-76NA", + }, + { + USB_VENDOR_SAITEK, USB_PRODUCT_SAITEK_CYBORG_3D_GOLD, + "Cyborg 3D Gold Joystick", + }, + { + USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_WIS09ABGN, + "WIS09ABGN Wireless LAN adapter", + }, + { + USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_SWL2100W, + "SWL-2100U", + }, + { + USB_VENDOR_SAMSUNG2, USB_PRODUCT_SAMSUNG2_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_SAMSUNG2, USB_PRODUCT_SAMSUNG2_ANDROID2, + "Android v2", + }, + { + USB_VENDOR_SAMSUNG2, USB_PRODUCT_SAMSUNG2_ANDROID, + "Android", + }, + { + USB_VENDOR_SAMSUNG2, USB_PRODUCT_SAMSUNG2_I330, + "I330", + }, + { + USB_VENDOR_SAMSUNG2, USB_PRODUCT_SAMSUNG2_AX88179, + "AX88179", + }, + { + USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR05A, + "ImageMate SDDR-05a", + }, + { + USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR31, + "ImageMate SDDR-31", + }, + { + USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR05, + "ImageMate SDDR-05", + }, + { + USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR12, + "ImageMate SDDR-12", + }, + { + USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR09, + "ImageMate SDDR-09", + }, + { + USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR75, + "ImageMate SDDR-75", + }, + { + USB_VENDOR_SANWASUPPLY, USB_PRODUCT_SANWASUPPLY_JYDV9USB, + "JY-DV9USB gamepad", + }, + { + USB_VENDOR_SANYO, USB_PRODUCT_SANYO_SCP4900, + "Sanyo SCP-4900 Phone", + }, + { + USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_SL11R, + "SL11R-IDE", + }, + { + USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_336CX, + "Phantom 336CX - C3", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2101, + "SeaLINK+232 (2101/2105)", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2102, + "SeaLINK+485 (2102)", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2103, + "SeaLINK+232I (2103)", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2104, + "SeaLINK+485I (2104)", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2201_1, + "SeaPORT+2/232 (2201) Port 1", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2202_1, + "SeaPORT+2/485 (2202) Port 1", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2203_1, + "SeaPORT+2 (2203) Port 1", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2201_2, + "SeaPORT+2/232 (2201) Port 2", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2202_2, + "SeaPORT+2/485 (2202) Port 2", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2203_2, + "SeaPORT+2 (2203) Port 2", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2401_1, + "SeaPORT+4/232 (2401) Port 1", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2402_1, + "SeaPORT+4/485 (2402) Port 1", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2403_1, + "SeaPORT+4 (2403) Port 1", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2401_2, + "SeaPORT+4/232 (2401) Port 2", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2402_2, + "SeaPORT+4/485 (2402) Port 2", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2403_2, + "SeaPORT+4 (2403) Port 2", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2401_3, + "SeaPORT+4/232 (2401) Port 3", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2402_3, + "SeaPORT+4/485 (2402) Port 3", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2403_3, + "SeaPORT+4 (2403) Port 3", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2401_4, + "SeaPORT+4/232 (2401) Port 4", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2402_4, + "SeaPORT+4/485 (2402) Port 4", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2403_4, + "SeaPORT+4 (2403) Port 4", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2801_1, + "SeaLINK+8/232 (2801) Port 1", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2802_1, + "SeaLINK+8/485 (2802) Port 1", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2803_1, + "SeaLINK+8 (2803) Port 1", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2801_2, + "SeaLINK+8/232 (2801) Port 2", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2802_2, + "SeaLINK+8/485 (2802) Port 2", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2803_2, + "SeaLINK+8 (2803) Port 2", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2801_3, + "SeaLINK+8/232 (2801) Port 3", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2802_3, + "SeaLINK+8/485 (2802) Port 3", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2803_3, + "SeaLINK+8 (2803) Port 3", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2801_4, + "SeaLINK+8/232 (2801) Port 4", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2802_4, + "SeaLINK+8/485 (2802) Port 4", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2803_4, + "SeaLINK+8 (2803) Port 4", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2801_5, + "SeaLINK+8/232 (2801) Port 5", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2802_5, + "SeaLINK+8/485 (2802) Port 5", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2803_5, + "SeaLINK+8 (2803) Port 5", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2801_6, + "SeaLINK+8/232 (2801) Port 6", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2802_6, + "SeaLINK+8/485 (2802) Port 6", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2803_6, + "SeaLINK+8 (2803) Port 6", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2801_7, + "SeaLINK+8/232 (2801) Port 7", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2802_7, + "SeaLINK+8/485 (2802) Port 7", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2803_7, + "SeaLINK+8 (2803) Port 7", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2801_8, + "SeaLINK+8/232 (2801) Port 8", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2802_8, + "SeaLINK+8/485 (2802) Port 8", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2803_8, + "SeaLINK+8 (2803) Port 8", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2106, + "SeaLINK+422 (2106)", + }, + { + USB_VENDOR_SEL, USB_PRODUCT_SEL_C662, + "C662", + }, + { + USB_VENDOR_SELUXIT, USB_PRODUCT_SELUXIT_RF, + "RF Dongle", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT2870_3, + "RT2870", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT2870_4, + "RT2870", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_NUB8301, + "NUB-8301", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_NUB862, + "NUB-862", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RTL8192SU_1, + "RTL8192SU", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RTL8192SU_2, + "RTL8192SU", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT3070, + "RT3070", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT3071, + "RT3071", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT3072_1, + "RT3072", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT3072_2, + "RT3072", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT3072_3, + "RT3072", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT3072_4, + "RT3072", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT3072_5, + "RT3072", + }, + { + USB_VENDOR_SERVERWORKS, USB_PRODUCT_SERVERWORKS_HUB, + "Root Hub", + }, + { + USB_VENDOR_SGI, USB_PRODUCT_SGI_SN1_L1_SC, + "SN1 L1 System Controller", + }, + { + USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ST268, + "ST268", + }, + { + USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9620A, + "DM9620A", + }, + { + USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9621A, + "DM9621A", + }, + { + USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ZT6688, + "ZT6688", + }, + { + USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ADM8515, + "ADM8515 Ethernet", + }, + { + USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9000E, + "DM9000E", + }, + { + USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9601, + "DM9601", + }, + { + USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9620, + "DM9620", + }, + { + USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9621, + "DM9621", + }, + { + USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9622, + "DM9622", + }, + { + USB_VENDOR_SHARK, USB_PRODUCT_SHARK_PA, + "Pocket Adapter", + }, + { + USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5500, + "SL5500", + }, + { + USB_VENDOR_SHARP, USB_PRODUCT_SHARP_A300, + "A300", + }, + { + USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5600, + "SL5600", + }, + { + USB_VENDOR_SHARP, USB_PRODUCT_SHARP_C700, + "C700", + }, + { + USB_VENDOR_SHARP, USB_PRODUCT_SHARP_C750, + "C750", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB, + "E-USB Bridge", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSCSI, + "eUSCSI Bridge", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_SDDR09, + "ImageMate SDDR09", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSBSMCF, + "eUSB SmartMedia / CompactFlash", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_ZIOMMC, + "eUSB MultiMediaCard", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_HIFD, + "Sony Hifd", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSBATAPI, + "eUSB ATA/ATAPI", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_CF, + "eUSB CompactFlash", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSCSI_B, + "eUSCSI Bridge", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSCSI_C, + "eUSCSI Bridge", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_CDRW, + "CD-RW Device", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_SCM, + "SCM Micro", + }, + { + USB_VENDOR_SIEMENS, USB_PRODUCT_SIEMENS_SPEEDSTREAM, + "SpeedStream", + }, + { + USB_VENDOR_SIEMENS, USB_PRODUCT_SIEMENS_SPEEDSTREAM22, + "SpeedStream 1022", + }, + { + USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_WLL013, + "WLL013", + }, + { + USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_ES75, + "GSM module MC35", + }, + { + USB_VENDOR_SIEMENS3, USB_PRODUCT_SIEMENS3_SX1, + "SX1", + }, + { + USB_VENDOR_SIEMENS3, USB_PRODUCT_SIEMENS3_X65, + "X65", + }, + { + USB_VENDOR_SIEMENS3, USB_PRODUCT_SIEMENS3_X75, + "X75", + }, + { + USB_VENDOR_SIEMENS4, USB_PRODUCT_SIEMENS4_RUGGEDCOM, + "RUGGEDCOM", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_EM5625, + "EM5625", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720, + "MC5720", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD_595, + "AirCard 595", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5725, + "MC5725", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC597E, + "597E", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_C597, + "Compass 597", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD_580, + "Aircard 580 EVDO", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC595U, + "595U", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720_2, + "MC5720", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5725_2, + "MC5725", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_TRUINSTALL, + "Aircard Tru Installer", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_2, + "MC8755", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8765, + "MC8765", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755, + "MC8755", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8775, + "MC8775", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_3, + "MC8755", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8775_2, + "MC8775", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD_875, + "875", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8780, + "MC8780", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8781, + "MC8781", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8790, + "MC8790", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880, + "880", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881, + "881", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880E, + "880E", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881E, + "881E", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880U, + "880U", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881U, + "881U", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC885U, + "885U", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_C01SW, + "C01SW", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC7700, + "MC7700", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_USB305, + "USB305", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC7304, + "MC7304", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8355, + "MC8355", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD_340U, + "Aircard 340U", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD_770S, + "Aircard 770S", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC7455, + "MC7455", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_EM7455, + "EM7455", + }, + { + USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_IRDA, + "IrDA", + }, + { + USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_DNSSF7X, + "Datum Networks SSF-7X Multi Players", + }, + { + USB_VENDOR_SIIG, USB_PRODUCT_SIIG_DIGIFILMREADER, + "DigiFilm-Combo", + }, + { + USB_VENDOR_SIIG, USB_PRODUCT_SIIG_MULTICARDREADER, + "MULTICARDREADER", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_VSTABI, + "VStabi Controller", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_ARKHAM_DS101_M, + "Arkham DS101 Monitor", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_ARKHAM_DS101_A, + "Arkham DS101 Adapter", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_BSM7DUSB, + "BSM7-D-USB", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_POLOLU, + "Pololu Serial", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_SB_PARAMOUNT_ME, + "Software Bisque Paramount ME", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CYGNAL_DEBUG, + "Cygnal Debug Adapter", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_SB_PARAMOUNT_ME2, + "Software Bisque Paramount ME", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_EDG1228, + "EDG1228", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_GSM2228, + "Enfora GSM2228", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_ARGUSISP, + "Argussoft ISP", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_IMS_USB_RS422, + "IMS USB-RS422", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CRUMB128, + "Crumb128", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_OPTRIS_MSPRO, + "Optris MSpro LT Thermometer", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_DEGREECONT, + "Degree Controls", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_TRACIENT, + "Tracient RFID", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_TRAQMATE, + "Track Systems Traqmate", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_SUUNTO, + "Suunto sports", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_ARYGON_MIFARE, + "Arygon Mifare RFID reader", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_DESKTOPMOBILE, + "Burnside Desktop mobile", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_TAMSMASTER, + "Tams Master Easy Control", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_RIGBLASTER, + "RIGblaster P&P", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_RIGTALK, + "RIGtalk", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_B_G_H3000, + "B&G H3000 Data Cable", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_IPLINK1220, + "IP-Link 1220", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_HAMLINKUSB, + "Timewave HamLinkUSB", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_AVIT_USB_TTL, + "AVIT Research USB-TTL", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_MJS_TOSLINK, + "MJS USB-TOSLINK", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_WAVIT, + "ThinkOptics WavIt", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_MULTIPLEX_RC, + "Multiplex RC adapter", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_MSD_DASHHAWK, + "MSD DashHawk", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_INSYS_MODEM, + "INSYS Modem", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_LIPOWSKY_JTAG, + "Lipowsky Baby-JTAG", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_LIPOWSKY_LIN, + "Lipowsky Baby-LIN", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_AEROCOMM, + "Aerocomm Radio", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_ZEPHYR_BIO, + "Zephyr Bioharness", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_EMS_C1007, + "EMS C1007 HF RFID reader", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_LIPOWSKY_HARP, + "Lipowsky HARP-1", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_C2_EDGE_MODEM, + "Commander 2 EDGE(GSM) Modem", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CYGNAL_GPS, + "Cygnal Fasttrax GPS", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_PLUGDRIVE, + "Nanotec Plug & Drive", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_TELEGESIS_ETRX2, + "Telegesis ETRX2USB", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_PROCYON_AVS, + "Procyon AVS", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_MC35PU, + "MC35pu", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CYGNAL, + "Cygnal", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_AMBER_AMB2560, + "Amber Wireless AMB2560", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_DEKTEK_DTAPLUS, + "DekTec DTA Plus VHF/UHF Booster", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_KYOCERA_GPS, + "Kyocera GPS", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_IRZ_SG10, + "IRZ SG-10 GSM/GPRS Modem", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_BEI_VCP, + "BEI USB Sensor (VCP)", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_JUNIPER_BX_CONS, + "Juniper BX Console", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_BALLUFF_RFID, + "Balluff RFID reader", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_AC_SERV_IBUS, + "AC-Services IBUS", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_AC_SERV_CIS, + "AC-Services CIS-IBUS", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_PREON32, + "Virtenio Preon32", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_AC_SERV_CAN, + "AC-Services CAN", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_AC_SERV_OBD, + "AC-Services OBD", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_EM357LR, + "CEL EM357 LR", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_EM357, + "CEL EM357", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_MMB_ZIGBEE, + "MMB Networks ZigBee", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_PII_ZIGBEE, + "Planet Innovation Ingeni ZigBee", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_KETRA_N1, + "Ketra N1", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CELDEVKIT, + "CEL MeshWorks DevKit", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_KCF_PRN, + "KCF Technologies PRN", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_HUBZ, + "HubZ ZigBee/Z-Wave", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP210X_1, + "CP210x Serial", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP210X_2, + "CP210x Serial", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP210X_3, + "CP210x Serial", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_INFINITY_MIC, + "Infinity GPS-MIC-1", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP2110, + "CP2110 USB HID Serial", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_USBSCOPE50, + "USBscope50", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_USBWAVE12, + "USBwave12", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_USBPULSE100, + "USBpulse100", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_USBCOUNT50, + "USBcount50", + }, + { + USB_VENDOR_SILABS2, USB_PRODUCT_SILABS2_DCU11CLONE, + "DCU-11 clone", + }, + { + USB_VENDOR_SILABS3, USB_PRODUCT_SILABS3_GPRS_MODEM, + "GPRS Modem", + }, + { + USB_VENDOR_SILABS4, USB_PRODUCT_SILABS4_100EU_MODEM, + "GPRS Modem 100EU", + }, + { + USB_VENDOR_SILABS5, USB_PRODUCT_SILABS5_EM358X, + "EM358x", + }, + { + USB_VENDOR_SILICOM, USB_PRODUCT_SILICOM_U2E, + "U2E", + }, + { + USB_VENDOR_SILICOM, USB_PRODUCT_SILICOM_GPE, + "Psion Dacom Gold Port Ethernet", + }, + { + USB_VENDOR_SILICONPORTALS, USB_PRODUCT_SILICONPORTALS_YAPPH_NF, + "YAP Phone (no firmware)", + }, + { + USB_VENDOR_SILICONPORTALS, USB_PRODUCT_SILICONPORTALS_YAPPHONE, + "YAP Phone", + }, + { + USB_VENDOR_SIMCOM, USB_PRODUCT_SIMCOM_SIM7600E, + "SIM7600E modem", + }, + { + USB_VENDOR_SIRIUS, USB_PRODUCT_SIRIUS_ROADSTER, + "NetComm Roadster II 56", + }, + { + USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_LN029, + "LN029", + }, + { + USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_CN104, + "CN104", + }, + { + USB_VENDOR_SITECOM2, USB_PRODUCT_SITECOM2_WL022, + "WL-022", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL168V1, + "WL-168 v1", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN030, + "LN-030", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL168V4, + "WL-168 v4", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT2870_3, + "RT2870", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL302, + "WL-302", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL603, + "WL-603", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL315, + "WL-315", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL321, + "WL-321", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3070_3, + "RT3070", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL324, + "WL-324", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL343, + "WL-343", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL608, + "WL-608", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL344, + "WL-344", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL329, + "WL-329", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL345, + "WL-345", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL353, + "WL-353", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3072_3, + "RT3072", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3072_4, + "RT3072", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL349V1, + "WL-349 v1", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3072_6, + "RT3072", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL349V4, + "WL-349 v4", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3070_1, + "RT3070", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8188CU, + "RTL8188CU", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8188CU_2, + "RTL8188CU", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3072_5, + "RT3072", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WLA4000, + "WLA-4000", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WLA5000, + "WLA-5000", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8192CU_2, + "RTL8192CU", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN032, + "LN-032", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WLA2100V2, + "WLA-2100 v2", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN028, + "LN-028", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL113, + "WL-113", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_ZD1211B, + "ZD1211B", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL172, + "WL-172", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL113R2, + "WL-113 rev 2", + }, + { + USB_VENDOR_SMART, USB_PRODUCT_SMART_PL2303, + "Serial", + }, + { + USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTLINK, + "SmartLink Ethernet", + }, + { + USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTNIC, + "smartNIC 2 PnP", + }, + { + USB_VENDOR_SMC, USB_PRODUCT_SMC_2102USB, + "10Mbps Ethernet", + }, + { + USB_VENDOR_SMC, USB_PRODUCT_SMC_2202USB, + "10/100 Ethernet", + }, + { + USB_VENDOR_SMC, USB_PRODUCT_SMC_2206USB, + "EZ Connect Ethernet", + }, + { + USB_VENDOR_SMC, USB_PRODUCT_SMC_2862WG, + "EZ Connect 54Mbps", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_2020HUB, + "Hub", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_2504HUB, + "Hub", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_2513HUB, + "Hub", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN7500, + "LAN7500", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN7505, + "LAN7505", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN7800, + "LAN7800", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN7801, + "LAN7801", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN7850, + "LAN7850", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9500, + "SMSC9500", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9505, + "SMSC9505", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9530, + "LAN9530", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9730, + "LAN9730", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9500_SAL10, + "SMSC9500", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9505_SAL10, + "SMSC9505", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9500A_SAL10, + "SMSC9500A", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9505A_SAL10, + "SMSC9505A", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9512_14_SAL10, + "SMSC9512/14", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9500A_HAL, + "SMSC9500A", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9505A_HAL, + "SMSC9505A", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9500_ALT, + "SMSC9500", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9500A_ALT, + "SMSC9500A", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9512_14_ALT, + "SMSC9512", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9500A, + "SMSC9500A", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9505A, + "SMSC9505A", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN89530, + "LAN89530", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9512_14, + "SMSC9512/14", + }, + { + USB_VENDOR_SMC3, USB_PRODUCT_SMC3_2662WV1, + "EZ Connect 11Mbps", + }, + { + USB_VENDOR_SMC3, USB_PRODUCT_SMC3_2662WV2, + "EZ Connect 11Mbps v2", + }, + { + USB_VENDOR_SOHOWARE, USB_PRODUCT_SOHOWARE_NUB100, + "NUB100 Ethernet", + }, + { + USB_VENDOR_SOHOWARE, USB_PRODUCT_SOHOWARE_NUB110, + "NUB110 Ethernet", + }, + { + USB_VENDOR_SOLIDYEAR, USB_PRODUCT_SOLIDYEAR_KEYBOARD, + "Keyboard", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC, + "DSC Cameras", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_NWMS7, + "Memorystick NW-MS7", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_DRIVEV2, + "Harddrive V2", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_MSACUS1, + "Memorystick MSAC-US1", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_HANDYCAM, + "Handycam", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_MSC, + "MSC Memorystick", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_35, + "Clie v3.5", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_PS2KEYBOARD, + "PlayStation2 keyboard", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_PS2KEYBOARDHUB, + "PlayStation2 keyboard hub", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_PS2MOUSE, + "PlayStation2 mouse", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40, + "Clie v4.0", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40_MS, + "Clie v4.0 Memory Stick", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_S360, + "Clie s360", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_41_MS, + "Clie v4.1 Memory Stick", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_41, + "Clie v4.1", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_NX60, + "Clie nx60", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_TJ25, + "Clie tj25", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_IFU_WLM2, + "IFU-WLM2", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_CXD9192, + "1seg TV tuner", + }, + { + USB_VENDOR_SOURCENEXT, USB_PRODUCT_SOURCENEXT_KEIKAI8_CHG, + "KeikaiDenwa 8 with charger", + }, + { + USB_VENDOR_SOURCENEXT, USB_PRODUCT_SOURCENEXT_KEIKAI8, + "KeikaiDenwa 8", + }, + { + USB_VENDOR_SPARKLAN, USB_PRODUCT_SPARKLAN_RT2573, + "RT2573", + }, + { + USB_VENDOR_SPARKLAN, USB_PRODUCT_SPARKLAN_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_SPARKLAN, USB_PRODUCT_SPARKLAN_RT3070, + "RT3070", + }, + { + USB_VENDOR_SPARKLAN, USB_PRODUCT_SPARKLAN_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_SPEEDDRAGON, USB_PRODUCT_SPEEDDRAGON_MS3303H, + "MS3303H Serial", + }, + { + USB_VENDOR_SPHAIRON, USB_PRODUCT_SPHAIRON_UB801R, + "UB801R", + }, + { + USB_VENDOR_SPHAIRON, USB_PRODUCT_SPHAIRON_RTL8187, + "RTL8187", + }, + { + USB_VENDOR_STARTECH, USB_PRODUCT_STARTECH_ICUSB232X, + "ICUSB2321X/2X/4X", + }, + { + USB_VENDOR_STMICRO, USB_PRODUCT_STMICRO_BIOMETRIC_COPR, + "Biometric Coprocessor", + }, + { + USB_VENDOR_STMICRO, USB_PRODUCT_STMICRO_COMMUNICATOR, + "Communicator", + }, + { + USB_VENDOR_STOLLMANN, USB_PRODUCT_STOLLMANN_ISDN_TA_USBA, + "ISDN TA+USBA", + }, + { + USB_VENDOR_STRAWBERRYLINUX, USB_PRODUCT_STRAWBERRYLINUX_USBRH, + "USBRH sensor", + }, + { + USB_VENDOR_STSN, USB_PRODUCT_STSN_STSN0001, + "Internet Access Device", + }, + { + USB_VENDOR_SUNCOMM, USB_PRODUCT_SUNCOMM_MB_ADAPTOR, + "Mobile Adaptor", + }, + { + USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_DS96L, + "U-Cable type D2", + }, + { + USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_PS64P1, + "U-Cable type P1", + }, + { + USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_VS10U, + "Slipper U", + }, + { + USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_IS96U, + "Ir-Trinity", + }, + { + USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_AS64LX, + "U-Cable type A3", + }, + { + USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_AS144L4, + "U-Cable type A4", + }, + { + USB_VENDOR_SUPERTOP, USB_PRODUCT_SUPERTOP_IDEBRIDGE, + "SuperTop IDE Bridge", + }, + { + USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_EP9001G2A, + "EP-9001-G rev 2A", + }, + { + USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2570, + "RT2570", + }, + { + USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2573, + "RT2573", + }, + { + USB_VENDOR_SUSTEEN, USB_PRODUCT_SUSTEEN_DCU11, + "Ericsson DCU-10/11", + }, + { + USB_VENDOR_SWEEX, USB_PRODUCT_SWEEX_ZD1211, + "ZD1211", + }, + { + USB_VENDOR_SWEEX2, USB_PRODUCT_SWEEX2_LW153, + "LW153", + }, + { + USB_VENDOR_SWEEX2, USB_PRODUCT_SWEEX2_LW154, + "LW154", + }, + { + USB_VENDOR_SWEEX2, USB_PRODUCT_SWEEX2_LW303, + "LW303", + }, + { + USB_VENDOR_SWEEX2, USB_PRODUCT_SWEEX2_LW313, + "LW313", + }, + { + USB_VENDOR_SYNTECH, USB_PRODUCT_SYNTECH_SERIAL, + "Serial", + }, + { + USB_VENDOR_SYNTECH, USB_PRODUCT_SYNTECH_CIPHERLAB100, + "CipherLab Barcode Scanner", + }, + { + USB_VENDOR_SYSTEMTALKS, USB_PRODUCT_SYSTEMTALKS_SGCX2UL, + "SGC-X2UL", + }, + { + USB_VENDOR_TANGTOP, USB_PRODUCT_TANGTOP_USBPS2, + "USBPS2", + }, + { + USB_VENDOR_TAPWAVE, USB_PRODUCT_TAPWAVE_ZODIAC, + "Zodiac", + }, + { + USB_VENDOR_TAUGA, USB_PRODUCT_TAUGA_CAMERAMATE, + "CameraMate (DPCM_USB)", + }, + { + USB_VENDOR_TCTMOBILE, USB_PRODUCT_TCTMOBILE_UMSM, + "Modem mode", + }, + { + USB_VENDOR_TCTMOBILE, USB_PRODUCT_TCTMOBILE_UMSM_2, + "Modem mode", + }, + { + USB_VENDOR_TCTMOBILE, USB_PRODUCT_TCTMOBILE_UMSM_3, + "Modem mode", + }, + { + USB_VENDOR_TCTMOBILE, USB_PRODUCT_TCTMOBILE_UMASS, + "Storage mode", + }, + { + USB_VENDOR_TCTMOBILE, USB_PRODUCT_TCTMOBILE_UMASS_2, + "Storage mode", + }, + { + USB_VENDOR_TDK, USB_PRODUCT_TDK_UPA9664, + "USB-PDC Adapter UPA9664", + }, + { + USB_VENDOR_TDK, USB_PRODUCT_TDK_UCA1464, + "USB-cdmaOne Adapter UCA1464", + }, + { + USB_VENDOR_TDK, USB_PRODUCT_TDK_UHA6400, + "USB-PHS Adapter UHA6400", + }, + { + USB_VENDOR_TDK, USB_PRODUCT_TDK_UPA6400, + "USB-PHS Adapter UPA6400", + }, + { + USB_VENDOR_TDK, USB_PRODUCT_TDK_BLUETOOTH, + "Bluetooth", + }, + { + USB_VENDOR_TEAC, USB_PRODUCT_TEAC_FD05PUB, + "FD-05PUB", + }, + { + USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_0193, + "ALLNET 0193 WLAN", + }, + { + USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_ZYAIR_B200, + "ZyXEL ZyAIR B200 WLAN", + }, + { + USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_U300C, + "U-300C", + }, + { + USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_QUICKWLAN, + "QuickWLAN", + }, + { + USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_ZD1211_1, + "ZD1211", + }, + { + USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_ZD1211_2, + "ZD1211", + }, + { + USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1, + "Microphone", + }, + { + USB_VENDOR_TENDA, USB_PRODUCT_TENDA_TWL541U, + "TWL541U WLAN", + }, + { + USB_VENDOR_TENX, USB_PRODUCT_TENX_MISSILE, + "Missile Launcher", + }, + { + USB_VENDOR_TENX, USB_PRODUCT_TENX_TEMPER, + "TEMPer sensor", + }, + { + USB_VENDOR_TERRATEC, USB_PRODUCT_TERRATEC_AUREON, + "Aureon Dual USB", + }, + { + USB_VENDOR_TESTO, USB_PRODUCT_TESTO_175, + "175/177 USB interface", + }, + { + USB_VENDOR_TESTO, USB_PRODUCT_TESTO_330, + "330 USB interface", + }, + { + USB_VENDOR_TESTO, USB_PRODUCT_TESTO_435, + "435/635/735 USB interface", + }, + { + USB_VENDOR_TESTO, USB_PRODUCT_TESTO_845, + "845 USB interface", + }, + { + USB_VENDOR_TESTO, USB_PRODUCT_TESTO_SERVICE, + "Service adapter", + }, + { + USB_VENDOR_TESTO, USB_PRODUCT_TESTO_580, + "580 USB interface", + }, + { + USB_VENDOR_TESTO, USB_PRODUCT_TESTO_174, + "174 USB interface", + }, + { + USB_VENDOR_TESTO, USB_PRODUCT_TESTO_556, + "556/560 USB interface", + }, + { + USB_VENDOR_TESTO, USB_PRODUCT_TESTO_SERIAL_1, + "USB adapter", + }, + { + USB_VENDOR_TESTO, USB_PRODUCT_TESTO_SERIAL_2, + "USB to serial converter", + }, + { + USB_VENDOR_THRUST, USB_PRODUCT_THRUST_FUSION_PAD, + "Fusion Digital Gamepad", + }, + { + USB_VENDOR_THURLBY, USB_PRODUCT_THURLBY_QL355P, + "QL355P power supply", + }, + { + USB_VENDOR_TI, USB_PRODUCT_TI_UTUSB41, + "UT-USB41 hub", + }, + { + USB_VENDOR_TI, USB_PRODUCT_TI_TUSB2046, + "TUSB2046 hub", + }, + { + USB_VENDOR_TI, USB_PRODUCT_TI_TUSB3410, + "TUSB3410", + }, + { + USB_VENDOR_TI, USB_PRODUCT_TI_NEXII, + "Nex II Digital", + }, + { + USB_VENDOR_TI, USB_PRODUCT_TI_MSP430_JTAG, + "MSP-FET430UIF JTAG", + }, + { + USB_VENDOR_TI, USB_PRODUCT_TI_MSP430, + "MSP-FET430UIF", + }, + { + USB_VENDOR_TML, USB_PRODUCT_TML_SERIAL, + "Serial", + }, + { + USB_VENDOR_TODOS, USB_PRODUCT_TODOS_ARGOS_MINI, + "Argos Mini Smartcard", + }, + { + USB_VENDOR_TOPRE, USB_PRODUCT_TOPRE_HHKB, + "HHKB Professional", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_RH, + "Toradex OAK RH sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_P, + "Toradex OAK P sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_LUX, + "Toradex OAK LUX sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_TILT, + "Toradex OAK Tilt sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_DIST, + "Toradex OAK DIST sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_MOVE, + "Toradex OAK MOVE sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_4_20, + "Toradex OAK 4-20mA sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_G, + "Toradex OAK G sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_MAGR, + "Toradex OAK MAGR sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_RELAY, + "Toradex OAK RELAY", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_10V, + "Toradex OAK 10V sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_LN, + "Toradex OAK LN sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_IO, + "Toradex OAK IO", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_ORIENT, + "Toradex ORIENT Tilt sensor", + }, + { + USB_VENDOR_TOSHIBA, USB_PRODUCT_TOSHIBA_RT3070, + "RT3070", + }, + { + USB_VENDOR_TOSHIBA, USB_PRODUCT_TOSHIBA_HSDPA, + "HSDPA", + }, + { + USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8812AU, + "RTL8812AU", + }, + { + USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8192EU, + "RTL8192EU", + }, + { + USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8188EUS, + "RTL8188EUS", + }, + { + USB_VENDOR_TREK, USB_PRODUCT_TREK_THUMBDRIVE, + "ThumbDrive", + }, + { + USB_VENDOR_TREK, USB_PRODUCT_TREK_THUMBDRIVE_8MB, + "ThumbDrive 8MB", + }, + { + USB_VENDOR_TRENDNET, USB_PRODUCT_TRENDNET_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_TRENDNET, USB_PRODUCT_TRENDNET_RTL8188CU, + "RTL8188CU", + }, + { + USB_VENDOR_TRIPPLITE, USB_PRODUCT_TRIPPLITE_U209, + "U209 Serial", + }, + { + USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_T33521, + "USB/MP3 decoder", + }, + { + USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_XXX1100, + "XXX 1100", + }, + { + USB_VENDOR_TRUST, USB_PRODUCT_TRUST_OPTMOUSE, + "Optical Mouse", + }, + { + USB_VENDOR_TRUST, USB_PRODUCT_TRUST_MOUSE, + "Mouse", + }, + { + USB_VENDOR_TSUNAMI, USB_PRODUCT_TSUNAMI_SM2000, + "SM-2000", + }, + { + USB_VENDOR_TWINMOS, USB_PRODUCT_TWINMOS_G240, + "G240", + }, + { + USB_VENDOR_UBLOX, USB_PRODUCT_UBLOX_ANTARIS4, + "ANTARIS4 GPS", + }, + { + USB_VENDOR_ULTIMA, USB_PRODUCT_ULTIMA_1200UBPLUS, + "1200 UB Plus", + }, + { + USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA1236U, + "Astra 1236U", + }, + { + USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA1220U, + "Astra 1220U", + }, + { + USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2000U, + "Astra 2000U", + }, + { + USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA3400, + "Astra 3400", + }, + { + USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2100U, + "Astra 2100U", + }, + { + USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2200U, + "Astra 2200U", + }, + { + USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_TEW444UBEU, + "TEW-444UB EU", + }, + { + USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_TEW444UBEU_NF, + "TEW-444UB EU", + }, + { + USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_TEW429UB_A, + "TEW-429UB_A", + }, + { + USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_TEW429UB, + "TEW-429UB", + }, + { + USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_TEW429UBC1, + "TEW-429UB C1", + }, + { + USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_TEW645UB, + "TEW-645UB", + }, + { + USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_ALL0298V2, + "ALL0298 v2", + }, + { + USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_AR5523_2, + "AR5523", + }, + { + USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_AR5523_2_NF, + "AR5523", + }, + { + USB_VENDOR_UNIACCESS, USB_PRODUCT_UNIACCESS_PANACHE, + "Panache Surf ISDN", + }, + { + USB_VENDOR_UNKNOWN2, USB_PRODUCT_UNKNOWN2_ZD1211B, + "ZD1211B", + }, + { + USB_VENDOR_UNKNOWN2, USB_PRODUCT_UNKNOWN2_NW3100, + "NW-3100", + }, + { + USB_VENDOR_UNKNOWN3, USB_PRODUCT_UNKNOWN3_ZD1211B, + "ZD1211B", + }, + { + USB_VENDOR_UNKNOWN4, USB_PRODUCT_UNKNOWN4_DM9601, + "DM9601", + }, + { + USB_VENDOR_UNKNOWN4, USB_PRODUCT_UNKNOWN4_RD9700, + "RD9700", + }, + { + USB_VENDOR_UNKNOWN5, USB_PRODUCT_UNKNOWN5_NF_RIC, + "NF RIC", + }, + { + USB_VENDOR_UNKNOWN6, USB_PRODUCT_UNKNOWN6_DM9601, + "DM9601", + }, + { + USB_VENDOR_USI, USB_PRODUCT_USI_MC60, + "MC60 Serial", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_USR1120, + "USR1120 WLAN", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_MILLER_A, + "USR9000 SureConnect ADSL", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_MILLER_A_NF, + "USR9000 SureConnect ADSL", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_HEINEKEN_A, + "USR9000 SureConnect ADSL", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_HEINEKEN_A_NF, + "USR9000 SureConnect ADSL", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_HEINEKEN_B, + "USR9000 SureConnect ADSL", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_HEINEKEN_B_NF, + "USR9000 SureConnect ADSL", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_MILLER_B, + "USR9000 SureConnect ADSL", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_MILLER_B_NF, + "USR9000 SureConnect ADSL", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_USR5422, + "USR5422 WLAN", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_USR5421A, + "USR5421A WLAN", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_USR5423, + "USR5423 WLAN", + }, + { + USB_VENDOR_VAISALA, USB_PRODUCT_VAISALA_USBINSTCABLE, + "USB instrument cable", + }, + { + USB_VENDOR_VALIDITY, USB_PRODUCT_VALIDITY_VFS101, + "VFS101 Fingerprint Reader", + }, + { + USB_VENDOR_VALIDITY, USB_PRODUCT_VALIDITY_VFS301, + "VFS301 Fingerprint Reader", + }, + { + USB_VENDOR_VALIDITY, USB_PRODUCT_VALIDITY_VFS451, + "VFS451 Fingerprint Reader", + }, + { + USB_VENDOR_VALIDITY, USB_PRODUCT_VALIDITY_VFS300, + "VFS300 Fingerprint Reader", + }, + { + USB_VENDOR_VALIDITY, USB_PRODUCT_VALIDITY_VFS5011, + "VFS5011 Fingerprint Reader", + }, + { + USB_VENDOR_VALIDITY, USB_PRODUCT_VALIDITY_VFS5011_2, + "VFS5011 Fingerprint Reader", + }, + { + USB_VENDOR_VALIDITY, USB_PRODUCT_VALIDITY_VFS5011_3, + "VFS5011 Fingerprint Reader", + }, + { + USB_VENDOR_VALIDITY, USB_PRODUCT_VALIDITY_VFS5471, + "VFS471 Fingerprint Reader", + }, + { + USB_VENDOR_VELLEMAN, USB_PRODUCT_VELLEMAN_K8055, + "K8055 USB Experiment interface board", + }, + { + USB_VENDOR_VERTEX, USB_PRODUCT_VERTEX_VW110L, + "VW110L", + }, + { + USB_VENDOR_VIA, USB_PRODUCT_VIA_AR9271, + "AR9271", + }, + { + USB_VENDOR_VIEWSONIC, USB_PRODUCT_VIEWSONIC_G773HUB, + "G773 Monitor Hub", + }, + { + USB_VENDOR_VIEWSONIC, USB_PRODUCT_VIEWSONIC_P815HUB, + "P815 Monitor Hub", + }, + { + USB_VENDOR_VIEWSONIC, USB_PRODUCT_VIEWSONIC_AIRSYNC, + "Airsync", + }, + { + USB_VENDOR_VIEWSONIC, USB_PRODUCT_VIEWSONIC_G773CTRL, + "G773 Monitor Control", + }, + { + USB_VENDOR_VISION, USB_PRODUCT_VISION_VC6452V002, + "CPiA Camera", + }, + { + USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_7600, + "OneTouch 7600", + }, + { + USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_5300, + "OneTouch 5300", + }, + { + USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_3000, + "Scanport 3000", + }, + { + USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_6100, + "OneTouch 6100", + }, + { + USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_6200, + "OneTouch 6200", + }, + { + USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_8100, + "OneTouch 8100", + }, + { + USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_8600, + "OneTouch 8600", + }, + { + USB_VENDOR_VIVITAR, USB_PRODUCT_VIVITAR_DSC350, + "DSC350", + }, + { + USB_VENDOR_VOTI, USB_PRODUCT_VOTI_SELETEK_1, + "Lunatico Seletek", + }, + { + USB_VENDOR_VOTI, USB_PRODUCT_VOTI_SELETEK_2, + "Lunatico Seletek", + }, + { + USB_VENDOR_VTECH, USB_PRODUCT_VTECH_RT2570, + "RT2570", + }, + { + USB_VENDOR_VTECH, USB_PRODUCT_VTECH_ZD1211B, + "ZD1211B", + }, + { + USB_VENDOR_WACOM, USB_PRODUCT_WACOM_CT0405U, + "CT-0405-U Tablet", + }, + { + USB_VENDOR_WACOM, USB_PRODUCT_WACOM_GRAPHIRE, + "Graphire", + }, + { + USB_VENDOR_WACOM, USB_PRODUCT_WACOM_GRAPHIRE3_4X5, + "Graphire3 4x5", + }, + { + USB_VENDOR_WACOM, USB_PRODUCT_WACOM_GRAPHIRE4_4X5, + "Graphire4 Classic A6", + }, + { + USB_VENDOR_WACOM, USB_PRODUCT_WACOM_INTUOSA5, + "Intuos A5", + }, + { + USB_VENDOR_WACOM, USB_PRODUCT_WACOM_INTUOS_DRAW, + "Intuos Draw (CTL-490)", + }, + { + USB_VENDOR_WAGO, USB_PRODUCT_WAGO_SERVICECABLE, + "Service Cable 750-923", + }, + { + USB_VENDOR_WAVESENSE, USB_PRODUCT_WAVESENSE_JAZZ, + "Jazz blood glucose meter", + }, + { + USB_VENDOR_WCH, USB_PRODUCT_WCH_CH341, + "CH341 serial/parallel", + }, + { + USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH341A, + "CH341A serial/parallel", + }, + { + USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH340, + "CH340 serial/parallel", + }, + { + USB_VENDOR_WIENERPLEINBAUS, USB_PRODUCT_WIENERPLEINBAUS_PL512, + "PL512 PSU", + }, + { + USB_VENDOR_WIENERPLEINBAUS, USB_PRODUCT_WIENERPLEINBAUS_RCM, + "RCM Remote Control", + }, + { + USB_VENDOR_WIENERPLEINBAUS, USB_PRODUCT_WIENERPLEINBAUS_MPOD, + "MPOD PSU", + }, + { + USB_VENDOR_WIENERPLEINBAUS, USB_PRODUCT_WIENERPLEINBAUS_CML, + "CML Data Logger", + }, + { + USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_WNC0600, + "WNC-0600USB", + }, + { + USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_UR045G, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_UR055G, + "UR055G", + }, + { + USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_O8494, + "ORiNOCO 802.11n", + }, + { + USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_AR5523_1, + "AR5523", + }, + { + USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_AR5523_1_NF, + "AR5523", + }, + { + USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_AR5523_2_NF, + "AR5523", + }, + { + USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_AR5523_2, + "AR5523", + }, + { + USB_VENDOR_WMR, USB_PRODUCT_WMR_RIGBLASTER, + "RIGblaster", + }, + { + USB_VENDOR_XIAOMI, USB_PRODUCT_XIAOMI_MT7601U, + "MT7601U", + }, + { + USB_VENDOR_XIRING, USB_PRODUCT_XIRING_XIMAX, + "Ximax CDC", + }, + { + USB_VENDOR_XIRLINK, USB_PRODUCT_XIRLINK_IMAGING, + "Imaging Device", + }, + { + USB_VENDOR_XIRLINK, USB_PRODUCT_XIRLINK_PCCAM, + "IBM PC Camera", + }, + { + USB_VENDOR_XYRATEX, USB_PRODUCT_XYRATEX_PRISM_GT_1, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_XYRATEX, USB_PRODUCT_XYRATEX_PRISM_GT_2, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_YAMAHA, USB_PRODUCT_YAMAHA_UX256, + "UX256 MIDI I/F", + }, + { + USB_VENDOR_YAMAHA, USB_PRODUCT_YAMAHA_UX96, + "UX96 MIDI I/F", + }, + { + USB_VENDOR_YAMAHA, USB_PRODUCT_YAMAHA_UR22, + "UR22", + }, + { + USB_VENDOR_YAMAHA, USB_PRODUCT_YAMAHA_RPU200, + "RP-U200", + }, + { + USB_VENDOR_YAMAHA, USB_PRODUCT_YAMAHA_RTA54I, + "NetVolante RTA54i", + }, + { + USB_VENDOR_YAMAHA, USB_PRODUCT_YAMAHA_RTW65B, + "NetVolante RTW65b", + }, + { + USB_VENDOR_YAMAHA, USB_PRODUCT_YAMAHA_RTW65I, + "NetVolante RTW65i", + }, + { + USB_VENDOR_YAMAHA, USB_PRODUCT_YAMAHA_RTA55I, + "NetVolante RTA55i", + }, + { + USB_VENDOR_YANO, USB_PRODUCT_YANO_U640MO, + "U640MO-03", + }, + { + USB_VENDOR_YCCABLE, USB_PRODUCT_YCCABLE_PL2303, + "PL2303 Serial", + }, + { + USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU, + "Flashbuster-U", + }, + { + USB_VENDOR_YUBICO, USB_PRODUCT_YUBICO_YUBIKEY, + "Yubikey", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_M4Y750, + "M4Y-750", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_XI725, + "XI-725/726", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_XI735, + "XI-735", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_MD40900, + "MD40900", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_XG703A, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_ZD1211, + "ZD1211", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_AR5523, + "AR5523", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_AR5523_NF, + "AR5523", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_ZD1211B, + "ZD1211B", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_UB81, + "UB81", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_UB82, + "UB82", + }, + { + USB_VENDOR_ZINWELL, USB_PRODUCT_ZINWELL_RT2570, + "RT2570", + }, + { + USB_VENDOR_ZINWELL, USB_PRODUCT_ZINWELL_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_ZINWELL, USB_PRODUCT_ZINWELL_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_ZINWELL, USB_PRODUCT_ZINWELL_RT3072_1, + "RT3072", + }, + { + USB_VENDOR_ZINWELL, USB_PRODUCT_ZINWELL_RT3072_2, + "RT3072", + }, + { + USB_VENDOR_ZINWELL, USB_PRODUCT_ZINWELL_RT3070, + "RT3070", + }, + { + USB_VENDOR_ZOOM, USB_PRODUCT_ZOOM_2986L, + "2986L Fax Modem", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_CDMA_MSM, + "CDMA Technologies MSM modem", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_MF633, + "ZTE MF633 USUPA USB modem", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_MF637, + "ZTE MF637 HSUPA USB modem", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_K3565Z, + "ZTE K3565-Z USB MSM modem", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_UMASS_INSTALLER4, + "ZTE USB MSM installer", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_MSA110UP, + "ONDA MSA110UP USB MSM modem", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_UMASS_INSTALLER2, + "ZTE USB MSM installer", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_MF112, + "ZTE MF112 HSUPA USB modem", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_HSUSB, + "ZTE HSUSB", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_UMASS_INSTALLER, + "ZTE USB MSM installer", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_AC2746, + "AC2746 CDMA USB modem", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_UMASS_INSTALLER3, + "ZTE USB CDMA installer", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_AC8700, + "AC8700 CDMA USB modem", + }, + { + USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ZD1201, + "ZD1201", + }, + { + USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ZD1211, + "ZD1211", + }, + { + USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ZD1211B, + "ZD1211B", + }, + { + USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ZD1221, + "ZD1221", + }, + { + USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ALL0298, + "ALL0298", + }, + { + USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ZD1211B_2, + "ZD1211B", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_OMNI56K, + "Omni 56K Plus", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_980N, + "Scorpion-980N", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_G220, + "G-220", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_G220F, + "G-220F", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_G200V2, + "G-200 v2", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_AG225H, + "AG-225H", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_M202, + "M-202", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_G270S, + "G-270S", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_G220V2, + "G-220 v2", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_G202, + "G-202", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_AG220, + "AG-220", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_AG225HV2, + "AG-225H v2", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RT2573, + "RT2573", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_NWD271N, + "NWD-271N", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_NWD211AN, + "NWD-211AN", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_NWD2105, + "NWD2105", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RT3070, + "RT3070", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_PRESTIGE, + "Prestige", + }, + { 0, 0, NULL } +}; + +const struct usb_known_vendor usb_known_vendors[] = { + { + USB_VENDOR_PLANEX4, + "Planex Communications", + }, + { + USB_VENDOR_UNKNOWN2, + "Unknown vendor", + }, + { + USB_VENDOR_EGALAX2, + "eGalax", + }, + { + USB_VENDOR_UNKNOWN6, + "Unknown vendor", + }, + { + USB_VENDOR_HUMAX, + "HUMAX", + }, + { + USB_VENDOR_BWCT, + "Bernd Walter Computer Technology", + }, + { + USB_VENDOR_AOX, + "AOX", + }, + { + USB_VENDOR_ATMEL, + "Atmel", + }, + { + USB_VENDOR_MITSUMI, + "Mitsumi", + }, + { + USB_VENDOR_HP, + "Hewlett Packard", + }, + { + USB_VENDOR_ADAPTEC, + "Adaptec", + }, + { + USB_VENDOR_NATIONAL, + "National Semiconductor", + }, + { + USB_VENDOR_ACERLABS, + "Acer Labs", + }, + { + USB_VENDOR_FTDI, + "Future Technology Devices", + }, + { + USB_VENDOR_QUANTA2, + "Quanta", + }, + { + USB_VENDOR_NEC, + "NEC", + }, + { + USB_VENDOR_KODAK, + "Eastman Kodak", + }, + { + USB_VENDOR_VIA, + "VIA", + }, + { + USB_VENDOR_MELCO, + "Melco", + }, + { + USB_VENDOR_LEADTEK, + "Leadtek", + }, + { + USB_VENDOR_CREATIVE, + "Creative Labs", + }, + { + USB_VENDOR_NOKIA2, + "Nokia", + }, + { + USB_VENDOR_ADI, + "ADI Systems", + }, + { + USB_VENDOR_CATC, + "Computer Access Technology", + }, + { + USB_VENDOR_SMC2, + "Standard Microsystems", + }, + { + USB_VENDOR_GRAVIS, + "Advanced Gravis Computer", + }, + { + USB_VENDOR_FUJITSUCOMP, + "Fujitsu Component", + }, + { + USB_VENDOR_TAUGA, + "Taugagreining HF", + }, + { + USB_VENDOR_AMD, + "Advanced Micro Devices", + }, + { + USB_VENDOR_LEXMARK, + "Lexmark International", + }, + { + USB_VENDOR_NANAO, + "NANAO", + }, + { + USB_VENDOR_ALPS, + "Alps Electric", + }, + { + USB_VENDOR_THRUST, + "Thrustmaster", + }, + { + USB_VENDOR_TI, + "Texas Instruments", + }, + { + USB_VENDOR_ANALOGDEVICES, + "Analog Devices", + }, + { + USB_VENDOR_SIS, + "Silicon Integrated Systems Corp.", + }, + { + USB_VENDOR_KYE, + "KYE Systems", + }, + { + USB_VENDOR_DIAMOND2, + "Diamond (Supra)", + }, + { + USB_VENDOR_RENESAS, + "Renesas", + }, + { + USB_VENDOR_MICROSOFT, + "Microsoft", + }, + { + USB_VENDOR_PRIMAX, + "Primax Electronics", + }, + { + USB_VENDOR_MGE, + "Eaton (MGE)", + }, + { + USB_VENDOR_AMP, + "AMP", + }, + { + USB_VENDOR_CHERRY, + "Cherry Mikroschalter", + }, + { + USB_VENDOR_MEGATRENDS, + "American Megatrends", + }, + { + USB_VENDOR_LOGITECH, + "Logitech", + }, + { + USB_VENDOR_BTC, + "Behavior Tech. Computer", + }, + { + USB_VENDOR_PHILIPS, + "Philips", + }, + { + USB_VENDOR_SANYO, + "Sanyo Electric", + }, + { + USB_VENDOR_CONNECTIX, + "Connectix", + }, + { + USB_VENDOR_DELL2, + "Dell", + }, + { + USB_VENDOR_KENSINGTON, + "Kensington", + }, + { + USB_VENDOR_LUCENT, + "Lucent", + }, + { + USB_VENDOR_PLANTRONICS, + "Plantronics", + }, + { + USB_VENDOR_KYOCERA, + "Kyocera", + }, + { + USB_VENDOR_STMICRO, + "STMicroelectronics", + }, + { + USB_VENDOR_FOXCONN, + "Foxconn", + }, + { + USB_VENDOR_YAMAHA, + "YAMAHA", + }, + { + USB_VENDOR_COMPAQ, + "Compaq", + }, + { + USB_VENDOR_HITACHI, + "Hitachi", + }, + { + USB_VENDOR_ACERP, + "Acer Peripherals", + }, + { + USB_VENDOR_DAVICOM, + "Davicom", + }, + { + USB_VENDOR_VISIONEER, + "Visioneer", + }, + { + USB_VENDOR_CANON, + "Canon", + }, + { + USB_VENDOR_NIKON, + "Nikon", + }, + { + USB_VENDOR_IBM, + "IBM", + }, + { + USB_VENDOR_CYPRESS, + "Cypress Semiconductor", + }, + { + USB_VENDOR_EPSON, + "Seiko Epson", + }, + { + USB_VENDOR_RAINBOW, + "Rainbow Technologies", + }, + { + USB_VENDOR_IODATA, + "I/O Data", + }, + { + USB_VENDOR_TDK, + "TDK", + }, + { + USB_VENDOR_3COMUSR, + "U.S. Robotics", + }, + { + USB_VENDOR_METHODE, + "Methode Electronics Far East", + }, + { + USB_VENDOR_MAXISWITCH, + "Maxi Switch", + }, + { + USB_VENDOR_LOCKHEEDMER, + "Lockheed Martin Energy Research", + }, + { + USB_VENDOR_FUJITSU, + "Fujitsu", + }, + { + USB_VENDOR_TOSHIBAAM, + "Toshiba America", + }, + { + USB_VENDOR_MICROMACRO, + "Micro Macro Technologies", + }, + { + USB_VENDOR_KONICA, + "Konica", + }, + { + USB_VENDOR_LITEON, + "Lite-On Technology", + }, + { + USB_VENDOR_FUJIPHOTO, + "Fuji Photo Film", + }, + { + USB_VENDOR_PHILIPSSEMI, + "Philips Semiconductors", + }, + { + USB_VENDOR_TATUNG, + "Tatung Co. Of America", + }, + { + USB_VENDOR_SCANLOGIC, + "ScanLogic", + }, + { + USB_VENDOR_MYSON, + "Myson Technology", + }, + { + USB_VENDOR_DIGI2, + "Digi", + }, + { + USB_VENDOR_ITTCANON, + "ITT Canon", + }, + { + USB_VENDOR_ALTEC, + "Altec Lansing", + }, + { + USB_VENDOR_MICROCHIP, + "Microchip Technology, Inc.", + }, + { + USB_VENDOR_HOLTEK, + "Holtek", + }, + { + USB_VENDOR_PANASONIC, + "Panasonic (Matsushita)", + }, + { + USB_VENDOR_SHARP, + "Sharp", + }, + { + USB_VENDOR_IIYAMA, + "Iiyama", + }, + { + USB_VENDOR_EXAR, + "Exar", + }, + { + USB_VENDOR_SHUTTLE, + "Shuttle Technology", + }, + { + USB_VENDOR_SAMSUNG2, + "Samsung Electronics", + }, + { + USB_VENDOR_ANNABOOKS, + "Annabooks", + }, + { + USB_VENDOR_JVC, + "JVC", + }, + { + USB_VENDOR_CHICONY, + "Chicony Electronics", + }, + { + USB_VENDOR_ELAN, + "Elan", + }, + { + USB_VENDOR_BROTHER, + "Brother Industries", + }, + { + USB_VENDOR_DALLAS, + "Dallas Semiconductor", + }, + { + USB_VENDOR_ACER, + "Acer", + }, + { + USB_VENDOR_3COM, + "3Com", + }, + { + USB_VENDOR_AZTECH, + "Aztech Systems", + }, + { + USB_VENDOR_BELKIN, + "Belkin Components", + }, + { + USB_VENDOR_KAWATSU, + "Kawatsu Semiconductor", + }, + { + USB_VENDOR_APC, + "American Power Conversion", + }, + { + USB_VENDOR_CONNECTEK, + "Advanced Connectek USA", + }, + { + USB_VENDOR_NETCHIP, + "NetChip Technology", + }, + { + USB_VENDOR_ALTRA, + "ALTRA", + }, + { + USB_VENDOR_ATI, + "ATI Technologies", + }, + { + USB_VENDOR_AKS, + "Aladdin Knowledge Systems", + }, + { + USB_VENDOR_UNIACCESS, + "Universal Access", + }, + { + USB_VENDOR_VIEWSONIC, + "ViewSonic", + }, + { + USB_VENDOR_XIRLINK, + "Xirlink", + }, + { + USB_VENDOR_ANCHOR, + "Anchor Chips", + }, + { + USB_VENDOR_SONY, + "Sony", + }, + { + USB_VENDOR_VISION, + "VLSI Vision", + }, + { + USB_VENDOR_ASAHIKASEI, + "Asahi Kasei Microsystems", + }, + { + USB_VENDOR_ATEN, + "ATEN International", + }, + { + USB_VENDOR_SAMSUNG, + "Samsung", + }, + { + USB_VENDOR_MUSTEK, + "Mustek Systems", + }, + { + USB_VENDOR_TELEX, + "Telex Communications", + }, + { + USB_VENDOR_PERACOM, + "Peracom Networks", + }, + { + USB_VENDOR_ALCOR2, + "Alcor Micro", + }, + { + USB_VENDOR_WACOM, + "WACOM", + }, + { + USB_VENDOR_ETEK, + "e-TEK Labs", + }, + { + USB_VENDOR_EIZO, + "EIZO", + }, + { + USB_VENDOR_ELECOM, + "Elecom", + }, + { + USB_VENDOR_XYRATEX, + "Xyratex", + }, + { + USB_VENDOR_HAUPPAUGE, + "Hauppauge Computer Works", + }, + { + USB_VENDOR_BAFO, + "BAFO/Quality Computer Accessories", + }, + { + USB_VENDOR_YEDATA, + "Y-E Data", + }, + { + USB_VENDOR_AVM, + "AVM", + }, + { + USB_VENDOR_QUICKSHOT, + "Quickshot", + }, + { + USB_VENDOR_ROLAND, + "Roland", + }, + { + USB_VENDOR_ROCKFIRE, + "Rockfire", + }, + { + USB_VENDOR_RATOC, + "RATOC Systems", + }, + { + USB_VENDOR_ZYXEL, + "ZyXEL Communication", + }, + { + USB_VENDOR_ALCOR, + "Alcor Micro", + }, + { + USB_VENDOR_OMRON, + "OMRON Corporation", + }, + { + USB_VENDOR_IOMEGA, + "Iomega", + }, + { + USB_VENDOR_ATREND, + "A-Trend Technology", + }, + { + USB_VENDOR_AID, + "Advanced Input Devices", + }, + { + USB_VENDOR_LACIE, + "LaCie", + }, + { + USB_VENDOR_THRUSTMASTER, + "Thrustmaster", + }, + { + USB_VENDOR_CISCOLINKSYS3, + "Cisco-Linksys", + }, + { + USB_VENDOR_OMNIVISION, + "OmniVision", + }, + { + USB_VENDOR_INSYSTEM, + "In-System Design", + }, + { + USB_VENDOR_APPLE, + "Apple Computer", + }, + { + USB_VENDOR_YCCABLE, + "Y.C. Cable", + }, + { + USB_VENDOR_JINGMOLD, + "Jing Mold", + }, + { + USB_VENDOR_DIGI, + "Digi International", + }, + { + USB_VENDOR_QUALCOMM, + "Qualcomm", + }, + { + USB_VENDOR_QTRONIX, + "Qtronix", + }, + { + USB_VENDOR_RICOH, + "Ricoh", + }, + { + USB_VENDOR_ELSA, + "ELSA", + }, + { + USB_VENDOR_BRAINBOXES, + "Brainboxes", + }, + { + USB_VENDOR_ULTIMA, + "Ultima", + }, + { + USB_VENDOR_AXIOHM, + "Axiohm Transaction Solutions", + }, + { + USB_VENDOR_MICROTEK, + "Microtek", + }, + { + USB_VENDOR_SUNTAC, + "SUN Corporation", + }, + { + USB_VENDOR_LEXAR, + "Lexar Media", + }, + { + USB_VENDOR_ADDTRON, + "Addtron", + }, + { + USB_VENDOR_SYMBOL, + "Symbol Technologies", + }, + { + USB_VENDOR_GENESYS, + "Genesys Logic", + }, + { + USB_VENDOR_FUJI, + "Fuji Electric", + }, + { + USB_VENDOR_KEITHLEY, + "Keithley Instruments", + }, + { + USB_VENDOR_EIZONANAO, + "EIZO Nanao", + }, + { + USB_VENDOR_KLSI, + "Kawasaki LSI", + }, + { + USB_VENDOR_FFC, + "FFC", + }, + { + USB_VENDOR_ANKO, + "Anko Electronic", + }, + { + USB_VENDOR_PIENGINEERING, + "P.I. Engineering", + }, + { + USB_VENDOR_AOC, + "AOC International", + }, + { + USB_VENDOR_CHIC, + "Chic Technology", + }, + { + USB_VENDOR_BARCO, + "Barco Display Systems", + }, + { + USB_VENDOR_BRIDGE, + "Bridge Information", + }, + { + USB_VENDOR_SOLIDYEAR, + "Solid Year", + }, + { + USB_VENDOR_BIORAD, + "Bio-Rad Laboratories", + }, + { + USB_VENDOR_MACALLY, + "Macally", + }, + { + USB_VENDOR_ACTLABS, + "Act Labs", + }, + { + USB_VENDOR_ALARIS, + "Alaris", + }, + { + USB_VENDOR_APEX, + "Apex", + }, + { + USB_VENDOR_VIVITAR, + "Vivitar", + }, + { + USB_VENDOR_GUNZE, + "Gunze Electronics USA", + }, + { + USB_VENDOR_AVISION, + "Avision", + }, + { + USB_VENDOR_TEAC, + "TEAC", + }, + { + USB_VENDOR_SGI, + "Silicon Graphics", + }, + { + USB_VENDOR_SANWASUPPLY, + "Sanwa Supply", + }, + { + USB_VENDOR_MUSTEK2, + "Mustek Systems", + }, + { + USB_VENDOR_LINKSYS, + "Linksys", + }, + { + USB_VENDOR_ACERSA, + "Acer Semiconductor America", + }, + { + USB_VENDOR_SIGMATEL, + "Sigmatel", + }, + { + USB_VENDOR_DRAYTEK, + "DrayTek", + }, + { + USB_VENDOR_AIWA, + "Aiwa", + }, + { + USB_VENDOR_ACARD, + "ACARD Technology", + }, + { + USB_VENDOR_PROLIFIC, + "Prolific Technology", + }, + { + USB_VENDOR_SIEMENS, + "Siemens", + }, + { + USB_VENDOR_AVANCELOGIC, + "Avance Logic", + }, + { + USB_VENDOR_SIEMENS2, + "Siemens", + }, + { + USB_VENDOR_MINOLTA, + "Minolta", + }, + { + USB_VENDOR_CHPRODUCTS, + "CH Products", + }, + { + USB_VENDOR_HAGIWARA, + "Hagiwara Sys-Com", + }, + { + USB_VENDOR_CTX, + "Chuntex", + }, + { + USB_VENDOR_ASKEY, + "Askey Computer", + }, + { + USB_VENDOR_SAITEK, + "Saitek", + }, + { + USB_VENDOR_ALCATELT, + "Alcatel Telecom", + }, + { + USB_VENDOR_AGFA, + "AGFA-Gevaert", + }, + { + USB_VENDOR_ASIAMD, + "Asia Microelectronic Development", + }, + { + USB_VENDOR_PHIDGETS, + "Phidgets", + }, + { + USB_VENDOR_BIZLINK, + "Bizlink International", + }, + { + USB_VENDOR_KEYSPAN, + "Keyspan", + }, + { + USB_VENDOR_AASHIMA, + "Aashima Technology", + }, + { + USB_VENDOR_LIEBERT, + "Liebert", + }, + { + USB_VENDOR_MULTITECH, + "MultiTech", + }, + { + USB_VENDOR_ADS, + "ADS Technologies", + }, + { + USB_VENDOR_ALCATELM, + "Alcatel Microelectronics", + }, + { + USB_VENDOR_SIRIUS, + "Sirius Technologies", + }, + { + USB_VENDOR_GUILLEMOT, + "Guillemot", + }, + { + USB_VENDOR_BOSTON, + "Boston Acoustics", + }, + { + USB_VENDOR_SMC, + "Standard Microsystems", + }, + { + USB_VENDOR_PUTERCOM, + "Putercom", + }, + { + USB_VENDOR_MCT, + "MCT", + }, + { + USB_VENDOR_IMATION, + "Imation", + }, + { + USB_VENDOR_DOMAIN, + "Domain Technologies, Inc.", + }, + { + USB_VENDOR_SUSTEEN, + "Susteen", + }, + { + USB_VENDOR_EICON, + "Eicon Networks", + }, + { + USB_VENDOR_STOLLMANN, + "Stollmann", + }, + { + USB_VENDOR_SYNTECH, + "Syntech Information", + }, + { + USB_VENDOR_DIGITALSTREAM, + "Digital Stream", + }, + { + USB_VENDOR_AUREAL, + "Aureal Semiconductor", + }, + { + USB_VENDOR_IDOWELL, + "iDowell", + }, + { + USB_VENDOR_MIDIMAN, + "Midiman", + }, + { + USB_VENDOR_CYBERPOWER, + "CyberPower", + }, + { + USB_VENDOR_SURECOM, + "Surecom Technology", + }, + { + USB_VENDOR_LINKSYS2, + "Linksys", + }, + { + USB_VENDOR_GRIFFIN, + "Griffin Technology", + }, + { + USB_VENDOR_SANDISK, + "SanDisk", + }, + { + USB_VENDOR_JENOPTIK, + "Jenoptik", + }, + { + USB_VENDOR_LOGITEC, + "Logitec", + }, + { + USB_VENDOR_NOKIA, + "Nokia", + }, + { + USB_VENDOR_BRIMAX, + "Brimax", + }, + { + USB_VENDOR_AXIS, + "Axis Communications", + }, + { + USB_VENDOR_ABL, + "ABL Electronics", + }, + { + USB_VENDOR_SAGEM, + "Sagem", + }, + { + USB_VENDOR_SUNCOMM, + "Sun Communications", + }, + { + USB_VENDOR_ALFADATA, + "Alfadata Computer", + }, + { + USB_VENDOR_NATIONALTECH, + "National Technical Systems", + }, + { + USB_VENDOR_ONNTO, + "Onnto", + }, + { + USB_VENDOR_BE, + "Be", + }, + { + USB_VENDOR_ADMTEK, + "ADMtek", + }, + { + USB_VENDOR_COREGA, + "Corega", + }, + { + USB_VENDOR_FREECOM, + "Freecom", + }, + { + USB_VENDOR_MICROTECH, + "Microtech", + }, + { + USB_VENDOR_MOTOROLA3, + "Motorola", + }, + { + USB_VENDOR_OLYMPUS, + "Olympus", + }, + { + USB_VENDOR_ABOCOM, + "AboCom Systems", + }, + { + USB_VENDOR_KEISOKUGIKEN, + "Keisokugiken", + }, + { + USB_VENDOR_ONSPEC, + "OnSpec", + }, + { + USB_VENDOR_APG, + "APG Cash Drawer", + }, + { + USB_VENDOR_BUG, + "B.U.G.", + }, + { + USB_VENDOR_ALLIEDTELESYN, + "Allied Telesyn International", + }, + { + USB_VENDOR_AVERMEDIA, + "AVerMedia Technologies", + }, + { + USB_VENDOR_SIIG, + "SIIG", + }, + { + USB_VENDOR_CASIO, + "CASIO", + }, + { + USB_VENDOR_DLINK2, + "D-Link", + }, + { + USB_VENDOR_APTIO, + "Aptio Products", + }, + { + USB_VENDOR_ARASAN, + "Arasan Chip Systems", + }, + { + USB_VENDOR_ALLIEDCABLE, + "Allied Cable", + }, + { + USB_VENDOR_STSN, + "STSN", + }, + { + USB_VENDOR_BEWAN, + "Bewan", + }, + { + USB_VENDOR_ZOOM, + "Zoom Telephonics", + }, + { + USB_VENDOR_BROADLOGIC, + "BroadLogic", + }, + { + USB_VENDOR_HANDSPRING, + "Handspring", + }, + { + USB_VENDOR_PALM, + "Palm Computing", + }, + { + USB_VENDOR_SOURCENEXT, + "SOURCENEXT", + }, + { + USB_VENDOR_ACTIONSTAR, + "Action Star Enterprise", + }, + { + USB_VENDOR_ACCTON, + "Accton Technology", + }, + { + USB_VENDOR_DIAMOND, + "Diamond", + }, + { + USB_VENDOR_NETGEAR, + "BayNETGEAR", + }, + { + USB_VENDOR_TOPRE, + "Topre Corporation", + }, + { + USB_VENDOR_ACTIVEWIRE, + "ActiveWire", + }, + { + USB_VENDOR_BBELECTR, + "B&B Electronics", + }, + { + USB_VENDOR_PORTGEAR, + "PortGear", + }, + { + USB_VENDOR_NETGEAR2, + "Netgear", + }, + { + USB_VENDOR_SYSTEMTALKS, + "System Talks", + }, + { + USB_VENDOR_METRICOM, + "Metricom", + }, + { + USB_VENDOR_ADESSOKBTEK, + "ADESSO/Kbtek America", + }, + { + USB_VENDOR_JATON, + "Jaton", + }, + { + USB_VENDOR_APT, + "APT Technologies", + }, + { + USB_VENDOR_BOCARESEARCH, + "Boca Research", + }, + { + USB_VENDOR_ANDREA, + "Andrea Electronics", + }, + { + USB_VENDOR_BURRBROWN, + "Burr-Brown Japan", + }, + { + USB_VENDOR_2WIRE, + "2Wire", + }, + { + USB_VENDOR_AIPTEK, + "AIPTEK International", + }, + { + USB_VENDOR_SMARTBRIDGES, + "SmartBridges", + }, + { + USB_VENDOR_BILLIONTON, + "Billionton Systems", + }, + { + USB_VENDOR_GEMPLUS, + "GEMPLUS", + }, + { + USB_VENDOR_EXTENDED, + "Extended Systems", + }, + { + USB_VENDOR_MSYSTEMS, + "M-Systems", + }, + { + USB_VENDOR_DIGIANSWER, + "Digianswer", + }, + { + USB_VENDOR_AUTHENTEC, + "AuthenTec", + }, + { + USB_VENDOR_SIEMENS4, + "Siemens", + }, + { + USB_VENDOR_AUDIOTECHNICA, + "Audio-Technica", + }, + { + USB_VENDOR_TRUMPION, + "Trumpion Microelectronics", + }, + { + USB_VENDOR_ALATION, + "Alation Systems", + }, + { + USB_VENDOR_GLOBESPAN, + "Globespan", + }, + { + USB_VENDOR_CONCORDCAMERA, + "Concord Camera", + }, + { + USB_VENDOR_GARMIN, + "Garmin International", + }, + { + USB_VENDOR_GOHUBS, + "GoHubs", + }, + { + USB_VENDOR_BIOMETRIC, + "American Biometric Company", + }, + { + USB_VENDOR_TOSHIBA, + "Toshiba Corp", + }, + { + USB_VENDOR_INTREPIDCS, + "Intrepid", + }, + { + USB_VENDOR_YANO, + "Yano", + }, + { + USB_VENDOR_KINGSTON, + "Kingston Technology", + }, + { + USB_VENDOR_BLUEWATER, + "BlueWater Systems", + }, + { + USB_VENDOR_AGILENT, + "Agilent Technologies", + }, + { + USB_VENDOR_GUDE, + "Gude ADS", + }, + { + USB_VENDOR_PORTSMITH, + "Portsmith", + }, + { + USB_VENDOR_ACERW, + "Acer", + }, + { + USB_VENDOR_ADIRONDACK, + "Adirondack Wire & Cable", + }, + { + USB_VENDOR_BECKHOFF, + "Beckhoff", + }, + { + USB_VENDOR_MINDSATWORK, + "Minds At Work", + }, + { + USB_VENDOR_INTERSIL, + "Intersil", + }, + { + USB_VENDOR_ALTIUS, + "Altius Solutions", + }, + { + USB_VENDOR_ARRIS, + "Arris Interactive", + }, + { + USB_VENDOR_ACTIVCARD, + "ACTIVCARD", + }, + { + USB_VENDOR_ACTISYS, + "ACTiSYS", + }, + { + USB_VENDOR_NOVATEL1, + "Novatel", + }, + { + USB_VENDOR_AFOURTECH, + "A-FOUR TECH", + }, + { + USB_VENDOR_AIMEX, + "AIMEX", + }, + { + USB_VENDOR_ADDONICS, + "Addonics Technologies", + }, + { + USB_VENDOR_AKAI, + "AKAI professional M.I.", + }, + { + USB_VENDOR_ARESCOM, + "ARESCOM", + }, + { + USB_VENDOR_BAY, + "Bay Associates", + }, + { + USB_VENDOR_ALTERA, + "Altera", + }, + { + USB_VENDOR_CSR, + "Cambridge Silicon Radio", + }, + { + USB_VENDOR_TREK, + "Trek Technology", + }, + { + USB_VENDOR_ASAHIOPTICAL, + "Asahi Optical", + }, + { + USB_VENDOR_BOCASYSTEMS, + "Boca Systems", + }, + { + USB_VENDOR_SHANTOU, + "ShanTou", + }, + { + USB_VENDOR_HIROSE, + "Hirose", + }, + { + USB_VENDOR_BROADCOM, + "Broadcom", + }, + { + USB_VENDOR_GREENHOUSE, + "GREENHOUSE", + }, + { + USB_VENDOR_GEOCAST, + "Geocast Network Systems", + }, + { + USB_VENDOR_DREAMCHEEKY, + "Dream Cheeky", + }, + { + USB_VENDOR_IDQUANTIQUE, + "id Quantique", + }, + { + USB_VENDOR_IDTECH, + "ID TECH", + }, + { + USB_VENDOR_ZYDAS, + "ZyDAS Technology", + }, + { + USB_VENDOR_CHENSOURCE, + "Chen-Source", + }, + { + USB_VENDOR_NEODIO, + "Neodio", + }, + { + USB_VENDOR_OPTION, + "Option", + }, + { + USB_VENDOR_ASUS, + "ASUS", + }, + { + USB_VENDOR_TODOS, + "Todos Data System", + }, + { + USB_VENDOR_OCT, + "Omnidirectional Control Technology", + }, + { + USB_VENDOR_TEKRAM, + "Tekram Technology", + }, + { + USB_VENDOR_HAL, + "HAL Corporation", + }, + { + USB_VENDOR_NEC2, + "NEC", + }, + { + USB_VENDOR_ATI2, + "ATI", + }, + { + USB_VENDOR_KURUSUGAWA, + "Kurusugawa Electronics", + }, + { + USB_VENDOR_SMART, + "Smart Technologies", + }, + { + USB_VENDOR_ASIX, + "ASIX Electronics", + }, + { + USB_VENDOR_O2MICRO, + "O2 Micro", + }, + { + USB_VENDOR_SACOM, + "System SACOM Industry Co.,Ltd", + }, + { + USB_VENDOR_USR, + "U.S. Robotics", + }, + { + USB_VENDOR_AMBIT, + "Ambit Microsystems", + }, + { + USB_VENDOR_HTC, + "HTC", + }, + { + USB_VENDOR_REALTEK, + "Realtek", + }, + { + USB_VENDOR_MEI, + "MEI", + }, + { + USB_VENDOR_ADDONICS2, + "Addonics Technology", + }, + { + USB_VENDOR_FSC, + "Fujitsu Siemens Computers", + }, + { + USB_VENDOR_AGATE, + "Agate Technologies", + }, + { + USB_VENDOR_DMI, + "DMI", + }, + { + USB_VENDOR_ICOM, + "Icom", + }, + { + USB_VENDOR_GNOTOMETRICS, + "GN Otometrics", + }, + { + USB_VENDOR_MICRODIA, + "Microdia / Sonix Technology Co., Ltd.", + }, + { + USB_VENDOR_SEALEVEL, + "Sealevel System", + }, + { + USB_VENDOR_JETI, + "JETI", + }, + { + USB_VENDOR_EASYDISK, + "EasyDisk", + }, + { + USB_VENDOR_ELEKTOR, + "Elektor Electronics", + }, + { + USB_VENDOR_KYOCERA2, + "Kyocera", + }, + { + USB_VENDOR_TERRATEC, + "TerraTec Electronic GmbH", + }, + { + USB_VENDOR_ZCOM, + "Z-Com", + }, + { + USB_VENDOR_ATHEROS2, + "Atheros Communications", + }, + { + USB_VENDOR_POSIFLEX, + "Posiflex Technologies", + }, + { + USB_VENDOR_TANGTOP, + "Tangtop", + }, + { + USB_VENDOR_KOBIL, + "Kobil Systems", + }, + { + USB_VENDOR_SMC3, + "SMC", + }, + { + USB_VENDOR_PEN, + "Pen Drive", + }, + { + USB_VENDOR_ABC, + "ABC", + }, + { + USB_VENDOR_CONCEPTRONIC, + "Conceptronic", + }, + { + USB_VENDOR_MSI, + "Micro Star International", + }, + { + USB_VENDOR_ELCON, + "ELCON Systemtechnik", + }, + { + USB_VENDOR_UNKNOWN5, + "Unknown Vendor", + }, + { + USB_VENDOR_SITECOMEU, + "Sitecom Europe", + }, + { + USB_VENDOR_MOBILEACTION, + "Mobile Action", + }, + { + USB_VENDOR_AMIGO, + "Amigo Technology", + }, + { + USB_VENDOR_VMWARE, + "VMware", + }, + { + USB_VENDOR_SPEEDDRAGON, + "Speed Dragon Multimedia", + }, + { + USB_VENDOR_CTC, + "CONWISE Technology", + }, + { + USB_VENDOR_HAWKING, + "Hawking", + }, + { + USB_VENDOR_FOSSIL, + "Fossil", + }, + { + USB_VENDOR_GMATE, + "G.Mate", + }, + { + USB_VENDOR_MEDIATEK, + "MediaTek Inc.", + }, + { + USB_VENDOR_OTI, + "Ours Technology", + }, + { + USB_VENDOR_PILOTECH, + "Pilotech", + }, + { + USB_VENDOR_NOVATECH, + "Nova Tech", + }, + { + USB_VENDOR_ITEGNO, + "iTegno", + }, + { + USB_VENDOR_NORITAKE, + "Noritake itron Corp", + }, + { + USB_VENDOR_EGALAX, + "eGalax", + }, + { + USB_VENDOR_XIRING, + "XIRING", + }, + { + USB_VENDOR_AIRPRIME, + "Airprime", + }, + { + USB_VENDOR_VTECH, + "VTech", + }, + { + USB_VENDOR_FALCOM, + "Falcom Wireless Communications", + }, + { + USB_VENDOR_RIM, + "Research In Motion", + }, + { + USB_VENDOR_DYNASTREAM, + "Dynastream Innovations", + }, + { + USB_VENDOR_LARSENBRUSGAARD, + "Larsen and Brusgaard", + }, + { + USB_VENDOR_OREGONSCI, + "Oregon Scientific", + }, + { + USB_VENDOR_UNKNOWN4, + "Unknown Vendor", + }, + { + USB_VENDOR_DVICO, + "DViCO", + }, + { + USB_VENDOR_QUALCOMM2, + "Qualcomm", + }, + { + USB_VENDOR_MOTOROLA4, + "Motorola", + }, + { + USB_VENDOR_HP3, + "Hewlett Packard", + }, + { + USB_VENDOR_THURLBY, + "Thurlby Thandar Instruments", + }, + { + USB_VENDOR_GIGABYTE, + "GIGABYTE", + }, + { + USB_VENDOR_YUBICO, + "Yubico.com", + }, + { + USB_VENDOR_MOTOROLA, + "Motorola", + }, + { + USB_VENDOR_CCYU, + "CCYU Technology", + }, + { + USB_VENDOR_HYUNDAI, + "Hyundai", + }, + { + USB_VENDOR_GCTSEMICON, + "GCT Semiconductor", + }, + { + USB_VENDOR_SILABS2, + "Silicon Labs", + }, + { + USB_VENDOR_USI, + "USI", + }, + { + USB_VENDOR_LIEBERT2, + "Liebert", + }, + { + USB_VENDOR_PLX, + "PLX", + }, + { + USB_VENDOR_ASANTE, + "Asante", + }, + { + USB_VENDOR_SILABS, + "Silicon Labs", + }, + { + USB_VENDOR_SILABS3, + "Silicon Labs", + }, + { + USB_VENDOR_SILABS4, + "Silicon Labs", + }, + { + USB_VENDOR_VELLEMAN, + "Velleman", + }, + { + USB_VENDOR_MOXA, + "Moxa Technologies", + }, + { + USB_VENDOR_ANALOG, + "Analog Devices", + }, + { + USB_VENDOR_TENX, + "Ten X Technology, Inc.", + }, + { + USB_VENDOR_ISSC, + "Integrated System Solution Corp.", + }, + { + USB_VENDOR_JRC, + "Japan Radio Company", + }, + { + USB_VENDOR_SPHAIRON, + "Sphairon Access Systems", + }, + { + USB_VENDOR_DELORME, + "DeLorme", + }, + { + USB_VENDOR_SERVERWORKS, + "ServerWorks", + }, + { + USB_VENDOR_ACERCM, + "Acer Communications & Multimedia", + }, + { + USB_VENDOR_SIERRA, + "Sierra Wireless", + }, + { + USB_VENDOR_SIEMENS3, + "Siemens", + }, + { + USB_VENDOR_ALCATEL, + "Alcatel", + }, + { + USB_VENDOR_INTERBIO, + "InterBiometrics", + }, + { + USB_VENDOR_UNKNOWN3, + "Unknown vendor", + }, + { + USB_VENDOR_TSUNAMI, + "Tsunami", + }, + { + USB_VENDOR_PHEENET, + "Pheenet", + }, + { + USB_VENDOR_RAPTORGAMING, + "Raptor Gaming", + }, + { + USB_VENDOR_TWINMOS, + "TwinMOS", + }, + { + USB_VENDOR_TENDA, + "Tenda", + }, + { + USB_VENDOR_TESTO, + "Testo AG", + }, + { + USB_VENDOR_CREATIVE2, + "Creative Labs", + }, + { + USB_VENDOR_BELKIN2, + "Belkin Components", + }, + { + USB_VENDOR_CYBERTAN, + "CyberTAN Technology", + }, + { + USB_VENDOR_HUAWEI, + "HUAWEI Technologies", + }, + { + USB_VENDOR_ARANEUS, + "Araneus Information Systems", + }, + { + USB_VENDOR_TAPWAVE, + "Tapwave", + }, + { + USB_VENDOR_AINCOMM, + "Aincomm", + }, + { + USB_VENDOR_MOBILITY, + "Mobility", + }, + { + USB_VENDOR_DICKSMITH, + "Dick Smith Electronics", + }, + { + USB_VENDOR_NETGEAR3, + "Netgear", + }, + { + USB_VENDOR_VALIDITY, + "Validity Sensors", + }, + { + USB_VENDOR_BALTECH, + "Baltech", + }, + { + USB_VENDOR_CISCOLINKSYS, + "Cisco-Linksys", + }, + { + USB_VENDOR_SHARK, + "Shark", + }, + { + USB_VENDOR_AZUREWAVE, + "AsureWave", + }, + { + USB_VENDOR_NOVATEL, + "Novatel", + }, + { + USB_VENDOR_WISTRONNEWEB, + "Wistron NeWeb", + }, + { + USB_VENDOR_RADIOSHACK, + "Radio Shack", + }, + { + USB_VENDOR_OPENMOKO, + "OpenMoko", + }, + { + USB_VENDOR_HUAWEI3COM, + "Huawei 3Com", + }, + { + USB_VENDOR_ABOCOM2, + "AboCom Systems", + }, + { + USB_VENDOR_SILICOM, + "Silicom", + }, + { + USB_VENDOR_RALINK, + "Ralink Technology", + }, + { + USB_VENDOR_STARTECH, + "StarTech.com", + }, + { + USB_VENDOR_CONCEPTRONIC2, + "Conceptronic", + }, + { + USB_VENDOR_SUPERTOP, + "SuperTop", + }, + { + USB_VENDOR_PLANEX3, + "Planex Communications", + }, + { + USB_VENDOR_SILICONPORTALS, + "Silicon Portals", + }, + { + USB_VENDOR_UBLOX, + "U-blox", + }, + { + USB_VENDOR_OWEN, + "Owen", + }, + { + USB_VENDOR_OQO, + "OQO", + }, + { + USB_VENDOR_UMEDIA, + "U-MEDIA Communications", + }, + { + USB_VENDOR_FIBERLINE, + "Fiberline", + }, + { + USB_VENDOR_SPARKLAN, + "SparkLAN", + }, + { + USB_VENDOR_OLIMEX, + "Olimex", + }, + { + USB_VENDOR_AMIT2, + "AMIT", + }, + { + USB_VENDOR_TRUST, + "Trust", + }, + { + USB_VENDOR_SOHOWARE, + "SOHOware", + }, + { + USB_VENDOR_UMAX, + "UMAX Data Systems", + }, + { + USB_VENDOR_INSIDEOUT, + "Inside Out Networks", + }, + { + USB_VENDOR_GOODWAY, + "Good Way Technology", + }, + { + USB_VENDOR_ENTREGA, + "Entrega", + }, + { + USB_VENDOR_ACTIONTEC, + "Actiontec Electronics", + }, + { + USB_VENDOR_CLIPSAL, + "Clipsal", + }, + { + USB_VENDOR_CISCOLINKSYS2, + "Cisco-Linksys", + }, + { + USB_VENDOR_ATHEROS, + "Atheros Communications", + }, + { + USB_VENDOR_GIGASET, + "Gigaset", + }, + { + USB_VENDOR_GLOBALSUN, + "Global Sun Technology", + }, + { + USB_VENDOR_VOTI, + "Van Ooijen Technische Informatica", + }, + { + USB_VENDOR_ANYDATA, + "AnyDATA Inc.", + }, + { + USB_VENDOR_JABLOTRON, + "Jablotron", + }, + { + USB_VENDOR_CMOTECH, + "CMOTECH", + }, + { + USB_VENDOR_WIENERPLEINBAUS, + "WIENER Plein & Baus", + }, + { + USB_VENDOR_AXESSTEL, + "Axesstel", + }, + { + USB_VENDOR_LINKSYS4, + "Linksys", + }, + { + USB_VENDOR_SENAO, + "Senao", + }, + { + USB_VENDOR_ASUS2, + "ASUS", + }, + { + USB_VENDOR_STRAWBERRYLINUX, + "Strawberry linux Co., Ltd.", + }, + { + USB_VENDOR_SWEEX2, + "Sweex", + }, + { + USB_VENDOR_MECANIQUE, + "Mecanique", + }, + { + USB_VENDOR_KAMSTRUP, + "Kamstrup A/S", + }, + { + USB_VENDOR_DISPLAYLINK, + "DisplayLink", + }, + { + USB_VENDOR_LENOVO, + "Lenovo", + }, + { + USB_VENDOR_WAVESENSE, + "WaveSense", + }, + { + USB_VENDOR_VAISALA, + "VAISALA", + }, + { + USB_VENDOR_AMIT, + "AMIT", + }, + { + USB_VENDOR_GOOGLE, + "Google", + }, + { + USB_VENDOR_QCOM, + "Qcom", + }, + { + USB_VENDOR_ELV, + "ELV", + }, + { + USB_VENDOR_LINKSYS3, + "Linksys", + }, + { + USB_VENDOR_AVAGO, + "Avago", + }, + { + USB_VENDOR_MEINBERG, + "Meinberg Funkuhren", + }, + { + USB_VENDOR_ZTE, + "ZTE Inc.", + }, + { + USB_VENDOR_QUANTA, + "Quanta", + }, + { + USB_VENDOR_TERMINUS, + "Terminus Technology", + }, + { + USB_VENDOR_ABBOTT, + "Abbott Labs", + }, + { + USB_VENDOR_BAYER, + "Bayer Health Care", + }, + { + USB_VENDOR_WCH2, + "QinHeng Electronics", + }, + { + USB_VENDOR_SEL, + "Schweitzer Engineering Laboratories", + }, + { + USB_VENDOR_CORSAIR, + "Corsair", + }, + { + USB_VENDOR_MATRIXORB, + "Matrix Orbital", + }, + { + USB_VENDOR_TORADEX, + "Toradex inc.", + }, + { + USB_VENDOR_FUSHICAI, + "Fushicai", + }, + { + USB_VENDOR_OVISLINK, + "OvisLink", + }, + { + USB_VENDOR_TML, + "The Mobility Lab", + }, + { + USB_VENDOR_SILABS5, + "Silicon Labs", + }, + { + USB_VENDOR_TCTMOBILE, + "TCT Mobile", + }, + { + USB_VENDOR_MDS, + "MDS", + }, + { + USB_VENDOR_ALTI2, + "Alti-2", + }, + { + USB_VENDOR_SUNPLUS, + "Sunplus", + }, + { + USB_VENDOR_WAGO, + "WAGO Kontakttechnik", + }, + { + USB_VENDOR_LONGCHEER, + "Longcheer Technology", + }, + { + USB_VENDOR_DRESDENELEC, + "Dresden Elektronic", + }, + { + USB_VENDOR_DREAMLINK, + "Dream Link", + }, + { + USB_VENDOR_PEGATRON, + "Pegatron", + }, + { + USB_VENDOR_OPENMOKO2, + "OpenMoko", + }, + { + USB_VENDOR_SELUXIT, + "Seluxit", + }, + { + USB_VENDOR_METAGEEK, + "MetaGeek", + }, + { + USB_VENDOR_SIMCOM, + "SIMCom Wireless Solutions Co., Ltd.", + }, + { + USB_VENDOR_FESTO, + "Festo", + }, + { + USB_VENDOR_MODACOM, + "Modacom", + }, + { + USB_VENDOR_AIRTIES, + "AirTies", + }, + { + USB_VENDOR_LAKESHORE, + "Lake Shore", + }, + { + USB_VENDOR_VERTEX, + "Vertex Wireless Co., Ltd.", + }, + { + USB_VENDOR_DLINK, + "D-Link", + }, + { + USB_VENDOR_PLANEX2, + "Planex Communications", + }, + { + USB_VENDOR_ENCORE, + "Encore", + }, + { + USB_VENDOR_PARA, + "PARA Industrial", + }, + { + USB_VENDOR_TRENDNET, + "TRENDnet", + }, + { + USB_VENDOR_RTSYSTEMS, + "RT Systems", + }, + { + USB_VENDOR_DLINK3, + "D-Link", + }, + { + USB_VENDOR_VIALABS, + "VIA Labs", + }, + { + USB_VENDOR_MOTOROLA2, + "Motorola", + }, + { + USB_VENDOR_ARDUINO, + "Arduino SA", + }, + { + USB_VENDOR_TPLINK, + "TP-Link", + }, + { + USB_VENDOR_WMR, + "West Mountain Radio", + }, + { + USB_VENDOR_TRIPPLITE, + "Tripp-Lite", + }, + { + USB_VENDOR_ARUBA, + "Aruba", + }, + { + USB_VENDOR_XIAOMI, + "Xiaomi", + }, + { + USB_VENDOR_NHJ, + "NHJ", + }, + { + USB_VENDOR_ASUSTEK, + "ASUSTeK Computer", + }, + { + USB_VENDOR_PLANEX, + "Planex Communications", + }, + { + USB_VENDOR_LINKINSTRUMENTS, + "Link Instruments", + }, + { + USB_VENDOR_AEI, + "AEI", + }, + { + USB_VENDOR_PQI, + "PQI", + }, + { + USB_VENDOR_DAISY, + "Daisy Technology", + }, + { + USB_VENDOR_NI, + "National Instruments", + }, + { + USB_VENDOR_MICRONET, + "Micronet Communications", + }, + { + USB_VENDOR_IODATA2, + "I-O Data", + }, + { + USB_VENDOR_IRIVER, + "iRiver", + }, + { + USB_VENDOR_DELL, + "Dell", + }, + { + USB_VENDOR_WCH, + "QinHeng Electronics", + }, + { + USB_VENDOR_ACEECA, + "Aceeca", + }, + { + USB_VENDOR_FEIXUN, + "FeiXun Communication", + }, + { + USB_VENDOR_NETWEEN, + "NetweeN", + }, + { + USB_VENDOR_PAPOUCH, + "Papouch s.r.o.", + }, + { + USB_VENDOR_AVERATEC, + "Averatec", + }, + { + USB_VENDOR_SWEEX, + "Sweex", + }, + { + USB_VENDOR_PROLIFIC2, + "Prolific Technology", + }, + { + USB_VENDOR_ONSPEC2, + "OnSpec", + }, + { + USB_VENDOR_ACERLABS2, + "Acer", + }, + { + USB_VENDOR_ZINWELL, + "Zinwell", + }, + { + USB_VENDOR_SITECOM, + "Sitecom", + }, + { + USB_VENDOR_ARKMICRO, + "Arkmicro", + }, + { + USB_VENDOR_3COM2, + "3Com", + }, + { + USB_VENDOR_EDIMAX, + "EDIMAX", + }, + { + USB_VENDOR_INTEL, + "Intel", + }, + { + USB_VENDOR_INTEL2, + "Intel", + }, + { + USB_VENDOR_ALLWIN, + "ALLWIN Tech", + }, + { + USB_VENDOR_SITECOM2, + "Sitecom", + }, + { + USB_VENDOR_MOSCHIP, + "MosChip", + }, + { + USB_VENDOR_NETGEAR4, + "Netgear", + }, + { + USB_VENDOR_MARVELL, + "Marvell", + }, + { + USB_VENDOR_3COM3, + "3Com", + }, + { + USB_VENDOR_CACE, + "CACE Technologies", + }, + { + USB_VENDOR_COMPARE, + "Compare", + }, + { + USB_VENDOR_DATAAPEX, + "DataApex", + }, + { + USB_VENDOR_EVOLUTION, + "Evolution Robotics", + }, + { + USB_VENDOR_EMPIA, + "eMPIA Technology", + }, + { + USB_VENDOR_HP2, + "Hewlett Packard", + }, + { 0, NULL } +}; diff --git a/test/test010.right.txt b/test/test010.right.txt new file mode 100644 index 000000000000..46844afad663 --- /dev/null +++ b/test/test010.right.txt @@ -0,0 +1,14201 @@ +/* $OpenBSD$ */ + +/* + * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. + * + * generated from: + * OpenBSD: usbdevs,v 1.709 2020/01/20 07:08:20 jsg Exp + */ +/* $NetBSD: usbdevs,v 1.322 2003/05/10 17:47:14 hamajima Exp $ */ + +/* + * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Lennart Augustsson (lennart@augustsson.net) at + * Carlstedt Research & Technology. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Descriptions of known vendors and devices ("products"). + */ +struct usb_known_vendor { + u_int16_t vendor; + char *vendorname; +}; + +struct usb_known_product { + u_int16_t vendor; + u_int16_t product; + char *productname; +}; + +const struct usb_known_product usb_known_products[] = { + { + USB_VENDOR_3COM, USB_PRODUCT_3COM_HOMECONN, + "HomeConnect", + }, + { + USB_VENDOR_3COM, USB_PRODUCT_3COM_3CREB96, + "Bluetooth", + }, + { + USB_VENDOR_3COM, USB_PRODUCT_3COM_3C19250, + "3C19250 Ethernet", + }, + { + USB_VENDOR_3COM, USB_PRODUCT_3COM_3CRSHEW696, + "3CRSHEW696", + }, + { + USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460, + "HomeConnect 3C460", + }, + { + USB_VENDOR_3COM, USB_PRODUCT_3COM_USR56K, + "U.S.Robotics 56000", + }, + { + USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460B, + "HomeConnect 3C460B", + }, + { + USB_VENDOR_3COM2, USB_PRODUCT_3COM2_3CRUSB10075, + "3CRUSB10075", + }, + { + USB_VENDOR_3COM3, USB_PRODUCT_3COM3_AR5523_1, + "AR5523", + }, + { + USB_VENDOR_3COM3, USB_PRODUCT_3COM3_AR5523_2, + "AR5523", + }, + { + USB_VENDOR_3COM3, USB_PRODUCT_3COM3_AR5523_3, + "AR5523", + }, + { + USB_VENDOR_3COMUSR, USB_PRODUCT_3COMUSR_OFFICECONN, + "3Com OfficeConnect Analog Modem", + }, + { + USB_VENDOR_3COMUSR, USB_PRODUCT_3COMUSR_USRISDN, + "3Com U.S. Robotics Pro ISDN TA", + }, + { + USB_VENDOR_3COMUSR, USB_PRODUCT_3COMUSR_HOMECONN, + "3Com HomeConnect", + }, + { + USB_VENDOR_3COMUSR, USB_PRODUCT_3COMUSR_USR56K, + "U.S.Robotics 56000", + }, + { + USB_VENDOR_ABBOTT, USB_PRODUCT_ABBOTT_STEREO_PLUG, + "Stereo Plug Cable", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX1, + "XX1", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX2, + "XX2", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2770, + "RT2770", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2870, + "RT2870", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT3070, + "RT3070", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT3071, + "RT3071", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT3072, + "RT3072", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_URE450, + "URE450 Ethernet", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UFE1000, + "UFE1000 Fast Ethernet", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_DSB650TX_PNA, + "1/10/100 Ethernet", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX4, + "XX4", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX5, + "XX5", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX6, + "XX6", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX7, + "XX7", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_LCS8138TX, + "LCS-8138TX", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX8, + "XX8", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX9, + "XX9", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UF200, + "UF200 Ethernet", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_WL54, + "WL54", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8188EU, + "RTL8188EU", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8188CU_1, + "RTL8188CU", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8188CU_2, + "RTL8188CU", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX10, + "XX10", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_BWU613, + "BWU613", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_HWU54DM, + "HWU54DM", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_2, + "RT2573", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_3, + "RT2573", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_4, + "RT2573", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_WUG2700, + "WUG2700", + }, + { + USB_VENDOR_ABOCOM2, USB_PRODUCT_ABOCOM2_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_USB320_EC, + "USB320-EC Ethernet", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_2664W, + "2664W", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_111, + "T-Sinus 111 WLAN", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SMCWUSBG, + "SMCWUSB-G", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SMCWUSBTG2, + "SMCWUSBT-G2", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SMCWUSBTG2_NF, + "SMCWUSBT-G2", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_PRISM_GT, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SS1001, + "SpeedStream Ethernet", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070, + "RT3070", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT2770, + "RT2770", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT2870_3, + "RT2870", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT2870_5, + "RT2870", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_4, + "RT3070", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT2870_4, + "RT2870", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_1, + "RT3070", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_2, + "RT3070", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_6, + "RT3070", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_AR9280, + "AR9280+AR7010", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RTL8192SU, + "RTL8192SU", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_3, + "RT3070", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_5, + "RT3070", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_ZD1211B, + "ZD1211B", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_WN4501H_LF_IR, + "WN4501H-LF-IR", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_WUS201, + "WUS-201", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_WN7512, + "WN7512", + }, + { + USB_VENDOR_ACEECA, USB_PRODUCT_ACEECA_MEZ1000, + "MEZ1000 RDA", + }, + { + USB_VENDOR_ACERCM, USB_PRODUCT_ACERCM_EP1427X2, + "EP-1427X-2 Ethernet", + }, + { + USB_VENDOR_ACERLABS, USB_PRODUCT_ACERLABS_M5632, + "USB 2.0 Data Link", + }, + { + USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_C310U, + "Acerscan C310U", + }, + { + USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_320U, + "Acerscan 320U", + }, + { + USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_640U, + "Acerscan 640U", + }, + { + USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_620U, + "Acerscan 620U", + }, + { + USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ATAPI, + "ATA/ATAPI", + }, + { + USB_VENDOR_ACERP, USB_PRODUCT_ACERP_AWL300, + "AWL300", + }, + { + USB_VENDOR_ACERP, USB_PRODUCT_ACERP_AWL400, + "AWL400", + }, + { + USB_VENDOR_ACERW, USB_PRODUCT_ACERW_WARPLINK, + "Warplink", + }, + { + USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_PRISM_25, + "Prism2.5 WLAN", + }, + { + USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_PRISM_25A, + "Prism2.5 WLAN A", + }, + { + USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_AR9287, + "AR9287+AR7010", + }, + { + USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_FREELAN, + "ROPEX FreeLan 802.11b", + }, + { + USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_802UAT1, + "802UAT1", + }, + { + USB_VENDOR_ACTISYS, USB_PRODUCT_ACTISYS_IR2000U, + "ACT-IR2000U FIR", + }, + { + USB_VENDOR_ACTIVEWIRE, USB_PRODUCT_ACTIVEWIRE_IOBOARD, + "I/O Board", + }, + { + USB_VENDOR_ACTIVEWIRE, USB_PRODUCT_ACTIVEWIRE_IOBOARD_FW1, + "I/O Board, rev. 1", + }, + { + USB_VENDOR_ADAPTEC, USB_PRODUCT_ADAPTEC_AWN8020, + "AWN-8020 WLAN", + }, + { + USB_VENDOR_ADDONICS2, USB_PRODUCT_ADDONICS2_205, + "Cable 205", + }, + { + USB_VENDOR_ADDTRON, USB_PRODUCT_ADDTRON_AWU120, + "AWU-120", + }, + { + USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_4, + "AN986A Ethernet", + }, + { + USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUS, + "AN986 Ethernet", + }, + { + USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII, + "AN8511 Ethernet", + }, + { + USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_2, + "AN8513 Ethernet", + }, + { + USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_3, + "AN8515 Ethernet", + }, + { + USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BT, + "UBS-10BT Ethernet", + }, + { + USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BTX, + "UBS-10BT Ethernet", + }, + { + USB_VENDOR_AEI, USB_PRODUCT_AEI_FASTETHERNET, + "Fast Ethernet", + }, + { + USB_VENDOR_AGATE, USB_PRODUCT_AGATE_QDRIVE, + "Q-Drive", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1212U, + "SnapScan 1212U", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1236U, + "SnapScan 1236U", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANTOUCH, + "SnapScan Touch", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1212U2, + "SnapScan 1212U", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE40, + "SnapScan e40", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE50, + "SnapScan e50", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE20, + "SnapScan e20", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE25, + "SnapScan e25", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE26, + "SnapScan e26", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE52, + "SnapScan e52", + }, + { + USB_VENDOR_AINCOMM, USB_PRODUCT_AINCOMM_AWU2000B, + "AWU2000B", + }, + { + USB_VENDOR_AIRPRIME, USB_PRODUCT_AIRPRIME_PC5220, + "CDMA Wireless EVDO card", + }, + { + USB_VENDOR_AIRPRIME, USB_PRODUCT_AIRPRIME_AIRCARD_313U, + "Aircard 313U", + }, + { + USB_VENDOR_AIRTIES, USB_PRODUCT_AIRTIES_RT3070_2, + "RT3070", + }, + { + USB_VENDOR_AIRTIES, USB_PRODUCT_AIRTIES_RT3070, + "RT3070", + }, + { + USB_VENDOR_AKS, USB_PRODUCT_AKS_USBHASP, + "USB-HASP 0.06", + }, + { + USB_VENDOR_ALCATEL, USB_PRODUCT_ALCATEL_OT535, + "One Touch 535/735", + }, + { + USB_VENDOR_ALCATELT, USB_PRODUCT_ALCATELT_ST120G, + "SpeedTouch 120g", + }, + { + USB_VENDOR_ALCATELT, USB_PRODUCT_ALCATELT_ST121G, + "SpeedTouch 121g", + }, + { + USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_MA_KBD_HUB, + "MacAlly Kbd Hub", + }, + { + USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_AU9814, + "AU9814 Hub", + }, + { + USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_SM_KBD, + "MicroConnectors/StrongMan", + }, + { + USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_NEC_KBD_HUB, + "NEC Kbd Hub", + }, + { + USB_VENDOR_ALCOR2, USB_PRODUCT_ALCOR2_KBD_HUB, + "Kbd Hub", + }, + { + USB_VENDOR_ALLIEDTELESYN, USB_PRODUCT_ALLIEDTELESYN_ATUSB100, + "AT-USB100", + }, + { + USB_VENDOR_ALLWIN, USB_PRODUCT_ALLWIN_RT2070, + "RT2070", + }, + { + USB_VENDOR_ALLWIN, USB_PRODUCT_ALLWIN_RT2770, + "RT2770", + }, + { + USB_VENDOR_ALLWIN, USB_PRODUCT_ALLWIN_RT2870, + "RT2870", + }, + { + USB_VENDOR_ALLWIN, USB_PRODUCT_ALLWIN_RT3070, + "RT3070", + }, + { + USB_VENDOR_ALLWIN, USB_PRODUCT_ALLWIN_RT3071, + "RT3071", + }, + { + USB_VENDOR_ALLWIN, USB_PRODUCT_ALLWIN_RT3072, + "RT3072", + }, + { + USB_VENDOR_ALLWIN, USB_PRODUCT_ALLWIN_RT3572, + "RT3572", + }, + { + USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ADA70, + "ADA70 Speakers", + }, + { + USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ASC495, + "ASC495 Speakers", + }, + { + USB_VENDOR_ALTI2, USB_PRODUCT_ALTI2_NEPTUNE3, + "Neptune 3", + }, + { + USB_VENDOR_AMBIT, USB_PRODUCT_AMBIT_WLAN, + "WLAN", + }, + { + USB_VENDOR_AMBIT, USB_PRODUCT_AMBIT_NTL_250, + "NTL 250 cable modem", + }, + { + USB_VENDOR_AMIGO, USB_PRODUCT_AMIGO_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_AMIGO, USB_PRODUCT_AMIGO_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_AMIT, USB_PRODUCT_AMIT_CGWLUSB2GO, + "CG-WLUSB2GO", + }, + { + USB_VENDOR_AMIT, USB_PRODUCT_AMIT_CGWLUSB2GNR, + "CG-WLUSB2GNR", + }, + { + USB_VENDOR_AMIT, USB_PRODUCT_AMIT_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_AMIT2, USB_PRODUCT_AMIT2_RT2870, + "RT2870", + }, + { + USB_VENDOR_ANALOG, USB_PRODUCT_ANALOG_EAGLEI, + "Eagle I", + }, + { + USB_VENDOR_ANALOG, USB_PRODUCT_ANALOG_EAGLEI_NF, + "Eagle I", + }, + { + USB_VENDOR_ANALOG, USB_PRODUCT_ANALOG_EAGLEII, + "Eagle II", + }, + { + USB_VENDOR_ANALOG, USB_PRODUCT_ANALOG_EAGLEII_NF, + "Eagle II", + }, + { + USB_VENDOR_ANALOG, USB_PRODUCT_ANALOG_EAGLEIIC, + "Eagle IIC", + }, + { + USB_VENDOR_ANALOG, USB_PRODUCT_ANALOG_EAGLEIIC_NF, + "Eagle IIC", + }, + { + USB_VENDOR_ANALOG, USB_PRODUCT_ANALOG_EAGLEIII, + "Eagle III", + }, + { + USB_VENDOR_ANALOG, USB_PRODUCT_ANALOG_EAGLEIII_NF, + "Eagle III", + }, + { + USB_VENDOR_ANALOGDEVICES, USB_PRODUCT_ANALOGDEVICES_GNICE, + "gnICE", + }, + { + USB_VENDOR_ANALOGDEVICES, USB_PRODUCT_ANALOGDEVICES_GNICEPLUS, + "gnICE+", + }, + { + USB_VENDOR_ANCHOR, USB_PRODUCT_ANCHOR_SERIAL, + "Serial", + }, + { + USB_VENDOR_ANCHOR, USB_PRODUCT_ANCHOR_EZUSB, + "EZUSB", + }, + { + USB_VENDOR_ANCHOR, USB_PRODUCT_ANCHOR_EZLINK, + "EZLINK", + }, + { + USB_VENDOR_ANYDATA, USB_PRODUCT_ANYDATA_A2502, + "NTT DoCoMo A2502", + }, + { + USB_VENDOR_ANYDATA, USB_PRODUCT_ANYDATA_ADU_E100H, + "ADU-E100H", + }, + { + USB_VENDOR_ANYDATA, USB_PRODUCT_ANYDATA_ADU_500A, + "ADU-500A", + }, + { + USB_VENDOR_AOX, USB_PRODUCT_AOX_USB101, + "Ethernet", + }, + { + USB_VENDOR_APC, USB_PRODUCT_APC_UPS, + "UPS", + }, + { + USB_VENDOR_APC, USB_PRODUCT_APC_UPS5G, + "5G UPS", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_FOUNTAIN_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_FOUNTAIN_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_GEYSER_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_GEYSER_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING2_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING2_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING2_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING3_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING3_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING3_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4A_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4A_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4A_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6A_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6A_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6A_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5A_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5A_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5A_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7A_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7A_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7A_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING9_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING9_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING9_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING8_ANSI, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING8_ISO, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING8_JIS, + "Keyboard/Trackpad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_OPTMOUSE, + "Optical mouse", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_BLUETOOTH_HCI, + "HID-proxy", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_SPEAKERS, + "Speakers", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE, + "iPhone", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPOD_TOUCH, + "iPod Touch", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_3G, + "iPhone 3G", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPOD_TOUCH_2G, + "iPod Touch 2G", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_3GS, + "iPhone 3GS", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_4_GSM, + "iPhone 4 GSM", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPOD_TOUCH_3G, + "iPod Touch 3G", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPAD, + "iPad", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_4_CDMA, + "iPhone 4 CDMA", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPOD_TOUCH_4G, + "iPod Touch 4G", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPAD2, + "iPad 2", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_4S, + "iPhone 4S", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_6, + "iPhone 6", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_ETHERNET, + "Ethernet A1277", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_BLUETOOTH2, + "Bluetooth", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_BLUETOOTH, + "Bluetooth", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_ISIGHT_1, + "iSight", + }, + { + USB_VENDOR_APPLE, USB_PRODUCT_APPLE_ISIGHT, + "iSight", + }, + { + USB_VENDOR_ARANEUS, USB_PRODUCT_ARANEUS_ALEA, + "True Random Number Generator", + }, + { + USB_VENDOR_ARDUINO, USB_PRODUCT_ARDUINO_LEONARDO, + "Leonardo", + }, + { + USB_VENDOR_ARKMICRO, USB_PRODUCT_ARKMICRO_ARK3116, + "ARK3116 Serial", + }, + { + USB_VENDOR_ARUBA, USB_PRODUCT_ARUBA_CP210X, + "CP210x Serial", + }, + { + USB_VENDOR_ASAHIOPTICAL, USB_PRODUCT_ASAHIOPTICAL_OPTIO230, + "PENTAX Optio230", + }, + { + USB_VENDOR_ASANTE, USB_PRODUCT_ASANTE_EA, + "Ethernet", + }, + { + USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88172, + "USB 2.0 10/100 Ethernet controller", + }, + { + USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88178, + "AX88178", + }, + { + USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88179, + "AX88179", + }, + { + USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772, + "AX88772", + }, + { + USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772A, + "AX88772A", + }, + { + USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772B, + "AX88772B", + }, + { + USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772B_1, + "AX88772B", + }, + { + USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_WLL013I, + "WLL013 (Intersil)", + }, + { + USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_WLL013, + "WLL013", + }, + { + USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_VOYAGER1010, + "Voyager 1010", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2570, + "RT2570", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2570_2, + "RT2570", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_WL159G, + "WL-159g", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_A9T_WIFI, + "A9T wireless", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_P5B_WIFI, + "P5B wireless", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_1, + "RT2573", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_2, + "RT2573", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2870_3, + "RT2870", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2870_4, + "RT2870", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2870_5, + "RT2870", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_USBN13, + "USB-N13", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_USBN10, + "USB-N10", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT3070_1, + "RT3070", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RTL8192SU_1, + "RTL8192SU", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_USBN53, + "USB-N53", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_USBN66, + "USB-N66", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RTL8192CU_2, + "RTL8192CU", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RTL8192CU_3, + "RTL8192CU", + }, + { + USB_VENDOR_ASUS, USB_PRODUCT_ASUS_MYPAL_A730, + "MyPal A730", + }, + { + USB_VENDOR_ASUS2, USB_PRODUCT_ASUS2_USBN11, + "USB-N11", + }, + { + USB_VENDOR_ASUSTEK, USB_PRODUCT_ASUSTEK_WL140, + "WL-140", + }, + { + USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC1284, + "Parallel", + }, + { + USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC10T, + "10Mbps Ethernet", + }, + { + USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC110T, + "UC-110T Ethernet", + }, + { + USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC232A, + "UC232A Serial", + }, + { + USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC210T, + "UC210T Ethernet", + }, + { + USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC2324, + "UC2324 Serial", + }, + { + USB_VENDOR_ATEN, USB_PRODUCT_ATEN_DSB650C, + "DSB-650C", + }, + { + USB_VENDOR_ATHEROS, USB_PRODUCT_ATHEROS_AR5523, + "AR5523", + }, + { + USB_VENDOR_ATHEROS, USB_PRODUCT_ATHEROS_AR5523_NF, + "AR5523", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR5523_1, + "AR5523", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR5523_1_NF, + "AR5523", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR5523_2, + "AR5523", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR5523_2_NF, + "AR5523", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR5523_3, + "AR5523", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR5523_3_NF, + "AR5523", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_TG121N, + "TG121N", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_WN821NV2, + "WN821NV2", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9271_1, + "AR9271", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_3CRUSBN275, + "3CRUSBN275", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_WN612, + "WN612", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR3011, + "AR3011", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9280, + "AR9280+AR7010", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9287, + "AR9287+AR7010", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9170, + "AR9170", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9271_2, + "AR9271", + }, + { + USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9271_3, + "AR9271", + }, + { + USB_VENDOR_ATI2, USB_PRODUCT_ATI2_205, + "USB Cable 205", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_STK541, + "STK541 Zigbee", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_UHB124, + "UHB124 hub", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_WN210, + "W-Buddie WN210", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_DWL900AP, + "DWL-900AP Wireless access point", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT91_CDC_ACM, + "AT91 CDC ACM", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503I1, + "AT76C503 (Intersil 3861 Radio)", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503I2, + "AT76C503 (Intersil 3863 Radio)", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503RFMD, + "AT76C503 (RFMD Radio)", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505RFMD, + "AT76C505 (RFMD Radio)", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505RFMD2958, + "AT76C505 (RFMD 2958 Radio)", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505A, + "AT76C505A (RFMD 2958 Radio)", + }, + { + USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505AS, + "AT76C505AS (RFMD 2958 Radio)", + }, + { + USB_VENDOR_AUDIOTECHNICA, USB_PRODUCT_AUDIOTECHNICA_ATCHA4USB, + "ATC-HA4USB USB headphone", + }, + { + USB_VENDOR_AVAGO, USB_PRODUCT_AVAGO_MOUSE, + "Mouse", + }, + { + USB_VENDOR_AVANCELOGIC, USB_PRODUCT_AVANCELOGIC_USBAUDIO, + "USB Audio Speaker", + }, + { + USB_VENDOR_AVERATEC, USB_PRODUCT_AVERATEC_USBWLAN, + "WLAN", + }, + { + USB_VENDOR_AVISION, USB_PRODUCT_AVISION_1200U, + "1200U", + }, + { + USB_VENDOR_AVM, USB_PRODUCT_AVM_FRITZWLAN, + "FRITZ!WLAN N", + }, + { + USB_VENDOR_AXESSTEL, USB_PRODUCT_AXESSTEL_DATAMODEM, + "Data Modem", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RT3070_1, + "RT3070", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RT3070_2, + "RT3070", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RT3070_3, + "RT3070", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_1, + "RTL8192SU", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RT3070_4, + "RT3070", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_2, + "RTL8192SU", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_3, + "RTL8192SU", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_4, + "RTL8192SU", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RT3070_5, + "RT3070", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_5, + "RTL8192SU", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_1, + "AR9271", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_2, + "AR9271", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_3, + "AR9271", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_4, + "AR9271", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_5, + "AR9271", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_6, + "AR9271", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8188CU, + "RTL8188CU", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8188CE_1, + "RTL8188CE", + }, + { + USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8188CE_2, + "RTL8188CE", + }, + { + USB_VENDOR_BALTECH, USB_PRODUCT_BALTECH_CARDREADER, + "Card reader", + }, + { + USB_VENDOR_BAYER, USB_PRODUCT_BAYER_CONTOUR, + "Ascensia Contour", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_USOTL4, + "USOTL4 RS-422/485", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_USTL4, + "USTL4 RS-422/485", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_USO9ML2, + "USO9ML2 RS-232", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_USOPTL4, + "USOPTL4 RS-422/485", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_USPTL4, + "USPTL4 RS-422/485", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_USO9ML2DR2, + "USO9ML2DR-2 RS-232", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_USO9ML2DR, + "USO9ML2DR RS-232", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_USOPTL4DR2, + "USOPTL4DR-2 RS-422/485", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_USOPTL4DR, + "USOPTL4DR RS-422/485", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_485USB9F2W, + "485USB9F-2W RS-422/485", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_485USB9F4W, + "485USB9F-4W RS-422/485", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_232USB9M, + "232USB9M RS-232", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_485USBTB_2W, + "485USBTB-2W RS-422/485", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_485USBTB_4W, + "485USBTB-4W RS-422/485", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_TTL5USB9M, + "TTL5USB9M", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_TTL3USB9M, + "TTL3USB9M", + }, + { + USB_VENDOR_BBELECTR, USB_PRODUCT_BBELECTR_ZZ_PROG1, + "ZZ Programmer", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D6050, + "F5D6050 802.11b Wireless adapter", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_FBT001V, + "Bluetooth", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F8T003V, + "Bluetooth", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_FBT003V, + "Bluetooth", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U103, + "F5U103 Serial", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U109, + "F5U109 Serial", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_SCSI, + "SCSI", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D5050, + "F5D5050 Ethernet", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U234, + "F5U234 USB 2.0 4-Port Hub", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U237, + "F5U237 USB 2.0 7-Port Hub", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U257, + "F5U257 Serial", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6H375, + "F6H375 UPS", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U409, + "F5U409 Serial", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C550AVR, + "F6C550-AVR UPS", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C1250EITWRK, + "F6C1250EITW-RK UPS", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C1500EITWRK, + "F6C1500EITW-RK UPS", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C900, + "F6C900 UPS", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C100, + "F6C100 UPS", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C120, + "F6C120 UPS", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C800, + "F6C800 UPS", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F9L1004V1, + "F9L1004V1", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C1100, + "F6C1100/1200 UPS", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8188CU, + "RTL8188CU", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F9L1103, + "F9L1103 Wireless Adapter", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8188CUS, + "RTL8188CUS", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U120, + "F5U120-PC Hub", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F7D2102, + "F7D2102", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192CU_1, + "RTL8192CU", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_ZD1211B, + "ZD1211B", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D5055, + "F5D5055", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050, + "F5D7050 54g USB Network Adapter", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050A, + "F5D705A 54g USB Network Adapter", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050C, + "F5D705C 54g USB Network Adapter", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050E, + "F5D705E 54g USB Network Adapter", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D8053V3, + "F5D8053 v3", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192SU_1, + "RTL8192SU", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D8055, + "F5D8055", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D8055V2, + "F5D8055 v2", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192SU_2, + "RTL8192SU", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D9050V3, + "F5D9050 ver 3", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D9050C, + "F5D9050C", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6D4050V1, + "F6D4050 ver 1", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6D4050V2, + "F6D4050 ver 2", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192SU_3, + "RTL8192SU", + }, + { + USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F7D1101V2, + "F7D1101 v2", + }, + { + USB_VENDOR_BELKIN2, USB_PRODUCT_BELKIN2_F5U002, + "F5U002 Parallel", + }, + { + USB_VENDOR_BEWAN, USB_PRODUCT_BEWAN_BWIFI_USB54AR, + "BWIFI-USB54AR", + }, + { + USB_VENDOR_BEWAN, USB_PRODUCT_BEWAN_RT3070, + "RT3070", + }, + { + USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB100, + "USB100N 10/100 Ethernet", + }, + { + USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBLP100, + "USB100LP", + }, + { + USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBEL100, + "USB100EL", + }, + { + USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBE100, + "USBE100", + }, + { + USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB2AR, + "USB2AR Ethernet", + }, + { + USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCMFW, + "BCMFW", + }, + { + USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM2033, + "BCM2033", + }, + { + USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM2033NF, + "BCM2033 (no fw)", + }, + { + USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM43236, + "BCM43236", + }, + { + USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM43143, + "BCM43143", + }, + { + USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM43242, + "BCM43242", + }, + { + USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM43569, + "BCM43569", + }, + { + USB_VENDOR_BROTHER, USB_PRODUCT_BROTHER_HL1050, + "HL-1050 laser printer", + }, + { + USB_VENDOR_BROTHER, USB_PRODUCT_BROTHER_MFC210C, + "MFC 210C", + }, + { + USB_VENDOR_BTC, USB_PRODUCT_BTC_BTC7932, + "Keyboard/Mouse", + }, + { + USB_VENDOR_BWCT, USB_PRODUCT_BWCT_6CHCONSER, + "6ch ConSer", + }, + { + USB_VENDOR_CACE, USB_PRODUCT_CACE_AIRPCAPNX, + "AirPcap Nx", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_N656U, + "CANOSCAN N656U", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_N1220U, + "CANOSCAN N1220U", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_N670U, + "CANOSCAN N670U", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_N1240U, + "CANOSCAN N1240U", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_LIDE60, + "CANOSCAN LiDE60", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_S10, + "PowerShot S10", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_S20, + "PowerShot S20", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_S100_US, + "PowerShot S100", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_S100_EU, + "PowerShot S100", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_G1, + "PowerShot G1", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_A20, + "PowerShot A20", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_A540, + "PowerShot A540", + }, + { + USB_VENDOR_CANON, USB_PRODUCT_CANON_SX100, + "PowerShot SX100", + }, + { + USB_VENDOR_CASIO, USB_PRODUCT_CASIO_QV, + "QV", + }, + { + USB_VENDOR_CASIO, USB_PRODUCT_CASIO_BE300, + "BE-300 PDA", + }, + { + USB_VENDOR_CASIO, USB_PRODUCT_CASIO_NAMELAND, + "CASIO Nameland EZ-USB", + }, + { + USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE, + "Netmate Ethernet", + }, + { + USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE2, + "Netmate2 Ethernet", + }, + { + USB_VENDOR_CATC, USB_PRODUCT_CATC_CHIEF, + "USB Chief Bus & Protocol Analyzer", + }, + { + USB_VENDOR_CATC, USB_PRODUCT_CATC_ANDROMEDA, + "Andromeda hub", + }, + { + USB_VENDOR_CCYU, USB_PRODUCT_CCYU_EASYDISK, + "EasyDisk Portable", + }, + { + USB_VENDOR_CHENSOURCE, USB_PRODUCT_CHENSOURCE_CM12402, + "CM12402 Eagle IR Cam", + }, + { + USB_VENDOR_CHERRY, USB_PRODUCT_CHERRY_MY3000KBD, + "My3000 keyboard", + }, + { + USB_VENDOR_CHERRY, USB_PRODUCT_CHERRY_MY3000HUB, + "My3000 hub", + }, + { + USB_VENDOR_CHIC, USB_PRODUCT_CHIC_MOUSE1, + "mouse", + }, + { + USB_VENDOR_CHIC, USB_PRODUCT_CHIC_CYPRESS, + "Cypress", + }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_KB8933, + "KB-8933 keyboard", + }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_CAMERA, + "Integrated Camera", + }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_1, + "RTL8188CUS", + }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_2, + "RTL8188CUS", + }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_3, + "RTL8188CUS", + }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_4, + "RTL8188CUS", + }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_5, + "RTL8188CUS", + }, + { + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_6, + "RTL8188CUS", + }, + { + USB_VENDOR_CHPRODUCTS, USB_PRODUCT_CHPRODUCTS_PROTHROTTLE, + "Pro Throttle", + }, + { + USB_VENDOR_CHPRODUCTS, USB_PRODUCT_CHPRODUCTS_PROPEDALS, + "Pro Pedals", + }, + { + USB_VENDOR_CHPRODUCTS, USB_PRODUCT_CHPRODUCTS_FIGHTERSTICK, + "Fighterstick", + }, + { + USB_VENDOR_CHPRODUCTS, USB_PRODUCT_CHPRODUCTS_FLIGHTYOKE, + "Flight Sim Yoke", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GV2, + "WUSB54G v2", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54AG, + "WUSB54AG", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54G, + "RT2570", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GP, + "RT2570", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_USB200MV2, + "USB200M v2", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_HU200TS, + "HU200-TS", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GC, + "WUSB54GC", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GR, + "WUSB54GR", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSBF54G, + "WUSBF54G", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB200, + "WUSB200", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_AE1000, + "AE1000", + }, + { + USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_AM10, + "AM10", + }, + { + USB_VENDOR_CISCOLINKSYS2, USB_PRODUCT_CISCOLINKSYS2_RT3070, + "RT3070", + }, + { + USB_VENDOR_CISCOLINKSYS3, USB_PRODUCT_CISCOLINKSYS3_RT3070, + "RT3070", + }, + { + USB_VENDOR_CLIPSAL, USB_PRODUCT_CLIPSAL_560884, + "560884 C-Bus Switch", + }, + { + USB_VENDOR_CLIPSAL, USB_PRODUCT_CLIPSAL_5500PACA, + "5500PACA C-Bus Controller", + }, + { + USB_VENDOR_CLIPSAL, USB_PRODUCT_CLIPSAL_5800PC, + "5800PC C-Bus Wireless", + }, + { + USB_VENDOR_CLIPSAL, USB_PRODUCT_CLIPSAL_5500PCU, + "5500PCU C-Bus", + }, + { + USB_VENDOR_CLIPSAL, USB_PRODUCT_CLIPSAL_5000CT2, + "5000CT2 C-Bus Touch Screen", + }, + { + USB_VENDOR_CLIPSAL, USB_PRODUCT_CLIPSAL_C5000CT2, + "C5000CT2 C-Bus Touch Screen", + }, + { + USB_VENDOR_CLIPSAL, USB_PRODUCT_CLIPSAL_L51XX, + "L51xx C-Bus Dimmer", + }, + { + USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CNU510, + "CDMA Technologies USB modem", + }, + { + USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CM5100P, + "CM-5100P EVDO", + }, + { + USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CCU550, + "CCU-550 EVDO", + }, + { + USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CNU550PRO, + "CNU-550pro EVDO", + }, + { + USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CGU628, + "CGU-628", + }, + { + USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CNU680, + "CNU-680", + }, + { + USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CGU628_DISK, + "CGU-628 disk mode", + }, + { + USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQPOCKETPC, + "iPAQ PocketPC", + }, + { + USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_A1500, + "A1500", + }, + { + USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQWLAN, + "iPAQ WLAN", + }, + { + USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_W100, + "W100", + }, + { + USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_W200, + "WLAN MultiPort W200", + }, + { + USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_PJB100, + "Personal Jukebox PJB100", + }, + { + USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQLINUX, + "iPAQ Linux", + }, + { + USB_VENDOR_COMPARE, USB_PRODUCT_COMPARE_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_PRISM_GT, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_C11U, + "C11U", + }, + { + USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_WL210, + "WL-210", + }, + { + USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_AR5523_1, + "AR5523", + }, + { + USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_AR5523_1_NF, + "AR5523", + }, + { + USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_AR5523_2, + "AR5523", + }, + { + USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_AR5523_2_NF, + "AR5523", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RTL8192SU_1, + "RTL8192SU", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RTL8192SU_2, + "RTL8192SU", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RTL8192SU_3, + "RTL8192SU", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_C54RU, + "C54RU WLAN", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT3070_1, + "RT3070", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_7, + "RT2870", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT3070_2, + "RT3070", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_8, + "RT2870", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_C54RU2, + "C54RU", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_3, + "RT2870", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2573, + "RT2573M", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_VIGORN61, + "VIGORN61", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_5, + "RT2870", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT2870_6, + "RT2870", + }, + { + USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_RT3070_3, + "RT3070", + }, + { + USB_VENDOR_CONCORDCAMERA, USB_PRODUCT_CONCORDCAMERA_EYE_Q_3X, + "Eye Q 3x", + }, + { + USB_VENDOR_CONNECTIX, USB_PRODUCT_CONNECTIX_QUICKCAM, + "QuickCam", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_ETHER_USB_T, + "Ether USB-T", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TX, + "FEther USB-TX", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_WLAN_USB_USB_11, + "WirelessLAN USB-11", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXS, + "FEther USB-TXS", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_WLANUSB, + "Wireless LAN Stick-11", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB2_TX, + "FEther USB2-TX", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_WLUSB_11_KEY, + "ULUSB-11 Key", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB2GL, + "CG-WLUSB2GL", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB2GPX, + "CG-WLUSB2GPX", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_RT2870_3, + "RT2870", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_RT3070, + "RT3070", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB300GNM, + "CG-WLUSB300GNM", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB300N, + "CG-WLUSB300N", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_RTL8192SU, + "RTL8192SU", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_WLUSB_11_STICK, + "WLAN USB Stick 11", + }, + { + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXC, + "FEther USB-TXC", + }, + { + USB_VENDOR_CORSAIR, USB_PRODUCT_CORSAIR_CP210X, + "CP210X", + }, + { + USB_VENDOR_CREATIVE, USB_PRODUCT_CREATIVE_NOMAD_II, + "Nomad II", + }, + { + USB_VENDOR_CREATIVE, USB_PRODUCT_CREATIVE_EMU0202, + "E-Mu 0202", + }, + { + USB_VENDOR_CREATIVE, USB_PRODUCT_CREATIVE_NOMAD_IIMG, + "Nomad II MG", + }, + { + USB_VENDOR_CREATIVE, USB_PRODUCT_CREATIVE_NOMAD, + "Nomad", + }, + { + USB_VENDOR_CREATIVE2, USB_PRODUCT_CREATIVE2_VOIP_BLASTER, + "Voip Blaster", + }, + { + USB_VENDOR_CSR, USB_PRODUCT_CSR_BLUETOOTH, + "Bluetooth", + }, + { + USB_VENDOR_CSR, USB_PRODUCT_CSR_BLUECORE, + "BlueCore", + }, + { + USB_VENDOR_CTC, USB_PRODUCT_CTC_CW6622, + "CW6622", + }, + { + USB_VENDOR_CTX, USB_PRODUCT_CTX_EX1300, + "Ex1300 hub", + }, + { + USB_VENDOR_CYBERPOWER, USB_PRODUCT_CYBERPOWER_UPS, + "UPS", + }, + { + USB_VENDOR_CYBERPOWER, USB_PRODUCT_CYBERPOWER_1500, + "1500 UPS", + }, + { + USB_VENDOR_CYBERPOWER, USB_PRODUCT_CYBERPOWER_OR2200, + "OR2200 UPS", + }, + { + USB_VENDOR_CYBERTAN, USB_PRODUCT_CYBERTAN_GIGASET108, + "Siemens Gigaset 108", + }, + { + USB_VENDOR_CYBERTAN, USB_PRODUCT_CYBERTAN_TG54USB, + "TG54USB", + }, + { + USB_VENDOR_CYBERTAN, USB_PRODUCT_CYBERTAN_ZD1211B, + "ZD1211B", + }, + { + USB_VENDOR_CYBERTAN, USB_PRODUCT_CYBERTAN_RT2870, + "RT2870", + }, + { + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_MOUSE, + "mouse", + }, + { + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_THERMO, + "thermometer", + }, + { + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_KBDHUB, + "Keyboard/Hub", + }, + { + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_FMRADIO, + "FM Radio", + }, + { + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_USBRS232, + "RS232", + }, + { + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_HUB2, + "USB2 Hub", + }, + { + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_LPRDK, + "CY4636 LP RDK Bridge", + }, + { + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_SISPM_OLD, + "Sispm - old version", + }, + { + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_SISPM, + "Sispm", + }, + { + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_SISPM_FLASH, + "Sispm - flash", + }, + { + USB_VENDOR_DAISY, USB_PRODUCT_DAISY_DMC, + "PhotoClip", + }, + { + USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_USB_FOB_IBUTTON, + "USB-FOB/iBUTTON", + }, + { + USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502, + "J-6502 speakers", + }, + { + USB_VENDOR_DATAAPEX, USB_PRODUCT_DATAAPEX_MULTICOM, + "MultiCom", + }, + { + USB_VENDOR_DAVICOM, USB_PRODUCT_DAVICOM_WK668, + "HenTong WK-668", + }, + { + USB_VENDOR_DAVICOM, USB_PRODUCT_DAVICOM_DM9601, + "DM9601", + }, + { + USB_VENDOR_DELL, USB_PRODUCT_DELL_AXIM, + "Axim X51v", + }, + { + USB_VENDOR_DELL, USB_PRODUCT_DELL_BC02, + "Bluetooth", + }, + { + USB_VENDOR_DELL, USB_PRODUCT_DELL_TM1180, + "TrueMobile 1180 WLAN", + }, + { + USB_VENDOR_DELL, USB_PRODUCT_DELL_PRISM_GT_1, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_DELL, USB_PRODUCT_DELL_BLUETOOTH350, + "Bluetooth", + }, + { + USB_VENDOR_DELL, USB_PRODUCT_DELL_PRISM_GT_2, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_DELL, USB_PRODUCT_DELL_W5500, + "W5500 HSDPA", + }, + { + USB_VENDOR_DELL, USB_PRODUCT_DELL_U740, + "Dell U740 CDMA", + }, + { + USB_VENDOR_DELL, USB_PRODUCT_DELL_EU870D, + "EU870D HSDPA", + }, + { + USB_VENDOR_DELL, USB_PRODUCT_DELL_DW700, + "DW700 GPS", + }, + { + USB_VENDOR_DELL2, USB_PRODUCT_DELL2_UPS, + "UPS", + }, + { + USB_VENDOR_DELORME, USB_PRODUCT_DELORME_EMUSB, + "Earthmate GPS", + }, + { + USB_VENDOR_DELORME, USB_PRODUCT_DELORME_EMLT20, + "Earthmate LT20", + }, + { + USB_VENDOR_DIAMOND, USB_PRODUCT_DIAMOND_RIO500USB, + "Rio 500", + }, + { + USB_VENDOR_DIAMOND2, USB_PRODUCT_DIAMOND2_SUPRAEXPRESS56K, + "Supra Express 56K", + }, + { + USB_VENDOR_DIAMOND2, USB_PRODUCT_DIAMOND2_SUPRA2890, + "SupraMax 2890 56K", + }, + { + USB_VENDOR_DIAMOND2, USB_PRODUCT_DIAMOND2_RIO600USB, + "Rio 600", + }, + { + USB_VENDOR_DIAMOND2, USB_PRODUCT_DIAMOND2_RIO800USB, + "Rio 800", + }, + { + USB_VENDOR_DIAMOND2, USB_PRODUCT_DIAMOND2_PSAPLAY120, + "Nike psa[play 120", + }, + { + USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_WL200U, + "WL-200U", + }, + { + USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_CHUSB611G, + "CHUSB 611G", + }, + { + USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_WL240U, + "WL-240U", + }, + { + USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_XH1153, + "XH1153 802.11b", + }, + { + USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_RT2573, + "RT2573", + }, + { + USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_CWD854F, + "C-Net CWD-854 rev F", + }, + { + USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_RTL8187, + "RTL8187", + }, + { + USB_VENDOR_DIGI, USB_PRODUCT_DIGI_ACCELEPORT2, + "AccelePort 2", + }, + { + USB_VENDOR_DIGI, USB_PRODUCT_DIGI_ACCELEPORT4, + "AccelePort 4", + }, + { + USB_VENDOR_DIGI, USB_PRODUCT_DIGI_ACCELEPORT8, + "AccelePort 8", + }, + { + USB_VENDOR_DIGIANSWER, USB_PRODUCT_DIGIANSWER_ZIGBEE802154, + "ZigBee", + }, + { + USB_VENDOR_DIGITALSTREAM, USB_PRODUCT_DIGITALSTREAM_PS2, + "PS/2 Active", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_GUC2020, + "IOGEAR DVI GUC2020", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_LD220, + "Samsung LD220", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_POLARIS2, + "Polaris2 USB dock", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_VCUD60, + "Rextron DVI", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_CONV, + "StarTech CONV-USB2DVI", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_DLDVI, + "DisplayLink DVI", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_VGA10, + "CMP-USBVGA10", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_WSDVI, + "WS Tech DVI", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_EC008, + "EasyCAP008 DVI", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_LCD4300U, + "LCD-4300U", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_LCD8000U, + "LCD-8000U", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_HPDOCK, + "HP USB Docking", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_NL571, + "HP USB DVI", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_M01061, + "Lenovo DVI", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_NBDOCK, + "VideoHome NBdock1920", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_SWDVI, + "SUNWEIT DVI", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_LUM70, + "Lilliput UM-70", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_LT1421, + "Lenovo ThinkVision LT1421", + }, + { + USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_UM7X0, + "nanovision MiMo", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100, + "10/100 Ethernet", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100C1, + "DUB-E100 rev C1", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX4, + "10/100 Ethernet", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWL120E, + "DWL-120 rev E", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA130C, + "DWA-130 rev C", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8192CU_1, + "RTL8192CU", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8188CU, + "RTL8188CU", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8192CU_2, + "RTL8192CU", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8192CU_3, + "RTL8192CU", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8192CU_4, + "RTL8192CU", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA131B, + "DWA-131 rev B", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA125D1, + "DWA-125 rev D1", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA123D1, + "DWA-123 rev D1", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA137A1, + "DWA-137 rev A1", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA131E1, + "DWA-131 rev E1", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA182D1, + "DWA-182 rev D1", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA171C1, + "DWA-171 rev C1", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWL122, + "DWL-122", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLG120, + "DWL-G120", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWL120F, + "DWL-120 rev F", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLG122A2, + "DWL-G122 rev A2", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLAG132, + "DWL-AG132", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLAG132_NF, + "DWL-AG132", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLG132, + "DWL-G132", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLG132_NF, + "DWL-G132", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLAG122, + "DWL-AG122", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLAG122_NF, + "DWL-AG122", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RT2570, + "RT2570", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100B1, + "DUB-E100 rev B1", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RT2870, + "RT2870", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RT3072, + "RT3072", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA140B3, + "DWA-140 rev B3", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA160B2, + "DWA-160 rev B2", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA127, + "DWA-127", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA125B2, + "DWA-125 rev B2", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA162, + "DWA-162 Wireless Adapter", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA140D1, + "DWA-140 rev D1", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA130F1, + "DWA-130 rev F1", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650C, + "10Mbps Ethernet", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX1, + "10/100 Ethernet", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX, + "10/100 Ethernet", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX_PNA, + "1/10/100 Ethernet", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX3, + "10/100 Ethernet", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX2, + "10/100 Ethernet", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUB1312, + "DUB-1312", + }, + { + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650, + "10/100 Ethernet", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RTL8192SU_1, + "RTL8192SU", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RTL8192SU_2, + "RTL8192SU", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA131A1, + "DWA-131 A1", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_WUA2340, + "WUA-2340", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_WUA2340_NF, + "WUA-2340", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA160A2, + "DWA-160 A2", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA130D1, + "DWA-130 rev D1", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_AR9271, + "AR9271", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWLG122C1, + "DWL-G122 rev C1", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_WUA1340, + "WUA-1340", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA111, + "DWA-111", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA110, + "DWA-110", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT3072, + "RT3072", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT3072_1, + "RT3072", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT3070_1, + "RT3070", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT3070_2, + "RT3070", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT3070_3, + "RT3070", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA160A1, + "DWA-160 A1", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA130, + "DWA-130", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT3070_4, + "RT3070", + }, + { + USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RT3070_5, + "RT3070", + }, + { + USB_VENDOR_DLINK3, USB_PRODUCT_DLINK3_KVM221, + "KVM-221", + }, + { + USB_VENDOR_DMI, USB_PRODUCT_DMI_SA2_0, + "Storage Adapter", + }, + { + USB_VENDOR_DOMAIN, USB_PRODUCT_DOMAIN_ROCKCHIP, + "RockChip Media Player", + }, + { + USB_VENDOR_DRAYTEK, USB_PRODUCT_DRAYTEK_VIGOR550, + "Vigor550", + }, + { + USB_VENDOR_DRAYTEK, USB_PRODUCT_DRAYTEK_VIGOR600, + "Vigor600", + }, + { + USB_VENDOR_DREAMCHEEKY, USB_PRODUCT_DREAMCHEEKY_ROCKETBABY, + "Missile Launcher", + }, + { + USB_VENDOR_DREAMLINK, USB_PRODUCT_DREAMLINK_ULMB1, + "USB LED Message Board v1.0", + }, + { + USB_VENDOR_DRESDENELEC, USB_PRODUCT_DRESDENELEC_STB, + "Sensor Terminal", + }, + { + USB_VENDOR_DRESDENELEC, USB_PRODUCT_DRESDENELEC_WHT, + "Wireless Terminal", + }, + { + USB_VENDOR_DVICO, USB_PRODUCT_DVICO_RT3070, + "RT3070", + }, + { + USB_VENDOR_DYNASTREAM, USB_PRODUCT_DYNASTREAM_ANTDEVBOARD, + "ANT dev board", + }, + { + USB_VENDOR_DYNASTREAM, USB_PRODUCT_DYNASTREAM_ANT2USB, + "ANT2USB", + }, + { + USB_VENDOR_DYNASTREAM, USB_PRODUCT_DYNASTREAM_ANTDEVBOARD2, + "ANT dev board", + }, + { + USB_VENDOR_DYNASTREAM, USB_PRODUCT_DYNASTREAM_ANTUSB2, + "ANTUSB-2 Stick", + }, + { + USB_VENDOR_DYNASTREAM, USB_PRODUCT_DYNASTREAM_ANTUSBM, + "ANTUSB-m Stick", + }, + { + USB_VENDOR_EASYDISK, USB_PRODUCT_EASYDISK_EASYDISK, + "Flash Disk", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7318, + "EW-7318", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RTL8192SU_1, + "RTL8192SU", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RTL8192SU_2, + "RTL8192SU", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7618, + "EW-7618", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RTL8192SU_3, + "RTL8192SU", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7717, + "EW-7717", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7718, + "EW-7718", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7722UTN, + "EW-7722UTn", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7811UN, + "EW-7811Un", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7611ULB, + "EW-7611ULB", + }, + { + USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7822ULC, + "EW-7822ULC", + }, + { + USB_VENDOR_EGALAX, USB_PRODUCT_EGALAX_TPANEL, + "Touch Panel", + }, + { + USB_VENDOR_EGALAX, USB_PRODUCT_EGALAX_TPANEL2, + "Touch Panel", + }, + { + USB_VENDOR_EGALAX2, USB_PRODUCT_EGALAX2_TPANEL, + "Touch Panel", + }, + { + USB_VENDOR_EICON, USB_PRODUCT_EICON_DIVA852, + "Diva 852 ISDN TA", + }, + { + USB_VENDOR_EIZO, USB_PRODUCT_EIZO_HUB, + "hub", + }, + { + USB_VENDOR_EIZO, USB_PRODUCT_EIZO_MONITOR, + "monitor", + }, + { + USB_VENDOR_ELAN, USB_PRODUCT_ELAN_BARCODE, + "Barcode Scanner", + }, + { + USB_VENDOR_ELCON, USB_PRODUCT_ELCON_PLAN, + "Goldpfeil P-LAN", + }, + { + USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_MOUSE29UO, + "29UO", + }, + { + USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX0, + "LD-USB/TX", + }, + { + USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX1, + "LD-USB/TX", + }, + { + USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBLTX, + "LD-USBL/TX", + }, + { + USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_WDC150SU2M, + "WDC-150SU2M", + }, + { + USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX2, + "LD-USB/TX", + }, + { + USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSB20, + "LD-USB20", + }, + { + USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_UCSGT, + "UC-SGT Serial", + }, + { + USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_UCSGT0, + "UC-SGT0 Serial", + }, + { + USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX3, + "LD-USB/TX", + }, + { + USB_VENDOR_ELEKTOR, USB_PRODUCT_ELEKTOR_FT323R, + "FT323R", + }, + { + USB_VENDOR_ELSA, USB_PRODUCT_ELSA_MODEM1, + "ELSA", + }, + { + USB_VENDOR_ELSA, USB_PRODUCT_ELSA_USB2ETHERNET, + "Microlink USB2Ethernet", + }, + { + USB_VENDOR_ELV, USB_PRODUCT_ELV_USBI2C, + "USB-I2C", + }, + { + USB_VENDOR_EMPIA, USB_PRODUCT_EMPIA_EEEPC701_VIDEO, + "EeePC701 camera", + }, + { + USB_VENDOR_ENCORE, USB_PRODUCT_ENCORE_RT3070_1, + "RT3070", + }, + { + USB_VENDOR_ENCORE, USB_PRODUCT_ENCORE_RT3070_2, + "RT3070", + }, + { + USB_VENDOR_ENCORE, USB_PRODUCT_ENCORE_RT3070_3, + "RT3070", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_1S, + "1S serial", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_2S, + "2S serial", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_1S25, + "1S25 serial", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_4S, + "4S serial", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_E45, + "E45 Ethernet", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_CENTRONICS, + "Centronics", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_XX1, + "Ethernet", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_1S9, + "1S9 serial", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_EZUSB, + "EZ-USB", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_2U4S, + "2U4S serial", + }, + { + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_XX2, + "Ethernet", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_PRINTER1, + "USB Printer", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_PRINTER2, + "ISD Smart Cable for Mac", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_PRINTER3, + "ISD Smart Cable", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_PRINTER5, + "USB Printer", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_636, + "Perfection 636U / 636Photo", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_610, + "Perfection 610", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1200, + "Perfection 1200U / 1200Photo", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1600, + "Expression 1600", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1640, + "Perfection 1640SU", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1240, + "Perfection 1240U / 1240Photo", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_640U, + "Perfection 640U", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1650, + "Perfection 1650", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_GT9700F, + "GT-9700F", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_2400, + "Perfection 2400", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1260, + "Perfection 1260", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1660, + "Perfection 1660", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1670, + "Perfection 1670", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_CX5400, + "CX5400", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_CX3650, + "Stylus CX3650", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX3800, + "Stylus DX3800", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX5000, + "Stylus DX5000", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX6000, + "Stylus DX6000", + }, + { + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX4000, + "Stylus DX4000", + }, + { + USB_VENDOR_ETEK, USB_PRODUCT_ETEK_1COM, + "Serial", + }, + { + USB_VENDOR_EVOLUTION, USB_PRODUCT_EVOLUTION_ER1, + "ER1 Control Module", + }, + { + USB_VENDOR_EVOLUTION, USB_PRODUCT_EVOLUTION_RCM4_1, + "RCM4 interface", + }, + { + USB_VENDOR_EVOLUTION, USB_PRODUCT_EVOLUTION_RCM4_2, + "RCM4 interface", + }, + { + USB_VENDOR_EXAR, USB_PRODUCT_EXAR_XR21V1410, + "XR21V1410", + }, + { + USB_VENDOR_EXTENDED, USB_PRODUCT_EXTENDED_XTNDACCESS, + "XTNDAccess IrDA", + }, + { + USB_VENDOR_FALCOM, USB_PRODUCT_FALCOM_TWIST, + "Twist", + }, + { + USB_VENDOR_FALCOM, USB_PRODUCT_FALCOM_SAMBA, + "Samba", + }, + { + USB_VENDOR_FEIXUN, USB_PRODUCT_FEIXUN_RTL8188CU, + "RTL8188CU", + }, + { + USB_VENDOR_FEIXUN, USB_PRODUCT_FEIXUN_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_FESTO, USB_PRODUCT_FESTO_CPX_USB, + "CPX-USB", + }, + { + USB_VENDOR_FESTO, USB_PRODUCT_FESTO_CMSP, + "CMSP", + }, + { + USB_VENDOR_FIBERLINE, USB_PRODUCT_FIBERLINE_WL430U, + "WL-430U", + }, + { + USB_VENDOR_FOSSIL, USB_PRODUCT_FOSSIL_WRISTPDA, + "Wrist PDA", + }, + { + USB_VENDOR_FOXCONN, USB_PRODUCT_FOXCONN_TCOM_TC_300, + "T-Com TC 300", + }, + { + USB_VENDOR_FOXCONN, USB_PRODUCT_FOXCONN_PIRELLI_DP_L10, + "Pirelli DP-L10", + }, + { + USB_VENDOR_FREECOM, USB_PRODUCT_FREECOM_DVD, + "Connector for DVD drive", + }, + { + USB_VENDOR_FSC, USB_PRODUCT_FSC_E5400, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_FT232_1, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_8U232AM, + "8U232AM Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_8U232AM4, + "8U232AM Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_FT232_3, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_FT232_4, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_FT232_5, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_FT232_6, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_2232C, + "2232C Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_FT4232H, + "FT4232H", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_FTX, + "FTX", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PS2KBDMS, + "PS/2 Keyboard/Mouse", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_8U100AX, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MJS_SIRIUS_PC_2, + "MJS Sirius To PC Interface", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_OPENRD, + "OpenRD JTAGKey", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CANDAPTER, + "CANdapter", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_NXTCAM, + "Mindstorms NXTCam", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_OOCDLINK, + "OOCDlink", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LM3S_DEVEL, + "LM3S Devel", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LM3S_EVAL, + "LM3S Eval", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_TURTELIZER_JTAG, + "JTAG/RS-232", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_OPENDCC, + "OpenDCC", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_OPENDCC_SNIFFER, + "OpenDCC Sniffer", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_OPENDCC_THROTTLE, + "OpenDCC Throttle", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_OPENDCC_GATEWAY, + "OpenDCC Gateway", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LOCOBUFFER, + "RR-CirKits LocoBuffer", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_DMX4ALL, + "DMX4ALL DMX interface", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ASK_RDR4X7_1, + "ASK RDR 4X7", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ASK_RDR4X7_2, + "ASK RDR 4X7", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ASK_RDR4X7_3, + "ASK RDR 4X7", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ASK_RDR4X7_4, + "ASK RDR 4X7", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ASK_RDR4X7_5, + "ASK RDR 4X7", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ASK_RDR4X7_6, + "ASK RDR 4X7", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ASK_RDR4X7_7, + "ASK RDR 4X7", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ASK_RDR4X7_8, + "ASK RDR 4X7", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MJS_SIRIUS_PC_1, + "MJS Sirius To PC Interface", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CHAMELEON, + "uChameleon", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_OPENPORT_13M, + "OpenPort 1.3 Mitsubishi", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_OPENPORT_13S, + "OpenPort 1.3 Subaru", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_OPENPORT_13U, + "OpenPort 1.3 Universal", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_2232L, + "2232L Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SCS_0, + "Radio Modem", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SCS_1, + "Radio Modem", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SCS_2, + "Radio Modem", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SCS_3, + "Radio Modem", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SCS_4, + "Radio Modem", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SCS_5, + "Radio Modem", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SCS_6, + "Radio Modem", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SCS_7, + "Radio Modem", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IPLUS, + "iPlus", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IPLUS2, + "iPlus", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_XSENS_1, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_XSENS_2, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_XSENS_3, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_XSENS_4, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_XSENS_5, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_XSENS_6, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_XSENS_7, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_XSENS_8, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GAMMASCOUT, + "Gamma Scout Online", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_JTAGCABLEII, + "Propox JTAG", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_WESTREX_777, + "Westrex 777", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_WESTREX_8900F, + "Westrex 8900F", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ACG_HFDUAL, + "HF Dual ISO Reader", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ARTEMIS, + "CCD camera", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ATK16, + "ATK-16 Camera", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ATK16HR, + "ATK-16HR Camera", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ATK16C, + "ATK-16C Camera", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ATK16HRC, + "ATK-16HRC Camera", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ATK16IC, + "ATK-16IC Camera", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_USR, + "USR", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_MSM1, + "Mini-Sound-Modul", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_KL100, + "KL 100", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_WS550, + "WS 550", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_WS888, + "WS 888", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_TWS550, + "WS 550", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_FEM, + "Funk Energie Monitor", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_YEI_SC31, + "ServoCenter3.1", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_FHZ1300PC, + "FHZ 1300 PC", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_WS500, + "WS 500", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_HS485, + "RS-485", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_UMS100, + "UMS 100", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_TFD128, + "TFD 128", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_FM3RX, + "FM3 RX", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_WS777, + "WS 777", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_EM1010PC, + "EM 1010 PC", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_CSI8, + "CSI 8", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_EM1000DL, + "EM 1000 DL", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_PCK100, + "PCK 100", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_RFP500, + "RFP 500", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_FS20SIG, + "FS 20 SIG", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_UTP8, + "UTP 8", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_WS300PC, + "WS 300 PC", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_WS444PC, + "WS 444 PC", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_FISCO, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ECO_PRO, + "EVER Eco Pro UPS", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ACTROBOTS, + "Active Robots comms", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PYRAMID, + "Pyramid Display", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_UNICOM, + "Unicom III", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_1, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_2, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_3, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_4, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_5, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_6, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_7, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_8, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_EISCOU, + "Expert ISDN", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_UOPTBR, + "RS232 OptoBridge", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_DCF, + "Expert mouseCLOCK USB II", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MSF, + "Expert mouseCLOCK USB II MSF", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_HBG, + "Expert mouseCLOCK USB II HBG", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_9, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_A, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GUDE_B, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ECLO_1WIRE, + "1-Wire", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_TNCX, + "TNC-X packet-radio", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_TERATRONIK_VCP, + "VCP", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_TERATRONIK_D2XX, + "D2XX", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_REU_TINY, + "RigExpert Tiny", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_HO870, + "HO870", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_HO820, + "HO820", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SERIAL_232BM, + "FT232BM Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MHAM_KW, + "KW", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MHAM_YS, + "YS", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MHAM_Y6, + "Y6", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MHAM_Y8, + "Y8", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MHAM_IC, + "IC", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MHAM_DB9, + "DB9", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MHAM_RS232, + "RS232", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MHAM_Y9, + "Y9", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_DGQG, + "DGQG", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_DUSB, + "DUSB", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_UAD8, + "UAD 8", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_UAD7, + "UAD 7", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_USI2, + "USI 2", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_T1100, + "T 1100", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_PCD200, + "PCD 200", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_ULA200, + "ULA 200", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_ALC8500, + "ALC 8500 Expert", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_FHZ1000PC, + "FHZ 1000 PC", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PERLE_UP, + "UltraPort", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SPROG_II, + "Sprog II", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PIEGROUP_IR, + "Infrared", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ACTZWAVE, + "HomePro ZWave", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GALAXY_1, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_GALAXY_2, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_COASTAL_TNCX, + "Coastal ChipWorks TNC-X", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LINX_MASTER2, + "Master Development 2.0", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LINX_1, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LINX_2, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LINX_3, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_OCEANIC, + "Oceanic instrument", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SUUNTO, + "Suunto Sports", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_USBUIRT, + "USB-UIRT", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_USBX_707, + "USBX-707", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CCS_ICDU20, + "ICD-U20", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CCS_ICDU40, + "ICD-U40", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CCS_MACHX, + "MACH-X", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CCS_LOAD_N_GO, + "LOAD N GO", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CCS_ICDU64, + "ICDU64", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CCS_PRIME8, + "PRIME8", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ITM_TOUCH, + "ITM Touchscreen", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_USBSERIAL, + "Matrix Orbital USB Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_MX200, + "Matrix Orbital MX200 Series LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_MTXO, + "Matrix Orbital LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_LK202_24, + "Matrix Orbital LK202-24 LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_LK204_24, + "Matrix Orbital LK204-24 LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MATRIX_2, + "Matrix Orbital LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_MATRIX_3, + "Matrix Orbital LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_RELAIS, + "Relais", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_TIRA1, + "Tira-1", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PCDJ_DAC2, + "DAC-2", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ACCESSO, + "Accesso reader", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_THORLABS, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_UR100, + "UR 100", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_CLI7000, + "CLI 7000", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_UM100, + "UM 100", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_UO100, + "UO 100", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_PPS7330, + "PPS 7330", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_TFM100, + "TFM 100", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_UDF77, + "UDF 77", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_ELV_UIO88, + "UIO 88", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_R2000KU_RNG, + "R2000KU RNG", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_BCS_SE923, + "BCS SE923", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_FT232RL, + "FT232RL", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_CFA_632, + "Crystalfontz CFA-632 LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_CFA_634, + "Crystalfontz CFA-634 LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_CFA_547, + "Crystalfontz CFA-547 LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_CFA_633, + "Crystalfontz CFA-633 LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_CFA_631, + "Crystalfontz CFA-631 LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_CFA_635, + "Crystalfontz CFA-635 LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_CFA_640, + "Crystalfontz CFA-640 LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_LCD_CFA_642, + "Crystalfontz CFA-642 LCD", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IRTRANS, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PROTEGO_1, + "Protego", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PROTEGO_R200, + "R200-USB TRNG", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PROTEGO_3, + "Protego", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_PROTEGO_4, + "Protego", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_SEMC_DSS20, + "SEMC DSS-20 SyncStation", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CANVIEW, + "CANview", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_VNHC, + "Modem", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_AMC232, + "AMC-232USB0", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_TTUSB, + "TT-USB", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IBS_US485, + "US485", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IBS_PICPRO, + "PIC-Programmer", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IBS_PCMCIA, + "PCMCIA SRAM-cards reader", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IBS_PK1, + "Particel counter PK1", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IBS_RS232MON, + "RS232", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IBS_APP70, + "APP 70 dust monitoring", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IBS_PEDO, + "IBS PEDO-Modem", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_IBS_1, + "Serial", + }, + { + USB_VENDOR_FTDI, USB_PRODUCT_FTDI_CANUSB, + "CANUSB", + }, + { + USB_VENDOR_FUJIPHOTO, USB_PRODUCT_FUJIPHOTO_MASS0100, + "Mass Storage", + }, + { + USB_VENDOR_FUJITSU, USB_PRODUCT_FUJITSU_AH_F401U, + "AH-F401U Air H device", + }, + { + USB_VENDOR_FUJITSUCOMP, USB_PRODUCT_FUJITSUCOMP_KEYBOARD6, + "Type 6 Keyboard", + }, + { + USB_VENDOR_FUJITSUCOMP, USB_PRODUCT_FUJITSUCOMP_KEYBOARD7, + "Type 7 Keyboard", + }, + { + USB_VENDOR_FUJITSUCOMP, USB_PRODUCT_FUJITSUCOMP_MOUSE, + "Type 6 Mouse", + }, + { + USB_VENDOR_FUJITSUCOMP, USB_PRODUCT_FUJITSUCOMP_FX5204PS, + "Smart Power Strip FX-5204PS", + }, + { + USB_VENDOR_FUJITSUCOMP, USB_PRODUCT_FUJITSUCOMP_FX5251WB, + "Base Station FX-5251WB", + }, + { + USB_VENDOR_FUJITSUCOMP, USB_PRODUCT_FUJITSUCOMP_VIRTETH, + "Virtual Eth Device", + }, + { + USB_VENDOR_FUSHICAI, USB_PRODUCT_FUSHICAI_USBTV007, + "Fushicai Audio-Video Grabber", + }, + { + USB_VENDOR_GARMIN, USB_PRODUCT_GARMIN_GPSMAP60CSX, + "GPSmap 60Csx", + }, + { + USB_VENDOR_GARMIN, USB_PRODUCT_GARMIN_IQUE3600, + "Ique 3600", + }, + { + USB_VENDOR_GARMIN, USB_PRODUCT_GARMIN_DAKOTA20, + "Dakota 20", + }, + { + USB_VENDOR_GARMIN, USB_PRODUCT_GARMIN_GPSMAP62S, + "GPSmap 62s", + }, + { + USB_VENDOR_GCTSEMICON, USB_PRODUCT_GCTSEMICON_INSTALL, + "GDM720x MASS storage mode", + }, + { + USB_VENDOR_GEMPLUS, USB_PRODUCT_GEMPLUS_PROXPU, + "Prox-PU/CU", + }, + { + USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL620USB_A, + "GL620USB-A GeneLink USB-USB Bridge", + }, + { + USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GENELINK, + "GeneLink Host-Host Bridge", + }, + { + USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL650, + "GL650 Hub", + }, + { + USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB, + "GL641USB CompactFlash", + }, + { + USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNBR402W, + "GN-BR402W", + }, + { + USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWLBM101, + "GN-WLBM101", + }, + { + USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWBKG, + "GN-WBKG", + }, + { + USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWB01GS, + "GN-WB01GS", + }, + { + USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWI05GS, + "GN-WI05GS", + }, + { + USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWB31N, + "GN-WB31N", + }, + { + USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWB32L, + "GN-WB32L", + }, + { + USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_WLAN, + "WLAN", + }, + { + USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_SMCWUSBTG, + "SMCWUSBT-G", + }, + { + USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_SMCWUSBTG_NF, + "SMCWUSBT-G", + }, + { + USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_AR5523, + "AR5523", + }, + { + USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_AR5523_NF, + "AR5523", + }, + { + USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_RT2573, + "RT2573", + }, + { + USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_RT3070_1, + "RT3070", + }, + { + USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_RT3070_2, + "RT3070", + }, + { + USB_VENDOR_GLOBALSUN, USB_PRODUCT_GLOBALSUN_AR5523_1, + "AR5523", + }, + { + USB_VENDOR_GLOBALSUN, USB_PRODUCT_GLOBALSUN_AR5523_1_NF, + "AR5523", + }, + { + USB_VENDOR_GLOBALSUN, USB_PRODUCT_GLOBALSUN_AR5523_2, + "AR5523", + }, + { + USB_VENDOR_GLOBALSUN, USB_PRODUCT_GLOBALSUN_AR5523_2_NF, + "AR5523", + }, + { + USB_VENDOR_GLOBESPAN, USB_PRODUCT_GLOBESPAN_PRISM_GT_1, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_GLOBESPAN, USB_PRODUCT_GLOBESPAN_PRISM_GT_2, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_GMATE, USB_PRODUCT_GMATE_YP3X00, + "YP3X00 PDA", + }, + { + USB_VENDOR_GNOTOMETRICS, USB_PRODUCT_GNOTOMETRICS_AURICAL, + "Aurical", + }, + { + USB_VENDOR_GOHUBS, USB_PRODUCT_GOHUBS_GOCOM232, + "GoCOM232 Serial converter", + }, + { + USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_GWUSB2E, + "GWUSB2E", + }, + { + USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_RT2573, + "RT2573", + }, + { + USB_VENDOR_GRAVIS, USB_PRODUCT_GRAVIS_GAMEPADPRO, + "GamePad Pro", + }, + { + USB_VENDOR_GREENHOUSE, USB_PRODUCT_GREENHOUSE_KANA21, + "CF-writer/MP3 Player", + }, + { + USB_VENDOR_GRIFFIN, USB_PRODUCT_GRIFFIN_IMATE, + "iMate, ADB adapter", + }, + { + USB_VENDOR_GUDE, USB_PRODUCT_GUDE_DCF, + "Expert mouseCLOCK USB", + }, + { + USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_DALEADER, + "DA Leader", + }, + { + USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254, + "HWGUSB2-54 WLAN", + }, + { + USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254LB, + "HWGUSB2-54-LB", + }, + { + USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254V2AP, + "HWGUSB2-54V2-AP", + }, + { + USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWNU300, + "HWNU-300", + }, + { + USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWNUM300, + "HWNUm-300", + }, + { + USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUN54, + "HWGUn-54", + }, + { + USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWNUP150, + "HWNUP-150", + }, + { + USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_GUNZE, USB_PRODUCT_GUNZE_TOUCHPANEL, + "Gunze USB Touch Panel", + }, + { + USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FGSM, + "FlashGate SmartMedia", + }, + { + USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FGCF, + "FlashGate CompactFlash", + }, + { + USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FG, + "FlashGate", + }, + { + USB_VENDOR_HAL, USB_PRODUCT_HAL_IMR001, + "Crossam2+USB IR commander", + }, + { + USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_VISOR, + "Handspring Visor", + }, + { + USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO, + "Handspring Treo", + }, + { + USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO600, + "Handspring Treo 600", + }, + { + USB_VENDOR_HAUPPAUGE, USB_PRODUCT_HAUPPAUGE_WINTV_USB_FM, + "WinTV FM", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_HWUN2, + "HWUN2", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_HWDN2, + "HWDN2", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RT2870_3, + "RT2870", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RTL8192SU_1, + "RTL8192SU", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RTL8192SU_2, + "RTL8192SU", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RT2870_4, + "RT2870", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RT2870_5, + "RT2870", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RTL8192CU_2, + "RTL8192CU", + }, + { + USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_UF100, + "10/100 Ethernet", + }, + { + USB_VENDOR_HIROSE, USB_PRODUCT_HIROSE_USB100, + "USB-100", + }, + { + USB_VENDOR_HITACHI, USB_PRODUCT_HITACHI_DZMV100A, + "DVD-CAM DZ-MV100A Camcorder", + }, + { + USB_VENDOR_HOLTEK, USB_PRODUCT_HOLTEK_MOUSE, + "Mouse", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_895C, + "DeskJet 895C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_4100C, + "Scanjet 4100C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_S20, + "Photosmart S20", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_880C, + "DeskJet 880C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_4200C, + "ScanJet 4200C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_CDWRITERPLUS, + "CD-Writer Plus", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_KBDHUB, + "Multimedia Keyboard Hub", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_HN210W, + "HN210W", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_HPX9GP, + "HP-x9G+", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_6200C, + "ScanJet 6200C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_S20B, + "PhotoSmart S20", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_815C, + "DeskJet 815C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_3300C, + "ScanJet 3300C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_CDW8200, + "CD-Writer Plus 8200e", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_1220C, + "DeskJet 1220C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_810C, + "DeskJet 810C/812C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_4300C, + "Scanjet 4300C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_CD4E, + "CD-Writer+ CD-4e", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_G85XI, + "OfficeJet G85xi", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_1200, + "LaserJet 1200", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_5200C, + "Scanjet 5200C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_830C, + "DeskJet 830C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_3400CSE, + "ScanJet 3400cse", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_885C, + "DeskJet 885C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_1000, + "LaserJet 1000", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_6300C, + "Scanjet 6300C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_840C, + "DeskJet 840c", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_2200C, + "ScanJet 2200C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_5300C, + "Scanjet 5300C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_816C, + "DeskJet 816C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_970CSE, + "Deskjet 970Cse", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_5400C, + "Scanjet 5400C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_2215, + "iPAQ 22xx/Jornada 548", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_959C, + "Deskjet 959C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_568J, + "Jornada 568", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_930C, + "DeskJet 930c", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_1005, + "LaserJet 1005", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_P2000U, + "Inkjet P-2000U", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_HS2300, + "HS2300", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_T750, + "T750 UPS", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_T1000, + "T1000 UPS", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_T1500, + "T1500 UPS", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_RT2200, + "R/T2200 UPS", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_R1500G2, + "R1500 G2 UPS", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_T750G2, + "T750 G2 UPS", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_640C, + "DeskJet 640c", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_1020, + "LaserJet 1020", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_P1100, + "Photosmart P1100", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_LD220, + "LD220", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_1018, + "LaserJet 1018", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_HN210E, + "HN210E Ethernet", + }, + { + USB_VENDOR_HP2, USB_PRODUCT_HP2_C500, + "PhotoSmart C500", + }, + { + USB_VENDOR_HP3, USB_PRODUCT_HP3_RTL8188CU, + "RTL8188CU", + }, + { + USB_VENDOR_HTC, USB_PRODUCT_HTC_PPC6700MODEM, + "PPC6700 Modem", + }, + { + USB_VENDOR_HTC, USB_PRODUCT_HTC_SMARTPHONE, + "SmartPhone", + }, + { + USB_VENDOR_HTC, USB_PRODUCT_HTC_ANDROID, + "Android phone", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E618, + "HUAWEI Mobile E618", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E220, + "HUAWEI Mobile Modem", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_MOBILE, + "HUAWEI Mobile Modem", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_EM770W, + "HUAWEI Mobile Modem", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E1750, + "HUAWEI Mobile Modem", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E180, + "HUAWEI Mobile E180", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E510, + "HUAWEI Mobile E510", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E181, + "HUAWEI Mobile E181", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E1752, + "HUAWEI Mobile Modem", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E182, + "HUAWEI Mobile Modem", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E3372, + "HUAWEI Mobile Modem", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E161, + "HUAWEI Mobile Modem", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_K3765, + "HUAWEI Mobile K3765", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E1820, + "HUAWEI Mobile Modem", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_K4511, + "HUAWEI Mobile Modem K4511", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_K4510, + "HUAWEI Mobile Modem", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_K3772, + "HUAWEI Mobile K3772", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E353_INIT, + "HUAWEI Mobile E353 Initial", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E392_INIT, + "HUAWEI Mobile E392 Initial", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_K3765_INIT, + "HUAWEI Mobile K3765 Initial", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_K3772_INIT, + "HUAWEI Mobile K3772 Initial", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_MU609, + "HUAWEI Mobile ME906", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E173S, + "HUAWEI Mobile E173s", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E173S_INIT, + "HUAWEI Mobile E173s Initial", + }, + { + USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E303, + "HUAWEI Mobile E303", + }, + { + USB_VENDOR_HUAWEI3COM, USB_PRODUCT_HUAWEI3COM_WUB320G, + "Aolynk WUB320g", + }, + { + USB_VENDOR_HUMAX, USB_PRODUCT_HUMAX_PVRSMART, + "PVR-SMART", + }, + { + USB_VENDOR_HYUNDAI, USB_PRODUCT_HYUNDAI_PC5740, + "PC5740 EVDO", + }, + { + USB_VENDOR_HYUNDAI, USB_PRODUCT_HYUNDAI_UM175, + "UM175 EVDO", + }, + { + USB_VENDOR_IBM, USB_PRODUCT_IBM_OPTTRAVELMOUSE, + "Optical", + }, + { + USB_VENDOR_IBM, USB_PRODUCT_IBM_OPTWHEELMOUSE, + "Wheel", + }, + { + USB_VENDOR_IBM, USB_PRODUCT_IBM_USBCDROMDRIVE, + "CD-ROM", + }, + { + USB_VENDOR_IBM, USB_PRODUCT_IBM_THINKPADHUB, + "Hub", + }, + { + USB_VENDOR_ICOM, USB_PRODUCT_ICOM_ID1, + "ID-1", + }, + { + USB_VENDOR_ICOM, USB_PRODUCT_ICOM_RP2C1, + "ID-RP2C service 1", + }, + { + USB_VENDOR_ICOM, USB_PRODUCT_ICOM_RP2C2, + "ID-RP2C service 2", + }, + { + USB_VENDOR_ICOM, USB_PRODUCT_ICOM_RP2D, + "ID-RP2D", + }, + { + USB_VENDOR_ICOM, USB_PRODUCT_ICOM_RP2VT, + "ID-RP2V service T", + }, + { + USB_VENDOR_ICOM, USB_PRODUCT_ICOM_RP2VR, + "ID-RP2V service R", + }, + { + USB_VENDOR_ICOM, USB_PRODUCT_ICOM_RP4000VT, + "ID-RP4000V service T", + }, + { + USB_VENDOR_ICOM, USB_PRODUCT_ICOM_RP4000VR, + "ID-RP4000V service R", + }, + { + USB_VENDOR_ICOM, USB_PRODUCT_ICOM_RP2000VT, + "ID-RP2000V service T", + }, + { + USB_VENDOR_ICOM, USB_PRODUCT_ICOM_RP2000VR, + "ID-RP2000V service R", + }, + { + USB_VENDOR_IDOWELL, USB_PRODUCT_IDOWELL_IDOWELL, + "UPS", + }, + { + USB_VENDOR_IDQUANTIQUE, USB_PRODUCT_IDQUANTIQUE_QUANTISUSB, + "Quantis USB", + }, + { + USB_VENDOR_IDTECH, USB_PRODUCT_IDTECH_SERIAL, + "Serial", + }, + { + USB_VENDOR_IIYAMA, USB_PRODUCT_IIYAMA_HUB, + "Hub", + }, + { + USB_VENDOR_IMATION, USB_PRODUCT_IMATION_FLASHGO, + "Flash Go!", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4, + "EdgePort/4 RS232", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_HUBPORT7, + "Hubport/7", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_RAPIDPORT4, + "Rapidport/4", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4T, + "Edgeport/4 RS232", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT2, + "Edgeport/2 RS232", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4I, + "Edgeport/4 RS422", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT2I, + "Edgeport/2 RS422/RS485", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_HUBPORT4, + "Hubport/4", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT8HAND, + "Hand-built Edgeport/8", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_MULTIMODEM, + "MultiTech version of RP/4", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORTPPORT, + "Edgeport/(4)21 Parallel", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT421, + "Edgeport/421 Hub+RS232+Parallel", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT21, + "Edgeport/21 RS232+Parallel", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT8DC, + "1/2 Edgeport/8", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT8, + "Edgeport/8", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT2DIN, + "Edgeport/2 RS232/DIN", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4DIN, + "Edgeport/4 RS232/DIN", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT16DC, + "1/2 Edgeport/16", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORTCOMP, + "Edgeport Compatible", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT8I, + "Edgeport/8 RS422", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_WATCHPORTH, + "WatchPort/H", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_MT4X56USB, + "OEM device", + }, + { + USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_F5U002, + "Parallel", + }, + { + USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ATAPI, + "ATAPI", + }, + { + USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_IDEUSB2, + "USB2 Storage", + }, + { + USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ISD110, + "IDE ISD110", + }, + { + USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ISD105, + "IDE ISD105", + }, + { + USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_DRIVEV2, + "Portable USB Harddrive V2", + }, + { + USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_DRIVEV2_5, + "Portable USB Harddrive V2", + }, + { + USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_USBCABLE, + "USB cable", + }, + { + USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ADAPTERV2, + "USB Storage Adapter V2", + }, + { + USB_VENDOR_INTEL, USB_PRODUCT_INTEL_EASYPC_CAMERA, + "EasyPC", + }, + { + USB_VENDOR_INTEL, USB_PRODUCT_INTEL_AP310, + "AP310 AnyPoint II", + }, + { + USB_VENDOR_INTEL, USB_PRODUCT_INTEL_I2011B, + "Wireless 2011B", + }, + { + USB_VENDOR_INTEL, USB_PRODUCT_INTEL_TESTBOARD, + "82930 test board", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_RMH_1, + "Rate Matching Hub", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_RMH_2, + "Rate Matching Hub", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_BLUETOOTH3, + "Bluetooth", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_BLUETOOTH, + "Bluetooth", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_BLUETOOTH2, + "Bluetooth", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_RMH_3, + "Rate Matching Hub", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_RMH_5, + "Rate Matching Hub", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_RMH_7, + "Rate Matching Hub", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_RMH_4, + "Rate Matching Hub", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_RMH_6, + "Rate Matching Hub", + }, + { + USB_VENDOR_INTEL2, USB_PRODUCT_INTEL2_RMH_8, + "Rate Matching Hub", + }, + { + USB_VENDOR_INTERBIO, USB_PRODUCT_INTERBIO_IOBOARD, + "IO Board", + }, + { + USB_VENDOR_INTERBIO, USB_PRODUCT_INTERBIO_MINIIOBOARD, + "Mini IO Board", + }, + { + USB_VENDOR_INTERBIO, USB_PRODUCT_INTERBIO_MINIIOBOARD2, + "Mini IO Board", + }, + { + USB_VENDOR_INTERSIL, USB_PRODUCT_INTERSIL_PRISM_GT, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_INTERSIL, USB_PRODUCT_INTERSIL_PRISM_2X, + "Prism2.x WLAN", + }, + { + USB_VENDOR_INTREPIDCS, USB_PRODUCT_INTREPIDCS_VALUECAN, + "ValueCAN", + }, + { + USB_VENDOR_INTREPIDCS, USB_PRODUCT_INTREPIDCS_NEOVI, + "NeoVI Blue", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBSSMRW, + "USB-SSMRW SD-card", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBSDRW, + "USB-SDRW SD-card", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETT, + "USB ET/T", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETTX, + "USB ET/TX", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETTXS, + "USB ET/TX-S", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBWNB11A, + "USB WN-B11", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBWNB11, + "USB Airport WN-B11", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBWNG54US, + "USB WN-G54/US", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBWNG54US_NF, + "USB WN-G54/US", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_ETXUS2, + "ETX-US2", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_ETGUS2, + "ETG-US2", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_FT232R, + "FT232R", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_WNGDNUS2, + "WN-GDN/US2", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_RT3072_1, + "RT3072", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_RT3072_2, + "RT3072", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_RT3072_3, + "RT3072", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_RT3072_4, + "RT3072", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_WNG150UM, + "WN-G150UM", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBRSAQ, + "RSAQ1 Serial", + }, + { + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBRSAQ5, + "RSAQ5 Serial", + }, + { + USB_VENDOR_IODATA2, USB_PRODUCT_IODATA2_USB2SC, + "USB2.0-SCSI Bridge USB2-SC", + }, + { + USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP100, + "Zip 100", + }, + { + USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP250, + "Zip 250", + }, + { + USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP250_2, + "Zip 250", + }, + { + USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_CDRW, + "CDRW 9602", + }, + { + USB_VENDOR_IRIVER, USB_PRODUCT_IRIVER_IFP_1XX, + "iFP-1xx", + }, + { + USB_VENDOR_IRIVER, USB_PRODUCT_IRIVER_IFP_3XX, + "iFP-3xx", + }, + { + USB_VENDOR_IRIVER, USB_PRODUCT_IRIVER_IFP_5XX, + "iFP-5xx", + }, + { + USB_VENDOR_ISSC, USB_PRODUCT_ISSC_KYBT100, + "KY-BT100 Bluetooth", + }, + { + USB_VENDOR_ITEGNO, USB_PRODUCT_ITEGNO_WM1080A, + "WM1080A", + }, + { + USB_VENDOR_JABLOTRON, USB_PRODUCT_JABLOTRON_PC60B, + "PC-60B", + }, + { + USB_VENDOR_JATON, USB_PRODUCT_JATON_EDA, + "Ethernet", + }, + { + USB_VENDOR_JENOPTIK, USB_PRODUCT_JENOPTIK_JD350, + "JD 350", + }, + { + USB_VENDOR_JETI, USB_PRODUCT_JETI_SPC1201, + "SPECBOS 1201", + }, + { + USB_VENDOR_JRC, USB_PRODUCT_JRC_AH_J3001V_J3002V, + "AirH\"PHONE AH-J3001V/J3002V", + }, + { + USB_VENDOR_JVC, USB_PRODUCT_JVC_MP_PRX1, + "MP-PRX1", + }, + { + USB_VENDOR_JVC, USB_PRODUCT_JVC_MP_XP7250_WL, + "MP-XP7250 Builtin WLAN", + }, + { + USB_VENDOR_KAMSTRUP, USB_PRODUCT_KAMSTRUP_OPTICALEYE, + "Optical Eye/3-wire", + }, + { + USB_VENDOR_KAMSTRUP, USB_PRODUCT_KAMSTRUP_MBUS_250D, + "M-Bus Master MultiPort 250D", + }, + { + USB_VENDOR_KAWATSU, USB_PRODUCT_KAWATSU_MH4000P, + "MiniHub 4000P", + }, + { + USB_VENDOR_KAWATSU, USB_PRODUCT_KAWATSU_KC180, + "KC-180 IrDA", + }, + { + USB_VENDOR_KEISOKUGIKEN, USB_PRODUCT_KEISOKUGIKEN_USBDAQ, + "HKS-0200 USBDAQ", + }, + { + USB_VENDOR_KENSINGTON, USB_PRODUCT_KENSINGTON_ORBIT, + "Orbit trackball", + }, + { + USB_VENDOR_KENSINGTON, USB_PRODUCT_KENSINGTON_TURBOBALL, + "TurboBall", + }, + { + USB_VENDOR_KENSINGTON, USB_PRODUCT_KENSINGTON_ORBIT_MAC, + "Orbit trackball for Mac", + }, + { + USB_VENDOR_KENSINGTON, USB_PRODUCT_KENSINGTON_BT_EDR, + "Bluetooth", + }, + { + USB_VENDOR_KENSINGTON, USB_PRODUCT_KENSINGTON_VIDEOCAM_VGA, + "VideoCAM VGA", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA28_NF, + "USA-28 serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA28X_NF, + "USA-28X serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19_NF, + "USA-19 serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA18_NF, + "USA-18 serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA18X_NF, + "USA-18X serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19W_NF, + "USA-19W serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19, + "USA-19 serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19W, + "USA-19W serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA49W_NF, + "USA-49W serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA49W, + "USA-49W serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19QI_NF, + "USA-19QI serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19QI, + "USA-19QI serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19Q_NF, + "USA-19Q serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19Q, + "USA-19Q serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA28, + "USA-28 serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA28XXB, + "USA-28X/XB serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA18, + "USA-18 serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA18X, + "USA-18X serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA28XB_NF, + "USA-28XB serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA28XA_NF, + "USA-28XB serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA28XA, + "USA-28XA serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA18XA_NF, + "USA-18XA serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA18XA, + "USA-18XA serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19QW_NF, + "USA-19WQ serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19QW, + "USA-19WQ serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_USA19HS, + "USA-19HS serial", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_UIA10, + "UIA-10 remote control", + }, + { + USB_VENDOR_KEYSPAN, USB_PRODUCT_KEYSPAN_UIA11, + "UIA-11 remote control", + }, + { + USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_XX1, + "Ethernet", + }, + { + USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_KNU101TX, + "KNU101TX Ethernet", + }, + { + USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BT, + "10BT Ethernet", + }, + { + USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BTN, + "10BT Ethernet", + }, + { + USB_VENDOR_KOBIL, USB_PRODUCT_KOBIL_B1, + "Konverter for B1", + }, + { + USB_VENDOR_KOBIL, USB_PRODUCT_KOBIL_KAAN, + "Konverter for KAAN", + }, + { + USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC220, + "Digital Science DC220", + }, + { + USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC260, + "Digital Science DC260", + }, + { + USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC265, + "Digital Science DC265", + }, + { + USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC290, + "Digital Science DC290", + }, + { + USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC240, + "Digital Science DC240", + }, + { + USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC280, + "Digital Science DC280", + }, + { + USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DX4900, + "EasyShare DX4900", + }, + { + USB_VENDOR_KONICA, USB_PRODUCT_KONICA_CAMERA, + "Camera", + }, + { + USB_VENDOR_KYE, USB_PRODUCT_KYE_NICHE, + "Niche mouse", + }, + { + USB_VENDOR_KYE, USB_PRODUCT_KYE_NETSCROLL, + "Genius NetScroll mouse", + }, + { + USB_VENDOR_KYE, USB_PRODUCT_KYE_FLIGHT2000, + "Flight 2000 joystick", + }, + { + USB_VENDOR_KYE, USB_PRODUCT_KYE_VIVIDPRO, + "ColorPage Vivid-Pro", + }, + { + USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_AHK3001V, + "AH-K3001V", + }, + { + USB_VENDOR_KYOCERA2, USB_PRODUCT_KYOCERA2_KPC650, + "KPC650 EVDO", + }, + { + USB_VENDOR_LACIE, USB_PRODUCT_LACIE_HD, + "Hard Disk", + }, + { + USB_VENDOR_LACIE, USB_PRODUCT_LACIE_CDRW, + "CD R/W", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M121, + "Model 121", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M218A, + "Model 218A", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M219, + "Model 219", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M233, + "Model 233", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M235, + "Model 235", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M335, + "Model 335", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M336, + "Model 336", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M350, + "Model 350", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M371, + "Model 371", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M411, + "Model 411", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M425, + "Model 425", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M455A, + "Model 455A", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M475A, + "Model 475A", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M465, + "Model 465", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M625A, + "Model 625A", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M642A, + "Model 642A", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M648, + "Model 648", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M737, + "Model 737", + }, + { + USB_VENDOR_LAKESHORE, USB_PRODUCT_LAKESHORE_M776, + "Model 776", + }, + { + USB_VENDOR_LARSENBRUSGAARD, USB_PRODUCT_LARSENBRUSGAARD_ALTITRACK, + "AltiTrack", + }, + { + USB_VENDOR_LEADTEK, USB_PRODUCT_LEADTEK_9531, + "9531 GPS", + }, + { + USB_VENDOR_LENOVO, USB_PRODUCT_LENOVO_AX88179, + "AX88179", + }, + { + USB_VENDOR_LENOVO, USB_PRODUCT_LENOVO_DOCK_ETHERNET, + "USB-C Dock Ethernet", + }, + { + USB_VENDOR_LENOVO, USB_PRODUCT_LENOVO_ETHERNET, + "USB 2.0 Ethernet", + }, + { + USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_JUMPSHOT, + "jumpSHOT CompactFlash", + }, + { + USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_2662WAR, + "2662W-AR", + }, + { + USB_VENDOR_LEXMARK, USB_PRODUCT_LEXMARK_S2450, + "Optra S 2450", + }, + { + USB_VENDOR_LIEBERT, USB_PRODUCT_LIEBERT_UPS, + "UPS", + }, + { + USB_VENDOR_LIEBERT2, USB_PRODUCT_LIEBERT2_PSA, + "PowerSure PSA UPS", + }, + { + USB_VENDOR_LINKINSTRUMENTS, USB_PRODUCT_LINKINSTRUMENTS_MSO19, + "Link Instruments MSO-19", + }, + { + USB_VENDOR_LINKINSTRUMENTS, USB_PRODUCT_LINKINSTRUMENTS_MSO28, + "Link Instruments MSO-28", + }, + { + USB_VENDOR_LINKINSTRUMENTS, USB_PRODUCT_LINKINSTRUMENTS_MSO28_2, + "Link Instruments MSO-28", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_MAUSB2, + "Camedia MAUSB-2", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TX1, + "USB10TX", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_HG20F9, + "HG20F9 Ethernet", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T, + "USB10T Ethernet", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100TX, + "USB100TX Ethernet", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100H1, + "USB100H1 Ethernet/HPNA", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TA, + "USB10TA Ethernet", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_WUSB11, + "WUSB11 802.11b", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_WUSB11_25, + "WUSB11 802.11b v2.5", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_WUSB12_11, + "WUSB12 802.11b v1.1", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TX2, + "USB10TX", + }, + { + USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_NWU11B, + "NWU11B", + }, + { + USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_USB200M, + "USB 2.0 10/100 Ethernet controller", + }, + { + USB_VENDOR_LINKSYS3, USB_PRODUCT_LINKSYS3_WUSB11V28, + "WUSB11 v2.8", + }, + { + USB_VENDOR_LINKSYS3, USB_PRODUCT_LINKSYS3_WUSB11V30, + "WUSB11 v3.0", + }, + { + USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_USB1000, + "USB1000", + }, + { + USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB100, + "WUSB100", + }, + { + USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB600N, + "WUSB600N", + }, + { + USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB54GCV2, + "WUSB54GC v2", + }, + { + USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB54GCV3, + "WUSB54GC v3", + }, + { + USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_RT3070, + "RT3070", + }, + { + USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB600NV2, + "WUSB600N v2", + }, + { + USB_VENDOR_LITEON, USB_PRODUCT_LITEON_AR9271, + "AR9271", + }, + { + USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LAN_GTJU2, + "LAN-GTJ/U2", + }, + { + USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LANTX, + "LAN-TX", + }, + { + USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_RTL8187, + "RTL8187", + }, + { + USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_RT2870_3, + "RT2870", + }, + { + USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LANW300NU2, + "LAN-W300N/U2", + }, + { + USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LANW150NU2, + "LAN-W150N/U2", + }, + { + USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LANW300NU2S, + "LAN-W300N/U2S", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_M2452, + "M2452 keyboard", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_M4848, + "M4848 mouse", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_PAGESCAN, + "PageScan", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMWEB, + "QuickCam Web", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WEBCAMC200, + "Webcam C200", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WEBCAMC250, + "Webcam C250", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WEBCAMC500, + "Webcam C500", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRO, + "QuickCam Pro", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WEBCAMC210, + "Webcam C210", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WEBCAMC310, + "Webcam C310", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_HDPROC910, + "HD Pro Webcam C910", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WEBCAMC270, + "Webcam C270", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMEXP, + "QuickCam Express", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAM, + "QuickCam", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMNBDLX, + "QuickCam Notebook Deluxe", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRO3K, + "QuickCam Pro 3000", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMNBPRO_1, + "QuickCam Notebook Pro", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRO4K, + "QuickCam Pro 4000", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMZOOM, + "QuickCam Zoom", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMFUSION_1, + "QuickCam Fusion", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMORBITMP_1, + "QuickCam Orbit MP", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMNBPRO, + "QuickCam Notebook Pro", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRO5K_1, + "QuickCam Pro 5000", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMOEM_1, + "QuickCam OEM", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMOEM_2, + "QuickCam OEM", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMULTVIS, + "QuickCam Ultra Vision", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMFUSION_2, + "QuickCam Fusion", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMNBPRO_2, + "QuickCam Notebook Pro", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMORBITMP_2, + "QuickCam Orbit MP", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRO5K_2, + "QuickCam Pro 5000", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRO9K, + "QuickCam Pro 9000", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRONB, + "QuickCam Pro Notebook", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMCOMMDLX, + "QuickCam Communicate Deluxe", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMORBITAF, + "QuickCam Orbit AF", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMCOMMMP, + "QuickCam Communicate MP", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAME3500P, + "QuickCam E 3500 Plus", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMDLXNB, + "QuickCam Deluxe Notebook", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_N43, + "N43", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_N48, + "N48 mouse", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_MBA47, + "M-BA47 mouse", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WMMOUSE, + "WingMan Gaming Mouse", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_BD58, + "BD58 mouse", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_UN58A, + "iFeel Mouse", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WMPAD, + "WingMan GamePad Extreme", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WMRPAD, + "WingMan RumblePad", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WMJOY, + "WingMan Force joystick", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WMFFGP, + "WingMan Formula Force GP (GT-Force)", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_ITOUCH, + "iTouch Keyboard", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_BB13, + "USB-PS/2 Trackball", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_BB18, + "TrackMan Wheel", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_RK53, + "Cordless mouse", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_RB6, + "Cordless keyboard", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_CDO, + "Cordless Desktop Optical", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRO2, + "QuickCam Pro", + }, + { + USB_VENDOR_LONGCHEER, USB_PRODUCT_LONGCHEER_D21LCMASS, + "Emobile D21LC Mass only mode", + }, + { + USB_VENDOR_LONGCHEER, USB_PRODUCT_LONGCHEER_D21LC, + "Emobile D21LC", + }, + { + USB_VENDOR_LONGCHEER, USB_PRODUCT_LONGCHEER_510FU, + "IIJmobile 510FU", + }, + { + USB_VENDOR_LONGCHEER, USB_PRODUCT_LONGCHEER_510FUMASS, + "IIJmobile 510FU Mass only mode", + }, + { + USB_VENDOR_LUCENT, USB_PRODUCT_LUCENT_EVALKIT, + "USS-720 evaluation kit", + }, + { + USB_VENDOR_MACALLY, USB_PRODUCT_MACALLY_MOUSE1, + "mouse", + }, + { + USB_VENDOR_MARVELL, USB_PRODUCT_MARVELL_SHEEVAPLUG, + "SheevaPlug", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0100, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0101, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0102, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0103, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0104, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0105, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0106, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0107, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0108, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0109, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_010A, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_010B, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_010C, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_010D, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_010E, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_010F, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0110, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0111, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0112, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0113, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0114, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0115, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0116, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0117, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0118, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0119, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_011A, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_011B, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_011C, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_011D, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_011E, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_011F, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0120, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0121, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0122, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0123, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0124, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0125, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0126, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0127, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0128, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0129, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_012A, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_012B, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_012C, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_012D, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_012E, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_012F, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0130, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0131, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0132, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0133, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0134, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0135, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0136, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0137, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0138, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0139, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_013A, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_013B, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_013C, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_013D, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_013E, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_013F, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0140, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0141, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0142, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0143, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0144, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0145, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0146, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0147, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0148, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0149, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_014A, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_014B, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_014C, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_014D, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_014E, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_014F, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0150, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0151, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0152, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0153, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0154, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0155, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0156, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0157, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0158, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0159, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_015A, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_015B, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_015C, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_015D, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_015E, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_015F, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0160, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0161, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0162, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0163, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0164, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0165, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0166, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0167, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0168, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0169, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_016A, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_016B, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_016C, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_016D, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_016E, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_016F, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0170, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0171, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0172, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0173, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0174, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0175, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0176, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0177, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0178, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0179, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_017A, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_017B, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_017C, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_017D, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_017E, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_017F, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0180, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0181, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0182, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0183, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0184, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0185, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0186, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0187, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0188, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0189, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_018A, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_018B, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_018C, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_018D, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_018E, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_018F, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0190, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0191, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0192, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0193, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0194, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0195, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0196, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0197, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0198, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_0199, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_019A, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_019B, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_019C, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_019D, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_019E, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_019F, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01A0, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01A1, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01A2, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01A3, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01A4, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01A5, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01A6, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01A7, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01A8, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01A9, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01AA, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01AB, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01AC, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01AD, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01AE, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01AF, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01B0, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01B1, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01B2, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01B3, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01B4, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01B5, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01B6, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01B7, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01B8, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01B9, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01BA, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01BB, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01BC, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01BD, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01BE, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01BF, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01C0, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01C1, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01C2, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01C3, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01C4, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01C5, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01C6, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01C7, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01C8, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01C9, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01CA, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01CB, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01CC, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01CD, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01CE, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01CF, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01D0, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01D1, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01D2, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01D3, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01D4, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01D5, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01D6, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01D7, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01D8, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01D9, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01DA, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01DB, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01DC, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01DD, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01DE, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01DF, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01E0, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01E1, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01E2, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01E3, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01E4, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01E5, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01E6, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01E7, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01E8, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01E9, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01EA, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01EB, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01EC, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01ED, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01EE, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01EF, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01F0, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01F1, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01F2, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01F3, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01F4, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01F5, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01F6, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01F7, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01F8, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01F9, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01FA, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01FB, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01FC, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01FD, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01FE, + "LCD", + }, + { + USB_VENDOR_MATRIXORB, USB_PRODUCT_MATRIXORB_LCD_01FF, + "LCD", + }, + { + USB_VENDOR_MCT, USB_PRODUCT_MCT_HUB0100, + "Hub", + }, + { + USB_VENDOR_MCT, USB_PRODUCT_MCT_DU_H3SP_USB232, + "D-Link DU-H3SP BAY Hub", + }, + { + USB_VENDOR_MCT, USB_PRODUCT_MCT_USB232, + "RS232", + }, + { + USB_VENDOR_MCT, USB_PRODUCT_MCT_SITECOM_USB232, + "Sitecom RS232", + }, + { + USB_VENDOR_MCT, USB_PRODUCT_MCT_ML_4500, + "ML-4500", + }, + { + USB_VENDOR_MDS, USB_PRODUCT_MDS_ISDBT, + "MDS ISDB-T tuner", + }, + { + USB_VENDOR_MECANIQUE, USB_PRODUCT_MECANIQUE_WISPY, + "MetaGeek Wi-Spy", + }, + { + USB_VENDOR_MECANIQUE, USB_PRODUCT_MECANIQUE_TELLSTICK, + "Telldus Tellstick", + }, + { + USB_VENDOR_MEDIATEK, USB_PRODUCT_MEDIATEK_UMASS, + "USB MSM installer", + }, + { + USB_VENDOR_MEDIATEK, USB_PRODUCT_MEDIATEK_DC_4COM, + "UMTS USB modem", + }, + { + USB_VENDOR_MEI, USB_PRODUCT_MEI_CASHFLOW_SC, + "Cashflow-SC", + }, + { + USB_VENDOR_MEI, USB_PRODUCT_MEI_S2000, + "Series 2000", + }, + { + USB_VENDOR_MEINBERG, USB_PRODUCT_MEINBERG_USB5131, + "USB 5131 DCF77 - Radio Clock", + }, + { + USB_VENDOR_MEINBERG, USB_PRODUCT_MEINBERG_DCF600USB, + "DCF600USB - Radio Clock", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX1, + "LUA-TX Ethernet", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX5, + "LUA-TX Ethernet", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUA2TX5, + "LUA2-TX Ethernet", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAKTX, + "LUA-KTX Ethernet", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_S11, + "WLI-USB-S11", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_MCRSM2, + "MCR-SM2 SmartMedia", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_DUBPXXG, + "USB-IDE Bridge: DUB-PxxG", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KS11G, + "WLI-USB-KS11G wlan", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2KTX, + "LUA-U2-KTX Ethernet", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KB11, + "WLI-USB-KB11 WLAN", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54YB, + "WLI-U2-KG54-YB WLAN", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54, + "WLI-U2-KG54 WLAN", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54AI, + "WLI-U2-KG54-AI WLAN", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2GT, + "LUA-U2-GT Ethernet", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_NINWIFI, + "Nintendo Wi-Fi", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIU2KAMG54, + "WLI-U2-KAMG54", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIU2KAMG54_NF, + "WLI-U2-KAMG54", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_PCOPRS1, + "PC-OP-RS1 RemoteStation", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HP, + "WLI-U2-SG54HP", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_G54HP, + "WLI-U2-G54HP", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54L, + "WLI-U2-KG54L", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCG300N, + "WLI-UC-G300N", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HG, + "WLI-U2-SG54HG", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCAG300N, + "WLI-UC-AG300N", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCGNHP, + "WLI-UC-GNHP", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCGN, + "WLI-UC-GN", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCG301N, + "WLI-UC-G301N", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCGNM, + "WLI-UC-GNM", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_WLIUCGNM2, + "WLI-UC-GNM2", + }, + { + USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY24I, + "Wi-Spy 2.4i", + }, + { + USB_VENDOR_METRICOM, USB_PRODUCT_METRICOM_RICOCHET_GS, + "Ricochet GS", + }, + { + USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS1, + "UPS", + }, + { + USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS2, + "UPS", + }, + { + USB_VENDOR_MICROCHIP, USB_PRODUCT_MICROCHIP_USBLCD20X2, + "USB-LCD-20x2", + }, + { + USB_VENDOR_MICROCHIP, USB_PRODUCT_MICROCHIP_USBLCD256X64, + "USB-LCD-256x64", + }, + { + USB_VENDOR_MICRODIA, USB_PRODUCT_MICRODIA_YUREX, + "YUREX", + }, + { + USB_VENDOR_MICRODIA, USB_PRODUCT_MICRODIA_CAM_1, + "CAM_1", + }, + { + USB_VENDOR_MICRODIA, USB_PRODUCT_MICRODIA_TEMPER, + "TEMPer sensor", + }, + { + USB_VENDOR_MICRODIA, USB_PRODUCT_MICRODIA_TEMPERHUM, + "TEMPerHUM sensor", + }, + { + USB_VENDOR_MICRONET, USB_PRODUCT_MICRONET_SP128AR, + "SP128AR EtherFast", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_SIDEPREC, + "SideWinder Precision Pro", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_INTELLIMOUSE, + "IntelliMouse", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_NATURALKBD, + "Natural", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_DDS80, + "Digital Sound System 80", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_SIDEWINDER, + "Sidewinder Precision Racing Wheel", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_INETPRO, + "Internet Keyboard Pro", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_TBEXPLORER, + "Trackball Explorer", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_INTELLIEYE, + "IntelliEye mouse", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_INETPRO2, + "Internet Keyboard Pro", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_MN510, + "MN510 Wireless", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_700WX, + "Palm 700WX", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_MN110, + "10/100 Ethernet", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLINTELLIMOUSE, + "Wireless Optical IntelliMouse", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLNOTEBOOK, + "Wireless Optical Mouse (Model 1023)", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLNOTEBOOK3, + "Wireless Optical Mouse 3000 (Model 1049)", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLNOTEBOOK2, + "Wireless Optical Mouse 3000 (Model 1056)", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_XBOX360_CONTROLLER, + "XBOX 360 Controller", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_XBOX360, + "XBOX 360 WLAN", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLMOBILEMOUSE3500, + "Wireless Mobile Mouse 3500", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_LIFECAM, + "Microsoft LifeCam", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLARCMOUSE, + "Wireless Arc Mouse (Model 1350)", + }, + { + USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIDB25, + "SCSI-DB25", + }, + { + USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIHD50, + "SCSI-HD50", + }, + { + USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_DPCM, + "CameraMate", + }, + { + USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_FREECOM, + "Freecom IDE", + }, + { + USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_336CX, + "Phantom 336CX - C3", + }, + { + USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_X6U, + "ScanMaker X6 - X6U", + }, + { + USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_C6, + "Phantom C6", + }, + { + USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_336CX2, + "Phantom 336CX - C3", + }, + { + USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6USL, + "ScanMaker V6USL", + }, + { + USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6USL2, + "ScanMaker V6USL", + }, + { + USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6UL, + "ScanMaker V6UL", + }, + { + USB_VENDOR_MIDIMAN, USB_PRODUCT_MIDIMAN_MIDISPORT2X2, + "Midisport 2x2", + }, + { + USB_VENDOR_MINDSATWORK, USB_PRODUCT_MINDSATWORK_DW, + "Digital Wallet", + }, + { + USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_S304, + "Dimage S304", + }, + { + USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_X, + "Dimage X", + }, + { + USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_DIMAGE7I, + "Dimage 7i", + }, + { + USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_DIMAGEA1, + "Dimage A1", + }, + { + USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_CDRRW, + "CD-R/RW Drive", + }, + { + USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_MOUSE, + "Mouse", + }, + { + USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_BLUETOOTH, + "Bluetooth", + }, + { + USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_FDD, + "FDD", + }, + { + USB_VENDOR_MOBILEACTION, USB_PRODUCT_MOBILEACTION_MA620, + "MA-620 IrDA", + }, + { + USB_VENDOR_MOBILITY, USB_PRODUCT_MOBILITY_ED200H, + "EasiDock 200 Serial", + }, + { + USB_VENDOR_MOBILITY, USB_PRODUCT_MOBILITY_EA, + "Ethernet", + }, + { + USB_VENDOR_MOBILITY, USB_PRODUCT_MOBILITY_EASIDOCK, + "EasiDock Ethernet", + }, + { + USB_VENDOR_MODACOM, USB_PRODUCT_MODACOM_MWIMAX, + "MODACOM Mobile wimax adaptor", + }, + { + USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7703, + "MCS7703 Serial", + }, + { + USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7715, + "MCS7715 Serial Parallel", + }, + { + USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7730, + "MCS7730 Ethernet", + }, + { + USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7810, + "MCS7810 Serial", + }, + { + USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7820, + "MCS7820 Serial", + }, + { + USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7830, + "MCS7830 Ethernet", + }, + { + USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7832, + "MCS7832 Ethernet", + }, + { + USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7840, + "MCS7840 Serial", + }, + { + USB_VENDOR_MOTOROLA, USB_PRODUCT_MOTOROLA_MC141555, + "MC141555 hub controller", + }, + { + USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_T720C, + "T720c", + }, + { + USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_V360, + "V360", + }, + { + USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN, + "USBLAN", + }, + { + USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN2, + "USBLAN", + }, + { + USB_VENDOR_MOTOROLA3, USB_PRODUCT_MOTOROLA3_SB4100, + "SB4100 Cable Modem", + }, + { + USB_VENDOR_MOTOROLA3, USB_PRODUCT_MOTOROLA3_SB5100, + "SB5100 Cable Modem", + }, + { + USB_VENDOR_MOTOROLA4, USB_PRODUCT_MOTOROLA4_RT2770, + "RT2770", + }, + { + USB_VENDOR_MOTOROLA4, USB_PRODUCT_MOTOROLA4_RT3070, + "RT3070", + }, + { + USB_VENDOR_MOXA, USB_PRODUCT_MOXA_UPORT1110, + "UPort 1110", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_WLAN, + "WLAN", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_BLUETOOTH, + "Bluetooth", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_1, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_2, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_8, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_3, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_9, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570, + "RT2570", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570_2, + "RT2570", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570_3, + "RT2570", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_1, + "RT2573", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_2, + "RT2573", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_4, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_5, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_10, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_12, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_13, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_6, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_11, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_14, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_15, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT3070_7, + "RT3070", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_3, + "RT2573", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_4, + "RT2573", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_AX88772A, + "AX88772A", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_BLUETOOTH_2, + "Bluetooth", + }, + { + USB_VENDOR_MSI, USB_PRODUCT_MSI_BLUETOOTH_3, + "Bluetooth", + }, + { + USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY, + "DiskOnKey", + }, + { + USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY2, + "DiskOnKey", + }, + { + USB_VENDOR_MULTITECH, USB_PRODUCT_MULTITECH_ATLAS, + "MT5634ZBA modem", + }, + { + USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200CU, + "1200 CU", + }, + { + USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_600CU, + "600 CU", + }, + { + USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200USB, + "1200", + }, + { + USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200UB, + "1200 UB", + }, + { + USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200USBPLUS, + "1200 Plus", + }, + { + USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200CUPLUS, + "1200 CU Plus", + }, + { + USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_BEARPAW1200F, + "BearPaw 1200F", + }, + { + USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_600USB, + "600", + }, + { + USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_MDC800, + "MDC-800", + }, + { + USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_DV2000, + "DV2000", + }, + { + USB_VENDOR_MUSTEK2, USB_PRODUCT_MUSTEK2_PM800, + "PowerMust 800", + }, + { + USB_VENDOR_NATIONAL, USB_PRODUCT_NATIONAL_BEARPAW1200, + "BearPaw 1200", + }, + { + USB_VENDOR_NATIONAL, USB_PRODUCT_NATIONAL_BEARPAW2400, + "BearPaw 2400", + }, + { + USB_VENDOR_NEC, USB_PRODUCT_NEC_HUB, + "hub", + }, + { + USB_VENDOR_NEC, USB_PRODUCT_NEC_WL300NUG, + "WL300NU-G", + }, + { + USB_VENDOR_NEC, USB_PRODUCT_NEC_USB2EXTEND, + "Repeater", + }, + { + USB_VENDOR_NEC, USB_PRODUCT_NEC_HUB_B, + "hub", + }, + { + USB_VENDOR_NEC, USB_PRODUCT_NEC_HUB_C, + "hub", + }, + { + USB_VENDOR_NEC, USB_PRODUCT_NEC_PICTY760, + "Picty760", + }, + { + USB_VENDOR_NEC, USB_PRODUCT_NEC_PICTY900, + "Picty900", + }, + { + USB_VENDOR_NEC, USB_PRODUCT_NEC_PICTY920, + "Picty920", + }, + { + USB_VENDOR_NEC, USB_PRODUCT_NEC_PICTY800, + "Picty800", + }, + { + USB_VENDOR_NEC2, USB_PRODUCT_NEC2_HUB2_0, + "USB2.0 Hub", + }, + { + USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND3050, + "6-in-1 Flash Device Controller", + }, + { + USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND3260, + "8-in-1 Flash Device Controller", + }, + { + USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND5010, + "Multi-format Flash Controller", + }, + { + USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_TURBOCONNECT, + "Turbo-Connect", + }, + { + USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_CLIK40, + "Clik! 40", + }, + { + USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_ETHERNETGADGET, + "EthernetGadget", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101, + "Ethernet", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101X, + "Ethernet", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA101, + "10/100 Ethernet", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA120, + "USB 2.0 Fast Ethernet", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_M7100, + "M7100", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_MA111NA, + "802.11b", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_MA111V2, + "802.11b V2", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WG111V2_2, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WG111V3, + "WG111v3", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WG111U, + "WG111U", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WG111U_NF, + "WG111U", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WG111V2, + "WG111v2", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WN111V2, + "WN111V2", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNDA3100, + "WNDA3100", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNDA3200, + "WNDA3200", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1100, + "WNA1100", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1000, + "WNA1000", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1000M, + "WNA1000M", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1000MV2, + "WNA1000Mv2", + }, + { + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_N300MA, + "N300MA", + }, + { + USB_VENDOR_NETGEAR2, USB_PRODUCT_NETGEAR2_MA101, + "MA101", + }, + { + USB_VENDOR_NETGEAR2, USB_PRODUCT_NETGEAR2_MA101B, + "MA101 Rev B", + }, + { + USB_VENDOR_NETGEAR3, USB_PRODUCT_NETGEAR3_WG111T, + "WG111T", + }, + { + USB_VENDOR_NETGEAR3, USB_PRODUCT_NETGEAR3_WG111T_NF, + "WG111T", + }, + { + USB_VENDOR_NETGEAR3, USB_PRODUCT_NETGEAR3_WG111T_1, + "WG111T", + }, + { + USB_VENDOR_NETGEAR3, USB_PRODUCT_NETGEAR3_WPN111, + "WPN111", + }, + { + USB_VENDOR_NETGEAR3, USB_PRODUCT_NETGEAR3_WPN111_NF, + "WPN111", + }, + { + USB_VENDOR_NETGEAR4, USB_PRODUCT_NETGEAR4_RTL8188CU, + "RTL8188CU", + }, + { + USB_VENDOR_NETWEEN, USB_PRODUCT_NETWEEN_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_NHJ, USB_PRODUCT_NHJ_CAM2, + "Camera", + }, + { + USB_VENDOR_NI, USB_PRODUCT_NI_GPIB_USB_A, + "GPIB-USB-A", + }, + { + USB_VENDOR_NIKON, USB_PRODUCT_NIKON_E990, + "E990", + }, + { + USB_VENDOR_NIKON, USB_PRODUCT_NIKON_E880, + "E880", + }, + { + USB_VENDOR_NIKON, USB_PRODUCT_NIKON_E885, + "E885", + }, + { + USB_VENDOR_NOKIA, USB_PRODUCT_NOKIA_CA42, + "CA-42 Serial", + }, + { + USB_VENDOR_NOKIA2, USB_PRODUCT_NOKIA2_CS15UMASS, + "Internet Stick CS-15 (umass mode)", + }, + { + USB_VENDOR_NOKIA2, USB_PRODUCT_NOKIA2_CS15, + "Internet Stick CS-15", + }, + { + USB_VENDOR_NORITAKE, USB_PRODUCT_NORITAKE_COMEMO, + "Noritake COMEMO", + }, + { + USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_NV902W, + "NV-902W", + }, + { + USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_RT2573, + "RT2573", + }, + { + USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_RTL8188CU, + "RTL8188CU", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_EXPRESSCARD, + "ExpressCard 3G", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MERLINV620, + "V620", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MERLINV740, + "V740", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V720, + "V720", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MERLINU740, + "U740", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MERLINU740_2, + "U740", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U870, + "U870", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_XU870, + "XU870", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_X950D, + "X950D", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ES620, + "ES620 CDMA", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U720, + "U720", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_EU870D, + "EU870D", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U727, + "U727", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MC950D, + "MC950D HSUPA", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MERLINX950D, + "X950D", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ZEROCD2, + "ZeroCD", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MC760CD, + "MC760 CD", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U760, + "U760", + }, + { + USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MC760, + "MC760", + }, + { + USB_VENDOR_NOVATEL1, USB_PRODUCT_NOVATEL1_FLEXPACKGPS, + "NovAtel FlexPack GPS", + }, + { + USB_VENDOR_O2MICRO, USB_PRODUCT_O2MICRO_OZ776HUB, + "OZ776 Hub", + }, + { + USB_VENDOR_OCT, USB_PRODUCT_OCT_USBTOETHER, + "Ethernet", + }, + { + USB_VENDOR_OCT, USB_PRODUCT_OCT_US2308, + "Serial", + }, + { + USB_VENDOR_OLIMEX, USB_PRODUCT_OLIMEX_OPENOCD_JTAG, + "OpenOCD JTAG", + }, + { + USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1, + "C-1", + }, + { + USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C700, + "C-700 Ultra Zoom", + }, + { + USB_VENDOR_OMNIVISION, USB_PRODUCT_OMNIVISION_OV511, + "OV511", + }, + { + USB_VENDOR_OMNIVISION, USB_PRODUCT_OMNIVISION_OV511PLUS, + "OV511+", + }, + { + USB_VENDOR_OMRON, USB_PRODUCT_OMRON_BX50F, + "BX50F UPS", + }, + { + USB_VENDOR_OMRON, USB_PRODUCT_OMRON_BX35F, + "BX35F UPS", + }, + { + USB_VENDOR_OMRON, USB_PRODUCT_OMRON_BY35S, + "BY35S UPS", + }, + { + USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MD2, + "disk", + }, + { + USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MDCFEB, + "MDCFE-B CF", + }, + { + USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_SIIGMS, + "Memory Stick+CF", + }, + { + USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_DATAFAB3, + "Datafab-based", + }, + { + USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_DATAFAB4, + "Datafab-based", + }, + { + USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_PNYCFSM, + "PNY/Datafab CF+SM", + }, + { + USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_STECHCFSM, + "Simple Tech/Datafab CF+SM", + }, + { + USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_LC1, + "CF + SM Combo (LC1)", + }, + { + USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MD1II, + "Datafab MD1-II PC-Card", + }, + { + USB_VENDOR_ONSPEC2, USB_PRODUCT_ONSPEC2_8IN2, + "8In2", + }, + { + USB_VENDOR_OPENMOKO, USB_PRODUCT_OPENMOKO_N1793D, + "Neo1973 Debug", + }, + { + USB_VENDOR_OPENMOKO2, USB_PRODUCT_OPENMOKO2_ONERNG, + "Moonbase Otago OneRNG", + }, + { + USB_VENDOR_OPENMOKO2, USB_PRODUCT_OPENMOKO2_CHAOSKEY, + "Altusmetrum ChaosKey 1.0", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_VODAFONEMC3G, + "Vodafone Mobile Connect 3G", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GFUSION, + "GlobeTrotter 3G FUSION", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GQUAD, + "GlobeTrotter 3G QUAD", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GQUADPLUS, + "GlobeTrotter 3G QUAD PLUS", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTMAX36, + "GlobeTrotter MAX 3.6/7.2", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GPLUS, + "GlobeTrotter 3G PLUS", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_SCORPION, + "GlobeTrotter HSDPA Modem", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GSICON72, + "GlobeSurfer iCON 7.2", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_ICON225, + "iCON 225", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTHSUPA380E, + "GlobeTrotter HSUPA 380E", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_ICON322, + "iCON 322", + }, + { + USB_VENDOR_OPTION, USB_PRODUCT_OPTION_ICON505, + "iCON 505", + }, + { + USB_VENDOR_OQO, USB_PRODUCT_OQO_WIFI01, + "model 01 WiFi", + }, + { + USB_VENDOR_OQO, USB_PRODUCT_OQO_BT01, + "model 01 Bluetooth", + }, + { + USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01PLUS, + "model 01+ Ethernet", + }, + { + USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01, + "model 01 Ethernet", + }, + { + USB_VENDOR_OREGONSCI, USB_PRODUCT_OREGONSCI_OWL_CM160, + "OWL CM-160", + }, + { + USB_VENDOR_OTI, USB_PRODUCT_OTI_SOLID, + "Solid state disk", + }, + { + USB_VENDOR_OTI, USB_PRODUCT_OTI_DKU5, + "DKU-5 Serial", + }, + { + USB_VENDOR_OVISLINK, USB_PRODUCT_OVISLINK_RT3071, + "RT3071", + }, + { + USB_VENDOR_OVISLINK, USB_PRODUCT_OVISLINK_RT3072, + "RT3072", + }, + { + USB_VENDOR_OWEN, USB_PRODUCT_OWEN_AC4, + "AC4 USB-RS485", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_M500, + "Palm m500", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_M505, + "Palm m505", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_M515, + "Palm m515", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_I705, + "Palm i705", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_Z, + "Palm Tungsten Z", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_M125, + "Palm m125", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_M130, + "Palm m130", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_T, + "Palm Tungsten T", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE_31, + "Palm Zire 31", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE, + "Palm Zire", + }, + { + USB_VENDOR_PALM, USB_PRODUCT_PALM_SERIAL, + "USB Serial Adaptor", + }, + { + USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_LS120, + "LS-120", + }, + { + USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_SDCAAE, + "MultiMediaCard", + }, + { + USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_TYTP50P6S, + "TY-TP50P6-S 50in Touch Panel", + }, + { + USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_N5HBZ0000055, + "UB94", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_SB485_1, + "SB485 USB-485/422", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_AP485_1, + "AP485 USB-RS485", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_SB422_1, + "SB422 USB-RS422", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_SB485_2, + "SB485 USB-485/422", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_AP485_2, + "AP485 USB-RS485", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_SB422_2, + "SB422 USB-RS422", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_SB485S, + "SB485S USB-485/422", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_SB485C, + "SB485C USB-485/422", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_SERIAL, + "Serial", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_LEC, + "Serial", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_SB232, + "SB232 USB-RS232", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_TMU, + "TMU Thermometer", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_IRAMP, + "IRAmp Duplex", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_DRAK5, + "DRAK5", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_QUIDO88, + "QUIDO USB 8/8", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_QUIDO44, + "QUIDO USB 4/4", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_QUIDO22, + "QUIDO USB 2/2", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_QUIDO101, + "QUIDO USB 10/1", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_QUIDO303, + "QUIDO USB 30/3", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_QUIDO603, + "QUIDO USB 60(100)/3", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_QUIDO216, + "QUIDO USB 2/16", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_QUIDO332, + "QUIDO USB 3/32", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_DRAK6, + "DRAK6 USB", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_STAVOVY, + "UPS-USB Stavovy", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_MUC, + "MU Controller", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_SIMUKEY, + "SimuKey", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_AD4USB, + "AD4USB", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_GOLIATH_MUX, + "GOLIATH MUX", + }, + { + USB_VENDOR_PAPOUCH, USB_PRODUCT_PAPOUCH_GOLIATH_MSR, + "GOLIATH MSR", + }, + { + USB_VENDOR_PARA, USB_PRODUCT_PARA_RT3070, + "RT3070", + }, + { + USB_VENDOR_PEGATRON, USB_PRODUCT_PEGATRON_RT2870, + "RT2870", + }, + { + USB_VENDOR_PEGATRON, USB_PRODUCT_PEGATRON_RT3070, + "RT3070", + }, + { + USB_VENDOR_PEGATRON, USB_PRODUCT_PEGATRON_RT3070_2, + "RT3070", + }, + { + USB_VENDOR_PEGATRON, USB_PRODUCT_PEGATRON_RT3070_3, + "RT3070", + }, + { + USB_VENDOR_PEGATRON, USB_PRODUCT_PEGATRON_RT3072, + "RT3072", + }, + { + USB_VENDOR_PEN, USB_PRODUCT_PEN_USBREADER, + "6 in 1", + }, + { + USB_VENDOR_PEN, USB_PRODUCT_PEN_MOBILEDRIVE, + "3 in 1", + }, + { + USB_VENDOR_PEN, USB_PRODUCT_PEN_USBDISK, + "Disk", + }, + { + USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_SERIAL1, + "Serial Converter", + }, + { + USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET, + "Ethernet", + }, + { + USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET3, + "At-Home Ethernet", + }, + { + USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET2, + "Ethernet", + }, + { + USB_VENDOR_PHEENET, USB_PRODUCT_PHEENET_WM168B, + "WM-168b", + }, + { + USB_VENDOR_PHEENET, USB_PRODUCT_PHEENET_WL503IA, + "WL-503IA", + }, + { + USB_VENDOR_PHEENET, USB_PRODUCT_PHEENET_GWU513, + "GWU513", + }, + { + USB_VENDOR_PHIDGETS, USB_PRODUCT_PHIDGETS_2X2, + "2x2 Interface Kit", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_DSS350, + "DSS 350 Digital Speaker System", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_DSS, + "DSS XXX Digital Speaker System", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_HUB, + "hub", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_PCA645VC, + "PCA645VC", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_PCA646VC, + "PCA646VC", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_PCVC675K, + "PCVC675K Vesta", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_PCVC680K, + "PCVC680K Vesta Pro", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_PCVC690K, + "PCVC690K Vesta Pro Scan Camera", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_PCVC730K, + "PCVC730K ToUCam Fun", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_PCVC740K, + "PCVC740K ToUCam Pro PC", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_PCVC750K, + "PCVC750K ToUCam Pro Scan", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_DSS150, + "DSS 150 Digital Speaker System", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_ACE1001, + "AKTAKOM ACE-1001", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_CPWUA054, + "CPWUA054", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_SNU6500, + "SNU6500", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_SNU6500_NF, + "SNU6500", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_SNU5600, + "SNU5600", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_SNU5630NS05, + "SNU5630NS/05", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_DIVAUSB, + "DIVA mp3 player", + }, + { + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_RT2870, + "RT2870", + }, + { + USB_VENDOR_PHILIPSSEMI, USB_PRODUCT_PHILIPSSEMI_HUB1122, + "hub", + }, + { + USB_VENDOR_PIENGINEERING, USB_PRODUCT_PIENGINEERING_PS2USB, + "PS2 to Mac", + }, + { + USB_VENDOR_PIENGINEERING, USB_PRODUCT_PIENGINEERING_XKEYS, + "Xkeys Programmable Keyboard", + }, + { + USB_VENDOR_PILOTECH, USB_PRODUCT_PILOTECH_CRW600, + "CRW-600 6-in-1", + }, + { + USB_VENDOR_PLANEX, USB_PRODUCT_PLANEX_GW_US11H, + "GW-US11H WLAN", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CUS, + "RTL8188CUS", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US11S, + "GW-US11S WLAN", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_3, + "RTL8188CU", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US54GXS, + "GW-US54GXS WLAN", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US300, + "GW-US300", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54HP, + "GW-US54HP", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS300MINIS, + "GW-US300MiniS", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RT3070, + "RT3070", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSNANO, + "GW-USNano", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSMICRO300, + "GW-USMicro300", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_1, + "RTL8188CU", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_4, + "RTL8188CU", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54MINI2, + "GW-US54Mini2", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54SG, + "GW-US54SG", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54GZL, + "GW-US54GZL", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54GD, + "GW-US54GD", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSMM, + "GW-USMM", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RT2870, + "RT2870", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSMICRON, + "GW-USMicroN", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSMICRON2W, + "GW-USMicroN2W", + }, + { + USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_2, + "RTL8188CU", + }, + { + USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GWUS54GZ, + "GW-US54GZ", + }, + { + USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GU1000T, + "GU-1000T", + }, + { + USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GWUS54MINI, + "GW-US54Mini", + }, + { + USB_VENDOR_PLANEX4, USB_PRODUCT_PLANEX4_GWUS54ZGL, + "GW-US54ZGL", + }, + { + USB_VENDOR_PLANEX4, USB_PRODUCT_PLANEX4_ZD1211B, + "ZD1211B", + }, + { + USB_VENDOR_PLANTRONICS, USB_PRODUCT_PLANTRONICS_HEADSET, + "DSP-400 Headset", + }, + { + USB_VENDOR_PLX, USB_PRODUCT_PLX_TESTBOARD, + "test board", + }, + { + USB_VENDOR_PLX, USB_PRODUCT_PLX_CA42, + "CA-42 Serial", + }, + { + USB_VENDOR_PORTGEAR, USB_PRODUCT_PORTGEAR_EA8, + "Ethernet", + }, + { + USB_VENDOR_PORTGEAR, USB_PRODUCT_PORTGEAR_EA9, + "Ethernet", + }, + { + USB_VENDOR_PORTSMITH, USB_PRODUCT_PORTSMITH_EEA, + "Express Ethernet", + }, + { + USB_VENDOR_POSIFLEX, USB_PRODUCT_POSIFLEX_PP7000_1, + "PP7000 series printer", + }, + { + USB_VENDOR_POSIFLEX, USB_PRODUCT_POSIFLEX_PP7000_2, + "PP7000 series printer", + }, + { + USB_VENDOR_PQI, USB_PRODUCT_PQI_TRAVELFLASH, + "Travel Flash Drive", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2X300, + "G2-200", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E300, + "G2E-300", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2300, + "G2-300", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E3002, + "G2E-300", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_9600, + "Colorado 9600", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_600U, + "Colorado 600u", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_6200, + "Visioneer 6200", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_19200, + "Colorado 19200", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_1200U, + "Colorado 1200u", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G600, + "G2-600", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_636I, + "ReadyScan 636i", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2600, + "G2-600", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E600, + "G2E-600", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_COMFORT, + "Comfort", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_MOUSEINABOX, + "Mouse-in-a-Box", + }, + { + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_PCGAUMS1, + "Sony PCGA-UMS1", + }, + { + USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2301, + "PL2301 Host-Host", + }, + { + USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2302, + "PL2302 Host-Host", + }, + { + USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_RSAQ2, + "PL2303 Serial", + }, + { + USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303BENQ, + "PL2303 Serial", + }, + { + USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303, + "PL2303 Serial", + }, + { + USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2305, + "Parallel printer", + }, + { + USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_ATAPI4, + "ATAPI-4 Bridge Controller", + }, + { + USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2501, + "PL2501 Host-Host", + }, + { + USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303X, + "PL2303 Serial", + }, + { + USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303X2, + "PL2303 Serial", + }, + { + USB_VENDOR_PROLIFIC2, USB_PRODUCT_PROLIFIC2_PL2303, + "PL2303 Serial", + }, + { + USB_VENDOR_PUTERCOM, USB_PRODUCT_PUTERCOM_UPA100, + "USB-1284 BRIDGE", + }, + { + USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573, + "RT2573", + }, + { + USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573_2, + "RT2573", + }, + { + USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573_3, + "RT2573", + }, + { + USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2870, + "RT2870", + }, + { + USB_VENDOR_QTRONIX, USB_PRODUCT_QTRONIX_980N, + "Scorpion-980N", + }, + { + USB_VENDOR_QUALCOMM, USB_PRODUCT_QUALCOMM_MSM_DRIVER, + "MSM driver", + }, + { + USB_VENDOR_QUALCOMM, USB_PRODUCT_QUALCOMM_MSM_MODEM, + "CDMA MSM modem", + }, + { + USB_VENDOR_QUALCOMM, USB_PRODUCT_QUALCOMM_MSM_HSDPA2, + "HSDPA MSM", + }, + { + USB_VENDOR_QUALCOMM, USB_PRODUCT_QUALCOMM_MSM_HSDPA, + "HSDPA MSM", + }, + { + USB_VENDOR_QUALCOMM, USB_PRODUCT_QUALCOMM_MSM_HSDPA3, + "HSDPA MSM", + }, + { + USB_VENDOR_QUALCOMM, USB_PRODUCT_QUALCOMM_MSM_DRIVER2, + "MSM driver", + }, + { + USB_VENDOR_QUALCOMM2, USB_PRODUCT_QUALCOMM2_MSM_PHONE, + "CDMA MSM phone", + }, + { + USB_VENDOR_QUANTA, USB_PRODUCT_QUANTA_RT3070, + "RT3070", + }, + { + USB_VENDOR_QUANTA2, USB_PRODUCT_QUANTA2_UMASS, + "Quanta USB MSM (umass mode)", + }, + { + USB_VENDOR_QUANTA2, USB_PRODUCT_QUANTA2_Q101, + "Quanta Q101 HSDPA USB modem", + }, + { + USB_VENDOR_QUICKSHOT, USB_PRODUCT_QUICKSHOT_STRIKEPAD, + "USB StrikePad", + }, + { + USB_VENDOR_RADIOSHACK, USB_PRODUCT_RADIOSHACK_PL2303, + "PL2303 Serial", + }, + { + USB_VENDOR_RAINBOW, USB_PRODUCT_RAINBOW_IKEY2000, + "i-Key 2000", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570, + "RT2570", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2070, + "RT2070", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570_2, + "RT2570", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573, + "RT2573", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2671, + "RT2671", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2770, + "RT2770", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2870, + "RT2870", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT3070, + "RT3070", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT3071, + "RT3071", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT3072, + "RT3072", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT3370, + "RT3370", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT3572, + "RT3572", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT3573, + "RT3573", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT5370, + "RT5370", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT5572, + "RT5572", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_MT7601, + "MT7601", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT8070, + "RT8070", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570_3, + "RT2570", + }, + { + USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573_2, + "RT2573", + }, + { + USB_VENDOR_RATOC, USB_PRODUCT_RATOC_REXUSB60, + "USB serial REX-USB60", + }, + { + USB_VENDOR_RATOC, USB_PRODUCT_RATOC_REXUSB60F, + "REX-USB60F", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188ETV, + "RTL8188ETV", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CTV, + "RTL8188CTV", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188RU_2, + "RTL8188RU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_4, + "RTL8188CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8150, + "RTL8150", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8151, + "RTL8151 PNA", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8152, + "RTL8152", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8153, + "RTL8153", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8156, + "RTL8156", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CE_0, + "RTL8188CE", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8171, + "RTL8171", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8172, + "RTL8172", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8173, + "RTL8173", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8174, + "RTL8174", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_0, + "RTL8188CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8191CU, + "RTL8191CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188EU, + "RTL8188EU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_1, + "RTL8188CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_2, + "RTL8188CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192CE, + "RTL8192CE", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188RU, + "RTL8188RU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CE_1, + "RTL8188CE", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188RU_3, + "RTL8188RU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192CE_VAU, + "RTL8192CE", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8187, + "RTL8187", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8187B_0, + "RTL8187B", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CUS, + "RTL8188CUS", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192EU, + "RTL8192EU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_3, + "RTL8188CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192U, + "RTL8192U", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8187B_1, + "RTL8187B", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8187B_2, + "RTL8187B", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_5, + "RTL8188CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8712, + "RTL8712", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8713, + "RTL8713", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_COMBO, + "RTL8188CU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8723BU, + "RTL8723BU", + }, + { + USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192SU, + "RTL8192SU", + }, + { + USB_VENDOR_RENESAS, USB_PRODUCT_RENESAS_RX610, + "RX610 RX-Stick", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC2, + "VGP-VCC2 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC3, + "VGP-VCC3 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC2_2, + "VGP-VCC2 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC2_3, + "VGP-VCC2 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC5, + "VGP-VCC5 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC4, + "VGP-VCC4 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC4_2, + "VGP-VCC4 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC6, + "VGP-VCC6 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC7, + "VGP-VCC7 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC8, + "VGP-VCC8 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC9, + "VGP-VCC9 Camera", + }, + { + USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VPGVCCX, + "VGP-VCCX Camera", + }, + { + USB_VENDOR_RIM, USB_PRODUCT_RIM_BLACKBERRY, + "BlackBerry", + }, + { + USB_VENDOR_RIM, USB_PRODUCT_RIM_PEARL_DUAL, + "RIM Mass Storage Device", + }, + { + USB_VENDOR_RIM, USB_PRODUCT_RIM_PEARL, + "BlackBerry pearl", + }, + { + USB_VENDOR_ROCKFIRE, USB_PRODUCT_ROCKFIRE_GAMEPAD, + "Gamepad 203USB", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_UA100, + "UA-100 Audio I/F", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_UM4, + "UM-4 MIDI I/F", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_SC8850, + "SC-8850 MIDI Synth", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_U8, + "U-8 Audio I/F", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_UM2, + "UM-2 MIDI I/F", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_SC8820, + "SC-8820 MIDI Synth", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_PC300, + "PC-300 MIDI Keyboard", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_UM1, + "UM-1 MIDI I/F", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_SK500, + "SK-500 MIDI Keyboard", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_SCD70, + "SC-D70 MIDI Synth", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_UM880N, + "UM-880 MIDI I/F", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_SD90, + "SD-90 MIDI Synth", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_UM550, + "UM-550 MIDI I/F", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_SD20, + "SD-20 MIDI Synth", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_SD80, + "SD-80 MIDI Synth", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_UA700, + "UA-700 Audio I/F", + }, + { + USB_VENDOR_ROLAND, USB_PRODUCT_ROLAND_UMONE, + "UM-ONE MIDI I/F", + }, + { + USB_VENDOR_RTSYSTEMS, USB_PRODUCT_RTSYSTEMS_CT57B, + "CT57B Radio Cable", + }, + { + USB_VENDOR_SACOM, USB_PRODUCT_SACOM_USB485BL, + "USB-485-BL", + }, + { + USB_VENDOR_SAGEM, USB_PRODUCT_SAGEM_SERIAL, + "Serial", + }, + { + USB_VENDOR_SAGEM, USB_PRODUCT_SAGEM_XG760A, + "XG-760A", + }, + { + USB_VENDOR_SAGEM, USB_PRODUCT_SAGEM_XG76NA, + "XG-76NA", + }, + { + USB_VENDOR_SAITEK, USB_PRODUCT_SAITEK_CYBORG_3D_GOLD, + "Cyborg 3D Gold Joystick", + }, + { + USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_WIS09ABGN, + "WIS09ABGN Wireless LAN adapter", + }, + { + USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_SWL2100W, + "SWL-2100U", + }, + { + USB_VENDOR_SAMSUNG2, USB_PRODUCT_SAMSUNG2_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_SAMSUNG2, USB_PRODUCT_SAMSUNG2_ANDROID2, + "Android v2", + }, + { + USB_VENDOR_SAMSUNG2, USB_PRODUCT_SAMSUNG2_ANDROID, + "Android", + }, + { + USB_VENDOR_SAMSUNG2, USB_PRODUCT_SAMSUNG2_I330, + "I330", + }, + { + USB_VENDOR_SAMSUNG2, USB_PRODUCT_SAMSUNG2_AX88179, + "AX88179", + }, + { + USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR05A, + "ImageMate SDDR-05a", + }, + { + USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR31, + "ImageMate SDDR-31", + }, + { + USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR05, + "ImageMate SDDR-05", + }, + { + USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR12, + "ImageMate SDDR-12", + }, + { + USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR09, + "ImageMate SDDR-09", + }, + { + USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR75, + "ImageMate SDDR-75", + }, + { + USB_VENDOR_SANWASUPPLY, USB_PRODUCT_SANWASUPPLY_JYDV9USB, + "JY-DV9USB gamepad", + }, + { + USB_VENDOR_SANYO, USB_PRODUCT_SANYO_SCP4900, + "Sanyo SCP-4900 Phone", + }, + { + USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_SL11R, + "SL11R-IDE", + }, + { + USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_336CX, + "Phantom 336CX - C3", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2101, + "SeaLINK+232 (2101/2105)", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2102, + "SeaLINK+485 (2102)", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2103, + "SeaLINK+232I (2103)", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2104, + "SeaLINK+485I (2104)", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2201_1, + "SeaPORT+2/232 (2201) Port 1", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2202_1, + "SeaPORT+2/485 (2202) Port 1", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2203_1, + "SeaPORT+2 (2203) Port 1", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2201_2, + "SeaPORT+2/232 (2201) Port 2", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2202_2, + "SeaPORT+2/485 (2202) Port 2", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2203_2, + "SeaPORT+2 (2203) Port 2", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2401_1, + "SeaPORT+4/232 (2401) Port 1", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2402_1, + "SeaPORT+4/485 (2402) Port 1", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2403_1, + "SeaPORT+4 (2403) Port 1", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2401_2, + "SeaPORT+4/232 (2401) Port 2", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2402_2, + "SeaPORT+4/485 (2402) Port 2", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2403_2, + "SeaPORT+4 (2403) Port 2", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2401_3, + "SeaPORT+4/232 (2401) Port 3", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2402_3, + "SeaPORT+4/485 (2402) Port 3", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2403_3, + "SeaPORT+4 (2403) Port 3", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2401_4, + "SeaPORT+4/232 (2401) Port 4", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2402_4, + "SeaPORT+4/485 (2402) Port 4", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2403_4, + "SeaPORT+4 (2403) Port 4", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2801_1, + "SeaLINK+8/232 (2801) Port 1", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2802_1, + "SeaLINK+8/485 (2802) Port 1", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2803_1, + "SeaLINK+8 (2803) Port 1", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2801_2, + "SeaLINK+8/232 (2801) Port 2", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2802_2, + "SeaLINK+8/485 (2802) Port 2", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2803_2, + "SeaLINK+8 (2803) Port 2", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2801_3, + "SeaLINK+8/232 (2801) Port 3", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2802_3, + "SeaLINK+8/485 (2802) Port 3", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2803_3, + "SeaLINK+8 (2803) Port 3", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2801_4, + "SeaLINK+8/232 (2801) Port 4", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2802_4, + "SeaLINK+8/485 (2802) Port 4", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2803_4, + "SeaLINK+8 (2803) Port 4", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2801_5, + "SeaLINK+8/232 (2801) Port 5", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2802_5, + "SeaLINK+8/485 (2802) Port 5", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2803_5, + "SeaLINK+8 (2803) Port 5", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2801_6, + "SeaLINK+8/232 (2801) Port 6", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2802_6, + "SeaLINK+8/485 (2802) Port 6", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2803_6, + "SeaLINK+8 (2803) Port 6", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2801_7, + "SeaLINK+8/232 (2801) Port 7", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2802_7, + "SeaLINK+8/485 (2802) Port 7", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2803_7, + "SeaLINK+8 (2803) Port 7", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2801_8, + "SeaLINK+8/232 (2801) Port 8", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2802_8, + "SeaLINK+8/485 (2802) Port 8", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2803_8, + "SeaLINK+8 (2803) Port 8", + }, + { + USB_VENDOR_SEALEVEL, USB_PRODUCT_SEALEVEL_2106, + "SeaLINK+422 (2106)", + }, + { + USB_VENDOR_SEL, USB_PRODUCT_SEL_C662, + "C662", + }, + { + USB_VENDOR_SELUXIT, USB_PRODUCT_SELUXIT_RF, + "RF Dongle", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT2870_3, + "RT2870", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT2870_4, + "RT2870", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_NUB8301, + "NUB-8301", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_NUB862, + "NUB-862", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RTL8192SU_1, + "RTL8192SU", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RTL8192SU_2, + "RTL8192SU", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT3070, + "RT3070", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT3071, + "RT3071", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT3072_1, + "RT3072", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT3072_2, + "RT3072", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT3072_3, + "RT3072", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT3072_4, + "RT3072", + }, + { + USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RT3072_5, + "RT3072", + }, + { + USB_VENDOR_SERVERWORKS, USB_PRODUCT_SERVERWORKS_HUB, + "Root Hub", + }, + { + USB_VENDOR_SGI, USB_PRODUCT_SGI_SN1_L1_SC, + "SN1 L1 System Controller", + }, + { + USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ST268, + "ST268", + }, + { + USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9620A, + "DM9620A", + }, + { + USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9621A, + "DM9621A", + }, + { + USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ZT6688, + "ZT6688", + }, + { + USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ADM8515, + "ADM8515 Ethernet", + }, + { + USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9000E, + "DM9000E", + }, + { + USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9601, + "DM9601", + }, + { + USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9620, + "DM9620", + }, + { + USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9621, + "DM9621", + }, + { + USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9622, + "DM9622", + }, + { + USB_VENDOR_SHARK, USB_PRODUCT_SHARK_PA, + "Pocket Adapter", + }, + { + USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5500, + "SL5500", + }, + { + USB_VENDOR_SHARP, USB_PRODUCT_SHARP_A300, + "A300", + }, + { + USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5600, + "SL5600", + }, + { + USB_VENDOR_SHARP, USB_PRODUCT_SHARP_C700, + "C700", + }, + { + USB_VENDOR_SHARP, USB_PRODUCT_SHARP_C750, + "C750", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB, + "E-USB Bridge", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSCSI, + "eUSCSI Bridge", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_SDDR09, + "ImageMate SDDR09", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSBSMCF, + "eUSB SmartMedia / CompactFlash", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_ZIOMMC, + "eUSB MultiMediaCard", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_HIFD, + "Sony Hifd", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSBATAPI, + "eUSB ATA/ATAPI", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_CF, + "eUSB CompactFlash", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSCSI_B, + "eUSCSI Bridge", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSCSI_C, + "eUSCSI Bridge", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_CDRW, + "CD-RW Device", + }, + { + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_SCM, + "SCM Micro", + }, + { + USB_VENDOR_SIEMENS, USB_PRODUCT_SIEMENS_SPEEDSTREAM, + "SpeedStream", + }, + { + USB_VENDOR_SIEMENS, USB_PRODUCT_SIEMENS_SPEEDSTREAM22, + "SpeedStream 1022", + }, + { + USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_WLL013, + "WLL013", + }, + { + USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_ES75, + "GSM module MC35", + }, + { + USB_VENDOR_SIEMENS3, USB_PRODUCT_SIEMENS3_SX1, + "SX1", + }, + { + USB_VENDOR_SIEMENS3, USB_PRODUCT_SIEMENS3_X65, + "X65", + }, + { + USB_VENDOR_SIEMENS3, USB_PRODUCT_SIEMENS3_X75, + "X75", + }, + { + USB_VENDOR_SIEMENS4, USB_PRODUCT_SIEMENS4_RUGGEDCOM, + "RUGGEDCOM", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_EM5625, + "EM5625", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720, + "MC5720", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD_595, + "AirCard 595", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5725, + "MC5725", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC597E, + "597E", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_C597, + "Compass 597", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD_580, + "Aircard 580 EVDO", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC595U, + "595U", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720_2, + "MC5720", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5725_2, + "MC5725", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_TRUINSTALL, + "Aircard Tru Installer", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_2, + "MC8755", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8765, + "MC8765", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755, + "MC8755", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8775, + "MC8775", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_3, + "MC8755", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8775_2, + "MC8775", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD_875, + "875", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8780, + "MC8780", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8781, + "MC8781", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8790, + "MC8790", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880, + "880", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881, + "881", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880E, + "880E", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881E, + "881E", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880U, + "880U", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881U, + "881U", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC885U, + "885U", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_C01SW, + "C01SW", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC7700, + "MC7700", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_USB305, + "USB305", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC7304, + "MC7304", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8355, + "MC8355", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD_340U, + "Aircard 340U", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD_770S, + "Aircard 770S", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC7455, + "MC7455", + }, + { + USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_EM7455, + "EM7455", + }, + { + USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_IRDA, + "IrDA", + }, + { + USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_DNSSF7X, + "Datum Networks SSF-7X Multi Players", + }, + { + USB_VENDOR_SIIG, USB_PRODUCT_SIIG_DIGIFILMREADER, + "DigiFilm-Combo", + }, + { + USB_VENDOR_SIIG, USB_PRODUCT_SIIG_MULTICARDREADER, + "MULTICARDREADER", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_VSTABI, + "VStabi Controller", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_ARKHAM_DS101_M, + "Arkham DS101 Monitor", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_ARKHAM_DS101_A, + "Arkham DS101 Adapter", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_BSM7DUSB, + "BSM7-D-USB", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_POLOLU, + "Pololu Serial", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_SB_PARAMOUNT_ME, + "Software Bisque Paramount ME", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CYGNAL_DEBUG, + "Cygnal Debug Adapter", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_SB_PARAMOUNT_ME2, + "Software Bisque Paramount ME", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_EDG1228, + "EDG1228", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_GSM2228, + "Enfora GSM2228", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_ARGUSISP, + "Argussoft ISP", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_IMS_USB_RS422, + "IMS USB-RS422", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CRUMB128, + "Crumb128", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_OPTRIS_MSPRO, + "Optris MSpro LT Thermometer", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_DEGREECONT, + "Degree Controls", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_TRACIENT, + "Tracient RFID", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_TRAQMATE, + "Track Systems Traqmate", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_SUUNTO, + "Suunto sports", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_ARYGON_MIFARE, + "Arygon Mifare RFID reader", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_DESKTOPMOBILE, + "Burnside Desktop mobile", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_TAMSMASTER, + "Tams Master Easy Control", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_RIGBLASTER, + "RIGblaster P&P", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_RIGTALK, + "RIGtalk", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_B_G_H3000, + "B&G H3000 Data Cable", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_IPLINK1220, + "IP-Link 1220", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_HAMLINKUSB, + "Timewave HamLinkUSB", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_AVIT_USB_TTL, + "AVIT Research USB-TTL", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_MJS_TOSLINK, + "MJS USB-TOSLINK", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_WAVIT, + "ThinkOptics WavIt", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_MULTIPLEX_RC, + "Multiplex RC adapter", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_MSD_DASHHAWK, + "MSD DashHawk", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_INSYS_MODEM, + "INSYS Modem", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_LIPOWSKY_JTAG, + "Lipowsky Baby-JTAG", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_LIPOWSKY_LIN, + "Lipowsky Baby-LIN", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_AEROCOMM, + "Aerocomm Radio", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_ZEPHYR_BIO, + "Zephyr Bioharness", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_EMS_C1007, + "EMS C1007 HF RFID reader", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_LIPOWSKY_HARP, + "Lipowsky HARP-1", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_C2_EDGE_MODEM, + "Commander 2 EDGE(GSM) Modem", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CYGNAL_GPS, + "Cygnal Fasttrax GPS", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_PLUGDRIVE, + "Nanotec Plug & Drive", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_TELEGESIS_ETRX2, + "Telegesis ETRX2USB", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_PROCYON_AVS, + "Procyon AVS", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_MC35PU, + "MC35pu", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CYGNAL, + "Cygnal", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_AMBER_AMB2560, + "Amber Wireless AMB2560", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_DEKTEK_DTAPLUS, + "DekTec DTA Plus VHF/UHF Booster", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_KYOCERA_GPS, + "Kyocera GPS", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_IRZ_SG10, + "IRZ SG-10 GSM/GPRS Modem", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_BEI_VCP, + "BEI USB Sensor (VCP)", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_JUNIPER_BX_CONS, + "Juniper BX Console", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_BALLUFF_RFID, + "Balluff RFID reader", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_AC_SERV_IBUS, + "AC-Services IBUS", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_AC_SERV_CIS, + "AC-Services CIS-IBUS", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_PREON32, + "Virtenio Preon32", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_AC_SERV_CAN, + "AC-Services CAN", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_AC_SERV_OBD, + "AC-Services OBD", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_EM357LR, + "CEL EM357 LR", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_EM357, + "CEL EM357", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_MMB_ZIGBEE, + "MMB Networks ZigBee", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_PII_ZIGBEE, + "Planet Innovation Ingeni ZigBee", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_KETRA_N1, + "Ketra N1", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CELDEVKIT, + "CEL MeshWorks DevKit", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_KCF_PRN, + "KCF Technologies PRN", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_HUBZ, + "HubZ ZigBee/Z-Wave", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP210X_1, + "CP210x Serial", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP210X_2, + "CP210x Serial", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP210X_3, + "CP210x Serial", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_INFINITY_MIC, + "Infinity GPS-MIC-1", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP2110, + "CP2110 USB HID Serial", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_USBSCOPE50, + "USBscope50", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_USBWAVE12, + "USBwave12", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_USBPULSE100, + "USBpulse100", + }, + { + USB_VENDOR_SILABS, USB_PRODUCT_SILABS_USBCOUNT50, + "USBcount50", + }, + { + USB_VENDOR_SILABS2, USB_PRODUCT_SILABS2_DCU11CLONE, + "DCU-11 clone", + }, + { + USB_VENDOR_SILABS3, USB_PRODUCT_SILABS3_GPRS_MODEM, + "GPRS Modem", + }, + { + USB_VENDOR_SILABS4, USB_PRODUCT_SILABS4_100EU_MODEM, + "GPRS Modem 100EU", + }, + { + USB_VENDOR_SILABS5, USB_PRODUCT_SILABS5_EM358X, + "EM358x", + }, + { + USB_VENDOR_SILICOM, USB_PRODUCT_SILICOM_U2E, + "U2E", + }, + { + USB_VENDOR_SILICOM, USB_PRODUCT_SILICOM_GPE, + "Psion Dacom Gold Port Ethernet", + }, + { + USB_VENDOR_SILICONPORTALS, USB_PRODUCT_SILICONPORTALS_YAPPH_NF, + "YAP Phone (no firmware)", + }, + { + USB_VENDOR_SILICONPORTALS, USB_PRODUCT_SILICONPORTALS_YAPPHONE, + "YAP Phone", + }, + { + USB_VENDOR_SIMCOM, USB_PRODUCT_SIMCOM_SIM7600E, + "SIM7600E modem", + }, + { + USB_VENDOR_SIRIUS, USB_PRODUCT_SIRIUS_ROADSTER, + "NetComm Roadster II 56", + }, + { + USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_LN029, + "LN029", + }, + { + USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_CN104, + "CN104", + }, + { + USB_VENDOR_SITECOM2, USB_PRODUCT_SITECOM2_WL022, + "WL-022", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL168V1, + "WL-168 v1", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN030, + "LN-030", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL168V4, + "WL-168 v4", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT2870_3, + "RT2870", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL302, + "WL-302", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL603, + "WL-603", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL315, + "WL-315", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL321, + "WL-321", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3070_3, + "RT3070", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL324, + "WL-324", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL343, + "WL-343", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL608, + "WL-608", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL344, + "WL-344", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL329, + "WL-329", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL345, + "WL-345", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL353, + "WL-353", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3072_3, + "RT3072", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3072_4, + "RT3072", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL349V1, + "WL-349 v1", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3072_6, + "RT3072", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL349V4, + "WL-349 v4", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3070_1, + "RT3070", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8188CU, + "RTL8188CU", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8188CU_2, + "RTL8188CU", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RT3072_5, + "RT3072", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WLA4000, + "WLA-4000", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WLA5000, + "WLA-5000", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8192CU_2, + "RTL8192CU", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN032, + "LN-032", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WLA2100V2, + "WLA-2100 v2", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN028, + "LN-028", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL113, + "WL-113", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_ZD1211B, + "ZD1211B", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL172, + "WL-172", + }, + { + USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL113R2, + "WL-113 rev 2", + }, + { + USB_VENDOR_SMART, USB_PRODUCT_SMART_PL2303, + "Serial", + }, + { + USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTLINK, + "SmartLink Ethernet", + }, + { + USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTNIC, + "smartNIC 2 PnP", + }, + { + USB_VENDOR_SMC, USB_PRODUCT_SMC_2102USB, + "10Mbps Ethernet", + }, + { + USB_VENDOR_SMC, USB_PRODUCT_SMC_2202USB, + "10/100 Ethernet", + }, + { + USB_VENDOR_SMC, USB_PRODUCT_SMC_2206USB, + "EZ Connect Ethernet", + }, + { + USB_VENDOR_SMC, USB_PRODUCT_SMC_2862WG, + "EZ Connect 54Mbps", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_2020HUB, + "Hub", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_2504HUB, + "Hub", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_2513HUB, + "Hub", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN7500, + "LAN7500", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN7505, + "LAN7505", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN7800, + "LAN7800", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN7801, + "LAN7801", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN7850, + "LAN7850", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9500, + "SMSC9500", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9505, + "SMSC9505", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9530, + "LAN9530", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN9730, + "LAN9730", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9500_SAL10, + "SMSC9500", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9505_SAL10, + "SMSC9505", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9500A_SAL10, + "SMSC9500A", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9505A_SAL10, + "SMSC9505A", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9512_14_SAL10, + "SMSC9512/14", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9500A_HAL, + "SMSC9500A", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9505A_HAL, + "SMSC9505A", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9500_ALT, + "SMSC9500", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9500A_ALT, + "SMSC9500A", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9512_14_ALT, + "SMSC9512", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9500A, + "SMSC9500A", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9505A, + "SMSC9505A", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_LAN89530, + "LAN89530", + }, + { + USB_VENDOR_SMC2, USB_PRODUCT_SMC2_SMSC9512_14, + "SMSC9512/14", + }, + { + USB_VENDOR_SMC3, USB_PRODUCT_SMC3_2662WV1, + "EZ Connect 11Mbps", + }, + { + USB_VENDOR_SMC3, USB_PRODUCT_SMC3_2662WV2, + "EZ Connect 11Mbps v2", + }, + { + USB_VENDOR_SOHOWARE, USB_PRODUCT_SOHOWARE_NUB100, + "NUB100 Ethernet", + }, + { + USB_VENDOR_SOHOWARE, USB_PRODUCT_SOHOWARE_NUB110, + "NUB110 Ethernet", + }, + { + USB_VENDOR_SOLIDYEAR, USB_PRODUCT_SOLIDYEAR_KEYBOARD, + "Keyboard", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC, + "DSC Cameras", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_NWMS7, + "Memorystick NW-MS7", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_DRIVEV2, + "Harddrive V2", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_MSACUS1, + "Memorystick MSAC-US1", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_HANDYCAM, + "Handycam", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_MSC, + "MSC Memorystick", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_35, + "Clie v3.5", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_PS2KEYBOARD, + "PlayStation2 keyboard", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_PS2KEYBOARDHUB, + "PlayStation2 keyboard hub", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_PS2MOUSE, + "PlayStation2 mouse", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40, + "Clie v4.0", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40_MS, + "Clie v4.0 Memory Stick", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_S360, + "Clie s360", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_41_MS, + "Clie v4.1 Memory Stick", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_41, + "Clie v4.1", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_NX60, + "Clie nx60", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_TJ25, + "Clie tj25", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_IFU_WLM2, + "IFU-WLM2", + }, + { + USB_VENDOR_SONY, USB_PRODUCT_SONY_CXD9192, + "1seg TV tuner", + }, + { + USB_VENDOR_SOURCENEXT, USB_PRODUCT_SOURCENEXT_KEIKAI8_CHG, + "KeikaiDenwa 8 with charger", + }, + { + USB_VENDOR_SOURCENEXT, USB_PRODUCT_SOURCENEXT_KEIKAI8, + "KeikaiDenwa 8", + }, + { + USB_VENDOR_SPARKLAN, USB_PRODUCT_SPARKLAN_RT2573, + "RT2573", + }, + { + USB_VENDOR_SPARKLAN, USB_PRODUCT_SPARKLAN_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_SPARKLAN, USB_PRODUCT_SPARKLAN_RT3070, + "RT3070", + }, + { + USB_VENDOR_SPARKLAN, USB_PRODUCT_SPARKLAN_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_SPEEDDRAGON, USB_PRODUCT_SPEEDDRAGON_MS3303H, + "MS3303H Serial", + }, + { + USB_VENDOR_SPHAIRON, USB_PRODUCT_SPHAIRON_UB801R, + "UB801R", + }, + { + USB_VENDOR_SPHAIRON, USB_PRODUCT_SPHAIRON_RTL8187, + "RTL8187", + }, + { + USB_VENDOR_STARTECH, USB_PRODUCT_STARTECH_ICUSB232X, + "ICUSB2321X/2X/4X", + }, + { + USB_VENDOR_STMICRO, USB_PRODUCT_STMICRO_BIOMETRIC_COPR, + "Biometric Coprocessor", + }, + { + USB_VENDOR_STMICRO, USB_PRODUCT_STMICRO_COMMUNICATOR, + "Communicator", + }, + { + USB_VENDOR_STOLLMANN, USB_PRODUCT_STOLLMANN_ISDN_TA_USBA, + "ISDN TA+USBA", + }, + { + USB_VENDOR_STRAWBERRYLINUX, USB_PRODUCT_STRAWBERRYLINUX_USBRH, + "USBRH sensor", + }, + { + USB_VENDOR_STSN, USB_PRODUCT_STSN_STSN0001, + "Internet Access Device", + }, + { + USB_VENDOR_SUNCOMM, USB_PRODUCT_SUNCOMM_MB_ADAPTOR, + "Mobile Adaptor", + }, + { + USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_DS96L, + "U-Cable type D2", + }, + { + USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_PS64P1, + "U-Cable type P1", + }, + { + USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_VS10U, + "Slipper U", + }, + { + USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_IS96U, + "Ir-Trinity", + }, + { + USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_AS64LX, + "U-Cable type A3", + }, + { + USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_AS144L4, + "U-Cable type A4", + }, + { + USB_VENDOR_SUPERTOP, USB_PRODUCT_SUPERTOP_IDEBRIDGE, + "SuperTop IDE Bridge", + }, + { + USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_EP9001G2A, + "EP-9001-G rev 2A", + }, + { + USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2570, + "RT2570", + }, + { + USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2573, + "RT2573", + }, + { + USB_VENDOR_SUSTEEN, USB_PRODUCT_SUSTEEN_DCU11, + "Ericsson DCU-10/11", + }, + { + USB_VENDOR_SWEEX, USB_PRODUCT_SWEEX_ZD1211, + "ZD1211", + }, + { + USB_VENDOR_SWEEX2, USB_PRODUCT_SWEEX2_LW153, + "LW153", + }, + { + USB_VENDOR_SWEEX2, USB_PRODUCT_SWEEX2_LW154, + "LW154", + }, + { + USB_VENDOR_SWEEX2, USB_PRODUCT_SWEEX2_LW303, + "LW303", + }, + { + USB_VENDOR_SWEEX2, USB_PRODUCT_SWEEX2_LW313, + "LW313", + }, + { + USB_VENDOR_SYNTECH, USB_PRODUCT_SYNTECH_SERIAL, + "Serial", + }, + { + USB_VENDOR_SYNTECH, USB_PRODUCT_SYNTECH_CIPHERLAB100, + "CipherLab Barcode Scanner", + }, + { + USB_VENDOR_SYSTEMTALKS, USB_PRODUCT_SYSTEMTALKS_SGCX2UL, + "SGC-X2UL", + }, + { + USB_VENDOR_TANGTOP, USB_PRODUCT_TANGTOP_USBPS2, + "USBPS2", + }, + { + USB_VENDOR_TAPWAVE, USB_PRODUCT_TAPWAVE_ZODIAC, + "Zodiac", + }, + { + USB_VENDOR_TAUGA, USB_PRODUCT_TAUGA_CAMERAMATE, + "CameraMate (DPCM_USB)", + }, + { + USB_VENDOR_TCTMOBILE, USB_PRODUCT_TCTMOBILE_UMSM, + "Modem mode", + }, + { + USB_VENDOR_TCTMOBILE, USB_PRODUCT_TCTMOBILE_UMSM_2, + "Modem mode", + }, + { + USB_VENDOR_TCTMOBILE, USB_PRODUCT_TCTMOBILE_UMSM_3, + "Modem mode", + }, + { + USB_VENDOR_TCTMOBILE, USB_PRODUCT_TCTMOBILE_UMASS, + "Storage mode", + }, + { + USB_VENDOR_TCTMOBILE, USB_PRODUCT_TCTMOBILE_UMASS_2, + "Storage mode", + }, + { + USB_VENDOR_TDK, USB_PRODUCT_TDK_UPA9664, + "USB-PDC Adapter UPA9664", + }, + { + USB_VENDOR_TDK, USB_PRODUCT_TDK_UCA1464, + "USB-cdmaOne Adapter UCA1464", + }, + { + USB_VENDOR_TDK, USB_PRODUCT_TDK_UHA6400, + "USB-PHS Adapter UHA6400", + }, + { + USB_VENDOR_TDK, USB_PRODUCT_TDK_UPA6400, + "USB-PHS Adapter UPA6400", + }, + { + USB_VENDOR_TDK, USB_PRODUCT_TDK_BLUETOOTH, + "Bluetooth", + }, + { + USB_VENDOR_TEAC, USB_PRODUCT_TEAC_FD05PUB, + "FD-05PUB", + }, + { + USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_0193, + "ALLNET 0193 WLAN", + }, + { + USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_ZYAIR_B200, + "ZyXEL ZyAIR B200 WLAN", + }, + { + USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_U300C, + "U-300C", + }, + { + USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_QUICKWLAN, + "QuickWLAN", + }, + { + USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_ZD1211_1, + "ZD1211", + }, + { + USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_ZD1211_2, + "ZD1211", + }, + { + USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1, + "Microphone", + }, + { + USB_VENDOR_TENDA, USB_PRODUCT_TENDA_TWL541U, + "TWL541U WLAN", + }, + { + USB_VENDOR_TENX, USB_PRODUCT_TENX_MISSILE, + "Missile Launcher", + }, + { + USB_VENDOR_TENX, USB_PRODUCT_TENX_TEMPER, + "TEMPer sensor", + }, + { + USB_VENDOR_TERRATEC, USB_PRODUCT_TERRATEC_AUREON, + "Aureon Dual USB", + }, + { + USB_VENDOR_TESTO, USB_PRODUCT_TESTO_175, + "175/177 USB interface", + }, + { + USB_VENDOR_TESTO, USB_PRODUCT_TESTO_330, + "330 USB interface", + }, + { + USB_VENDOR_TESTO, USB_PRODUCT_TESTO_435, + "435/635/735 USB interface", + }, + { + USB_VENDOR_TESTO, USB_PRODUCT_TESTO_845, + "845 USB interface", + }, + { + USB_VENDOR_TESTO, USB_PRODUCT_TESTO_SERVICE, + "Service adapter", + }, + { + USB_VENDOR_TESTO, USB_PRODUCT_TESTO_580, + "580 USB interface", + }, + { + USB_VENDOR_TESTO, USB_PRODUCT_TESTO_174, + "174 USB interface", + }, + { + USB_VENDOR_TESTO, USB_PRODUCT_TESTO_556, + "556/560 USB interface", + }, + { + USB_VENDOR_TESTO, USB_PRODUCT_TESTO_SERIAL_1, + "USB adapter", + }, + { + USB_VENDOR_TESTO, USB_PRODUCT_TESTO_SERIAL_2, + "USB to serial converter", + }, + { + USB_VENDOR_THRUST, USB_PRODUCT_THRUST_FUSION_PAD, + "Fusion Digital Gamepad", + }, + { + USB_VENDOR_THURLBY, USB_PRODUCT_THURLBY_QL355P, + "QL355P power supply", + }, + { + USB_VENDOR_TI, USB_PRODUCT_TI_UTUSB41, + "UT-USB41 hub", + }, + { + USB_VENDOR_TI, USB_PRODUCT_TI_TUSB2046, + "TUSB2046 hub", + }, + { + USB_VENDOR_TI, USB_PRODUCT_TI_TUSB3410, + "TUSB3410", + }, + { + USB_VENDOR_TI, USB_PRODUCT_TI_NEXII, + "Nex II Digital", + }, + { + USB_VENDOR_TI, USB_PRODUCT_TI_MSP430_JTAG, + "MSP-FET430UIF JTAG", + }, + { + USB_VENDOR_TI, USB_PRODUCT_TI_MSP430, + "MSP-FET430UIF", + }, + { + USB_VENDOR_TML, USB_PRODUCT_TML_SERIAL, + "Serial", + }, + { + USB_VENDOR_TODOS, USB_PRODUCT_TODOS_ARGOS_MINI, + "Argos Mini Smartcard", + }, + { + USB_VENDOR_TOPRE, USB_PRODUCT_TOPRE_HHKB, + "HHKB Professional", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_RH, + "Toradex OAK RH sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_P, + "Toradex OAK P sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_LUX, + "Toradex OAK LUX sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_TILT, + "Toradex OAK Tilt sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_DIST, + "Toradex OAK DIST sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_MOVE, + "Toradex OAK MOVE sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_4_20, + "Toradex OAK 4-20mA sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_G, + "Toradex OAK G sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_MAGR, + "Toradex OAK MAGR sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_RELAY, + "Toradex OAK RELAY", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_10V, + "Toradex OAK 10V sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_LN, + "Toradex OAK LN sensor", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_IO, + "Toradex OAK IO", + }, + { + USB_VENDOR_TORADEX, USB_PRODUCT_TORADEX_ORIENT, + "Toradex ORIENT Tilt sensor", + }, + { + USB_VENDOR_TOSHIBA, USB_PRODUCT_TOSHIBA_RT3070, + "RT3070", + }, + { + USB_VENDOR_TOSHIBA, USB_PRODUCT_TOSHIBA_HSDPA, + "HSDPA", + }, + { + USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8812AU, + "RTL8812AU", + }, + { + USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8192EU, + "RTL8192EU", + }, + { + USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8192EU_2, + "RTL8192EU", + }, + { + USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8188EUS, + "RTL8188EUS", + }, + { + USB_VENDOR_TREK, USB_PRODUCT_TREK_THUMBDRIVE, + "ThumbDrive", + }, + { + USB_VENDOR_TREK, USB_PRODUCT_TREK_THUMBDRIVE_8MB, + "ThumbDrive 8MB", + }, + { + USB_VENDOR_TRENDNET, USB_PRODUCT_TRENDNET_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_TRENDNET, USB_PRODUCT_TRENDNET_RTL8188CU, + "RTL8188CU", + }, + { + USB_VENDOR_TRIPPLITE, USB_PRODUCT_TRIPPLITE_U209, + "U209 Serial", + }, + { + USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_T33521, + "USB/MP3 decoder", + }, + { + USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_XXX1100, + "XXX 1100", + }, + { + USB_VENDOR_TRUST, USB_PRODUCT_TRUST_OPTMOUSE, + "Optical Mouse", + }, + { + USB_VENDOR_TRUST, USB_PRODUCT_TRUST_MOUSE, + "Mouse", + }, + { + USB_VENDOR_TSUNAMI, USB_PRODUCT_TSUNAMI_SM2000, + "SM-2000", + }, + { + USB_VENDOR_TWINMOS, USB_PRODUCT_TWINMOS_G240, + "G240", + }, + { + USB_VENDOR_UBLOX, USB_PRODUCT_UBLOX_ANTARIS4, + "ANTARIS4 GPS", + }, + { + USB_VENDOR_ULTIMA, USB_PRODUCT_ULTIMA_1200UBPLUS, + "1200 UB Plus", + }, + { + USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA1236U, + "Astra 1236U", + }, + { + USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA1220U, + "Astra 1220U", + }, + { + USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2000U, + "Astra 2000U", + }, + { + USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA3400, + "Astra 3400", + }, + { + USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2100U, + "Astra 2100U", + }, + { + USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2200U, + "Astra 2200U", + }, + { + USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_TEW444UBEU, + "TEW-444UB EU", + }, + { + USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_TEW444UBEU_NF, + "TEW-444UB EU", + }, + { + USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_TEW429UB_A, + "TEW-429UB_A", + }, + { + USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_TEW429UB, + "TEW-429UB", + }, + { + USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_TEW429UBC1, + "TEW-429UB C1", + }, + { + USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_TEW645UB, + "TEW-645UB", + }, + { + USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_ALL0298V2, + "ALL0298 v2", + }, + { + USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_AR5523_2, + "AR5523", + }, + { + USB_VENDOR_UMEDIA, USB_PRODUCT_UMEDIA_AR5523_2_NF, + "AR5523", + }, + { + USB_VENDOR_UNIACCESS, USB_PRODUCT_UNIACCESS_PANACHE, + "Panache Surf ISDN", + }, + { + USB_VENDOR_UNKNOWN2, USB_PRODUCT_UNKNOWN2_ZD1211B, + "ZD1211B", + }, + { + USB_VENDOR_UNKNOWN2, USB_PRODUCT_UNKNOWN2_NW3100, + "NW-3100", + }, + { + USB_VENDOR_UNKNOWN3, USB_PRODUCT_UNKNOWN3_ZD1211B, + "ZD1211B", + }, + { + USB_VENDOR_UNKNOWN4, USB_PRODUCT_UNKNOWN4_DM9601, + "DM9601", + }, + { + USB_VENDOR_UNKNOWN4, USB_PRODUCT_UNKNOWN4_RD9700, + "RD9700", + }, + { + USB_VENDOR_UNKNOWN5, USB_PRODUCT_UNKNOWN5_NF_RIC, + "NF RIC", + }, + { + USB_VENDOR_UNKNOWN6, USB_PRODUCT_UNKNOWN6_DM9601, + "DM9601", + }, + { + USB_VENDOR_USI, USB_PRODUCT_USI_MC60, + "MC60 Serial", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_USR1120, + "USR1120 WLAN", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_MILLER_A, + "USR9000 SureConnect ADSL", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_MILLER_A_NF, + "USR9000 SureConnect ADSL", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_HEINEKEN_A, + "USR9000 SureConnect ADSL", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_HEINEKEN_A_NF, + "USR9000 SureConnect ADSL", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_HEINEKEN_B, + "USR9000 SureConnect ADSL", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_HEINEKEN_B_NF, + "USR9000 SureConnect ADSL", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_MILLER_B, + "USR9000 SureConnect ADSL", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_MILLER_B_NF, + "USR9000 SureConnect ADSL", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_USR5422, + "USR5422 WLAN", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_USR5421A, + "USR5421A WLAN", + }, + { + USB_VENDOR_USR, USB_PRODUCT_USR_USR5423, + "USR5423 WLAN", + }, + { + USB_VENDOR_VAISALA, USB_PRODUCT_VAISALA_USBINSTCABLE, + "USB instrument cable", + }, + { + USB_VENDOR_VALIDITY, USB_PRODUCT_VALIDITY_VFS101, + "VFS101 Fingerprint Reader", + }, + { + USB_VENDOR_VALIDITY, USB_PRODUCT_VALIDITY_VFS301, + "VFS301 Fingerprint Reader", + }, + { + USB_VENDOR_VALIDITY, USB_PRODUCT_VALIDITY_VFS451, + "VFS451 Fingerprint Reader", + }, + { + USB_VENDOR_VALIDITY, USB_PRODUCT_VALIDITY_VFS300, + "VFS300 Fingerprint Reader", + }, + { + USB_VENDOR_VALIDITY, USB_PRODUCT_VALIDITY_VFS5011, + "VFS5011 Fingerprint Reader", + }, + { + USB_VENDOR_VALIDITY, USB_PRODUCT_VALIDITY_VFS5011_2, + "VFS5011 Fingerprint Reader", + }, + { + USB_VENDOR_VALIDITY, USB_PRODUCT_VALIDITY_VFS5011_3, + "VFS5011 Fingerprint Reader", + }, + { + USB_VENDOR_VALIDITY, USB_PRODUCT_VALIDITY_VFS5471, + "VFS471 Fingerprint Reader", + }, + { + USB_VENDOR_VELLEMAN, USB_PRODUCT_VELLEMAN_K8055, + "K8055 USB Experiment interface board", + }, + { + USB_VENDOR_VERTEX, USB_PRODUCT_VERTEX_VW110L, + "VW110L", + }, + { + USB_VENDOR_VIA, USB_PRODUCT_VIA_AR9271, + "AR9271", + }, + { + USB_VENDOR_VIEWSONIC, USB_PRODUCT_VIEWSONIC_G773HUB, + "G773 Monitor Hub", + }, + { + USB_VENDOR_VIEWSONIC, USB_PRODUCT_VIEWSONIC_P815HUB, + "P815 Monitor Hub", + }, + { + USB_VENDOR_VIEWSONIC, USB_PRODUCT_VIEWSONIC_AIRSYNC, + "Airsync", + }, + { + USB_VENDOR_VIEWSONIC, USB_PRODUCT_VIEWSONIC_G773CTRL, + "G773 Monitor Control", + }, + { + USB_VENDOR_VISION, USB_PRODUCT_VISION_VC6452V002, + "CPiA Camera", + }, + { + USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_7600, + "OneTouch 7600", + }, + { + USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_5300, + "OneTouch 5300", + }, + { + USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_3000, + "Scanport 3000", + }, + { + USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_6100, + "OneTouch 6100", + }, + { + USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_6200, + "OneTouch 6200", + }, + { + USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_8100, + "OneTouch 8100", + }, + { + USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_8600, + "OneTouch 8600", + }, + { + USB_VENDOR_VIVITAR, USB_PRODUCT_VIVITAR_DSC350, + "DSC350", + }, + { + USB_VENDOR_VOTI, USB_PRODUCT_VOTI_SELETEK_1, + "Lunatico Seletek", + }, + { + USB_VENDOR_VOTI, USB_PRODUCT_VOTI_SELETEK_2, + "Lunatico Seletek", + }, + { + USB_VENDOR_VTECH, USB_PRODUCT_VTECH_RT2570, + "RT2570", + }, + { + USB_VENDOR_VTECH, USB_PRODUCT_VTECH_ZD1211B, + "ZD1211B", + }, + { + USB_VENDOR_WACOM, USB_PRODUCT_WACOM_CT0405U, + "CT-0405-U Tablet", + }, + { + USB_VENDOR_WACOM, USB_PRODUCT_WACOM_GRAPHIRE, + "Graphire", + }, + { + USB_VENDOR_WACOM, USB_PRODUCT_WACOM_GRAPHIRE3_4X5, + "Graphire3 4x5", + }, + { + USB_VENDOR_WACOM, USB_PRODUCT_WACOM_GRAPHIRE4_4X5, + "Graphire4 Classic A6", + }, + { + USB_VENDOR_WACOM, USB_PRODUCT_WACOM_INTUOSA5, + "Intuos A5", + }, + { + USB_VENDOR_WACOM, USB_PRODUCT_WACOM_INTUOS_DRAW, + "Intuos Draw (CTL-490)", + }, + { + USB_VENDOR_WAGO, USB_PRODUCT_WAGO_SERVICECABLE, + "Service Cable 750-923", + }, + { + USB_VENDOR_WAVESENSE, USB_PRODUCT_WAVESENSE_JAZZ, + "Jazz blood glucose meter", + }, + { + USB_VENDOR_WCH, USB_PRODUCT_WCH_CH341, + "CH341 serial/parallel", + }, + { + USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH341A, + "CH341A serial/parallel", + }, + { + USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH340, + "CH340 serial/parallel", + }, + { + USB_VENDOR_WIENERPLEINBAUS, USB_PRODUCT_WIENERPLEINBAUS_PL512, + "PL512 PSU", + }, + { + USB_VENDOR_WIENERPLEINBAUS, USB_PRODUCT_WIENERPLEINBAUS_RCM, + "RCM Remote Control", + }, + { + USB_VENDOR_WIENERPLEINBAUS, USB_PRODUCT_WIENERPLEINBAUS_MPOD, + "MPOD PSU", + }, + { + USB_VENDOR_WIENERPLEINBAUS, USB_PRODUCT_WIENERPLEINBAUS_CML, + "CML Data Logger", + }, + { + USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_WNC0600, + "WNC-0600USB", + }, + { + USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_UR045G, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_UR055G, + "UR055G", + }, + { + USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_O8494, + "ORiNOCO 802.11n", + }, + { + USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_AR5523_1, + "AR5523", + }, + { + USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_AR5523_1_NF, + "AR5523", + }, + { + USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_AR5523_2_NF, + "AR5523", + }, + { + USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_AR5523_2, + "AR5523", + }, + { + USB_VENDOR_WMR, USB_PRODUCT_WMR_RIGBLASTER, + "RIGblaster", + }, + { + USB_VENDOR_XIAOMI, USB_PRODUCT_XIAOMI_MT7601U, + "MT7601U", + }, + { + USB_VENDOR_XIRING, USB_PRODUCT_XIRING_XIMAX, + "Ximax CDC", + }, + { + USB_VENDOR_XIRLINK, USB_PRODUCT_XIRLINK_IMAGING, + "Imaging Device", + }, + { + USB_VENDOR_XIRLINK, USB_PRODUCT_XIRLINK_PCCAM, + "IBM PC Camera", + }, + { + USB_VENDOR_XYRATEX, USB_PRODUCT_XYRATEX_PRISM_GT_1, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_XYRATEX, USB_PRODUCT_XYRATEX_PRISM_GT_2, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_YAMAHA, USB_PRODUCT_YAMAHA_UX256, + "UX256 MIDI I/F", + }, + { + USB_VENDOR_YAMAHA, USB_PRODUCT_YAMAHA_UX96, + "UX96 MIDI I/F", + }, + { + USB_VENDOR_YAMAHA, USB_PRODUCT_YAMAHA_UR22, + "UR22", + }, + { + USB_VENDOR_YAMAHA, USB_PRODUCT_YAMAHA_RPU200, + "RP-U200", + }, + { + USB_VENDOR_YAMAHA, USB_PRODUCT_YAMAHA_RTA54I, + "NetVolante RTA54i", + }, + { + USB_VENDOR_YAMAHA, USB_PRODUCT_YAMAHA_RTW65B, + "NetVolante RTW65b", + }, + { + USB_VENDOR_YAMAHA, USB_PRODUCT_YAMAHA_RTW65I, + "NetVolante RTW65i", + }, + { + USB_VENDOR_YAMAHA, USB_PRODUCT_YAMAHA_RTA55I, + "NetVolante RTA55i", + }, + { + USB_VENDOR_YANO, USB_PRODUCT_YANO_U640MO, + "U640MO-03", + }, + { + USB_VENDOR_YCCABLE, USB_PRODUCT_YCCABLE_PL2303, + "PL2303 Serial", + }, + { + USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU, + "Flashbuster-U", + }, + { + USB_VENDOR_YUBICO, USB_PRODUCT_YUBICO_YUBIKEY, + "Yubikey", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_M4Y750, + "M4Y-750", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_XI725, + "XI-725/726", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_XI735, + "XI-735", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_MD40900, + "MD40900", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_XG703A, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_ZD1211, + "ZD1211", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_AR5523, + "AR5523", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_AR5523_NF, + "AR5523", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_ZD1211B, + "ZD1211B", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_UB81, + "UB81", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_UB82, + "UB82", + }, + { + USB_VENDOR_ZINWELL, USB_PRODUCT_ZINWELL_RT2570, + "RT2570", + }, + { + USB_VENDOR_ZINWELL, USB_PRODUCT_ZINWELL_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_ZINWELL, USB_PRODUCT_ZINWELL_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_ZINWELL, USB_PRODUCT_ZINWELL_RT3072_1, + "RT3072", + }, + { + USB_VENDOR_ZINWELL, USB_PRODUCT_ZINWELL_RT3072_2, + "RT3072", + }, + { + USB_VENDOR_ZINWELL, USB_PRODUCT_ZINWELL_RT3070, + "RT3070", + }, + { + USB_VENDOR_ZOOM, USB_PRODUCT_ZOOM_2986L, + "2986L Fax Modem", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_CDMA_MSM, + "CDMA Technologies MSM modem", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_MF633, + "ZTE MF633 USUPA USB modem", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_MF637, + "ZTE MF637 HSUPA USB modem", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_K3565Z, + "ZTE K3565-Z USB MSM modem", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_UMASS_INSTALLER4, + "ZTE USB MSM installer", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_MSA110UP, + "ONDA MSA110UP USB MSM modem", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_UMASS_INSTALLER2, + "ZTE USB MSM installer", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_MF112, + "ZTE MF112 HSUPA USB modem", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_HSUSB, + "ZTE HSUSB", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_UMASS_INSTALLER, + "ZTE USB MSM installer", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_AC2746, + "AC2746 CDMA USB modem", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_UMASS_INSTALLER3, + "ZTE USB CDMA installer", + }, + { + USB_VENDOR_ZTE, USB_PRODUCT_ZTE_AC8700, + "AC8700 CDMA USB modem", + }, + { + USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ZD1201, + "ZD1201", + }, + { + USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ZD1211, + "ZD1211", + }, + { + USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ZD1211B, + "ZD1211B", + }, + { + USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ZD1221, + "ZD1221", + }, + { + USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ALL0298, + "ALL0298", + }, + { + USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ZD1211B_2, + "ZD1211B", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_OMNI56K, + "Omni 56K Plus", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_980N, + "Scorpion-980N", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_G220, + "G-220", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_G220F, + "G-220F", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_G200V2, + "G-200 v2", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_AG225H, + "AG-225H", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_M202, + "M-202", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_G270S, + "G-270S", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_G220V2, + "G-220 v2", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_G202, + "G-202", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_AG220, + "AG-220", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_AG225HV2, + "AG-225H v2", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RT2573, + "RT2573", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_NWD271N, + "NWD-271N", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_NWD211AN, + "NWD-211AN", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_NWD2105, + "NWD2105", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RT3070, + "RT3070", + }, + { + USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_PRESTIGE, + "Prestige", + }, + { 0, 0, NULL } +}; + +const struct usb_known_vendor usb_known_vendors[] = { + { + USB_VENDOR_PLANEX4, + "Planex Communications", + }, + { + USB_VENDOR_UNKNOWN2, + "Unknown vendor", + }, + { + USB_VENDOR_EGALAX2, + "eGalax", + }, + { + USB_VENDOR_UNKNOWN6, + "Unknown vendor", + }, + { + USB_VENDOR_HUMAX, + "HUMAX", + }, + { + USB_VENDOR_BWCT, + "Bernd Walter Computer Technology", + }, + { + USB_VENDOR_AOX, + "AOX", + }, + { + USB_VENDOR_ATMEL, + "Atmel", + }, + { + USB_VENDOR_MITSUMI, + "Mitsumi", + }, + { + USB_VENDOR_HP, + "Hewlett Packard", + }, + { + USB_VENDOR_ADAPTEC, + "Adaptec", + }, + { + USB_VENDOR_NATIONAL, + "National Semiconductor", + }, + { + USB_VENDOR_ACERLABS, + "Acer Labs", + }, + { + USB_VENDOR_FTDI, + "Future Technology Devices", + }, + { + USB_VENDOR_QUANTA2, + "Quanta", + }, + { + USB_VENDOR_NEC, + "NEC", + }, + { + USB_VENDOR_KODAK, + "Eastman Kodak", + }, + { + USB_VENDOR_VIA, + "VIA", + }, + { + USB_VENDOR_MELCO, + "Melco", + }, + { + USB_VENDOR_LEADTEK, + "Leadtek", + }, + { + USB_VENDOR_CREATIVE, + "Creative Labs", + }, + { + USB_VENDOR_NOKIA2, + "Nokia", + }, + { + USB_VENDOR_ADI, + "ADI Systems", + }, + { + USB_VENDOR_CATC, + "Computer Access Technology", + }, + { + USB_VENDOR_SMC2, + "Standard Microsystems", + }, + { + USB_VENDOR_GRAVIS, + "Advanced Gravis Computer", + }, + { + USB_VENDOR_FUJITSUCOMP, + "Fujitsu Component", + }, + { + USB_VENDOR_TAUGA, + "Taugagreining HF", + }, + { + USB_VENDOR_AMD, + "Advanced Micro Devices", + }, + { + USB_VENDOR_LEXMARK, + "Lexmark International", + }, + { + USB_VENDOR_NANAO, + "NANAO", + }, + { + USB_VENDOR_ALPS, + "Alps Electric", + }, + { + USB_VENDOR_THRUST, + "Thrustmaster", + }, + { + USB_VENDOR_TI, + "Texas Instruments", + }, + { + USB_VENDOR_ANALOGDEVICES, + "Analog Devices", + }, + { + USB_VENDOR_SIS, + "Silicon Integrated Systems Corp.", + }, + { + USB_VENDOR_KYE, + "KYE Systems", + }, + { + USB_VENDOR_DIAMOND2, + "Diamond (Supra)", + }, + { + USB_VENDOR_RENESAS, + "Renesas", + }, + { + USB_VENDOR_MICROSOFT, + "Microsoft", + }, + { + USB_VENDOR_PRIMAX, + "Primax Electronics", + }, + { + USB_VENDOR_MGE, + "Eaton (MGE)", + }, + { + USB_VENDOR_AMP, + "AMP", + }, + { + USB_VENDOR_CHERRY, + "Cherry Mikroschalter", + }, + { + USB_VENDOR_MEGATRENDS, + "American Megatrends", + }, + { + USB_VENDOR_LOGITECH, + "Logitech", + }, + { + USB_VENDOR_BTC, + "Behavior Tech. Computer", + }, + { + USB_VENDOR_PHILIPS, + "Philips", + }, + { + USB_VENDOR_SANYO, + "Sanyo Electric", + }, + { + USB_VENDOR_CONNECTIX, + "Connectix", + }, + { + USB_VENDOR_DELL2, + "Dell", + }, + { + USB_VENDOR_KENSINGTON, + "Kensington", + }, + { + USB_VENDOR_LUCENT, + "Lucent", + }, + { + USB_VENDOR_PLANTRONICS, + "Plantronics", + }, + { + USB_VENDOR_KYOCERA, + "Kyocera", + }, + { + USB_VENDOR_STMICRO, + "STMicroelectronics", + }, + { + USB_VENDOR_FOXCONN, + "Foxconn", + }, + { + USB_VENDOR_YAMAHA, + "YAMAHA", + }, + { + USB_VENDOR_COMPAQ, + "Compaq", + }, + { + USB_VENDOR_HITACHI, + "Hitachi", + }, + { + USB_VENDOR_ACERP, + "Acer Peripherals", + }, + { + USB_VENDOR_DAVICOM, + "Davicom", + }, + { + USB_VENDOR_VISIONEER, + "Visioneer", + }, + { + USB_VENDOR_CANON, + "Canon", + }, + { + USB_VENDOR_NIKON, + "Nikon", + }, + { + USB_VENDOR_IBM, + "IBM", + }, + { + USB_VENDOR_CYPRESS, + "Cypress Semiconductor", + }, + { + USB_VENDOR_EPSON, + "Seiko Epson", + }, + { + USB_VENDOR_RAINBOW, + "Rainbow Technologies", + }, + { + USB_VENDOR_IODATA, + "I/O Data", + }, + { + USB_VENDOR_TDK, + "TDK", + }, + { + USB_VENDOR_3COMUSR, + "U.S. Robotics", + }, + { + USB_VENDOR_METHODE, + "Methode Electronics Far East", + }, + { + USB_VENDOR_MAXISWITCH, + "Maxi Switch", + }, + { + USB_VENDOR_LOCKHEEDMER, + "Lockheed Martin Energy Research", + }, + { + USB_VENDOR_FUJITSU, + "Fujitsu", + }, + { + USB_VENDOR_TOSHIBAAM, + "Toshiba America", + }, + { + USB_VENDOR_MICROMACRO, + "Micro Macro Technologies", + }, + { + USB_VENDOR_KONICA, + "Konica", + }, + { + USB_VENDOR_LITEON, + "Lite-On Technology", + }, + { + USB_VENDOR_FUJIPHOTO, + "Fuji Photo Film", + }, + { + USB_VENDOR_PHILIPSSEMI, + "Philips Semiconductors", + }, + { + USB_VENDOR_TATUNG, + "Tatung Co. Of America", + }, + { + USB_VENDOR_SCANLOGIC, + "ScanLogic", + }, + { + USB_VENDOR_MYSON, + "Myson Technology", + }, + { + USB_VENDOR_DIGI2, + "Digi", + }, + { + USB_VENDOR_ITTCANON, + "ITT Canon", + }, + { + USB_VENDOR_ALTEC, + "Altec Lansing", + }, + { + USB_VENDOR_MICROCHIP, + "Microchip Technology, Inc.", + }, + { + USB_VENDOR_HOLTEK, + "Holtek", + }, + { + USB_VENDOR_PANASONIC, + "Panasonic (Matsushita)", + }, + { + USB_VENDOR_SHARP, + "Sharp", + }, + { + USB_VENDOR_IIYAMA, + "Iiyama", + }, + { + USB_VENDOR_EXAR, + "Exar", + }, + { + USB_VENDOR_SHUTTLE, + "Shuttle Technology", + }, + { + USB_VENDOR_SAMSUNG2, + "Samsung Electronics", + }, + { + USB_VENDOR_ANNABOOKS, + "Annabooks", + }, + { + USB_VENDOR_JVC, + "JVC", + }, + { + USB_VENDOR_CHICONY, + "Chicony Electronics", + }, + { + USB_VENDOR_ELAN, + "Elan", + }, + { + USB_VENDOR_BROTHER, + "Brother Industries", + }, + { + USB_VENDOR_DALLAS, + "Dallas Semiconductor", + }, + { + USB_VENDOR_ACER, + "Acer", + }, + { + USB_VENDOR_3COM, + "3Com", + }, + { + USB_VENDOR_AZTECH, + "Aztech Systems", + }, + { + USB_VENDOR_BELKIN, + "Belkin Components", + }, + { + USB_VENDOR_KAWATSU, + "Kawatsu Semiconductor", + }, + { + USB_VENDOR_APC, + "American Power Conversion", + }, + { + USB_VENDOR_CONNECTEK, + "Advanced Connectek USA", + }, + { + USB_VENDOR_NETCHIP, + "NetChip Technology", + }, + { + USB_VENDOR_ALTRA, + "ALTRA", + }, + { + USB_VENDOR_ATI, + "ATI Technologies", + }, + { + USB_VENDOR_AKS, + "Aladdin Knowledge Systems", + }, + { + USB_VENDOR_UNIACCESS, + "Universal Access", + }, + { + USB_VENDOR_VIEWSONIC, + "ViewSonic", + }, + { + USB_VENDOR_XIRLINK, + "Xirlink", + }, + { + USB_VENDOR_ANCHOR, + "Anchor Chips", + }, + { + USB_VENDOR_SONY, + "Sony", + }, + { + USB_VENDOR_VISION, + "VLSI Vision", + }, + { + USB_VENDOR_ASAHIKASEI, + "Asahi Kasei Microsystems", + }, + { + USB_VENDOR_ATEN, + "ATEN International", + }, + { + USB_VENDOR_SAMSUNG, + "Samsung", + }, + { + USB_VENDOR_MUSTEK, + "Mustek Systems", + }, + { + USB_VENDOR_TELEX, + "Telex Communications", + }, + { + USB_VENDOR_PERACOM, + "Peracom Networks", + }, + { + USB_VENDOR_ALCOR2, + "Alcor Micro", + }, + { + USB_VENDOR_WACOM, + "WACOM", + }, + { + USB_VENDOR_ETEK, + "e-TEK Labs", + }, + { + USB_VENDOR_EIZO, + "EIZO", + }, + { + USB_VENDOR_ELECOM, + "Elecom", + }, + { + USB_VENDOR_XYRATEX, + "Xyratex", + }, + { + USB_VENDOR_HAUPPAUGE, + "Hauppauge Computer Works", + }, + { + USB_VENDOR_BAFO, + "BAFO/Quality Computer Accessories", + }, + { + USB_VENDOR_YEDATA, + "Y-E Data", + }, + { + USB_VENDOR_AVM, + "AVM", + }, + { + USB_VENDOR_QUICKSHOT, + "Quickshot", + }, + { + USB_VENDOR_ROLAND, + "Roland", + }, + { + USB_VENDOR_ROCKFIRE, + "Rockfire", + }, + { + USB_VENDOR_RATOC, + "RATOC Systems", + }, + { + USB_VENDOR_ZYXEL, + "ZyXEL Communication", + }, + { + USB_VENDOR_ALCOR, + "Alcor Micro", + }, + { + USB_VENDOR_OMRON, + "OMRON Corporation", + }, + { + USB_VENDOR_IOMEGA, + "Iomega", + }, + { + USB_VENDOR_ATREND, + "A-Trend Technology", + }, + { + USB_VENDOR_AID, + "Advanced Input Devices", + }, + { + USB_VENDOR_LACIE, + "LaCie", + }, + { + USB_VENDOR_THRUSTMASTER, + "Thrustmaster", + }, + { + USB_VENDOR_CISCOLINKSYS3, + "Cisco-Linksys", + }, + { + USB_VENDOR_OMNIVISION, + "OmniVision", + }, + { + USB_VENDOR_INSYSTEM, + "In-System Design", + }, + { + USB_VENDOR_APPLE, + "Apple Computer", + }, + { + USB_VENDOR_YCCABLE, + "Y.C. Cable", + }, + { + USB_VENDOR_JINGMOLD, + "Jing Mold", + }, + { + USB_VENDOR_DIGI, + "Digi International", + }, + { + USB_VENDOR_QUALCOMM, + "Qualcomm", + }, + { + USB_VENDOR_QTRONIX, + "Qtronix", + }, + { + USB_VENDOR_RICOH, + "Ricoh", + }, + { + USB_VENDOR_ELSA, + "ELSA", + }, + { + USB_VENDOR_BRAINBOXES, + "Brainboxes", + }, + { + USB_VENDOR_ULTIMA, + "Ultima", + }, + { + USB_VENDOR_AXIOHM, + "Axiohm Transaction Solutions", + }, + { + USB_VENDOR_MICROTEK, + "Microtek", + }, + { + USB_VENDOR_SUNTAC, + "SUN Corporation", + }, + { + USB_VENDOR_LEXAR, + "Lexar Media", + }, + { + USB_VENDOR_ADDTRON, + "Addtron", + }, + { + USB_VENDOR_SYMBOL, + "Symbol Technologies", + }, + { + USB_VENDOR_GENESYS, + "Genesys Logic", + }, + { + USB_VENDOR_FUJI, + "Fuji Electric", + }, + { + USB_VENDOR_KEITHLEY, + "Keithley Instruments", + }, + { + USB_VENDOR_EIZONANAO, + "EIZO Nanao", + }, + { + USB_VENDOR_KLSI, + "Kawasaki LSI", + }, + { + USB_VENDOR_FFC, + "FFC", + }, + { + USB_VENDOR_ANKO, + "Anko Electronic", + }, + { + USB_VENDOR_PIENGINEERING, + "P.I. Engineering", + }, + { + USB_VENDOR_AOC, + "AOC International", + }, + { + USB_VENDOR_CHIC, + "Chic Technology", + }, + { + USB_VENDOR_BARCO, + "Barco Display Systems", + }, + { + USB_VENDOR_BRIDGE, + "Bridge Information", + }, + { + USB_VENDOR_SOLIDYEAR, + "Solid Year", + }, + { + USB_VENDOR_BIORAD, + "Bio-Rad Laboratories", + }, + { + USB_VENDOR_MACALLY, + "Macally", + }, + { + USB_VENDOR_ACTLABS, + "Act Labs", + }, + { + USB_VENDOR_ALARIS, + "Alaris", + }, + { + USB_VENDOR_APEX, + "Apex", + }, + { + USB_VENDOR_VIVITAR, + "Vivitar", + }, + { + USB_VENDOR_GUNZE, + "Gunze Electronics USA", + }, + { + USB_VENDOR_AVISION, + "Avision", + }, + { + USB_VENDOR_TEAC, + "TEAC", + }, + { + USB_VENDOR_SGI, + "Silicon Graphics", + }, + { + USB_VENDOR_SANWASUPPLY, + "Sanwa Supply", + }, + { + USB_VENDOR_MUSTEK2, + "Mustek Systems", + }, + { + USB_VENDOR_LINKSYS, + "Linksys", + }, + { + USB_VENDOR_ACERSA, + "Acer Semiconductor America", + }, + { + USB_VENDOR_SIGMATEL, + "Sigmatel", + }, + { + USB_VENDOR_DRAYTEK, + "DrayTek", + }, + { + USB_VENDOR_AIWA, + "Aiwa", + }, + { + USB_VENDOR_ACARD, + "ACARD Technology", + }, + { + USB_VENDOR_PROLIFIC, + "Prolific Technology", + }, + { + USB_VENDOR_SIEMENS, + "Siemens", + }, + { + USB_VENDOR_AVANCELOGIC, + "Avance Logic", + }, + { + USB_VENDOR_SIEMENS2, + "Siemens", + }, + { + USB_VENDOR_MINOLTA, + "Minolta", + }, + { + USB_VENDOR_CHPRODUCTS, + "CH Products", + }, + { + USB_VENDOR_HAGIWARA, + "Hagiwara Sys-Com", + }, + { + USB_VENDOR_CTX, + "Chuntex", + }, + { + USB_VENDOR_ASKEY, + "Askey Computer", + }, + { + USB_VENDOR_SAITEK, + "Saitek", + }, + { + USB_VENDOR_ALCATELT, + "Alcatel Telecom", + }, + { + USB_VENDOR_AGFA, + "AGFA-Gevaert", + }, + { + USB_VENDOR_ASIAMD, + "Asia Microelectronic Development", + }, + { + USB_VENDOR_PHIDGETS, + "Phidgets", + }, + { + USB_VENDOR_BIZLINK, + "Bizlink International", + }, + { + USB_VENDOR_KEYSPAN, + "Keyspan", + }, + { + USB_VENDOR_AASHIMA, + "Aashima Technology", + }, + { + USB_VENDOR_LIEBERT, + "Liebert", + }, + { + USB_VENDOR_MULTITECH, + "MultiTech", + }, + { + USB_VENDOR_ADS, + "ADS Technologies", + }, + { + USB_VENDOR_ALCATELM, + "Alcatel Microelectronics", + }, + { + USB_VENDOR_SIRIUS, + "Sirius Technologies", + }, + { + USB_VENDOR_GUILLEMOT, + "Guillemot", + }, + { + USB_VENDOR_BOSTON, + "Boston Acoustics", + }, + { + USB_VENDOR_SMC, + "Standard Microsystems", + }, + { + USB_VENDOR_PUTERCOM, + "Putercom", + }, + { + USB_VENDOR_MCT, + "MCT", + }, + { + USB_VENDOR_IMATION, + "Imation", + }, + { + USB_VENDOR_DOMAIN, + "Domain Technologies, Inc.", + }, + { + USB_VENDOR_SUSTEEN, + "Susteen", + }, + { + USB_VENDOR_EICON, + "Eicon Networks", + }, + { + USB_VENDOR_STOLLMANN, + "Stollmann", + }, + { + USB_VENDOR_SYNTECH, + "Syntech Information", + }, + { + USB_VENDOR_DIGITALSTREAM, + "Digital Stream", + }, + { + USB_VENDOR_AUREAL, + "Aureal Semiconductor", + }, + { + USB_VENDOR_IDOWELL, + "iDowell", + }, + { + USB_VENDOR_MIDIMAN, + "Midiman", + }, + { + USB_VENDOR_CYBERPOWER, + "CyberPower", + }, + { + USB_VENDOR_SURECOM, + "Surecom Technology", + }, + { + USB_VENDOR_LINKSYS2, + "Linksys", + }, + { + USB_VENDOR_GRIFFIN, + "Griffin Technology", + }, + { + USB_VENDOR_SANDISK, + "SanDisk", + }, + { + USB_VENDOR_JENOPTIK, + "Jenoptik", + }, + { + USB_VENDOR_LOGITEC, + "Logitec", + }, + { + USB_VENDOR_NOKIA, + "Nokia", + }, + { + USB_VENDOR_BRIMAX, + "Brimax", + }, + { + USB_VENDOR_AXIS, + "Axis Communications", + }, + { + USB_VENDOR_ABL, + "ABL Electronics", + }, + { + USB_VENDOR_SAGEM, + "Sagem", + }, + { + USB_VENDOR_SUNCOMM, + "Sun Communications", + }, + { + USB_VENDOR_ALFADATA, + "Alfadata Computer", + }, + { + USB_VENDOR_NATIONALTECH, + "National Technical Systems", + }, + { + USB_VENDOR_ONNTO, + "Onnto", + }, + { + USB_VENDOR_BE, + "Be", + }, + { + USB_VENDOR_ADMTEK, + "ADMtek", + }, + { + USB_VENDOR_COREGA, + "Corega", + }, + { + USB_VENDOR_FREECOM, + "Freecom", + }, + { + USB_VENDOR_MICROTECH, + "Microtech", + }, + { + USB_VENDOR_MOTOROLA3, + "Motorola", + }, + { + USB_VENDOR_OLYMPUS, + "Olympus", + }, + { + USB_VENDOR_ABOCOM, + "AboCom Systems", + }, + { + USB_VENDOR_KEISOKUGIKEN, + "Keisokugiken", + }, + { + USB_VENDOR_ONSPEC, + "OnSpec", + }, + { + USB_VENDOR_APG, + "APG Cash Drawer", + }, + { + USB_VENDOR_BUG, + "B.U.G.", + }, + { + USB_VENDOR_ALLIEDTELESYN, + "Allied Telesyn International", + }, + { + USB_VENDOR_AVERMEDIA, + "AVerMedia Technologies", + }, + { + USB_VENDOR_SIIG, + "SIIG", + }, + { + USB_VENDOR_CASIO, + "CASIO", + }, + { + USB_VENDOR_DLINK2, + "D-Link", + }, + { + USB_VENDOR_APTIO, + "Aptio Products", + }, + { + USB_VENDOR_ARASAN, + "Arasan Chip Systems", + }, + { + USB_VENDOR_ALLIEDCABLE, + "Allied Cable", + }, + { + USB_VENDOR_STSN, + "STSN", + }, + { + USB_VENDOR_BEWAN, + "Bewan", + }, + { + USB_VENDOR_ZOOM, + "Zoom Telephonics", + }, + { + USB_VENDOR_BROADLOGIC, + "BroadLogic", + }, + { + USB_VENDOR_HANDSPRING, + "Handspring", + }, + { + USB_VENDOR_PALM, + "Palm Computing", + }, + { + USB_VENDOR_SOURCENEXT, + "SOURCENEXT", + }, + { + USB_VENDOR_ACTIONSTAR, + "Action Star Enterprise", + }, + { + USB_VENDOR_ACCTON, + "Accton Technology", + }, + { + USB_VENDOR_DIAMOND, + "Diamond", + }, + { + USB_VENDOR_NETGEAR, + "BayNETGEAR", + }, + { + USB_VENDOR_TOPRE, + "Topre Corporation", + }, + { + USB_VENDOR_ACTIVEWIRE, + "ActiveWire", + }, + { + USB_VENDOR_BBELECTR, + "B&B Electronics", + }, + { + USB_VENDOR_PORTGEAR, + "PortGear", + }, + { + USB_VENDOR_NETGEAR2, + "Netgear", + }, + { + USB_VENDOR_SYSTEMTALKS, + "System Talks", + }, + { + USB_VENDOR_METRICOM, + "Metricom", + }, + { + USB_VENDOR_ADESSOKBTEK, + "ADESSO/Kbtek America", + }, + { + USB_VENDOR_JATON, + "Jaton", + }, + { + USB_VENDOR_APT, + "APT Technologies", + }, + { + USB_VENDOR_BOCARESEARCH, + "Boca Research", + }, + { + USB_VENDOR_ANDREA, + "Andrea Electronics", + }, + { + USB_VENDOR_BURRBROWN, + "Burr-Brown Japan", + }, + { + USB_VENDOR_2WIRE, + "2Wire", + }, + { + USB_VENDOR_AIPTEK, + "AIPTEK International", + }, + { + USB_VENDOR_SMARTBRIDGES, + "SmartBridges", + }, + { + USB_VENDOR_BILLIONTON, + "Billionton Systems", + }, + { + USB_VENDOR_GEMPLUS, + "GEMPLUS", + }, + { + USB_VENDOR_EXTENDED, + "Extended Systems", + }, + { + USB_VENDOR_MSYSTEMS, + "M-Systems", + }, + { + USB_VENDOR_DIGIANSWER, + "Digianswer", + }, + { + USB_VENDOR_AUTHENTEC, + "AuthenTec", + }, + { + USB_VENDOR_SIEMENS4, + "Siemens", + }, + { + USB_VENDOR_AUDIOTECHNICA, + "Audio-Technica", + }, + { + USB_VENDOR_TRUMPION, + "Trumpion Microelectronics", + }, + { + USB_VENDOR_ALATION, + "Alation Systems", + }, + { + USB_VENDOR_GLOBESPAN, + "Globespan", + }, + { + USB_VENDOR_CONCORDCAMERA, + "Concord Camera", + }, + { + USB_VENDOR_GARMIN, + "Garmin International", + }, + { + USB_VENDOR_GOHUBS, + "GoHubs", + }, + { + USB_VENDOR_BIOMETRIC, + "American Biometric Company", + }, + { + USB_VENDOR_TOSHIBA, + "Toshiba Corp", + }, + { + USB_VENDOR_INTREPIDCS, + "Intrepid", + }, + { + USB_VENDOR_YANO, + "Yano", + }, + { + USB_VENDOR_KINGSTON, + "Kingston Technology", + }, + { + USB_VENDOR_BLUEWATER, + "BlueWater Systems", + }, + { + USB_VENDOR_AGILENT, + "Agilent Technologies", + }, + { + USB_VENDOR_GUDE, + "Gude ADS", + }, + { + USB_VENDOR_PORTSMITH, + "Portsmith", + }, + { + USB_VENDOR_ACERW, + "Acer", + }, + { + USB_VENDOR_ADIRONDACK, + "Adirondack Wire & Cable", + }, + { + USB_VENDOR_BECKHOFF, + "Beckhoff", + }, + { + USB_VENDOR_MINDSATWORK, + "Minds At Work", + }, + { + USB_VENDOR_INTERSIL, + "Intersil", + }, + { + USB_VENDOR_ALTIUS, + "Altius Solutions", + }, + { + USB_VENDOR_ARRIS, + "Arris Interactive", + }, + { + USB_VENDOR_ACTIVCARD, + "ACTIVCARD", + }, + { + USB_VENDOR_ACTISYS, + "ACTiSYS", + }, + { + USB_VENDOR_NOVATEL1, + "Novatel", + }, + { + USB_VENDOR_AFOURTECH, + "A-FOUR TECH", + }, + { + USB_VENDOR_AIMEX, + "AIMEX", + }, + { + USB_VENDOR_ADDONICS, + "Addonics Technologies", + }, + { + USB_VENDOR_AKAI, + "AKAI professional M.I.", + }, + { + USB_VENDOR_ARESCOM, + "ARESCOM", + }, + { + USB_VENDOR_BAY, + "Bay Associates", + }, + { + USB_VENDOR_ALTERA, + "Altera", + }, + { + USB_VENDOR_CSR, + "Cambridge Silicon Radio", + }, + { + USB_VENDOR_TREK, + "Trek Technology", + }, + { + USB_VENDOR_ASAHIOPTICAL, + "Asahi Optical", + }, + { + USB_VENDOR_BOCASYSTEMS, + "Boca Systems", + }, + { + USB_VENDOR_SHANTOU, + "ShanTou", + }, + { + USB_VENDOR_HIROSE, + "Hirose", + }, + { + USB_VENDOR_BROADCOM, + "Broadcom", + }, + { + USB_VENDOR_GREENHOUSE, + "GREENHOUSE", + }, + { + USB_VENDOR_GEOCAST, + "Geocast Network Systems", + }, + { + USB_VENDOR_DREAMCHEEKY, + "Dream Cheeky", + }, + { + USB_VENDOR_IDQUANTIQUE, + "id Quantique", + }, + { + USB_VENDOR_IDTECH, + "ID TECH", + }, + { + USB_VENDOR_ZYDAS, + "ZyDAS Technology", + }, + { + USB_VENDOR_CHENSOURCE, + "Chen-Source", + }, + { + USB_VENDOR_NEODIO, + "Neodio", + }, + { + USB_VENDOR_OPTION, + "Option", + }, + { + USB_VENDOR_ASUS, + "ASUS", + }, + { + USB_VENDOR_TODOS, + "Todos Data System", + }, + { + USB_VENDOR_OCT, + "Omnidirectional Control Technology", + }, + { + USB_VENDOR_TEKRAM, + "Tekram Technology", + }, + { + USB_VENDOR_HAL, + "HAL Corporation", + }, + { + USB_VENDOR_NEC2, + "NEC", + }, + { + USB_VENDOR_ATI2, + "ATI", + }, + { + USB_VENDOR_KURUSUGAWA, + "Kurusugawa Electronics", + }, + { + USB_VENDOR_SMART, + "Smart Technologies", + }, + { + USB_VENDOR_ASIX, + "ASIX Electronics", + }, + { + USB_VENDOR_O2MICRO, + "O2 Micro", + }, + { + USB_VENDOR_SACOM, + "System SACOM Industry Co.,Ltd", + }, + { + USB_VENDOR_USR, + "U.S. Robotics", + }, + { + USB_VENDOR_AMBIT, + "Ambit Microsystems", + }, + { + USB_VENDOR_HTC, + "HTC", + }, + { + USB_VENDOR_REALTEK, + "Realtek", + }, + { + USB_VENDOR_MEI, + "MEI", + }, + { + USB_VENDOR_ADDONICS2, + "Addonics Technology", + }, + { + USB_VENDOR_FSC, + "Fujitsu Siemens Computers", + }, + { + USB_VENDOR_AGATE, + "Agate Technologies", + }, + { + USB_VENDOR_DMI, + "DMI", + }, + { + USB_VENDOR_ICOM, + "Icom", + }, + { + USB_VENDOR_GNOTOMETRICS, + "GN Otometrics", + }, + { + USB_VENDOR_MICRODIA, + "Microdia / Sonix Technology Co., Ltd.", + }, + { + USB_VENDOR_SEALEVEL, + "Sealevel System", + }, + { + USB_VENDOR_JETI, + "JETI", + }, + { + USB_VENDOR_EASYDISK, + "EasyDisk", + }, + { + USB_VENDOR_ELEKTOR, + "Elektor Electronics", + }, + { + USB_VENDOR_KYOCERA2, + "Kyocera", + }, + { + USB_VENDOR_TERRATEC, + "TerraTec Electronic GmbH", + }, + { + USB_VENDOR_ZCOM, + "Z-Com", + }, + { + USB_VENDOR_ATHEROS2, + "Atheros Communications", + }, + { + USB_VENDOR_POSIFLEX, + "Posiflex Technologies", + }, + { + USB_VENDOR_TANGTOP, + "Tangtop", + }, + { + USB_VENDOR_KOBIL, + "Kobil Systems", + }, + { + USB_VENDOR_SMC3, + "SMC", + }, + { + USB_VENDOR_PEN, + "Pen Drive", + }, + { + USB_VENDOR_ABC, + "ABC", + }, + { + USB_VENDOR_CONCEPTRONIC, + "Conceptronic", + }, + { + USB_VENDOR_MSI, + "Micro Star International", + }, + { + USB_VENDOR_ELCON, + "ELCON Systemtechnik", + }, + { + USB_VENDOR_UNKNOWN5, + "Unknown Vendor", + }, + { + USB_VENDOR_SITECOMEU, + "Sitecom Europe", + }, + { + USB_VENDOR_MOBILEACTION, + "Mobile Action", + }, + { + USB_VENDOR_AMIGO, + "Amigo Technology", + }, + { + USB_VENDOR_VMWARE, + "VMware", + }, + { + USB_VENDOR_SPEEDDRAGON, + "Speed Dragon Multimedia", + }, + { + USB_VENDOR_CTC, + "CONWISE Technology", + }, + { + USB_VENDOR_HAWKING, + "Hawking", + }, + { + USB_VENDOR_FOSSIL, + "Fossil", + }, + { + USB_VENDOR_GMATE, + "G.Mate", + }, + { + USB_VENDOR_MEDIATEK, + "MediaTek Inc.", + }, + { + USB_VENDOR_OTI, + "Ours Technology", + }, + { + USB_VENDOR_PILOTECH, + "Pilotech", + }, + { + USB_VENDOR_NOVATECH, + "Nova Tech", + }, + { + USB_VENDOR_ITEGNO, + "iTegno", + }, + { + USB_VENDOR_NORITAKE, + "Noritake itron Corp", + }, + { + USB_VENDOR_EGALAX, + "eGalax", + }, + { + USB_VENDOR_XIRING, + "XIRING", + }, + { + USB_VENDOR_AIRPRIME, + "Airprime", + }, + { + USB_VENDOR_VTECH, + "VTech", + }, + { + USB_VENDOR_FALCOM, + "Falcom Wireless Communications", + }, + { + USB_VENDOR_RIM, + "Research In Motion", + }, + { + USB_VENDOR_DYNASTREAM, + "Dynastream Innovations", + }, + { + USB_VENDOR_LARSENBRUSGAARD, + "Larsen and Brusgaard", + }, + { + USB_VENDOR_OREGONSCI, + "Oregon Scientific", + }, + { + USB_VENDOR_UNKNOWN4, + "Unknown Vendor", + }, + { + USB_VENDOR_DVICO, + "DViCO", + }, + { + USB_VENDOR_QUALCOMM2, + "Qualcomm", + }, + { + USB_VENDOR_MOTOROLA4, + "Motorola", + }, + { + USB_VENDOR_HP3, + "Hewlett Packard", + }, + { + USB_VENDOR_THURLBY, + "Thurlby Thandar Instruments", + }, + { + USB_VENDOR_GIGABYTE, + "GIGABYTE", + }, + { + USB_VENDOR_YUBICO, + "Yubico.com", + }, + { + USB_VENDOR_MOTOROLA, + "Motorola", + }, + { + USB_VENDOR_CCYU, + "CCYU Technology", + }, + { + USB_VENDOR_HYUNDAI, + "Hyundai", + }, + { + USB_VENDOR_GCTSEMICON, + "GCT Semiconductor", + }, + { + USB_VENDOR_SILABS2, + "Silicon Labs", + }, + { + USB_VENDOR_USI, + "USI", + }, + { + USB_VENDOR_LIEBERT2, + "Liebert", + }, + { + USB_VENDOR_PLX, + "PLX", + }, + { + USB_VENDOR_ASANTE, + "Asante", + }, + { + USB_VENDOR_SILABS, + "Silicon Labs", + }, + { + USB_VENDOR_SILABS3, + "Silicon Labs", + }, + { + USB_VENDOR_SILABS4, + "Silicon Labs", + }, + { + USB_VENDOR_VELLEMAN, + "Velleman", + }, + { + USB_VENDOR_MOXA, + "Moxa Technologies", + }, + { + USB_VENDOR_ANALOG, + "Analog Devices", + }, + { + USB_VENDOR_TENX, + "Ten X Technology, Inc.", + }, + { + USB_VENDOR_ISSC, + "Integrated System Solution Corp.", + }, + { + USB_VENDOR_JRC, + "Japan Radio Company", + }, + { + USB_VENDOR_SPHAIRON, + "Sphairon Access Systems", + }, + { + USB_VENDOR_DELORME, + "DeLorme", + }, + { + USB_VENDOR_SERVERWORKS, + "ServerWorks", + }, + { + USB_VENDOR_ACERCM, + "Acer Communications & Multimedia", + }, + { + USB_VENDOR_SIERRA, + "Sierra Wireless", + }, + { + USB_VENDOR_SIEMENS3, + "Siemens", + }, + { + USB_VENDOR_ALCATEL, + "Alcatel", + }, + { + USB_VENDOR_INTERBIO, + "InterBiometrics", + }, + { + USB_VENDOR_UNKNOWN3, + "Unknown vendor", + }, + { + USB_VENDOR_TSUNAMI, + "Tsunami", + }, + { + USB_VENDOR_PHEENET, + "Pheenet", + }, + { + USB_VENDOR_RAPTORGAMING, + "Raptor Gaming", + }, + { + USB_VENDOR_TWINMOS, + "TwinMOS", + }, + { + USB_VENDOR_TENDA, + "Tenda", + }, + { + USB_VENDOR_TESTO, + "Testo AG", + }, + { + USB_VENDOR_CREATIVE2, + "Creative Labs", + }, + { + USB_VENDOR_BELKIN2, + "Belkin Components", + }, + { + USB_VENDOR_CYBERTAN, + "CyberTAN Technology", + }, + { + USB_VENDOR_HUAWEI, + "HUAWEI Technologies", + }, + { + USB_VENDOR_ARANEUS, + "Araneus Information Systems", + }, + { + USB_VENDOR_TAPWAVE, + "Tapwave", + }, + { + USB_VENDOR_AINCOMM, + "Aincomm", + }, + { + USB_VENDOR_MOBILITY, + "Mobility", + }, + { + USB_VENDOR_DICKSMITH, + "Dick Smith Electronics", + }, + { + USB_VENDOR_NETGEAR3, + "Netgear", + }, + { + USB_VENDOR_VALIDITY, + "Validity Sensors", + }, + { + USB_VENDOR_BALTECH, + "Baltech", + }, + { + USB_VENDOR_CISCOLINKSYS, + "Cisco-Linksys", + }, + { + USB_VENDOR_SHARK, + "Shark", + }, + { + USB_VENDOR_AZUREWAVE, + "AsureWave", + }, + { + USB_VENDOR_NOVATEL, + "Novatel", + }, + { + USB_VENDOR_WISTRONNEWEB, + "Wistron NeWeb", + }, + { + USB_VENDOR_RADIOSHACK, + "Radio Shack", + }, + { + USB_VENDOR_OPENMOKO, + "OpenMoko", + }, + { + USB_VENDOR_HUAWEI3COM, + "Huawei 3Com", + }, + { + USB_VENDOR_ABOCOM2, + "AboCom Systems", + }, + { + USB_VENDOR_SILICOM, + "Silicom", + }, + { + USB_VENDOR_RALINK, + "Ralink Technology", + }, + { + USB_VENDOR_STARTECH, + "StarTech.com", + }, + { + USB_VENDOR_CONCEPTRONIC2, + "Conceptronic", + }, + { + USB_VENDOR_SUPERTOP, + "SuperTop", + }, + { + USB_VENDOR_PLANEX3, + "Planex Communications", + }, + { + USB_VENDOR_SILICONPORTALS, + "Silicon Portals", + }, + { + USB_VENDOR_UBLOX, + "U-blox", + }, + { + USB_VENDOR_OWEN, + "Owen", + }, + { + USB_VENDOR_OQO, + "OQO", + }, + { + USB_VENDOR_UMEDIA, + "U-MEDIA Communications", + }, + { + USB_VENDOR_FIBERLINE, + "Fiberline", + }, + { + USB_VENDOR_SPARKLAN, + "SparkLAN", + }, + { + USB_VENDOR_OLIMEX, + "Olimex", + }, + { + USB_VENDOR_AMIT2, + "AMIT", + }, + { + USB_VENDOR_TRUST, + "Trust", + }, + { + USB_VENDOR_SOHOWARE, + "SOHOware", + }, + { + USB_VENDOR_UMAX, + "UMAX Data Systems", + }, + { + USB_VENDOR_INSIDEOUT, + "Inside Out Networks", + }, + { + USB_VENDOR_GOODWAY, + "Good Way Technology", + }, + { + USB_VENDOR_ENTREGA, + "Entrega", + }, + { + USB_VENDOR_ACTIONTEC, + "Actiontec Electronics", + }, + { + USB_VENDOR_CLIPSAL, + "Clipsal", + }, + { + USB_VENDOR_CISCOLINKSYS2, + "Cisco-Linksys", + }, + { + USB_VENDOR_ATHEROS, + "Atheros Communications", + }, + { + USB_VENDOR_GIGASET, + "Gigaset", + }, + { + USB_VENDOR_GLOBALSUN, + "Global Sun Technology", + }, + { + USB_VENDOR_VOTI, + "Van Ooijen Technische Informatica", + }, + { + USB_VENDOR_ANYDATA, + "AnyDATA Inc.", + }, + { + USB_VENDOR_JABLOTRON, + "Jablotron", + }, + { + USB_VENDOR_CMOTECH, + "CMOTECH", + }, + { + USB_VENDOR_WIENERPLEINBAUS, + "WIENER Plein & Baus", + }, + { + USB_VENDOR_AXESSTEL, + "Axesstel", + }, + { + USB_VENDOR_LINKSYS4, + "Linksys", + }, + { + USB_VENDOR_SENAO, + "Senao", + }, + { + USB_VENDOR_ASUS2, + "ASUS", + }, + { + USB_VENDOR_STRAWBERRYLINUX, + "Strawberry linux Co., Ltd.", + }, + { + USB_VENDOR_SWEEX2, + "Sweex", + }, + { + USB_VENDOR_MECANIQUE, + "Mecanique", + }, + { + USB_VENDOR_KAMSTRUP, + "Kamstrup A/S", + }, + { + USB_VENDOR_DISPLAYLINK, + "DisplayLink", + }, + { + USB_VENDOR_LENOVO, + "Lenovo", + }, + { + USB_VENDOR_WAVESENSE, + "WaveSense", + }, + { + USB_VENDOR_VAISALA, + "VAISALA", + }, + { + USB_VENDOR_AMIT, + "AMIT", + }, + { + USB_VENDOR_GOOGLE, + "Google", + }, + { + USB_VENDOR_QCOM, + "Qcom", + }, + { + USB_VENDOR_ELV, + "ELV", + }, + { + USB_VENDOR_LINKSYS3, + "Linksys", + }, + { + USB_VENDOR_AVAGO, + "Avago", + }, + { + USB_VENDOR_MEINBERG, + "Meinberg Funkuhren", + }, + { + USB_VENDOR_ZTE, + "ZTE Inc.", + }, + { + USB_VENDOR_QUANTA, + "Quanta", + }, + { + USB_VENDOR_TERMINUS, + "Terminus Technology", + }, + { + USB_VENDOR_ABBOTT, + "Abbott Labs", + }, + { + USB_VENDOR_BAYER, + "Bayer Health Care", + }, + { + USB_VENDOR_WCH2, + "QinHeng Electronics", + }, + { + USB_VENDOR_SEL, + "Schweitzer Engineering Laboratories", + }, + { + USB_VENDOR_CORSAIR, + "Corsair", + }, + { + USB_VENDOR_MATRIXORB, + "Matrix Orbital", + }, + { + USB_VENDOR_TORADEX, + "Toradex inc.", + }, + { + USB_VENDOR_FUSHICAI, + "Fushicai", + }, + { + USB_VENDOR_OVISLINK, + "OvisLink", + }, + { + USB_VENDOR_TML, + "The Mobility Lab", + }, + { + USB_VENDOR_SILABS5, + "Silicon Labs", + }, + { + USB_VENDOR_TCTMOBILE, + "TCT Mobile", + }, + { + USB_VENDOR_MDS, + "MDS", + }, + { + USB_VENDOR_ALTI2, + "Alti-2", + }, + { + USB_VENDOR_SUNPLUS, + "Sunplus", + }, + { + USB_VENDOR_WAGO, + "WAGO Kontakttechnik", + }, + { + USB_VENDOR_LONGCHEER, + "Longcheer Technology", + }, + { + USB_VENDOR_DRESDENELEC, + "Dresden Elektronic", + }, + { + USB_VENDOR_DREAMLINK, + "Dream Link", + }, + { + USB_VENDOR_PEGATRON, + "Pegatron", + }, + { + USB_VENDOR_OPENMOKO2, + "OpenMoko", + }, + { + USB_VENDOR_SELUXIT, + "Seluxit", + }, + { + USB_VENDOR_METAGEEK, + "MetaGeek", + }, + { + USB_VENDOR_SIMCOM, + "SIMCom Wireless Solutions Co., Ltd.", + }, + { + USB_VENDOR_FESTO, + "Festo", + }, + { + USB_VENDOR_MODACOM, + "Modacom", + }, + { + USB_VENDOR_AIRTIES, + "AirTies", + }, + { + USB_VENDOR_LAKESHORE, + "Lake Shore", + }, + { + USB_VENDOR_VERTEX, + "Vertex Wireless Co., Ltd.", + }, + { + USB_VENDOR_DLINK, + "D-Link", + }, + { + USB_VENDOR_PLANEX2, + "Planex Communications", + }, + { + USB_VENDOR_ENCORE, + "Encore", + }, + { + USB_VENDOR_PARA, + "PARA Industrial", + }, + { + USB_VENDOR_TRENDNET, + "TRENDnet", + }, + { + USB_VENDOR_RTSYSTEMS, + "RT Systems", + }, + { + USB_VENDOR_DLINK3, + "D-Link", + }, + { + USB_VENDOR_VIALABS, + "VIA Labs", + }, + { + USB_VENDOR_MOTOROLA2, + "Motorola", + }, + { + USB_VENDOR_ARDUINO, + "Arduino SA", + }, + { + USB_VENDOR_TPLINK, + "TP-Link", + }, + { + USB_VENDOR_WMR, + "West Mountain Radio", + }, + { + USB_VENDOR_TRIPPLITE, + "Tripp-Lite", + }, + { + USB_VENDOR_ARUBA, + "Aruba", + }, + { + USB_VENDOR_XIAOMI, + "Xiaomi", + }, + { + USB_VENDOR_NHJ, + "NHJ", + }, + { + USB_VENDOR_ASUSTEK, + "ASUSTeK Computer", + }, + { + USB_VENDOR_PLANEX, + "Planex Communications", + }, + { + USB_VENDOR_LINKINSTRUMENTS, + "Link Instruments", + }, + { + USB_VENDOR_AEI, + "AEI", + }, + { + USB_VENDOR_PQI, + "PQI", + }, + { + USB_VENDOR_DAISY, + "Daisy Technology", + }, + { + USB_VENDOR_NI, + "National Instruments", + }, + { + USB_VENDOR_MICRONET, + "Micronet Communications", + }, + { + USB_VENDOR_IODATA2, + "I-O Data", + }, + { + USB_VENDOR_IRIVER, + "iRiver", + }, + { + USB_VENDOR_DELL, + "Dell", + }, + { + USB_VENDOR_WCH, + "QinHeng Electronics", + }, + { + USB_VENDOR_ACEECA, + "Aceeca", + }, + { + USB_VENDOR_FEIXUN, + "FeiXun Communication", + }, + { + USB_VENDOR_NETWEEN, + "NetweeN", + }, + { + USB_VENDOR_PAPOUCH, + "Papouch s.r.o.", + }, + { + USB_VENDOR_AVERATEC, + "Averatec", + }, + { + USB_VENDOR_SWEEX, + "Sweex", + }, + { + USB_VENDOR_PROLIFIC2, + "Prolific Technology", + }, + { + USB_VENDOR_ONSPEC2, + "OnSpec", + }, + { + USB_VENDOR_ACERLABS2, + "Acer", + }, + { + USB_VENDOR_ZINWELL, + "Zinwell", + }, + { + USB_VENDOR_SITECOM, + "Sitecom", + }, + { + USB_VENDOR_ARKMICRO, + "Arkmicro", + }, + { + USB_VENDOR_3COM2, + "3Com", + }, + { + USB_VENDOR_EDIMAX, + "EDIMAX", + }, + { + USB_VENDOR_INTEL, + "Intel", + }, + { + USB_VENDOR_INTEL2, + "Intel", + }, + { + USB_VENDOR_ALLWIN, + "ALLWIN Tech", + }, + { + USB_VENDOR_SITECOM2, + "Sitecom", + }, + { + USB_VENDOR_MOSCHIP, + "MosChip", + }, + { + USB_VENDOR_NETGEAR4, + "Netgear", + }, + { + USB_VENDOR_MARVELL, + "Marvell", + }, + { + USB_VENDOR_3COM3, + "3Com", + }, + { + USB_VENDOR_CACE, + "CACE Technologies", + }, + { + USB_VENDOR_COMPARE, + "Compare", + }, + { + USB_VENDOR_DATAAPEX, + "DataApex", + }, + { + USB_VENDOR_EVOLUTION, + "Evolution Robotics", + }, + { + USB_VENDOR_EMPIA, + "eMPIA Technology", + }, + { + USB_VENDOR_HP2, + "Hewlett Packard", + }, + { 0, NULL } +}; diff --git a/test/test011.left.txt b/test/test011.left.txt new file mode 100644 index 000000000000..2fbc5affa850 --- /dev/null +++ b/test/test011.left.txt @@ -0,0 +1,393 @@ +/* $OpenBSD: usbdevs_data.h,v 1.715 2020/01/20 07:09:11 jsg Exp $ */ + +/* + * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. + * + * generated from: + * OpenBSD: usbdevs,v 1.709 2020/01/20 07:08:20 jsg Exp + */ +/* $NetBSD: usbdevs,v 1.322 2003/05/10 17:47:14 hamajima Exp $ */ + +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 + + { + USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8812AU, + "RTL8812AU", + }, + { + USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8192EU, + "RTL8192EU", + }, + { + USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8188EUS, + "RTL8188EUS", + }, + { + USB_VENDOR_TREK, USB_PRODUCT_TREK_THUMBDRIVE, + "ThumbDrive", + }, + { + USB_VENDOR_HP2, + "Hewlett Packard", + }, + { 0, NULL } +}; diff --git a/test/test011.right.txt b/test/test011.right.txt new file mode 100644 index 000000000000..417db010011c --- /dev/null +++ b/test/test011.right.txt @@ -0,0 +1,397 @@ +/* $OpenBSD$ */ + +/* + * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. + * + * generated from: + * OpenBSD: usbdevs,v 1.709 2020/01/20 07:08:20 jsg Exp + */ +/* $NetBSD: usbdevs,v 1.322 2003/05/10 17:47:14 hamajima Exp $ */ + +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 + + { + USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8812AU, + "RTL8812AU", + }, + { + USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8192EU, + "RTL8192EU", + }, + { + USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8192EU_2, + "RTL8192EU", + }, + { + USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8188EUS, + "RTL8188EUS", + }, + { + USB_VENDOR_TREK, USB_PRODUCT_TREK_THUMBDRIVE, + "ThumbDrive", + }, + { + USB_VENDOR_HP2, + "Hewlett Packard", + }, + { 0, NULL } +}; diff --git a/test/test012.left.txt b/test/test012.left.txt new file mode 100644 index 000000000000..1081d16c6e49 --- /dev/null +++ b/test/test012.left.txt @@ -0,0 +1,23 @@ +1 left +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 diff --git a/test/test012.right.txt b/test/test012.right.txt new file mode 100644 index 000000000000..dee7f5e68de3 --- /dev/null +++ b/test/test012.right.txt @@ -0,0 +1,29 @@ +1 right +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +14 +15 +16 right +17 +18 +19 +20 +21 +22 +23 diff --git a/test/test013.left-w.txt b/test/test013.left-w.txt new file mode 100644 index 000000000000..53b3adf33dac --- /dev/null +++ b/test/test013.left-w.txt @@ -0,0 +1,7 @@ +A +B +C +D +E +F +G diff --git a/test/test013.right-w.txt b/test/test013.right-w.txt new file mode 100644 index 000000000000..1509b4b4fdfa --- /dev/null +++ b/test/test013.right-w.txt @@ -0,0 +1,7 @@ +A + B +C + D +E +F x +y G diff --git a/test/test014.left.txt b/test/test014.left.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/test014.right.txt b/test/test014.right.txt new file mode 100644 index 000000000000..f70f10e4db19 --- /dev/null +++ b/test/test014.right.txt @@ -0,0 +1 @@ +A diff --git a/test/test015.left.txt b/test/test015.left.txt new file mode 100644 index 000000000000..f70f10e4db19 --- /dev/null +++ b/test/test015.left.txt @@ -0,0 +1 @@ +A diff --git a/test/test015.right.txt b/test/test015.right.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/test016.left.txt b/test/test016.left.txt new file mode 100644 index 000000000000..9a6e925fd9fb --- /dev/null +++ b/test/test016.left.txt @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2017 Martin Pieuchot + * Copyright (c) 2018, 2019, 2020 Stefan Sperling + * Copyright (c) 2020 Ori Bernstein + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +static const struct got_error * +cmd_import(int argc, char *argv[]) +{ + const struct got_error *error = NULL; + char *path_dir = NULL, *repo_path = NULL, *logmsg = NULL; + char *gitconfig_path = NULL, *editor = NULL, *author = NULL; + const char *branch_name = "main"; + char *refname = NULL, *id_str = NULL, *logmsg_path = NULL; + struct got_repository *repo = NULL; + struct got_reference *branch_ref = NULL, *head_ref = NULL; + struct got_object_id *new_commit_id = NULL; + int ch; + struct got_pathlist_head ignores; + struct got_pathlist_entry *pe; + int preserve_logmsg = 0; + + TAILQ_INIT(&ignores); + + while ((ch = getopt(argc, argv, "b:m:r:I:")) != -1) { + switch (ch) { + case 'b': + branch_name = optarg; + break; + case 'm': + logmsg = strdup(optarg); + if (logmsg == NULL) { + error = got_error_from_errno("strdup"); + goto done; + } + break; + case 'r': + repo_path = realpath(optarg, NULL); + if (repo_path == NULL) { + error = got_error_from_errno2("realpath", + optarg); + goto done; + } + break; + case 'I': + if (optarg[0] == '\0') + break; + error = got_pathlist_insert(&pe, &ignores, optarg, + NULL); + if (error) + goto done; + break; + default: + usage_import(); + /* NOTREACHED */ + } + } + +#ifndef PROFILE + if (pledge("stdio rpath wpath cpath fattr flock proc exec sendfd " + "unveil", + NULL) == -1) + err(1, "pledge"); +#endif + if (argc != 1) + usage_import(); + + if (repo_path == NULL) { + repo_path = getcwd(NULL, 0); + if (repo_path == NULL) + return got_error_from_errno("getcwd"); + } + error = get_gitconfig_path(&gitconfig_path); + if (error) + goto done; + error = got_repo_open(&repo, repo_path, gitconfig_path); + if (error) + goto done; + + error = get_author(&author, repo, NULL); + if (error) + return error; + + /* + * Don't let the user create a branch name with a leading '-'. + * While technically a valid reference name, this case is usually + * an unintended typo. + */ + if (branch_name[0] == '-') + return got_error_path(branch_name, GOT_ERR_REF_NAME_MINUS); + + if (asprintf(&refname, "refs/heads/%s", branch_name) == -1) { + error = got_error_from_errno("asprintf"); + goto done; + } + + error = got_ref_open(&branch_ref, repo, refname, 0); + if (error) { + if (error->code != GOT_ERR_NOT_REF) + goto done; + } else { + error = got_error_msg(GOT_ERR_BRANCH_EXISTS, + "import target branch already exists"); + goto done; + } + + path_dir = realpath(argv[0], NULL); + if (path_dir == NULL) { + error = got_error_from_errno2("realpath", argv[0]); + goto done; + } + got_path_strip_trailing_slashes(path_dir); + + /* + * unveil(2) traverses exec(2); if an editor is used we have + * to apply unveil after the log message has been written. + */ + if (logmsg == NULL || strlen(logmsg) == 0) { + error = get_editor(&editor); + if (error) + goto done; + free(logmsg); + error = collect_import_msg(&logmsg, &logmsg_path, editor, + path_dir, refname); + if (error) { + if (error->code != GOT_ERR_COMMIT_MSG_EMPTY && + logmsg_path != NULL) + preserve_logmsg = 1; + goto done; + } + } + + if (unveil(path_dir, "r") != 0) { + error = got_error_from_errno2("unveil", path_dir); + if (logmsg_path) + preserve_logmsg = 1; + goto done; + } + + error = apply_unveil(got_repo_get_path(repo), 0, NULL); + if (error) { + if (logmsg_path) + preserve_logmsg = 1; + goto done; + } + + error = got_repo_import(&new_commit_id, path_dir, logmsg, + author, &ignores, repo, import_progress, NULL); + if (error) { + if (logmsg_path) + preserve_logmsg = 1; + goto done; + } + + error = got_ref_alloc(&branch_ref, refname, new_commit_id); + if (error) { + if (logmsg_path) + preserve_logmsg = 1; + goto done; + } + + error = got_ref_write(branch_ref, repo); + if (error) { + if (logmsg_path) + preserve_logmsg = 1; + goto done; + } + + error = got_object_id_str(&id_str, new_commit_id); + if (error) { + if (logmsg_path) + preserve_logmsg = 1; + goto done; + } + + error = got_ref_open(&head_ref, repo, GOT_REF_HEAD, 0); + if (error) { + if (error->code != GOT_ERR_NOT_REF) { + if (logmsg_path) + preserve_logmsg = 1; + goto done; + } + + error = got_ref_alloc_symref(&head_ref, GOT_REF_HEAD, + branch_ref); + if (error) { + if (logmsg_path) + preserve_logmsg = 1; + goto done; + } + + error = got_ref_write(head_ref, repo); + if (error) { + if (logmsg_path) + preserve_logmsg = 1; + goto done; + } + } + + printf("Created branch %s with commit %s\n", + got_ref_get_name(branch_ref), id_str); +done: + if (preserve_logmsg) { + fprintf(stderr, "%s: log message preserved in %s\n", + getprogname(), logmsg_path); + } else if (logmsg_path && unlink(logmsg_path) == -1 && error == NULL) + error = got_error_from_errno2("unlink", logmsg_path); + free(logmsg); + free(logmsg_path); + free(repo_path); + free(editor); + free(refname); + free(new_commit_id); + free(id_str); + free(author); + free(gitconfig_path); + if (branch_ref) + got_ref_close(branch_ref); + if (head_ref) + got_ref_close(head_ref); + return error; +} + +__dead static void +usage_clone(void) +{ + fprintf(stderr, "usage: %s clone [-a] [-b branch] [-l] [-m] [-q] [-v] " + "[-R reference] repository-url [directory]\n", getprogname()); + exit(1); +} + +static const struct got_error * +cmd_clone(int argc, char *argv[]) +{ + const struct got_error *error = NULL; + const char *uri, *dirname; + char *proto, *host, *port, *repo_name, *server_path; + char *default_destdir = NULL, *id_str = NULL; + const char *repo_path; + struct got_repository *repo = NULL; + struct got_pathlist_head refs, symrefs, wanted_branches, wanted_refs; + struct got_pathlist_entry *pe; + struct got_object_id *pack_hash = NULL; + int ch, fetchfd = -1, fetchstatus; + pid_t fetchpid = -1; + x + + /* Create got.conf(5). */ + gotconfig_path = got_repo_get_path_gotconfig(repo); + if (gotconfig_path == NULL) { + error = got_error_from_errno("got_repo_get_path_gotconfig"); + goto done; + } + gotconfig_file = fopen(gotconfig_path, "a"); + if (gotconfig_file == NULL) { + error = got_error_from_errno2("fopen", gotconfig_path); + goto done; + } + got_path_strip_trailing_slashes(server_path); + if (asprintf(&gotconfig, + "remote \"%s\" {\n" + "\tserver %s\n" + "\tprotocol %s\n" + "%s%s%s" + "\trepository \"%s\"\n" + "%s" + "}\n", + GOT_FETCH_DEFAULT_REMOTE_NAME, host, proto, + port ? "\tport " : "", port ? port : "", port ? "\n" : "", + server_path, + mirror_references ? "\tmirror-references yes\n" : "") == -1) { + error = got_error_from_errno("asprintf"); + goto done; + } + n = fwrite(gotconfig, 1, strlen(gotconfig), gotconfig_file); + if (n != strlen(gotconfig)) { + error = got_ferror(gotconfig_file, GOT_ERR_IO); + goto done; + } +} diff --git a/test/test016.right.txt b/test/test016.right.txt new file mode 100644 index 000000000000..005c3dbd02ea --- /dev/null +++ b/test/test016.right.txt @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2017 Martin Pieuchot + * Copyright (c) 2018, 2019, 2020 Stefan Sperling + * Copyright (c) 2020 Ori Bernstein + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +static const struct got_error * +cmd_import(int argc, char *argv[]) +{ + const struct got_error *error = NULL; + char *path_dir = NULL, *repo_path = NULL, *logmsg = NULL; + char *gitconfig_path = NULL, *editor = NULL, *author = NULL; + const char *branch_name = "main"; + char *refname = NULL, *id_str = NULL, *logmsg_path = NULL; + struct got_repository *repo = NULL; + struct got_reference *branch_ref = NULL, *head_ref = NULL; + struct got_object_id *new_commit_id = NULL; + int ch; + struct got_pathlist_head ignores; + struct got_pathlist_entry *pe; + int preserve_logmsg = 0; + + TAILQ_INIT(&ignores); + + while ((ch = getopt(argc, argv, "b:m:r:I:")) != -1) { + switch (ch) { + case 'b': + branch_name = optarg; + break; + case 'm': + logmsg = strdup(optarg); + if (logmsg == NULL) { + error = got_error_from_errno("strdup"); + goto done; + } + break; + case 'r': + repo_path = realpath(optarg, NULL); + if (repo_path == NULL) { + error = got_error_from_errno2("realpath", + optarg); + goto done; + } + break; + case 'I': + if (optarg[0] == '\0') + break; + error = got_pathlist_insert(&pe, &ignores, optarg, + NULL); + if (error) + goto done; + break; + default: + usage_import(); + /* NOTREACHED */ + } + } + +#ifndef PROFILE + if (pledge("stdio rpath wpath cpath fattr flock proc exec sendfd " + "unveil", + NULL) == -1) + err(1, "pledge"); +#endif + if (argc != 1) + usage_import(); + + if (repo_path == NULL) { + repo_path = getcwd(NULL, 0); + if (repo_path == NULL) + return got_error_from_errno("getcwd"); + } + error = get_gitconfig_path(&gitconfig_path); + if (error) + goto done; + error = got_repo_open(&repo, repo_path, gitconfig_path); + if (error) + goto done; + + error = get_author(&author, repo, NULL); + if (error) + return error; + + /* + * Don't let the user create a branch name with a leading '-'. + * While technically a valid reference name, this case is usually + * an unintended typo. + */ + if (branch_name[0] == '-') + return got_error_path(branch_name, GOT_ERR_REF_NAME_MINUS); + + if (asprintf(&refname, "refs/heads/%s", branch_name) == -1) { + error = got_error_from_errno("asprintf"); + goto done; + } + + error = got_ref_open(&branch_ref, repo, refname, 0); + if (error) { + if (error->code != GOT_ERR_NOT_REF) + goto done; + } else { + error = got_error_msg(GOT_ERR_BRANCH_EXISTS, + "import target branch already exists"); + goto done; + } + + path_dir = realpath(argv[0], NULL); + if (path_dir == NULL) { + error = got_error_from_errno2("realpath", argv[0]); + goto done; + } + got_path_strip_trailing_slashes(path_dir); + + /* + * unveil(2) traverses exec(2); if an editor is used we have + * to apply unveil after the log message has been written. + */ + if (logmsg == NULL || strlen(logmsg) == 0) { + error = get_editor(&editor); + if (error) + goto done; + free(logmsg); + error = collect_import_msg(&logmsg, &logmsg_path, editor, + path_dir, refname); + if (error) { + if (error->code != GOT_ERR_COMMIT_MSG_EMPTY && + logmsg_path != NULL) + preserve_logmsg = 1; + goto done; + } + } + + if (unveil(path_dir, "r") != 0) { + error = got_error_from_errno2("unveil", path_dir); + if (logmsg_path) + preserve_logmsg = 1; + goto done; + } + + error = apply_unveil(got_repo_get_path(repo), 0, NULL); + if (error) { + if (logmsg_path) + preserve_logmsg = 1; + goto done; + } + + error = got_repo_import(&new_commit_id, path_dir, logmsg, + author, &ignores, repo, import_progress, NULL); + if (error) { + if (logmsg_path) + preserve_logmsg = 1; + goto done; + } + + error = got_ref_alloc(&branch_ref, refname, new_commit_id); + if (error) { + if (logmsg_path) + preserve_logmsg = 1; + goto done; + } + + error = got_ref_write(branch_ref, repo); + if (error) { + if (logmsg_path) + preserve_logmsg = 1; + goto done; + } + + error = got_object_id_str(&id_str, new_commit_id); + if (error) { + if (logmsg_path) + preserve_logmsg = 1; + goto done; + } + + error = got_ref_open(&head_ref, repo, GOT_REF_HEAD, 0); + if (error) { + if (error->code != GOT_ERR_NOT_REF) { + if (logmsg_path) + preserve_logmsg = 1; + goto done; + } + + error = got_ref_alloc_symref(&head_ref, GOT_REF_HEAD, + branch_ref); + if (error) { + if (logmsg_path) + preserve_logmsg = 1; + goto done; + } + + error = got_ref_write(head_ref, repo); + if (error) { + if (logmsg_path) + preserve_logmsg = 1; + goto done; + } + } + + printf("Created branch %s with commit %s\n", + got_ref_get_name(branch_ref), id_str); +done: + if (preserve_logmsg) { + fprintf(stderr, "%s: log message preserved in %s\n", + getprogname(), logmsg_path); + } else if (logmsg_path && unlink(logmsg_path) == -1 && error == NULL) + error = got_error_from_errno2("unlink", logmsg_path); + free(logmsg); + free(logmsg_path); + free(repo_path); + free(editor); + free(refname); + free(new_commit_id); + free(id_str); + free(author); + free(gitconfig_path); + if (branch_ref) + got_ref_close(branch_ref); + if (head_ref) + got_ref_close(head_ref); + return error; +} + +__dead static void +usage_clone(void) +{ + fprintf(stderr, "usage: %s clone [-a] [-b branch] [-l] [-m] [-q] [-v] " + "[-R reference] repository-url [directory]\n", getprogname()); + exit(1); +} + +static const struct got_error * +cmd_clone(int argc, char *argv[]) +{ + const struct got_error *error = NULL; + const char *uri, *dirname; + char *proto, *host, *port, *repo_name, *server_path; + char *default_destdir = NULL, *id_str = NULL; + const char *repo_path, *remote_repo_path; + struct got_repository *repo = NULL; + struct got_pathlist_head refs, symrefs, wanted_branches, wanted_refs; + struct got_pathlist_entry *pe; + struct got_object_id *pack_hash = NULL; + int ch, fetchfd = -1, fetchstatus; + pid_t fetchpid = -1; + x + + /* Create got.conf(5). */ + gotconfig_path = got_repo_get_path_gotconfig(repo); + if (gotconfig_path == NULL) { + error = got_error_from_errno("got_repo_get_path_gotconfig"); + goto done; + } + gotconfig_file = fopen(gotconfig_path, "a"); + if (gotconfig_file == NULL) { + error = got_error_from_errno2("fopen", gotconfig_path); + goto done; + } + got_path_strip_trailing_slashes(server_path); + remote_repo_path = server_path; + while (remote_repo_path[0] == '/') + remote_repo_path++; + if (asprintf(&gotconfig, + "remote \"%s\" {\n" + "\tserver %s\n" + "\tprotocol %s\n" + "%s%s%s" + "\trepository \"%s\"\n" + "%s" + "}\n", + GOT_FETCH_DEFAULT_REMOTE_NAME, host, proto, + port ? "\tport " : "", port ? port : "", port ? "\n" : "", + remote_repo_path, + mirror_references ? "\tmirror-references yes\n" : "") == -1) { + error = got_error_from_errno("asprintf"); + goto done; + } + n = fwrite(gotconfig, 1, strlen(gotconfig), gotconfig_file); + if (n != strlen(gotconfig)) { + error = got_ferror(gotconfig_file, GOT_ERR_IO); + goto done; + } +} diff --git a/test/test017.left-U0.txt b/test/test017.left-U0.txt new file mode 100644 index 000000000000..e622c0db8bdf --- /dev/null +++ b/test/test017.left-U0.txt @@ -0,0 +1,15 @@ +a +x +x +x +x +x +x +x +x +x +x +f +g +h +j diff --git a/test/test017.right-U0.txt b/test/test017.right-U0.txt new file mode 100644 index 000000000000..9495dcd762b8 --- /dev/null +++ b/test/test017.right-U0.txt @@ -0,0 +1,19 @@ +a +b +c +d +x +x +x +x +x +k +x +x +x +x +x +c +v +b +n diff --git a/test/test018.left-T.txt b/test/test018.left-T.txt new file mode 100644 index 000000000000..fd113b0f7150 --- /dev/null +++ b/test/test018.left-T.txt @@ -0,0 +1,7 @@ +A +B +C +A +B +B +A diff --git a/test/test018.right-T.txt b/test/test018.right-T.txt new file mode 100644 index 000000000000..0075e6d23de0 --- /dev/null +++ b/test/test018.right-T.txt @@ -0,0 +1,6 @@ +C +B +A +B +A +C diff --git a/test/test019.left.txt b/test/test019.left.txt new file mode 100644 index 000000000000..ac4b5ececbb3 --- /dev/null +++ b/test/test019.left.txt @@ -0,0 +1,845 @@ +/* + * Copyright (c) 2017 Stefan Sperling + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "got_object.h" +#include "got_repository.h" +#include "got_error.h" +#include "got_diff.h" +#include "got_opentemp.h" +#include "got_path.h" +#include "got_cancel.h" +#include "got_worktree.h" + +#include "got_lib_diff.h" +#include "got_lib_delta.h" +#include "got_lib_inflate.h" +#include "got_lib_object.h" + +static const struct got_error * +diff_blobs(struct got_diffreg_result **resultp, +struct got_blob_object *blob1, struct got_blob_object *blob2, + const char *label1, const char *label2, mode_t mode1, mode_t mode2, + int diff_context, int ignore_whitespace, FILE *outfile) +{ + const struct got_error *err = NULL, *free_err; + FILE *f1 = NULL, *f2 = NULL; + char hex1[SHA1_DIGEST_STRING_LENGTH]; + char hex2[SHA1_DIGEST_STRING_LENGTH]; + char *idstr1 = NULL, *idstr2 = NULL; + size_t size1, size2; + struct got_diffreg_result *result; + + if (resultp) + *resultp = NULL; + + if (blob1) { + f1 = got_opentemp(); + if (f1 == NULL) + return got_error_from_errno("got_opentemp"); + } + + if (blob2) { + f2 = got_opentemp(); + if (f2 == NULL) { + err = got_error_from_errno("got_opentemp"); + fclose(f1); + return err; + } + } + + size1 = 0; + if (blob1) { + idstr1 = got_object_blob_id_str(blob1, hex1, sizeof(hex1)); + err = got_object_blob_dump_to_file(&size1, NULL, NULL, f1, + blob1); + if (err) + goto done; + } else + idstr1 = "/dev/null"; + + size2 = 0; + if (blob2) { + idstr2 = got_object_blob_id_str(blob2, hex2, sizeof(hex2)); + err = got_object_blob_dump_to_file(&size2, NULL, NULL, f2, + blob2); + if (err) + goto done; + } else + idstr2 = "/dev/null"; + + if (outfile) { + char *modestr1 = NULL, *modestr2 = NULL; + int modebits; + if (mode1 && mode1 != mode2) { + if (S_ISLNK(mode1)) + modebits = S_IFLNK; + else + modebits = (S_IRWXU | S_IRWXG | S_IRWXO); + if (asprintf(&modestr1, " (mode %o)", + mode1 & modebits) == -1) { + err = got_error_from_errno("asprintf"); + goto done; + } + } + if (mode2 && mode1 != mode2) { + if (S_ISLNK(mode2)) + modebits = S_IFLNK; + else + modebits = (S_IRWXU | S_IRWXG | S_IRWXO); + if (asprintf(&modestr2, " (mode %o)", + mode2 & modebits) == -1) { + err = got_error_from_errno("asprintf"); + goto done; + } + } + fprintf(outfile, "blob - %s%s\n", idstr1, + modestr1 ? modestr1 : ""); + fprintf(outfile, "blob + %s%s\n", idstr2, + modestr2 ? modestr2 : ""); + free(modestr1); + free(modestr2); + } + err = got_diffreg(&result, f1, f2, GOT_DIFF_ALGORITHM_MYERS, + ignore_whitespace); + if (err) + goto done; + + if (outfile) { + err = got_diffreg_output(NULL, NULL, result, f1, f2, + label1 ? label1 : idstr1, + label2 ? label2 : idstr2, + GOT_DIFF_OUTPUT_UNIDIFF, diff_context, outfile); + if (err) + goto done; + } + + if (resultp && err == NULL) + *resultp = result; + else { + free_err = got_diffreg_result_free(result); + if (free_err && err == NULL) + err = free_err; + } +done: + if (f1 && fclose(f1) != 0 && err == NULL) + err = got_error_from_errno("fclose"); + if (f2 && fclose(f2) != 0 && err == NULL) + err = got_error_from_errno("fclose"); + return err; +} + +const struct got_error * +got_diff_blob_output_unidiff(void *arg, struct got_blob_object *blob1, + struct got_blob_object *blob2, struct got_object_id *id1, + struct got_object_id *id2, const char *label1, const char *label2, + mode_t mode1, mode_t mode2, struct got_repository *repo) +{ + const struct got_error *err; + struct got_diff_blob_output_unidiff_arg *a = arg; + + err = diff_blobs(NULL, blob1, blob2, label1, label2, mode1, mode2, + a->diff_context, a->ignore_whitespace, a->outfile); + return err; +} + +const struct got_error * +got_diff_blob(struct got_blob_object *blob1, struct got_blob_object *blob2, + const char *label1, const char *label2, int diff_context, + int ignore_whitespace, FILE *outfile) +{ + return diff_blobs(NULL, blob1, blob2, label1, label2, 0, 0, diff_context, + ignore_whitespace, outfile); +} + +static const struct got_error * +diff_blob_file(struct got_diffreg_result **resultp, + struct got_blob_object *blob1, const char *label1, FILE *f2, size_t size2, + const char *label2, int diff_context, int ignore_whitespace, FILE *outfile) +{ + const struct got_error *err = NULL, *free_err; + FILE *f1 = NULL; + char hex1[SHA1_DIGEST_STRING_LENGTH]; + char *idstr1 = NULL; + size_t size1; + struct got_diffreg_result *result = NULL; + + if (resultp) + *resultp = NULL; + + size1 = 0; + if (blob1) { + f1 = got_opentemp(); + if (f1 == NULL) + return got_error_from_errno("got_opentemp"); + idstr1 = got_object_blob_id_str(blob1, hex1, sizeof(hex1)); + err = got_object_blob_dump_to_file(&size1, NULL, NULL, f1, + blob1); + if (err) + goto done; + } else { + idstr1 = "/dev/null"; + } + + if (outfile) { + fprintf(outfile, "blob - %s\n", label1 ? label1 : idstr1); + fprintf(outfile, "file + %s\n", + f2 == NULL ? "/dev/null" : label2); + } + + err = got_diffreg(&result, f1, f2, GOT_DIFF_ALGORITHM_MYERS, + ignore_whitespace); + if (err) + goto done; + + if (outfile) { + err = got_diffreg_output(NULL, NULL, result, f1, f2, + label2, label2, GOT_DIFF_OUTPUT_UNIDIFF, diff_context, + outfile); + if (err) + goto done; + } + + if (resultp && err == NULL) + *resultp = result; + else if (result) { + free_err = got_diffreg_result_free(result); + if (free_err && err == NULL) + err = free_err; + } +done: + if (f1 && fclose(f1) != 0 && err == NULL) + err = got_error_from_errno("fclose"); + return err; +} + +const struct got_error * +got_diff_blob_file(struct got_blob_object *blob1, const char *label1, + FILE *f2, size_t size2, const char *label2, int diff_context, + int ignore_whitespace, FILE *outfile) +{ + return diff_blob_file(NULL, blob1, label1, f2, size2, label2, + diff_context, ignore_whitespace, outfile); +} + +const struct got_error * +got_diff_blob_file_lines_changed(struct got_diffreg_result **result, + struct got_blob_object *blob1, FILE *f2, size_t size2) +{ + return diff_blob_file(result, blob1, NULL, f2, size2, NULL, + 0, 0, NULL); +} + +const struct got_error * +got_diff_blob_lines_changed(struct got_diffreg_result **result, + struct got_blob_object *blob1, struct got_blob_object *blob2) +{ + const struct got_error *err = NULL; + + err = diff_blobs(result, blob1, blob2, NULL, NULL, 0, 0, 3, 0, NULL); + if (err) { + got_diffreg_result_free(*result); + *result = NULL; + } + return err; +} + +static const struct got_error * +diff_added_blob(struct got_object_id *id, const char *label, mode_t mode, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg) +{ + const struct got_error *err; + struct got_blob_object *blob = NULL; + struct got_object *obj = NULL; + + err = got_object_open(&obj, repo, id); + if (err) + return err; + + err = got_object_blob_open(&blob, repo, obj, 8192); + if (err) + goto done; + err = cb(cb_arg, NULL, blob, NULL, id, NULL, label, 0, mode, repo); +done: + got_object_close(obj); + if (blob) + got_object_blob_close(blob); + return err; +} + +static const struct got_error * +diff_modified_blob(struct got_object_id *id1, struct got_object_id *id2, + const char *label1, const char *label2, mode_t mode1, mode_t mode2, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg) +{ + const struct got_error *err; + struct got_object *obj1 = NULL; + struct got_object *obj2 = NULL; + struct got_blob_object *blob1 = NULL; + struct got_blob_object *blob2 = NULL; + + err = got_object_open(&obj1, repo, id1); + if (err) + return err; + if (obj1->type != GOT_OBJ_TYPE_BLOB) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + + err = got_object_open(&obj2, repo, id2); + if (err) + goto done; + if (obj2->type != GOT_OBJ_TYPE_BLOB) { + err = got_error(GOT_ERR_BAD_OBJ_DATA); + goto done; + } + + err = got_object_blob_open(&blob1, repo, obj1, 8192); + if (err) + goto done; + + err = got_object_blob_open(&blob2, repo, obj2, 8192); + if (err) + goto done; + + err = cb(cb_arg, blob1, blob2, id1, id2, label1, label2, mode1, mode2, + repo); +done: + if (obj1) + got_object_close(obj1); + if (obj2) + got_object_close(obj2); + if (blob1) + got_object_blob_close(blob1); + if (blob2) + got_object_blob_close(blob2); + return err; +} + +static const struct got_error * +diff_deleted_blob(struct got_object_id *id, const char *label, mode_t mode, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg) +{ + const struct got_error *err; + struct got_blob_object *blob = NULL; + struct got_object *obj = NULL; + + err = got_object_open(&obj, repo, id); + if (err) + return err; + + err = got_object_blob_open(&blob, repo, obj, 8192); + if (err) + goto done; + err = cb(cb_arg, blob, NULL, id, NULL, label, NULL, mode, 0, repo); +done: + got_object_close(obj); + if (blob) + got_object_blob_close(blob); + return err; +} + +static const struct got_error * +diff_added_tree(struct got_object_id *id, const char *label, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg, + int diff_content) +{ + const struct got_error *err = NULL; + struct got_object *treeobj = NULL; + struct got_tree_object *tree = NULL; + + err = got_object_open(&treeobj, repo, id); + if (err) + goto done; + + if (treeobj->type != GOT_OBJ_TYPE_TREE) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + + err = got_object_tree_open(&tree, repo, treeobj); + if (err) + goto done; + + err = got_diff_tree(NULL, tree, NULL, label, repo, cb, cb_arg, + diff_content); +done: + if (tree) + got_object_tree_close(tree); + if (treeobj) + got_object_close(treeobj); + return err; +} + +static const struct got_error * +diff_modified_tree(struct got_object_id *id1, struct got_object_id *id2, + const char *label1, const char *label2, struct got_repository *repo, + got_diff_blob_cb cb, void *cb_arg, int diff_content) +{ + const struct got_error *err; + struct got_object *treeobj1 = NULL; + struct got_object *treeobj2 = NULL; + struct got_tree_object *tree1 = NULL; + struct got_tree_object *tree2 = NULL; + + err = got_object_open(&treeobj1, repo, id1); + if (err) + goto done; + + if (treeobj1->type != GOT_OBJ_TYPE_TREE) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + + err = got_object_open(&treeobj2, repo, id2); + if (err) + goto done; + + if (treeobj2->type != GOT_OBJ_TYPE_TREE) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + + err = got_object_tree_open(&tree1, repo, treeobj1); + if (err) + goto done; + + err = got_object_tree_open(&tree2, repo, treeobj2); + if (err) + goto done; + + err = got_diff_tree(tree1, tree2, label1, label2, repo, cb, cb_arg, + diff_content); + +done: + if (tree1) + got_object_tree_close(tree1); + if (tree2) + got_object_tree_close(tree2); + if (treeobj1) + got_object_close(treeobj1); + if (treeobj2) + got_object_close(treeobj2); + return err; +} + +static const struct got_error * +diff_deleted_tree(struct got_object_id *id, const char *label, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg, + int diff_content) +{ + const struct got_error *err; + struct got_object *treeobj = NULL; + struct got_tree_object *tree = NULL; + + err = got_object_open(&treeobj, repo, id); + if (err) + goto done; + + if (treeobj->type != GOT_OBJ_TYPE_TREE) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + + err = got_object_tree_open(&tree, repo, treeobj); + if (err) + goto done; + + err = got_diff_tree(tree, NULL, label, NULL, repo, cb, cb_arg, + diff_content); +done: + if (tree) + got_object_tree_close(tree); + if (treeobj) + got_object_close(treeobj); + return err; +} + +static const struct got_error * +diff_kind_mismatch(struct got_object_id *id1, struct got_object_id *id2, + const char *label1, const char *label2, struct got_repository *repo, + got_diff_blob_cb cb, void *cb_arg) +{ + /* XXX TODO */ + return NULL; +} + +static const struct got_error * +diff_entry_old_new(struct got_tree_entry *te1, + struct got_tree_entry *te2, const char *label1, const char *label2, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg, + int diff_content) +{ + const struct got_error *err = NULL; + int id_match; + + if (got_object_tree_entry_is_submodule(te1)) + return NULL; + + if (te2 == NULL) { + if (S_ISDIR(te1->mode)) + err = diff_deleted_tree(&te1->id, label1, repo, + cb, cb_arg, diff_content); + else { + if (diff_content) + err = diff_deleted_blob(&te1->id, label1, + te1->mode, repo, cb, cb_arg); + else + err = cb(cb_arg, NULL, NULL, &te1->id, NULL, + label1, NULL, te1->mode, 0, repo); + } + return err; + } else if (got_object_tree_entry_is_submodule(te2)) + return NULL; + + id_match = (got_object_id_cmp(&te1->id, &te2->id) == 0); + if (S_ISDIR(te1->mode) && S_ISDIR(te2->mode)) { + if (!id_match) + return diff_modified_tree(&te1->id, &te2->id, + label1, label2, repo, cb, cb_arg, diff_content); + } else if ((S_ISREG(te1->mode) || S_ISLNK(te1->mode)) && + (S_ISREG(te2->mode) || S_ISLNK(te2->mode))) { + if (!id_match || + ((te1->mode & (S_IFLNK | S_IXUSR))) != + (te2->mode & (S_IFLNK | S_IXUSR))) { + if (diff_content) + return diff_modified_blob(&te1->id, &te2->id, + label1, label2, te1->mode, te2->mode, + repo, cb, cb_arg); + else + return cb(cb_arg, NULL, NULL, &te1->id, + &te2->id, label1, label2, te1->mode, + te2->mode, repo); + } + } + + if (id_match) + return NULL; + + return diff_kind_mismatch(&te1->id, &te2->id, label1, label2, repo, + cb, cb_arg); +} + +static const struct got_error * +diff_entry_new_old(struct got_tree_entry *te2, + struct got_tree_entry *te1, const char *label2, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg, + int diff_content) +{ + if (te1 != NULL) /* handled by diff_entry_old_new() */ + return NULL; + + if (got_object_tree_entry_is_submodule(te2)) + return NULL; + + if (S_ISDIR(te2->mode)) + return diff_added_tree(&te2->id, label2, repo, cb, cb_arg, + diff_content); + + if (diff_content) + return diff_added_blob(&te2->id, label2, te2->mode, repo, cb, + cb_arg); + + return cb(cb_arg, NULL, NULL, NULL, &te2->id, NULL, label2, 0, + te2->mode, repo); +} + +const struct got_error * +got_diff_tree_collect_changed_paths(void *arg, struct got_blob_object *blob1, + struct got_blob_object *blob2, struct got_object_id *id1, + struct got_object_id *id2, const char *label1, const char *label2, + mode_t mode1, mode_t mode2, struct got_repository *repo) +{ + const struct got_error *err = NULL; + struct got_pathlist_head *paths = arg; + struct got_diff_changed_path *change = NULL; + char *path = NULL; + + path = strdup(label2 ? label2 : label1); + if (path == NULL) + return got_error_from_errno("malloc"); + + change = malloc(sizeof(*change)); + if (change == NULL) { + err = got_error_from_errno("malloc"); + goto done; + } + + change->status = GOT_STATUS_NO_CHANGE; + if (id1 == NULL) + change->status = GOT_STATUS_ADD; + else if (id2 == NULL) + change->status = GOT_STATUS_DELETE; + else { + if (got_object_id_cmp(id1, id2) != 0) + change->status = GOT_STATUS_MODIFY; + else if (mode1 != mode2) + change->status = GOT_STATUS_MODE_CHANGE; + } + + err = got_pathlist_insert(NULL, paths, path, change); +done: + if (err) { + free(path); + free(change); + } + return err; +} + +const struct got_error * +got_diff_tree(struct got_tree_object *tree1, struct got_tree_object *tree2, + const char *label1, const char *label2, struct got_repository *repo, + got_diff_blob_cb cb, void *cb_arg, int diff_content) +{ + const struct got_error *err = NULL; + struct got_tree_entry *te1 = NULL; + struct got_tree_entry *te2 = NULL; + char *l1 = NULL, *l2 = NULL; + int tidx1 = 0, tidx2 = 0; + + if (tree1) { + te1 = got_object_tree_get_entry(tree1, 0); + if (te1 && asprintf(&l1, "%s%s%s", label1, label1[0] ? "/" : "", + te1->name) == -1) + return got_error_from_errno("asprintf"); + } + if (tree2) { + te2 = got_object_tree_get_entry(tree2, 0); + if (te2 && asprintf(&l2, "%s%s%s", label2, label2[0] ? "/" : "", + te2->name) == -1) + return got_error_from_errno("asprintf"); + } + + do { + if (te1) { + struct got_tree_entry *te = NULL; + if (tree2) + te = got_object_tree_find_entry(tree2, + te1->name); + if (te) { + free(l2); + l2 = NULL; + if (te && asprintf(&l2, "%s%s%s", label2, + label2[0] ? "/" : "", te->name) == -1) + return + got_error_from_errno("asprintf"); + } + err = diff_entry_old_new(te1, te, l1, l2, repo, cb, + cb_arg, diff_content); + if (err) + break; + } + + if (te2) { + struct got_tree_entry *te = NULL; + if (tree1) + te = got_object_tree_find_entry(tree1, + te2->name); + free(l2); + if (te) { + if (asprintf(&l2, "%s%s%s", label2, + label2[0] ? "/" : "", te->name) == -1) + return + got_error_from_errno("asprintf"); + } else { + if (asprintf(&l2, "%s%s%s", label2, + label2[0] ? "/" : "", te2->name) == -1) + return + got_error_from_errno("asprintf"); + } + err = diff_entry_new_old(te2, te, l2, repo, + cb, cb_arg, diff_content); + if (err) + break; + } + + free(l1); + l1 = NULL; + if (te1) { + tidx1++; + te1 = got_object_tree_get_entry(tree1, tidx1); + if (te1 && + asprintf(&l1, "%s%s%s", label1, + label1[0] ? "/" : "", te1->name) == -1) + return got_error_from_errno("asprintf"); + } + free(l2); + l2 = NULL; + if (te2) { + tidx2++; + te2 = got_object_tree_get_entry(tree2, tidx2); + if (te2 && + asprintf(&l2, "%s%s%s", label2, + label2[0] ? "/" : "", te2->name) == -1) + return got_error_from_errno("asprintf"); + } + } while (te1 || te2); + + return err; +} + +const struct got_error * +got_diff_objects_as_blobs(struct got_object_id *id1, struct got_object_id *id2, + const char *label1, const char *label2, int diff_context, + int ignore_whitespace, struct got_repository *repo, FILE *outfile) +{ + const struct got_error *err; + struct got_blob_object *blob1 = NULL, *blob2 = NULL; + + if (id1 == NULL && id2 == NULL) + return got_error(GOT_ERR_NO_OBJ); + + if (id1) { + err = got_object_open_as_blob(&blob1, repo, id1, 8192); + if (err) + goto done; + } + if (id2) { + err = got_object_open_as_blob(&blob2, repo, id2, 8192); + if (err) + goto done; + } + err = got_diff_blob(blob1, blob2, label1, label2, diff_context, + ignore_whitespace, outfile); +done: + if (blob1) + got_object_blob_close(blob1); + if (blob2) + got_object_blob_close(blob2); + return err; +} + +const struct got_error * +got_diff_objects_as_trees(struct got_object_id *id1, struct got_object_id *id2, + char *label1, char *label2, int diff_context, int ignore_whitespace, + struct got_repository *repo, FILE *outfile) +{ + const struct got_error *err; + struct got_tree_object *tree1 = NULL, *tree2 = NULL; + struct got_diff_blob_output_unidiff_arg arg; + + if (id1 == NULL && id2 == NULL) + return got_error(GOT_ERR_NO_OBJ); + + if (id1) { + err = got_object_open_as_tree(&tree1, repo, id1); + if (err) + goto done; + } + if (id2) { + err = got_object_open_as_tree(&tree2, repo, id2); + if (err) + goto done; + } + arg.diff_context = diff_context; + arg.ignore_whitespace = ignore_whitespace; + arg.outfile = outfile; + err = got_diff_tree(tree1, tree2, label1, label2, repo, + got_diff_blob_output_unidiff, &arg, 1); +done: + if (tree1) + got_object_tree_close(tree1); + if (tree2) + got_object_tree_close(tree2); + return err; +} + +const struct got_error * +got_diff_objects_as_commits(struct got_object_id *id1, + struct got_object_id *id2, int diff_context, int ignore_whitespace, + struct got_repository *repo, FILE *outfile) +{ + const struct got_error *err; + struct got_commit_object *commit1 = NULL, *commit2 = NULL; + + if (id2 == NULL) + return got_error(GOT_ERR_NO_OBJ); + + if (id1) { + err = got_object_open_as_commit(&commit1, repo, id1); + if (err) + goto done; + } + + err = got_object_open_as_commit(&commit2, repo, id2); + if (err) + goto done; + + err = got_diff_objects_as_trees( + commit1 ? got_object_commit_get_tree_id(commit1) : NULL, + got_object_commit_get_tree_id(commit2), "", "", diff_context, + ignore_whitespace, repo, outfile); +done: + if (commit1) + got_object_commit_close(commit1); + if (commit2) + got_object_commit_close(commit2); + return err; +} + +const struct got_error * +got_diff_files(struct got_diffreg_result **resultp, + FILE *f1, const char *label1, FILE *f2, const char *label2, + int diff_context, int ignore_whitespace, FILE *outfile) +{ + const struct got_error *err = NULL; + struct got_diffreg_result *diffreg_result = NULL; + + if (resultp) + *resultp = NULL; + + if (outfile) { + fprintf(outfile, "file - %s\n", + f1 == NULL ? "/dev/null" : label1); + fprintf(outfile, "file + %s\n", + f2 == NULL ? "/dev/null" : label2); + } + + err = got_diffreg(&diffreg_result, f1, f2, GOT_DIFF_ALGORITHM_MYERS, + ignore_whitespace); + if (err) + goto done; + + if (outfile) { + err = got_diffreg_output(NULL, NULL, diffreg_result, + f1, f2, label1, label2, GOT_DIFF_OUTPUT_UNIDIFF, + diff_context, outfile); + if (err) + goto done; + } + +done: + if (resultp && err == NULL) + *resultp = diffreg_result; + else if (diffreg_result) { + const struct got_error *free_err; + free_err = got_diffreg_result_free(diffreg_result); + if (free_err && err == NULL) + err = free_err; + } + + return err; +} diff --git a/test/test019.right.txt b/test/test019.right.txt new file mode 100644 index 000000000000..69c2895af058 --- /dev/null +++ b/test/test019.right.txt @@ -0,0 +1,904 @@ +/* + * Copyright (c) 2017 Stefan Sperling + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "got_object.h" +#include "got_repository.h" +#include "got_error.h" +#include "got_diff.h" +#include "got_opentemp.h" +#include "got_path.h" +#include "got_cancel.h" +#include "got_worktree.h" + +#include "got_lib_diff.h" +#include "got_lib_delta.h" +#include "got_lib_inflate.h" +#include "got_lib_object.h" + +static const struct got_error * +add_line_offset(off_t **line_offsets, size_t *nlines, off_t off) +{ + off_t *p; + + p = reallocarray(*line_offsets, *nlines + 1, sizeof(off_t)); + if (p == NULL) + return got_error_from_errno("reallocarray"); + *line_offsets = p; + (*line_offsets)[*nlines] = off; + (*nlines)++; + return NULL; +} + +static const struct got_error * +diff_blobs(off_t **line_offsets, size_t *nlines, + struct got_diffreg_result **resultp, struct got_blob_object *blob1, + struct got_blob_object *blob2, + const char *label1, const char *label2, mode_t mode1, mode_t mode2, + int diff_context, int ignore_whitespace, FILE *outfile) +{ + const struct got_error *err = NULL, *free_err; + FILE *f1 = NULL, *f2 = NULL; + char hex1[SHA1_DIGEST_STRING_LENGTH]; + char hex2[SHA1_DIGEST_STRING_LENGTH]; + char *idstr1 = NULL, *idstr2 = NULL; + size_t size1, size2; + struct got_diffreg_result *result; + off_t outoff = 0; + int n; + + if (line_offsets && *line_offsets && *nlines > 0) + outoff = (*line_offsets)[*nlines - 1]; + + if (resultp) + *resultp = NULL; + + if (blob1) { + f1 = got_opentemp(); + if (f1 == NULL) + return got_error_from_errno("got_opentemp"); + } + + if (blob2) { + f2 = got_opentemp(); + if (f2 == NULL) { + err = got_error_from_errno("got_opentemp"); + fclose(f1); + return err; + } + } + + size1 = 0; + if (blob1) { + idstr1 = got_object_blob_id_str(blob1, hex1, sizeof(hex1)); + err = got_object_blob_dump_to_file(&size1, NULL, NULL, f1, + blob1); + if (err) + goto done; + } else + idstr1 = "/dev/null"; + + size2 = 0; + if (blob2) { + idstr2 = got_object_blob_id_str(blob2, hex2, sizeof(hex2)); + err = got_object_blob_dump_to_file(&size2, NULL, NULL, f2, + blob2); + if (err) + goto done; + } else + idstr2 = "/dev/null"; + + if (outfile) { + char *modestr1 = NULL, *modestr2 = NULL; + int modebits; + if (mode1 && mode1 != mode2) { + if (S_ISLNK(mode1)) + modebits = S_IFLNK; + else + modebits = (S_IRWXU | S_IRWXG | S_IRWXO); + if (asprintf(&modestr1, " (mode %o)", + mode1 & modebits) == -1) { + err = got_error_from_errno("asprintf"); + goto done; + } + } + if (mode2 && mode1 != mode2) { + if (S_ISLNK(mode2)) + modebits = S_IFLNK; + else + modebits = (S_IRWXU | S_IRWXG | S_IRWXO); + if (asprintf(&modestr2, " (mode %o)", + mode2 & modebits) == -1) { + err = got_error_from_errno("asprintf"); + goto done; + } + } + n = fprintf(outfile, "blob - %s%s\n", idstr1, + modestr1 ? modestr1 : ""); + if (n < 0) { + err = got_error_from_errno("fprintf"); + goto done; + } + outoff += n; + if (line_offsets) { + err = add_line_offset(line_offsets, nlines, outoff); + if (err) + goto done; + } + + n = fprintf(outfile, "blob + %s%s\n", idstr2, + modestr2 ? modestr2 : ""); + if (n < 0) { + err = got_error_from_errno("fprintf"); + goto done; + } + outoff += n; + if (line_offsets) { + err = add_line_offset(line_offsets, nlines, outoff); + if (err) + goto done; + } + + free(modestr1); + free(modestr2); + } + err = got_diffreg(&result, f1, f2, GOT_DIFF_ALGORITHM_MYERS, + ignore_whitespace); + if (err) + goto done; + + if (outfile) { + err = got_diffreg_output(line_offsets, nlines, result, f1, f2, + label1 ? label1 : idstr1, + label2 ? label2 : idstr2, + GOT_DIFF_OUTPUT_UNIDIFF, diff_context, outfile); + if (err) + goto done; + } + + if (resultp && err == NULL) + *resultp = result; + else { + free_err = got_diffreg_result_free(result); + if (free_err && err == NULL) + err = free_err; + } +done: + if (f1 && fclose(f1) != 0 && err == NULL) + err = got_error_from_errno("fclose"); + if (f2 && fclose(f2) != 0 && err == NULL) + err = got_error_from_errno("fclose"); + return err; +} + +const struct got_error * +got_diff_blob_output_unidiff(void *arg, struct got_blob_object *blob1, + struct got_blob_object *blob2, struct got_object_id *id1, + struct got_object_id *id2, const char *label1, const char *label2, + mode_t mode1, mode_t mode2, struct got_repository *repo) +{ + struct got_diff_blob_output_unidiff_arg *a = arg; + + return diff_blobs(&a->line_offsets, &a->nlines, NULL, + blob1, blob2, label1, label2, mode1, mode2, a->diff_context, + a->ignore_whitespace, a->outfile); +} + +const struct got_error * +got_diff_blob(off_t **line_offsets, size_t *nlines, + struct got_blob_object *blob1, struct got_blob_object *blob2, + const char *label1, const char *label2, int diff_context, + int ignore_whitespace, FILE *outfile) +{ + return diff_blobs(line_offsets, nlines, NULL, blob1, blob2, + label1, label2, 0, 0, diff_context, ignore_whitespace, outfile); +} + +static const struct got_error * +diff_blob_file(struct got_diffreg_result **resultp, + struct got_blob_object *blob1, const char *label1, FILE *f2, size_t size2, + const char *label2, int diff_context, int ignore_whitespace, FILE *outfile) +{ + const struct got_error *err = NULL, *free_err; + FILE *f1 = NULL; + char hex1[SHA1_DIGEST_STRING_LENGTH]; + char *idstr1 = NULL; + size_t size1; + struct got_diffreg_result *result = NULL; + + if (resultp) + *resultp = NULL; + + size1 = 0; + if (blob1) { + f1 = got_opentemp(); + if (f1 == NULL) + return got_error_from_errno("got_opentemp"); + idstr1 = got_object_blob_id_str(blob1, hex1, sizeof(hex1)); + err = got_object_blob_dump_to_file(&size1, NULL, NULL, f1, + blob1); + if (err) + goto done; + } else { + idstr1 = "/dev/null"; + } + + if (outfile) { + fprintf(outfile, "blob - %s\n", label1 ? label1 : idstr1); + fprintf(outfile, "file + %s\n", + f2 == NULL ? "/dev/null" : label2); + } + + err = got_diffreg(&result, f1, f2, GOT_DIFF_ALGORITHM_MYERS, + ignore_whitespace); + if (err) + goto done; + + if (outfile) { + err = got_diffreg_output(NULL, NULL, result, f1, f2, + label2, label2, GOT_DIFF_OUTPUT_UNIDIFF, diff_context, + outfile); + if (err) + goto done; + } + + if (resultp && err == NULL) + *resultp = result; + else if (result) { + free_err = got_diffreg_result_free(result); + if (free_err && err == NULL) + err = free_err; + } +done: + if (f1 && fclose(f1) != 0 && err == NULL) + err = got_error_from_errno("fclose"); + return err; +} + +const struct got_error * +got_diff_blob_file(struct got_blob_object *blob1, const char *label1, + FILE *f2, size_t size2, const char *label2, int diff_context, + int ignore_whitespace, FILE *outfile) +{ + return diff_blob_file(NULL, blob1, label1, f2, size2, label2, + diff_context, ignore_whitespace, outfile); +} + +const struct got_error * +got_diff_blob_file_lines_changed(struct got_diffreg_result **result, + struct got_blob_object *blob1, FILE *f2, size_t size2) +{ + return diff_blob_file(result, blob1, NULL, f2, size2, NULL, + 0, 0, NULL); +} + +const struct got_error * +got_diff_blob_lines_changed(struct got_diffreg_result **result, + struct got_blob_object *blob1, struct got_blob_object *blob2) +{ + const struct got_error *err = NULL; + + err = diff_blobs(NULL, NULL, result, blob1, blob2, + NULL, NULL, 0, 0, 3, 0, NULL); + if (err) { + got_diffreg_result_free(*result); + *result = NULL; + } + return err; +} + +static const struct got_error * +diff_added_blob(struct got_object_id *id, const char *label, mode_t mode, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg) +{ + const struct got_error *err; + struct got_blob_object *blob = NULL; + struct got_object *obj = NULL; + + err = got_object_open(&obj, repo, id); + if (err) + return err; + + err = got_object_blob_open(&blob, repo, obj, 8192); + if (err) + goto done; + err = cb(cb_arg, NULL, blob, NULL, id, NULL, label, 0, mode, repo); +done: + got_object_close(obj); + if (blob) + got_object_blob_close(blob); + return err; +} + +static const struct got_error * +diff_modified_blob(struct got_object_id *id1, struct got_object_id *id2, + const char *label1, const char *label2, mode_t mode1, mode_t mode2, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg) +{ + const struct got_error *err; + struct got_object *obj1 = NULL; + struct got_object *obj2 = NULL; + struct got_blob_object *blob1 = NULL; + struct got_blob_object *blob2 = NULL; + + err = got_object_open(&obj1, repo, id1); + if (err) + return err; + if (obj1->type != GOT_OBJ_TYPE_BLOB) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + + err = got_object_open(&obj2, repo, id2); + if (err) + goto done; + if (obj2->type != GOT_OBJ_TYPE_BLOB) { + err = got_error(GOT_ERR_BAD_OBJ_DATA); + goto done; + } + + err = got_object_blob_open(&blob1, repo, obj1, 8192); + if (err) + goto done; + + err = got_object_blob_open(&blob2, repo, obj2, 8192); + if (err) + goto done; + + err = cb(cb_arg, blob1, blob2, id1, id2, label1, label2, mode1, mode2, + repo); +done: + if (obj1) + got_object_close(obj1); + if (obj2) + got_object_close(obj2); + if (blob1) + got_object_blob_close(blob1); + if (blob2) + got_object_blob_close(blob2); + return err; +} + +static const struct got_error * +diff_deleted_blob(struct got_object_id *id, const char *label, mode_t mode, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg) +{ + const struct got_error *err; + struct got_blob_object *blob = NULL; + struct got_object *obj = NULL; + + err = got_object_open(&obj, repo, id); + if (err) + return err; + + err = got_object_blob_open(&blob, repo, obj, 8192); + if (err) + goto done; + err = cb(cb_arg, blob, NULL, id, NULL, label, NULL, mode, 0, repo); +done: + got_object_close(obj); + if (blob) + got_object_blob_close(blob); + return err; +} + +static const struct got_error * +diff_added_tree(struct got_object_id *id, const char *label, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg, + int diff_content) +{ + const struct got_error *err = NULL; + struct got_object *treeobj = NULL; + struct got_tree_object *tree = NULL; + + err = got_object_open(&treeobj, repo, id); + if (err) + goto done; + + if (treeobj->type != GOT_OBJ_TYPE_TREE) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + + err = got_object_tree_open(&tree, repo, treeobj); + if (err) + goto done; + + err = got_diff_tree(NULL, tree, NULL, label, repo, cb, cb_arg, + diff_content); +done: + if (tree) + got_object_tree_close(tree); + if (treeobj) + got_object_close(treeobj); + return err; +} + +static const struct got_error * +diff_modified_tree(struct got_object_id *id1, struct got_object_id *id2, + const char *label1, const char *label2, struct got_repository *repo, + got_diff_blob_cb cb, void *cb_arg, int diff_content) +{ + const struct got_error *err; + struct got_object *treeobj1 = NULL; + struct got_object *treeobj2 = NULL; + struct got_tree_object *tree1 = NULL; + struct got_tree_object *tree2 = NULL; + + err = got_object_open(&treeobj1, repo, id1); + if (err) + goto done; + + if (treeobj1->type != GOT_OBJ_TYPE_TREE) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + + err = got_object_open(&treeobj2, repo, id2); + if (err) + goto done; + + if (treeobj2->type != GOT_OBJ_TYPE_TREE) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + + err = got_object_tree_open(&tree1, repo, treeobj1); + if (err) + goto done; + + err = got_object_tree_open(&tree2, repo, treeobj2); + if (err) + goto done; + + err = got_diff_tree(tree1, tree2, label1, label2, repo, cb, cb_arg, + diff_content); + +done: + if (tree1) + got_object_tree_close(tree1); + if (tree2) + got_object_tree_close(tree2); + if (treeobj1) + got_object_close(treeobj1); + if (treeobj2) + got_object_close(treeobj2); + return err; +} + +static const struct got_error * +diff_deleted_tree(struct got_object_id *id, const char *label, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg, + int diff_content) +{ + const struct got_error *err; + struct got_object *treeobj = NULL; + struct got_tree_object *tree = NULL; + + err = got_object_open(&treeobj, repo, id); + if (err) + goto done; + + if (treeobj->type != GOT_OBJ_TYPE_TREE) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + + err = got_object_tree_open(&tree, repo, treeobj); + if (err) + goto done; + + err = got_diff_tree(tree, NULL, label, NULL, repo, cb, cb_arg, + diff_content); +done: + if (tree) + got_object_tree_close(tree); + if (treeobj) + got_object_close(treeobj); + return err; +} + +static const struct got_error * +diff_kind_mismatch(struct got_object_id *id1, struct got_object_id *id2, + const char *label1, const char *label2, struct got_repository *repo, + got_diff_blob_cb cb, void *cb_arg) +{ + /* XXX TODO */ + return NULL; +} + +static const struct got_error * +diff_entry_old_new(struct got_tree_entry *te1, + struct got_tree_entry *te2, const char *label1, const char *label2, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg, + int diff_content) +{ + const struct got_error *err = NULL; + int id_match; + + if (got_object_tree_entry_is_submodule(te1)) + return NULL; + + if (te2 == NULL) { + if (S_ISDIR(te1->mode)) + err = diff_deleted_tree(&te1->id, label1, repo, + cb, cb_arg, diff_content); + else { + if (diff_content) + err = diff_deleted_blob(&te1->id, label1, + te1->mode, repo, cb, cb_arg); + else + err = cb(cb_arg, NULL, NULL, &te1->id, NULL, + label1, NULL, te1->mode, 0, repo); + } + return err; + } else if (got_object_tree_entry_is_submodule(te2)) + return NULL; + + id_match = (got_object_id_cmp(&te1->id, &te2->id) == 0); + if (S_ISDIR(te1->mode) && S_ISDIR(te2->mode)) { + if (!id_match) + return diff_modified_tree(&te1->id, &te2->id, + label1, label2, repo, cb, cb_arg, diff_content); + } else if ((S_ISREG(te1->mode) || S_ISLNK(te1->mode)) && + (S_ISREG(te2->mode) || S_ISLNK(te2->mode))) { + if (!id_match || + ((te1->mode & (S_IFLNK | S_IXUSR))) != + (te2->mode & (S_IFLNK | S_IXUSR))) { + if (diff_content) + return diff_modified_blob(&te1->id, &te2->id, + label1, label2, te1->mode, te2->mode, + repo, cb, cb_arg); + else + return cb(cb_arg, NULL, NULL, &te1->id, + &te2->id, label1, label2, te1->mode, + te2->mode, repo); + } + } + + if (id_match) + return NULL; + + return diff_kind_mismatch(&te1->id, &te2->id, label1, label2, repo, + cb, cb_arg); +} + +static const struct got_error * +diff_entry_new_old(struct got_tree_entry *te2, + struct got_tree_entry *te1, const char *label2, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg, + int diff_content) +{ + if (te1 != NULL) /* handled by diff_entry_old_new() */ + return NULL; + + if (got_object_tree_entry_is_submodule(te2)) + return NULL; + + if (S_ISDIR(te2->mode)) + return diff_added_tree(&te2->id, label2, repo, cb, cb_arg, + diff_content); + + if (diff_content) + return diff_added_blob(&te2->id, label2, te2->mode, repo, cb, + cb_arg); + + return cb(cb_arg, NULL, NULL, NULL, &te2->id, NULL, label2, 0, + te2->mode, repo); +} + +const struct got_error * +got_diff_tree_collect_changed_paths(void *arg, struct got_blob_object *blob1, + struct got_blob_object *blob2, struct got_object_id *id1, + struct got_object_id *id2, const char *label1, const char *label2, + mode_t mode1, mode_t mode2, struct got_repository *repo) +{ + const struct got_error *err = NULL; + struct got_pathlist_head *paths = arg; + struct got_diff_changed_path *change = NULL; + char *path = NULL; + + path = strdup(label2 ? label2 : label1); + if (path == NULL) + return got_error_from_errno("malloc"); + + change = malloc(sizeof(*change)); + if (change == NULL) { + err = got_error_from_errno("malloc"); + goto done; + } + + change->status = GOT_STATUS_NO_CHANGE; + if (id1 == NULL) + change->status = GOT_STATUS_ADD; + else if (id2 == NULL) + change->status = GOT_STATUS_DELETE; + else { + if (got_object_id_cmp(id1, id2) != 0) + change->status = GOT_STATUS_MODIFY; + else if (mode1 != mode2) + change->status = GOT_STATUS_MODE_CHANGE; + } + + err = got_pathlist_insert(NULL, paths, path, change); +done: + if (err) { + free(path); + free(change); + } + return err; +} + +const struct got_error * +got_diff_tree(struct got_tree_object *tree1, struct got_tree_object *tree2, + const char *label1, const char *label2, struct got_repository *repo, + got_diff_blob_cb cb, void *cb_arg, int diff_content) +{ + const struct got_error *err = NULL; + struct got_tree_entry *te1 = NULL; + struct got_tree_entry *te2 = NULL; + char *l1 = NULL, *l2 = NULL; + int tidx1 = 0, tidx2 = 0; + + if (tree1) { + te1 = got_object_tree_get_entry(tree1, 0); + if (te1 && asprintf(&l1, "%s%s%s", label1, label1[0] ? "/" : "", + te1->name) == -1) + return got_error_from_errno("asprintf"); + } + if (tree2) { + te2 = got_object_tree_get_entry(tree2, 0); + if (te2 && asprintf(&l2, "%s%s%s", label2, label2[0] ? "/" : "", + te2->name) == -1) + return got_error_from_errno("asprintf"); + } + + do { + if (te1) { + struct got_tree_entry *te = NULL; + if (tree2) + te = got_object_tree_find_entry(tree2, + te1->name); + if (te) { + free(l2); + l2 = NULL; + if (te && asprintf(&l2, "%s%s%s", label2, + label2[0] ? "/" : "", te->name) == -1) + return + got_error_from_errno("asprintf"); + } + err = diff_entry_old_new(te1, te, l1, l2, repo, cb, + cb_arg, diff_content); + if (err) + break; + } + + if (te2) { + struct got_tree_entry *te = NULL; + if (tree1) + te = got_object_tree_find_entry(tree1, + te2->name); + free(l2); + if (te) { + if (asprintf(&l2, "%s%s%s", label2, + label2[0] ? "/" : "", te->name) == -1) + return + got_error_from_errno("asprintf"); + } else { + if (asprintf(&l2, "%s%s%s", label2, + label2[0] ? "/" : "", te2->name) == -1) + return + got_error_from_errno("asprintf"); + } + err = diff_entry_new_old(te2, te, l2, repo, + cb, cb_arg, diff_content); + if (err) + break; + } + + free(l1); + l1 = NULL; + if (te1) { + tidx1++; + te1 = got_object_tree_get_entry(tree1, tidx1); + if (te1 && + asprintf(&l1, "%s%s%s", label1, + label1[0] ? "/" : "", te1->name) == -1) + return got_error_from_errno("asprintf"); + } + free(l2); + l2 = NULL; + if (te2) { + tidx2++; + te2 = got_object_tree_get_entry(tree2, tidx2); + if (te2 && + asprintf(&l2, "%s%s%s", label2, + label2[0] ? "/" : "", te2->name) == -1) + return got_error_from_errno("asprintf"); + } + } while (te1 || te2); + + return err; +} + +const struct got_error * +got_diff_objects_as_blobs(off_t **line_offsets, size_t *nlines, + struct got_object_id *id1, struct got_object_id *id2, + const char *label1, const char *label2, int diff_context, + int ignore_whitespace, struct got_repository *repo, FILE *outfile) +{ + const struct got_error *err; + struct got_blob_object *blob1 = NULL, *blob2 = NULL; + + if (id1 == NULL && id2 == NULL) + return got_error(GOT_ERR_NO_OBJ); + + if (id1) { + err = got_object_open_as_blob(&blob1, repo, id1, 8192); + if (err) + goto done; + } + if (id2) { + err = got_object_open_as_blob(&blob2, repo, id2, 8192); + if (err) + goto done; + } + err = got_diff_blob(line_offsets, nlines, blob1, blob2, + label1, label2, diff_context, ignore_whitespace, outfile); +done: + if (blob1) + got_object_blob_close(blob1); + if (blob2) + got_object_blob_close(blob2); + return err; +} + +const struct got_error * +got_diff_objects_as_trees(off_t **line_offsets, size_t *nlines, + struct got_object_id *id1, struct got_object_id *id2, + char *label1, char *label2, int diff_context, int ignore_whitespace, + struct got_repository *repo, FILE *outfile) +{ + const struct got_error *err; + struct got_tree_object *tree1 = NULL, *tree2 = NULL; + struct got_diff_blob_output_unidiff_arg arg; + int want_lineoffsets = (line_offsets != NULL && *line_offsets != NULL); + + if (id1 == NULL && id2 == NULL) + return got_error(GOT_ERR_NO_OBJ); + + if (id1) { + err = got_object_open_as_tree(&tree1, repo, id1); + if (err) + goto done; + } + if (id2) { + err = got_object_open_as_tree(&tree2, repo, id2); + if (err) + goto done; + } + arg.diff_context = diff_context; + arg.ignore_whitespace = ignore_whitespace; + arg.outfile = outfile; + if (want_lineoffsets) { + arg.line_offsets = *line_offsets; + arg.nlines = *nlines; + } else { + arg.line_offsets = NULL; + arg.nlines = 0; + } + err = got_diff_tree(tree1, tree2, label1, label2, repo, + got_diff_blob_output_unidiff, &arg, 1); + + if (want_lineoffsets) { + *line_offsets = arg.line_offsets; /* was likely re-allocated */ + *nlines = arg.nlines; + } +done: + if (tree1) + got_object_tree_close(tree1); + if (tree2) + got_object_tree_close(tree2); + return err; +} + +const struct got_error * +got_diff_objects_as_commits(off_t **line_offsets, size_t *nlines, + struct got_object_id *id1, struct got_object_id *id2, + int diff_context, int ignore_whitespace, + struct got_repository *repo, FILE *outfile) +{ + const struct got_error *err; + struct got_commit_object *commit1 = NULL, *commit2 = NULL; + + if (id2 == NULL) + return got_error(GOT_ERR_NO_OBJ); + + if (id1) { + err = got_object_open_as_commit(&commit1, repo, id1); + if (err) + goto done; + } + + err = got_object_open_as_commit(&commit2, repo, id2); + if (err) + goto done; + + err = got_diff_objects_as_trees(line_offsets, nlines, + commit1 ? got_object_commit_get_tree_id(commit1) : NULL, + got_object_commit_get_tree_id(commit2), "", "", diff_context, + ignore_whitespace, repo, outfile); +done: + if (commit1) + got_object_commit_close(commit1); + if (commit2) + got_object_commit_close(commit2); + return err; +} + +const struct got_error * +got_diff_files(struct got_diffreg_result **resultp, + FILE *f1, const char *label1, FILE *f2, const char *label2, + int diff_context, int ignore_whitespace, FILE *outfile) +{ + const struct got_error *err = NULL; + struct got_diffreg_result *diffreg_result = NULL; + + if (resultp) + *resultp = NULL; + + if (outfile) { + fprintf(outfile, "file - %s\n", + f1 == NULL ? "/dev/null" : label1); + fprintf(outfile, "file + %s\n", + f2 == NULL ? "/dev/null" : label2); + } + + err = got_diffreg(&diffreg_result, f1, f2, GOT_DIFF_ALGORITHM_MYERS, + ignore_whitespace); + if (err) + goto done; + + if (outfile) { + err = got_diffreg_output(NULL, NULL, diffreg_result, + f1, f2, label1, label2, GOT_DIFF_OUTPUT_UNIDIFF, + diff_context, outfile); + if (err) + goto done; + } + +done: + if (resultp && err == NULL) + *resultp = diffreg_result; + else if (diffreg_result) { + const struct got_error *free_err; + free_err = got_diffreg_result_free(diffreg_result); + if (free_err && err == NULL) + err = free_err; + } + + return err; +} diff --git a/test/test020.left.txt b/test/test020.left.txt new file mode 100644 index 000000000000..7e5ee06994a5 --- /dev/null +++ b/test/test020.left.txt @@ -0,0 +1,919 @@ +/* + * Copyright (c) 2017 Stefan Sperling + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "got_object.h" +#include "got_repository.h" +#include "got_error.h" +#include "got_diff.h" +#include "got_opentemp.h" +#include "got_path.h" +#include "got_cancel.h" +#include "got_worktree.h" + +#include "got_lib_diff.h" +#include "got_lib_delta.h" +#include "got_lib_inflate.h" +#include "got_lib_object.h" + +static const struct got_error * +diff_blobs(struct got_blob_object *blob1, struct got_blob_object *blob2, + const char *label1, const char *label2, mode_t mode1, mode_t mode2, + int diff_context, int ignore_whitespace, FILE *outfile, + struct got_diff_changes *changes) +{ + struct got_diff_state ds; + struct got_diff_args args; + const struct got_error *err = NULL; + FILE *f1 = NULL, *f2 = NULL; + char hex1[SHA1_DIGEST_STRING_LENGTH]; + char hex2[SHA1_DIGEST_STRING_LENGTH]; + char *idstr1 = NULL, *idstr2 = NULL; + size_t size1, size2; + int res, flags = 0; + + if (blob1) { + f1 = got_opentemp(); + if (f1 == NULL) + return got_error_from_errno("got_opentemp"); + } else + flags |= D_EMPTY1; + + if (blob2) { + f2 = got_opentemp(); + if (f2 == NULL) { + err = got_error_from_errno("got_opentemp"); + fclose(f1); + return err; + } + } else + flags |= D_EMPTY2; + + size1 = 0; + if (blob1) { + idstr1 = got_object_blob_id_str(blob1, hex1, sizeof(hex1)); + err = got_object_blob_dump_to_file(&size1, NULL, NULL, f1, + blob1); + if (err) + goto done; + } else + idstr1 = "/dev/null"; + + size2 = 0; + if (blob2) { + idstr2 = got_object_blob_id_str(blob2, hex2, sizeof(hex2)); + err = got_object_blob_dump_to_file(&size2, NULL, NULL, f2, + blob2); + if (err) + goto done; + } else + idstr2 = "/dev/null"; + + memset(&ds, 0, sizeof(ds)); + /* XXX should stat buffers be passed in args instead of ds? */ + ds.stb1.st_mode = S_IFREG; + if (blob1) + ds.stb1.st_size = size1; + ds.stb1.st_mtime = 0; /* XXX */ + + ds.stb2.st_mode = S_IFREG; + if (blob2) + ds.stb2.st_size = size2; + ds.stb2.st_mtime = 0; /* XXX */ + + memset(&args, 0, sizeof(args)); + args.diff_format = D_UNIFIED; + args.label[0] = label1 ? label1 : idstr1; + args.label[1] = label2 ? label2 : idstr2; + args.diff_context = diff_context; + flags |= D_PROTOTYPE; + if (ignore_whitespace) + flags |= D_IGNOREBLANKS; + + if (outfile) { + char *modestr1 = NULL, *modestr2 = NULL; + int modebits; + if (mode1 && mode1 != mode2) { + if (S_ISLNK(mode1)) + modebits = S_IFLNK; + else + modebits = (S_IRWXU | S_IRWXG | S_IRWXO); + if (asprintf(&modestr1, " (mode %o)", + mode1 & modebits) == -1) { + err = got_error_from_errno("asprintf"); + goto done; + } + } + if (mode2 && mode1 != mode2) { + if (S_ISLNK(mode2)) + modebits = S_IFLNK; + else + modebits = (S_IRWXU | S_IRWXG | S_IRWXO); + if (asprintf(&modestr2, " (mode %o)", + mode2 & modebits) == -1) { + err = got_error_from_errno("asprintf"); + goto done; + } + } + fprintf(outfile, "blob - %s%s\n", idstr1, + modestr1 ? modestr1 : ""); + fprintf(outfile, "blob + %s%s\n", idstr2, + modestr2 ? modestr2 : ""); + free(modestr1); + free(modestr2); + } + err = got_diffreg(&res, f1, f2, flags, &args, &ds, outfile, changes); + got_diff_state_free(&ds); +done: + if (f1 && fclose(f1) != 0 && err == NULL) + err = got_error_from_errno("fclose"); + if (f2 && fclose(f2) != 0 && err == NULL) + err = got_error_from_errno("fclose"); + return err; +} + +const struct got_error * +got_diff_blob_output_unidiff(void *arg, struct got_blob_object *blob1, + struct got_blob_object *blob2, struct got_object_id *id1, + struct got_object_id *id2, const char *label1, const char *label2, + mode_t mode1, mode_t mode2, struct got_repository *repo) +{ + struct got_diff_blob_output_unidiff_arg *a = arg; + + return diff_blobs(blob1, blob2, label1, label2, mode1, mode2, + a->diff_context, a->ignore_whitespace, a->outfile, NULL); +} + +const struct got_error * +got_diff_blob(struct got_blob_object *blob1, struct got_blob_object *blob2, + const char *label1, const char *label2, int diff_context, + int ignore_whitespace, FILE *outfile) +{ + return diff_blobs(blob1, blob2, label1, label2, 0, 0, diff_context, + ignore_whitespace, outfile, NULL); +} + +static const struct got_error * +alloc_changes(struct got_diff_changes **changes) +{ + *changes = calloc(1, sizeof(**changes)); + if (*changes == NULL) + return got_error_from_errno("calloc"); + SIMPLEQ_INIT(&(*changes)->entries); + return NULL; +} + +static const struct got_error * +diff_blob_file(struct got_diff_changes **changes, + struct got_blob_object *blob1, const char *label1, FILE *f2, size_t size2, + const char *label2, int diff_context, int ignore_whitespace, FILE *outfile) +{ + struct got_diff_state ds; + struct got_diff_args args; + const struct got_error *err = NULL; + FILE *f1 = NULL; + char hex1[SHA1_DIGEST_STRING_LENGTH]; + char *idstr1 = NULL; + size_t size1; + int res, flags = 0; + + if (changes) + *changes = NULL; + + size1 = 0; + if (blob1) { + f1 = got_opentemp(); + if (f1 == NULL) + return got_error_from_errno("got_opentemp"); + idstr1 = got_object_blob_id_str(blob1, hex1, sizeof(hex1)); + err = got_object_blob_dump_to_file(&size1, NULL, NULL, f1, + blob1); + if (err) + goto done; + } else { + flags |= D_EMPTY1; + idstr1 = "/dev/null"; + } + + if (f2 == NULL) + flags |= D_EMPTY2; + + memset(&ds, 0, sizeof(ds)); + /* XXX should stat buffers be passed in args instead of ds? */ + ds.stb1.st_mode = S_IFREG; + if (blob1) + ds.stb1.st_size = size1; + ds.stb1.st_mtime = 0; /* XXX */ + + ds.stb2.st_mode = S_IFREG; + ds.stb2.st_size = size2; + ds.stb2.st_mtime = 0; /* XXX */ + + memset(&args, 0, sizeof(args)); + args.diff_format = D_UNIFIED; + args.label[0] = label2; + args.label[1] = label2; + args.diff_context = diff_context; + flags |= D_PROTOTYPE; + if (ignore_whitespace) + flags |= D_IGNOREBLANKS; + + if (outfile) { + fprintf(outfile, "blob - %s\n", label1 ? label1 : idstr1); + fprintf(outfile, "file + %s\n", + f2 == NULL ? "/dev/null" : label2); + } + if (changes) { + err = alloc_changes(changes); + if (err) + return err; + } + err = got_diffreg(&res, f1, f2, flags, &args, &ds, outfile, + changes ? *changes : NULL); + got_diff_state_free(&ds); +done: + if (f1 && fclose(f1) != 0 && err == NULL) + err = got_error_from_errno("fclose"); + return err; +} + +const struct got_error * +got_diff_blob_file(struct got_blob_object *blob1, const char *label1, + FILE *f2, size_t size2, const char *label2, int diff_context, + int ignore_whitespace, FILE *outfile) +{ + return diff_blob_file(NULL, blob1, label1, f2, size2, label2, + diff_context, ignore_whitespace, outfile); +} + +const struct got_error * +got_diff_blob_file_lines_changed(struct got_diff_changes **changes, + struct got_blob_object *blob1, FILE *f2, size_t size2) +{ + return diff_blob_file(changes, blob1, NULL, f2, size2, NULL, + 0, 0, NULL); +} + +const struct got_error * +got_diff_blob_lines_changed(struct got_diff_changes **changes, + struct got_blob_object *blob1, struct got_blob_object *blob2) +{ + const struct got_error *err = NULL; + + err = alloc_changes(changes); + if (err) + return err; + + err = diff_blobs(blob1, blob2, NULL, NULL, 0, 0, 3, 0, NULL, *changes); + if (err) { + got_diff_free_changes(*changes); + *changes = NULL; + } + return err; +} + +void +got_diff_free_changes(struct got_diff_changes *changes) +{ + struct got_diff_change *change; + while (!SIMPLEQ_EMPTY(&changes->entries)) { + change = SIMPLEQ_FIRST(&changes->entries); + SIMPLEQ_REMOVE_HEAD(&changes->entries, entry); + free(change); + } + free(changes); +} + +static const struct got_error * +diff_added_blob(struct got_object_id *id, const char *label, mode_t mode, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg) +{ + const struct got_error *err; + struct got_blob_object *blob = NULL; + struct got_object *obj = NULL; + + err = got_object_open(&obj, repo, id); + if (err) + return err; + + err = got_object_blob_open(&blob, repo, obj, 8192); + if (err) + goto done; + err = cb(cb_arg, NULL, blob, NULL, id, NULL, label, 0, mode, repo); +done: + got_object_close(obj); + if (blob) + got_object_blob_close(blob); + return err; +} + +static const struct got_error * +diff_modified_blob(struct got_object_id *id1, struct got_object_id *id2, + const char *label1, const char *label2, mode_t mode1, mode_t mode2, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg) +{ + const struct got_error *err; + struct got_object *obj1 = NULL; + struct got_object *obj2 = NULL; + struct got_blob_object *blob1 = NULL; + struct got_blob_object *blob2 = NULL; + + err = got_object_open(&obj1, repo, id1); + if (err) + return err; + if (obj1->type != GOT_OBJ_TYPE_BLOB) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + + err = got_object_open(&obj2, repo, id2); + if (err) + goto done; + if (obj2->type != GOT_OBJ_TYPE_BLOB) { + err = got_error(GOT_ERR_BAD_OBJ_DATA); + goto done; + } + + err = got_object_blob_open(&blob1, repo, obj1, 8192); + if (err) + goto done; + + err = got_object_blob_open(&blob2, repo, obj2, 8192); + if (err) + goto done; + + err = cb(cb_arg, blob1, blob2, id1, id2, label1, label2, mode1, mode2, + repo); +done: + if (obj1) + got_object_close(obj1); + if (obj2) + got_object_close(obj2); + if (blob1) + got_object_blob_close(blob1); + if (blob2) + got_object_blob_close(blob2); + return err; +} + +static const struct got_error * +diff_deleted_blob(struct got_object_id *id, const char *label, mode_t mode, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg) +{ + const struct got_error *err; + struct got_blob_object *blob = NULL; + struct got_object *obj = NULL; + + err = got_object_open(&obj, repo, id); + if (err) + return err; + + err = got_object_blob_open(&blob, repo, obj, 8192); + if (err) + goto done; + err = cb(cb_arg, blob, NULL, id, NULL, label, NULL, mode, 0, repo); +done: + got_object_close(obj); + if (blob) + got_object_blob_close(blob); + return err; +} + +static const struct got_error * +diff_added_tree(struct got_object_id *id, const char *label, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg, + int diff_content) +{ + const struct got_error *err = NULL; + struct got_object *treeobj = NULL; + struct got_tree_object *tree = NULL; + + err = got_object_open(&treeobj, repo, id); + if (err) + goto done; + + if (treeobj->type != GOT_OBJ_TYPE_TREE) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + + err = got_object_tree_open(&tree, repo, treeobj); + if (err) + goto done; + + err = got_diff_tree(NULL, tree, NULL, label, repo, cb, cb_arg, + diff_content); +done: + if (tree) + got_object_tree_close(tree); + if (treeobj) + got_object_close(treeobj); + return err; +} + +static const struct got_error * +diff_modified_tree(struct got_object_id *id1, struct got_object_id *id2, + const char *label1, const char *label2, struct got_repository *repo, + got_diff_blob_cb cb, void *cb_arg, int diff_content) +{ + const struct got_error *err; + struct got_object *treeobj1 = NULL; + struct got_object *treeobj2 = NULL; + struct got_tree_object *tree1 = NULL; + struct got_tree_object *tree2 = NULL; + + err = got_object_open(&treeobj1, repo, id1); + if (err) + goto done; + + if (treeobj1->type != GOT_OBJ_TYPE_TREE) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + + err = got_object_open(&treeobj2, repo, id2); + if (err) + goto done; + + if (treeobj2->type != GOT_OBJ_TYPE_TREE) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + + err = got_object_tree_open(&tree1, repo, treeobj1); + if (err) + goto done; + + err = got_object_tree_open(&tree2, repo, treeobj2); + if (err) + goto done; + + err = got_diff_tree(tree1, tree2, label1, label2, repo, cb, cb_arg, + diff_content); + +done: + if (tree1) + got_object_tree_close(tree1); + if (tree2) + got_object_tree_close(tree2); + if (treeobj1) + got_object_close(treeobj1); + if (treeobj2) + got_object_close(treeobj2); + return err; +} + +static const struct got_error * +diff_deleted_tree(struct got_object_id *id, const char *label, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg, + int diff_content) +{ + const struct got_error *err; + struct got_object *treeobj = NULL; + struct got_tree_object *tree = NULL; + + err = got_object_open(&treeobj, repo, id); + if (err) + goto done; + + if (treeobj->type != GOT_OBJ_TYPE_TREE) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + + err = got_object_tree_open(&tree, repo, treeobj); + if (err) + goto done; + + err = got_diff_tree(tree, NULL, label, NULL, repo, cb, cb_arg, + diff_content); +done: + if (tree) + got_object_tree_close(tree); + if (treeobj) + got_object_close(treeobj); + return err; +} + +static const struct got_error * +diff_kind_mismatch(struct got_object_id *id1, struct got_object_id *id2, + const char *label1, const char *label2, struct got_repository *repo, + got_diff_blob_cb cb, void *cb_arg) +{ + /* XXX TODO */ + return NULL; +} + +static const struct got_error * +diff_entry_old_new(struct got_tree_entry *te1, + struct got_tree_entry *te2, const char *label1, const char *label2, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg, + int diff_content) +{ + const struct got_error *err = NULL; + int id_match; + + if (got_object_tree_entry_is_submodule(te1)) + return NULL; + + if (te2 == NULL) { + if (S_ISDIR(te1->mode)) + err = diff_deleted_tree(&te1->id, label1, repo, + cb, cb_arg, diff_content); + else { + if (diff_content) + err = diff_deleted_blob(&te1->id, label1, + te1->mode, repo, cb, cb_arg); + else + err = cb(cb_arg, NULL, NULL, &te1->id, NULL, + label1, NULL, te1->mode, 0, repo); + } + return err; + } else if (got_object_tree_entry_is_submodule(te2)) + return NULL; + + id_match = (got_object_id_cmp(&te1->id, &te2->id) == 0); + if (S_ISDIR(te1->mode) && S_ISDIR(te2->mode)) { + if (!id_match) + return diff_modified_tree(&te1->id, &te2->id, + label1, label2, repo, cb, cb_arg, diff_content); + } else if ((S_ISREG(te1->mode) || S_ISLNK(te1->mode)) && + (S_ISREG(te2->mode) || S_ISLNK(te2->mode))) { + if (!id_match || + ((te1->mode & (S_IFLNK | S_IXUSR))) != + (te2->mode & (S_IFLNK | S_IXUSR))) { + if (diff_content) + return diff_modified_blob(&te1->id, &te2->id, + label1, label2, te1->mode, te2->mode, + repo, cb, cb_arg); + else + return cb(cb_arg, NULL, NULL, &te1->id, + &te2->id, label1, label2, te1->mode, + te2->mode, repo); + } + } + + if (id_match) + return NULL; + + return diff_kind_mismatch(&te1->id, &te2->id, label1, label2, repo, + cb, cb_arg); +} + +static const struct got_error * +diff_entry_new_old(struct got_tree_entry *te2, + struct got_tree_entry *te1, const char *label2, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg, + int diff_content) +{ + if (te1 != NULL) /* handled by diff_entry_old_new() */ + return NULL; + + if (got_object_tree_entry_is_submodule(te2)) + return NULL; + + if (S_ISDIR(te2->mode)) + return diff_added_tree(&te2->id, label2, repo, cb, cb_arg, + diff_content); + + if (diff_content) + return diff_added_blob(&te2->id, label2, te2->mode, repo, cb, + cb_arg); + + return cb(cb_arg, NULL, NULL, NULL, &te2->id, NULL, label2, 0, + te2->mode, repo); +} + +const struct got_error * +got_diff_tree_collect_changed_paths(void *arg, struct got_blob_object *blob1, + struct got_blob_object *blob2, struct got_object_id *id1, + struct got_object_id *id2, const char *label1, const char *label2, + mode_t mode1, mode_t mode2, struct got_repository *repo) +{ + const struct got_error *err = NULL; + struct got_pathlist_head *paths = arg; + struct got_diff_changed_path *change = NULL; + char *path = NULL; + + path = strdup(label2 ? label2 : label1); + if (path == NULL) + return got_error_from_errno("malloc"); + + change = malloc(sizeof(*change)); + if (change == NULL) { + err = got_error_from_errno("malloc"); + goto done; + } + + change->status = GOT_STATUS_NO_CHANGE; + if (id1 == NULL) + change->status = GOT_STATUS_ADD; + else if (id2 == NULL) + change->status = GOT_STATUS_DELETE; + else { + if (got_object_id_cmp(id1, id2) != 0) + change->status = GOT_STATUS_MODIFY; + else if (mode1 != mode2) + change->status = GOT_STATUS_MODE_CHANGE; + } + + err = got_pathlist_insert(NULL, paths, path, change); +done: + if (err) { + free(path); + free(change); + } + return err; +} + +const struct got_error * +got_diff_tree(struct got_tree_object *tree1, struct got_tree_object *tree2, + const char *label1, const char *label2, struct got_repository *repo, + got_diff_blob_cb cb, void *cb_arg, int diff_content) +{ + const struct got_error *err = NULL; + struct got_tree_entry *te1 = NULL; + struct got_tree_entry *te2 = NULL; + char *l1 = NULL, *l2 = NULL; + int tidx1 = 0, tidx2 = 0; + + if (tree1) { + te1 = got_object_tree_get_entry(tree1, 0); + if (te1 && asprintf(&l1, "%s%s%s", label1, label1[0] ? "/" : "", + te1->name) == -1) + return got_error_from_errno("asprintf"); + } + if (tree2) { + te2 = got_object_tree_get_entry(tree2, 0); + if (te2 && asprintf(&l2, "%s%s%s", label2, label2[0] ? "/" : "", + te2->name) == -1) + return got_error_from_errno("asprintf"); + } + + do { + if (te1) { + struct got_tree_entry *te = NULL; + if (tree2) + te = got_object_tree_find_entry(tree2, + te1->name); + if (te) { + free(l2); + l2 = NULL; + if (te && asprintf(&l2, "%s%s%s", label2, + label2[0] ? "/" : "", te->name) == -1) + return + got_error_from_errno("asprintf"); + } + err = diff_entry_old_new(te1, te, l1, l2, repo, cb, + cb_arg, diff_content); + if (err) + break; + } + + if (te2) { + struct got_tree_entry *te = NULL; + if (tree1) + te = got_object_tree_find_entry(tree1, + te2->name); + free(l2); + if (te) { + if (asprintf(&l2, "%s%s%s", label2, + label2[0] ? "/" : "", te->name) == -1) + return + got_error_from_errno("asprintf"); + } else { + if (asprintf(&l2, "%s%s%s", label2, + label2[0] ? "/" : "", te2->name) == -1) + return + got_error_from_errno("asprintf"); + } + err = diff_entry_new_old(te2, te, l2, repo, + cb, cb_arg, diff_content); + if (err) + break; + } + + free(l1); + l1 = NULL; + if (te1) { + tidx1++; + te1 = got_object_tree_get_entry(tree1, tidx1); + if (te1 && + asprintf(&l1, "%s%s%s", label1, + label1[0] ? "/" : "", te1->name) == -1) + return got_error_from_errno("asprintf"); + } + free(l2); + l2 = NULL; + if (te2) { + tidx2++; + te2 = got_object_tree_get_entry(tree2, tidx2); + if (te2 && + asprintf(&l2, "%s%s%s", label2, + label2[0] ? "/" : "", te2->name) == -1) + return got_error_from_errno("asprintf"); + } + } while (te1 || te2); + + return err; +} + +const struct got_error * +got_diff_objects_as_blobs(struct got_object_id *id1, struct got_object_id *id2, + const char *label1, const char *label2, int diff_context, + int ignore_whitespace, struct got_repository *repo, FILE *outfile) +{ + const struct got_error *err; + struct got_blob_object *blob1 = NULL, *blob2 = NULL; + + if (id1 == NULL && id2 == NULL) + return got_error(GOT_ERR_NO_OBJ); + + if (id1) { + err = got_object_open_as_blob(&blob1, repo, id1, 8192); + if (err) + goto done; + } + if (id2) { + err = got_object_open_as_blob(&blob2, repo, id2, 8192); + if (err) + goto done; + } + err = got_diff_blob(blob1, blob2, label1, label2, diff_context, + ignore_whitespace, outfile); +done: + if (blob1) + got_object_blob_close(blob1); + if (blob2) + got_object_blob_close(blob2); + return err; +} + +const struct got_error * +got_diff_objects_as_trees(struct got_object_id *id1, struct got_object_id *id2, + char *label1, char *label2, int diff_context, int ignore_whitespace, + struct got_repository *repo, FILE *outfile) +{ + const struct got_error *err; + struct got_tree_object *tree1 = NULL, *tree2 = NULL; + struct got_diff_blob_output_unidiff_arg arg; + + if (id1 == NULL && id2 == NULL) + return got_error(GOT_ERR_NO_OBJ); + + if (id1) { + err = got_object_open_as_tree(&tree1, repo, id1); + if (err) + goto done; + } + if (id2) { + err = got_object_open_as_tree(&tree2, repo, id2); + if (err) + goto done; + } + arg.diff_context = diff_context; + arg.ignore_whitespace = ignore_whitespace; + arg.outfile = outfile; + err = got_diff_tree(tree1, tree2, label1, label2, repo, + got_diff_blob_output_unidiff, &arg, 1); +done: + if (tree1) + got_object_tree_close(tree1); + if (tree2) + got_object_tree_close(tree2); + return err; +} + +const struct got_error * +got_diff_objects_as_commits(struct got_object_id *id1, + struct got_object_id *id2, int diff_context, int ignore_whitespace, + struct got_repository *repo, FILE *outfile) +{ + const struct got_error *err; + struct got_commit_object *commit1 = NULL, *commit2 = NULL; + + if (id2 == NULL) + return got_error(GOT_ERR_NO_OBJ); + + if (id1) { + err = got_object_open_as_commit(&commit1, repo, id1); + if (err) + goto done; + } + + err = got_object_open_as_commit(&commit2, repo, id2); + if (err) + goto done; + + err = got_diff_objects_as_trees( + commit1 ? got_object_commit_get_tree_id(commit1) : NULL, + got_object_commit_get_tree_id(commit2), "", "", diff_context, + ignore_whitespace, repo, outfile); +done: + if (commit1) + got_object_commit_close(commit1); + if (commit2) + got_object_commit_close(commit2); + return err; +} + +const struct got_error * +got_diff_files(struct got_diff_changes **changes, + struct got_diff_state **ds, + struct got_diff_args **args, + int *flags, + FILE *f1, size_t size1, const char *label1, + FILE *f2, size_t size2, const char *label2, + int diff_context, FILE *outfile) +{ + const struct got_error *err = NULL; + int res; + + *flags = 0; + *ds = calloc(1, sizeof(**ds)); + if (*ds == NULL) + return got_error_from_errno("calloc"); + *args = calloc(1, sizeof(**args)); + if (*args == NULL) { + err = got_error_from_errno("calloc"); + goto done; + } + + if (changes) + *changes = NULL; + + if (f1 == NULL) + *flags |= D_EMPTY1; + + if (f2 == NULL) + *flags |= D_EMPTY2; + + /* XXX should stat buffers be passed in args instead of ds? */ + (*ds)->stb1.st_mode = S_IFREG; + (*ds)->stb1.st_size = size1; + (*ds)->stb1.st_mtime = 0; /* XXX */ + + (*ds)->stb2.st_mode = S_IFREG; + (*ds)->stb2.st_size = size2; + (*ds)->stb2.st_mtime = 0; /* XXX */ + + (*args)->diff_format = D_UNIFIED; + (*args)->label[0] = label1; + (*args)->label[1] = label2; + (*args)->diff_context = diff_context; + *flags |= D_PROTOTYPE; + + if (outfile) { + fprintf(outfile, "file - %s\n", + f1 == NULL ? "/dev/null" : label1); + fprintf(outfile, "file + %s\n", + f2 == NULL ? "/dev/null" : label2); + } + if (changes) { + err = alloc_changes(changes); + if (err) + goto done; + } + err = got_diffreg(&res, f1, f2, *flags, *args, *ds, outfile, + changes ? *changes : NULL); +done: + if (err) { + if (*ds) { + got_diff_state_free(*ds); + free(*ds); + *ds = NULL; + } + if (*args) { + free(*args); + *args = NULL; + } + if (changes) { + if (*changes) + got_diff_free_changes(*changes); + *changes = NULL; + } + } + return err; +} diff --git a/test/test020.right.txt b/test/test020.right.txt new file mode 100644 index 000000000000..9ed331be5c5b --- /dev/null +++ b/test/test020.right.txt @@ -0,0 +1,935 @@ +/* + * Copyright (c) 2017 Stefan Sperling + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "got_object.h" +#include "got_repository.h" +#include "got_error.h" +#include "got_diff.h" +#include "got_opentemp.h" +#include "got_path.h" +#include "got_cancel.h" +#include "got_worktree.h" + +#include "got_lib_diff.h" +#include "got_lib_delta.h" +#include "got_lib_inflate.h" +#include "got_lib_object.h" + +static const struct got_error * +add_line_offset(off_t **line_offsets, size_t *nlines, off_t off) +{ + off_t *p; + + p = reallocarray(*line_offsets, *nlines + 1, sizeof(off_t)); + if (p == NULL) + return got_error_from_errno("reallocarray"); + *line_offsets = p; + (*line_offsets)[*nlines] = off; + (*nlines)++; + return NULL; +} + +static const struct got_error * +diff_blobs(off_t **line_offsets, size_t *nlines, + struct got_diffreg_result **resultp, struct got_blob_object *blob1, + struct got_blob_object *blob2, + const char *label1, const char *label2, mode_t mode1, mode_t mode2, + int diff_context, int ignore_whitespace, FILE *outfile) +{ + const struct got_error *err = NULL, *free_err; + FILE *f1 = NULL, *f2 = NULL; + char hex1[SHA1_DIGEST_STRING_LENGTH]; + char hex2[SHA1_DIGEST_STRING_LENGTH]; + char *idstr1 = NULL, *idstr2 = NULL; + size_t size1, size2; + struct got_diffreg_result *result; + off_t outoff = 0; + int n; + + if (line_offsets && *line_offsets && *nlines > 0) + outoff = (*line_offsets)[*nlines - 1]; + + if (resultp) + *resultp = NULL; + + if (blob1) { + f1 = got_opentemp(); + if (f1 == NULL) + return got_error_from_errno("got_opentemp"); + } + + if (blob2) { + f2 = got_opentemp(); + if (f2 == NULL) { + err = got_error_from_errno("got_opentemp"); + fclose(f1); + return err; + } + } + + size1 = 0; + if (blob1) { + idstr1 = got_object_blob_id_str(blob1, hex1, sizeof(hex1)); + err = got_object_blob_dump_to_file(&size1, NULL, NULL, f1, + blob1); + if (err) + goto done; + } else + idstr1 = "/dev/null"; + + size2 = 0; + if (blob2) { + idstr2 = got_object_blob_id_str(blob2, hex2, sizeof(hex2)); + err = got_object_blob_dump_to_file(&size2, NULL, NULL, f2, + blob2); + if (err) + goto done; + } else + idstr2 = "/dev/null"; + + if (outfile) { + char *modestr1 = NULL, *modestr2 = NULL; + int modebits; + if (mode1 && mode1 != mode2) { + if (S_ISLNK(mode1)) + modebits = S_IFLNK; + else + modebits = (S_IRWXU | S_IRWXG | S_IRWXO); + if (asprintf(&modestr1, " (mode %o)", + mode1 & modebits) == -1) { + err = got_error_from_errno("asprintf"); + goto done; + } + } + if (mode2 && mode1 != mode2) { + if (S_ISLNK(mode2)) + modebits = S_IFLNK; + else + modebits = (S_IRWXU | S_IRWXG | S_IRWXO); + if (asprintf(&modestr2, " (mode %o)", + mode2 & modebits) == -1) { + err = got_error_from_errno("asprintf"); + goto done; + } + } + n = fprintf(outfile, "blob - %s%s\n", idstr1, + modestr1 ? modestr1 : ""); + if (n < 0) { + err = got_error_from_errno("fprintf"); + goto done; + } + outoff += n; + if (line_offsets) { + err = add_line_offset(line_offsets, nlines, outoff); + if (err) + goto done; + } + + n = fprintf(outfile, "blob + %s%s\n", idstr2, + modestr2 ? modestr2 : ""); + if (n < 0) { + err = got_error_from_errno("fprintf"); + goto done; + } + outoff += n; + if (line_offsets) { + err = add_line_offset(line_offsets, nlines, outoff); + if (err) + goto done; + } + + free(modestr1); + free(modestr2); + } + err = got_diffreg(&result, f1, f2, GOT_DIFF_ALGORITHM_MYERS, + ignore_whitespace); + if (err) + goto done; + + if (outfile) { + err = got_diffreg_output(line_offsets, nlines, result, f1, f2, + label1 ? label1 : idstr1, + label2 ? label2 : idstr2, + GOT_DIFF_OUTPUT_UNIDIFF, diff_context, outfile); + if (err) + goto done; + } + + if (resultp && err == NULL) + *resultp = result; + else { + free_err = got_diffreg_result_free(result); + if (free_err && err == NULL) + err = free_err; + } +done: + if (f1 && fclose(f1) != 0 && err == NULL) + err = got_error_from_errno("fclose"); + if (f2 && fclose(f2) != 0 && err == NULL) + err = got_error_from_errno("fclose"); + return err; +} + +const struct got_error * +got_diff_blob_output_unidiff(void *arg, struct got_blob_object *blob1, + struct got_blob_object *blob2, struct got_object_id *id1, + struct got_object_id *id2, const char *label1, const char *label2, + mode_t mode1, mode_t mode2, struct got_repository *repo) +{ + struct got_diff_blob_output_unidiff_arg *a = arg; + + return diff_blobs(&a->line_offsets, &a->nlines, NULL, + blob1, blob2, label1, label2, mode1, mode2, a->diff_context, + a->ignore_whitespace, a->outfile); +} + +const struct got_error * +got_diff_blob(off_t **line_offsets, size_t *nlines, + struct got_blob_object *blob1, struct got_blob_object *blob2, + const char *label1, const char *label2, int diff_context, + int ignore_whitespace, FILE *outfile) +{ + return diff_blobs(line_offsets, nlines, NULL, blob1, blob2, + label1, label2, 0, 0, diff_context, ignore_whitespace, outfile); +} + +static const struct got_error * +diff_blob_file(struct got_diffreg_result **resultp, + struct got_blob_object *blob1, const char *label1, FILE *f2, size_t size2, + const char *label2, int diff_context, int ignore_whitespace, FILE *outfile) +{ + const struct got_error *err = NULL, *free_err; + FILE *f1 = NULL; + char hex1[SHA1_DIGEST_STRING_LENGTH]; + char *idstr1 = NULL; + size_t size1; + struct got_diffreg_result *result = NULL; + + if (resultp) + *resultp = NULL; + + size1 = 0; + if (blob1) { + f1 = got_opentemp(); + if (f1 == NULL) + return got_error_from_errno("got_opentemp"); + idstr1 = got_object_blob_id_str(blob1, hex1, sizeof(hex1)); + err = got_object_blob_dump_to_file(&size1, NULL, NULL, f1, + blob1); + if (err) + goto done; + } else { + idstr1 = "/dev/null"; + } + + if (outfile) { + fprintf(outfile, "blob - %s\n", label1 ? label1 : idstr1); + fprintf(outfile, "file + %s\n", + f2 == NULL ? "/dev/null" : label2); + } + + err = got_diffreg(&result, f1, f2, GOT_DIFF_ALGORITHM_MYERS, + ignore_whitespace); + if (err) + goto done; + + if (outfile) { + err = got_diffreg_output(NULL, NULL, result, f1, f2, + label2, label2, GOT_DIFF_OUTPUT_UNIDIFF, diff_context, + outfile); + if (err) + goto done; + } + + if (resultp && err == NULL) + *resultp = result; + else if (result) { + free_err = got_diffreg_result_free(result); + if (free_err && err == NULL) + err = free_err; + } +done: + if (f1 && fclose(f1) != 0 && err == NULL) + err = got_error_from_errno("fclose"); + return err; +} + +const struct got_error * +got_diff_blob_file(struct got_blob_object *blob1, const char *label1, + FILE *f2, size_t size2, const char *label2, int diff_context, + int ignore_whitespace, FILE *outfile) +{ + return diff_blob_file(NULL, blob1, label1, f2, size2, label2, + diff_context, ignore_whitespace, outfile); +} + +const struct got_error * +got_diff_blob_prepared_file(struct got_diffreg_result **resultp, + struct diff_data *data1, struct got_blob_object *blob1, + struct diff_data *data2, FILE *f2, char *p2, size_t size2, + const struct diff_config *cfg, int ignore_whitespace) +{ + const struct got_error *err = NULL, *free_err; + FILE *f1 = NULL; + char hex1[SHA1_DIGEST_STRING_LENGTH]; + char *idstr1 = NULL, *p1 = NULL; + size_t size1, size; + struct got_diffreg_result *result = NULL; + int f1_created = 0; + + *resultp = NULL; + + size1 = 0; + if (blob1) { + f1 = got_opentemp(); + if (f1 == NULL) + return got_error_from_errno("got_opentemp"); + idstr1 = got_object_blob_id_str(blob1, hex1, sizeof(hex1)); + err = got_object_blob_dump_to_file(&size1, NULL, NULL, f1, + blob1); + if (err) + goto done; + } else { + idstr1 = "/dev/null"; + } + + err = got_diff_prepare_file(&f1, &p1, &f1_created, &size, + data1, cfg, ignore_whitespace); + if (err) + goto done; + + err = got_diffreg_prepared_files(&result, cfg, data1, f1, + p1, size1, data2, f2, p2, size2); + if (err) + goto done; + + *resultp = result; +done: + if (err) { + if (result) + free_err = got_diffreg_result_free_left(result); + else + free_err = got_diffreg_close(f1, p1, size1, NULL, + NULL, 0); + if (free_err && err == NULL) + err = free_err; + } + return err; +} + +static const struct got_error * +diff_added_blob(struct got_object_id *id, const char *label, mode_t mode, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg) +{ + const struct got_error *err; + struct got_blob_object *blob = NULL; + struct got_object *obj = NULL; + + err = got_object_open(&obj, repo, id); + if (err) + return err; + + err = got_object_blob_open(&blob, repo, obj, 8192); + if (err) + goto done; + err = cb(cb_arg, NULL, blob, NULL, id, NULL, label, 0, mode, repo); +done: + got_object_close(obj); + if (blob) + got_object_blob_close(blob); + return err; +} + +static const struct got_error * +diff_modified_blob(struct got_object_id *id1, struct got_object_id *id2, + const char *label1, const char *label2, mode_t mode1, mode_t mode2, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg) +{ + const struct got_error *err; + struct got_object *obj1 = NULL; + struct got_object *obj2 = NULL; + struct got_blob_object *blob1 = NULL; + struct got_blob_object *blob2 = NULL; + + err = got_object_open(&obj1, repo, id1); + if (err) + return err; + if (obj1->type != GOT_OBJ_TYPE_BLOB) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + + err = got_object_open(&obj2, repo, id2); + if (err) + goto done; + if (obj2->type != GOT_OBJ_TYPE_BLOB) { + err = got_error(GOT_ERR_BAD_OBJ_DATA); + goto done; + } + + err = got_object_blob_open(&blob1, repo, obj1, 8192); + if (err) + goto done; + + err = got_object_blob_open(&blob2, repo, obj2, 8192); + if (err) + goto done; + + err = cb(cb_arg, blob1, blob2, id1, id2, label1, label2, mode1, mode2, + repo); +done: + if (obj1) + got_object_close(obj1); + if (obj2) + got_object_close(obj2); + if (blob1) + got_object_blob_close(blob1); + if (blob2) + got_object_blob_close(blob2); + return err; +} + +static const struct got_error * +diff_deleted_blob(struct got_object_id *id, const char *label, mode_t mode, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg) +{ + const struct got_error *err; + struct got_blob_object *blob = NULL; + struct got_object *obj = NULL; + + err = got_object_open(&obj, repo, id); + if (err) + return err; + + err = got_object_blob_open(&blob, repo, obj, 8192); + if (err) + goto done; + err = cb(cb_arg, blob, NULL, id, NULL, label, NULL, mode, 0, repo); +done: + got_object_close(obj); + if (blob) + got_object_blob_close(blob); + return err; +} + +static const struct got_error * +diff_added_tree(struct got_object_id *id, const char *label, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg, + int diff_content) +{ + const struct got_error *err = NULL; + struct got_object *treeobj = NULL; + struct got_tree_object *tree = NULL; + + err = got_object_open(&treeobj, repo, id); + if (err) + goto done; + + if (treeobj->type != GOT_OBJ_TYPE_TREE) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + + err = got_object_tree_open(&tree, repo, treeobj); + if (err) + goto done; + + err = got_diff_tree(NULL, tree, NULL, label, repo, cb, cb_arg, + diff_content); +done: + if (tree) + got_object_tree_close(tree); + if (treeobj) + got_object_close(treeobj); + return err; +} + +static const struct got_error * +diff_modified_tree(struct got_object_id *id1, struct got_object_id *id2, + const char *label1, const char *label2, struct got_repository *repo, + got_diff_blob_cb cb, void *cb_arg, int diff_content) +{ + const struct got_error *err; + struct got_object *treeobj1 = NULL; + struct got_object *treeobj2 = NULL; + struct got_tree_object *tree1 = NULL; + struct got_tree_object *tree2 = NULL; + + err = got_object_open(&treeobj1, repo, id1); + if (err) + goto done; + + if (treeobj1->type != GOT_OBJ_TYPE_TREE) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + + err = got_object_open(&treeobj2, repo, id2); + if (err) + goto done; + + if (treeobj2->type != GOT_OBJ_TYPE_TREE) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + + err = got_object_tree_open(&tree1, repo, treeobj1); + if (err) + goto done; + + err = got_object_tree_open(&tree2, repo, treeobj2); + if (err) + goto done; + + err = got_diff_tree(tree1, tree2, label1, label2, repo, cb, cb_arg, + diff_content); + +done: + if (tree1) + got_object_tree_close(tree1); + if (tree2) + got_object_tree_close(tree2); + if (treeobj1) + got_object_close(treeobj1); + if (treeobj2) + got_object_close(treeobj2); + return err; +} + +static const struct got_error * +diff_deleted_tree(struct got_object_id *id, const char *label, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg, + int diff_content) +{ + const struct got_error *err; + struct got_object *treeobj = NULL; + struct got_tree_object *tree = NULL; + + err = got_object_open(&treeobj, repo, id); + if (err) + goto done; + + if (treeobj->type != GOT_OBJ_TYPE_TREE) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + + err = got_object_tree_open(&tree, repo, treeobj); + if (err) + goto done; + + err = got_diff_tree(tree, NULL, label, NULL, repo, cb, cb_arg, + diff_content); +done: + if (tree) + got_object_tree_close(tree); + if (treeobj) + got_object_close(treeobj); + return err; +} + +static const struct got_error * +diff_kind_mismatch(struct got_object_id *id1, struct got_object_id *id2, + const char *label1, const char *label2, struct got_repository *repo, + got_diff_blob_cb cb, void *cb_arg) +{ + /* XXX TODO */ + return NULL; +} + +static const struct got_error * +diff_entry_old_new(struct got_tree_entry *te1, + struct got_tree_entry *te2, const char *label1, const char *label2, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg, + int diff_content) +{ + const struct got_error *err = NULL; + int id_match; + + if (got_object_tree_entry_is_submodule(te1)) + return NULL; + + if (te2 == NULL) { + if (S_ISDIR(te1->mode)) + err = diff_deleted_tree(&te1->id, label1, repo, + cb, cb_arg, diff_content); + else { + if (diff_content) + err = diff_deleted_blob(&te1->id, label1, + te1->mode, repo, cb, cb_arg); + else + err = cb(cb_arg, NULL, NULL, &te1->id, NULL, + label1, NULL, te1->mode, 0, repo); + } + return err; + } else if (got_object_tree_entry_is_submodule(te2)) + return NULL; + + id_match = (got_object_id_cmp(&te1->id, &te2->id) == 0); + if (S_ISDIR(te1->mode) && S_ISDIR(te2->mode)) { + if (!id_match) + return diff_modified_tree(&te1->id, &te2->id, + label1, label2, repo, cb, cb_arg, diff_content); + } else if ((S_ISREG(te1->mode) || S_ISLNK(te1->mode)) && + (S_ISREG(te2->mode) || S_ISLNK(te2->mode))) { + if (!id_match || + ((te1->mode & (S_IFLNK | S_IXUSR))) != + (te2->mode & (S_IFLNK | S_IXUSR))) { + if (diff_content) + return diff_modified_blob(&te1->id, &te2->id, + label1, label2, te1->mode, te2->mode, + repo, cb, cb_arg); + else + return cb(cb_arg, NULL, NULL, &te1->id, + &te2->id, label1, label2, te1->mode, + te2->mode, repo); + } + } + + if (id_match) + return NULL; + + return diff_kind_mismatch(&te1->id, &te2->id, label1, label2, repo, + cb, cb_arg); +} + +static const struct got_error * +diff_entry_new_old(struct got_tree_entry *te2, + struct got_tree_entry *te1, const char *label2, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg, + int diff_content) +{ + if (te1 != NULL) /* handled by diff_entry_old_new() */ + return NULL; + + if (got_object_tree_entry_is_submodule(te2)) + return NULL; + + if (S_ISDIR(te2->mode)) + return diff_added_tree(&te2->id, label2, repo, cb, cb_arg, + diff_content); + + if (diff_content) + return diff_added_blob(&te2->id, label2, te2->mode, repo, cb, + cb_arg); + + return cb(cb_arg, NULL, NULL, NULL, &te2->id, NULL, label2, 0, + te2->mode, repo); +} + +const struct got_error * +got_diff_tree_collect_changed_paths(void *arg, struct got_blob_object *blob1, + struct got_blob_object *blob2, struct got_object_id *id1, + struct got_object_id *id2, const char *label1, const char *label2, + mode_t mode1, mode_t mode2, struct got_repository *repo) +{ + const struct got_error *err = NULL; + struct got_pathlist_head *paths = arg; + struct got_diff_changed_path *change = NULL; + char *path = NULL; + + path = strdup(label2 ? label2 : label1); + if (path == NULL) + return got_error_from_errno("malloc"); + + change = malloc(sizeof(*change)); + if (change == NULL) { + err = got_error_from_errno("malloc"); + goto done; + } + + change->status = GOT_STATUS_NO_CHANGE; + if (id1 == NULL) + change->status = GOT_STATUS_ADD; + else if (id2 == NULL) + change->status = GOT_STATUS_DELETE; + else { + if (got_object_id_cmp(id1, id2) != 0) + change->status = GOT_STATUS_MODIFY; + else if (mode1 != mode2) + change->status = GOT_STATUS_MODE_CHANGE; + } + + err = got_pathlist_insert(NULL, paths, path, change); +done: + if (err) { + free(path); + free(change); + } + return err; +} + +const struct got_error * +got_diff_tree(struct got_tree_object *tree1, struct got_tree_object *tree2, + const char *label1, const char *label2, struct got_repository *repo, + got_diff_blob_cb cb, void *cb_arg, int diff_content) +{ + const struct got_error *err = NULL; + struct got_tree_entry *te1 = NULL; + struct got_tree_entry *te2 = NULL; + char *l1 = NULL, *l2 = NULL; + int tidx1 = 0, tidx2 = 0; + + if (tree1) { + te1 = got_object_tree_get_entry(tree1, 0); + if (te1 && asprintf(&l1, "%s%s%s", label1, label1[0] ? "/" : "", + te1->name) == -1) + return got_error_from_errno("asprintf"); + } + if (tree2) { + te2 = got_object_tree_get_entry(tree2, 0); + if (te2 && asprintf(&l2, "%s%s%s", label2, label2[0] ? "/" : "", + te2->name) == -1) + return got_error_from_errno("asprintf"); + } + + do { + if (te1) { + struct got_tree_entry *te = NULL; + if (tree2) + te = got_object_tree_find_entry(tree2, + te1->name); + if (te) { + free(l2); + l2 = NULL; + if (te && asprintf(&l2, "%s%s%s", label2, + label2[0] ? "/" : "", te->name) == -1) + return + got_error_from_errno("asprintf"); + } + err = diff_entry_old_new(te1, te, l1, l2, repo, cb, + cb_arg, diff_content); + if (err) + break; + } + + if (te2) { + struct got_tree_entry *te = NULL; + if (tree1) + te = got_object_tree_find_entry(tree1, + te2->name); + free(l2); + if (te) { + if (asprintf(&l2, "%s%s%s", label2, + label2[0] ? "/" : "", te->name) == -1) + return + got_error_from_errno("asprintf"); + } else { + if (asprintf(&l2, "%s%s%s", label2, + label2[0] ? "/" : "", te2->name) == -1) + return + got_error_from_errno("asprintf"); + } + err = diff_entry_new_old(te2, te, l2, repo, + cb, cb_arg, diff_content); + if (err) + break; + } + + free(l1); + l1 = NULL; + if (te1) { + tidx1++; + te1 = got_object_tree_get_entry(tree1, tidx1); + if (te1 && + asprintf(&l1, "%s%s%s", label1, + label1[0] ? "/" : "", te1->name) == -1) + return got_error_from_errno("asprintf"); + } + free(l2); + l2 = NULL; + if (te2) { + tidx2++; + te2 = got_object_tree_get_entry(tree2, tidx2); + if (te2 && + asprintf(&l2, "%s%s%s", label2, + label2[0] ? "/" : "", te2->name) == -1) + return got_error_from_errno("asprintf"); + } + } while (te1 || te2); + + return err; +} + +const struct got_error * +got_diff_objects_as_blobs(off_t **line_offsets, size_t *nlines, + struct got_object_id *id1, struct got_object_id *id2, + const char *label1, const char *label2, int diff_context, + int ignore_whitespace, struct got_repository *repo, FILE *outfile) +{ + const struct got_error *err; + struct got_blob_object *blob1 = NULL, *blob2 = NULL; + + if (id1 == NULL && id2 == NULL) + return got_error(GOT_ERR_NO_OBJ); + + if (id1) { + err = got_object_open_as_blob(&blob1, repo, id1, 8192); + if (err) + goto done; + } + if (id2) { + err = got_object_open_as_blob(&blob2, repo, id2, 8192); + if (err) + goto done; + } + err = got_diff_blob(line_offsets, nlines, blob1, blob2, + label1, label2, diff_context, ignore_whitespace, outfile); +done: + if (blob1) + got_object_blob_close(blob1); + if (blob2) + got_object_blob_close(blob2); + return err; +} + +const struct got_error * +got_diff_objects_as_trees(off_t **line_offsets, size_t *nlines, + struct got_object_id *id1, struct got_object_id *id2, + char *label1, char *label2, int diff_context, int ignore_whitespace, + struct got_repository *repo, FILE *outfile) +{ + const struct got_error *err; + struct got_tree_object *tree1 = NULL, *tree2 = NULL; + struct got_diff_blob_output_unidiff_arg arg; + int want_lineoffsets = (line_offsets != NULL && *line_offsets != NULL); + + if (id1 == NULL && id2 == NULL) + return got_error(GOT_ERR_NO_OBJ); + + if (id1) { + err = got_object_open_as_tree(&tree1, repo, id1); + if (err) + goto done; + } + if (id2) { + err = got_object_open_as_tree(&tree2, repo, id2); + if (err) + goto done; + } + arg.diff_context = diff_context; + arg.ignore_whitespace = ignore_whitespace; + arg.outfile = outfile; + if (want_lineoffsets) { + arg.line_offsets = *line_offsets; + arg.nlines = *nlines; + } else { + arg.line_offsets = NULL; + arg.nlines = 0; + } + err = got_diff_tree(tree1, tree2, label1, label2, repo, + got_diff_blob_output_unidiff, &arg, 1); + + if (want_lineoffsets) { + *line_offsets = arg.line_offsets; /* was likely re-allocated */ + *nlines = arg.nlines; + } +done: + if (tree1) + got_object_tree_close(tree1); + if (tree2) + got_object_tree_close(tree2); + return err; +} + +const struct got_error * +got_diff_objects_as_commits(off_t **line_offsets, size_t *nlines, + struct got_object_id *id1, struct got_object_id *id2, + int diff_context, int ignore_whitespace, + struct got_repository *repo, FILE *outfile) +{ + const struct got_error *err; + struct got_commit_object *commit1 = NULL, *commit2 = NULL; + + if (id2 == NULL) + return got_error(GOT_ERR_NO_OBJ); + + if (id1) { + err = got_object_open_as_commit(&commit1, repo, id1); + if (err) + goto done; + } + + err = got_object_open_as_commit(&commit2, repo, id2); + if (err) + goto done; + + err = got_diff_objects_as_trees(line_offsets, nlines, + commit1 ? got_object_commit_get_tree_id(commit1) : NULL, + got_object_commit_get_tree_id(commit2), "", "", diff_context, + ignore_whitespace, repo, outfile); +done: + if (commit1) + got_object_commit_close(commit1); + if (commit2) + got_object_commit_close(commit2); + return err; +} + +const struct got_error * +got_diff_files(struct got_diffreg_result **resultp, + FILE *f1, const char *label1, FILE *f2, const char *label2, + int diff_context, int ignore_whitespace, FILE *outfile) +{ + const struct got_error *err = NULL; + struct got_diffreg_result *diffreg_result = NULL; + + if (resultp) + *resultp = NULL; + + if (outfile) { + fprintf(outfile, "file - %s\n", + f1 == NULL ? "/dev/null" : label1); + fprintf(outfile, "file + %s\n", + f2 == NULL ? "/dev/null" : label2); + } + + err = got_diffreg(&diffreg_result, f1, f2, GOT_DIFF_ALGORITHM_MYERS, + ignore_whitespace); + if (err) + goto done; + + if (outfile) { + err = got_diffreg_output(NULL, NULL, diffreg_result, + f1, f2, label1, label2, GOT_DIFF_OUTPUT_UNIDIFF, + diff_context, outfile); + if (err) + goto done; + } + +done: + if (resultp && err == NULL) + *resultp = diffreg_result; + else if (diffreg_result) { + const struct got_error *free_err; + free_err = got_diffreg_result_free(diffreg_result); + if (free_err && err == NULL) + err = free_err; + } + + return err; +} diff --git a/test/test021.left.txt b/test/test021.left.txt new file mode 100644 index 000000000000..952d28523094 --- /dev/null +++ b/test/test021.left.txt @@ -0,0 +1,1367 @@ +/* $OpenBSD: softraid_crypto.c,v 1.91 2013/03/31 15:44:52 jsing Exp $ */ +/* + * Copyright (c) 2007 Marco Peereboom + * Copyright (c) 2008 Hans-Joerg Hoexer + * Copyright (c) 2008 Damien Miller + * Copyright (c) 2009 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "bio.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +/* + * The per-I/O data that we need to preallocate. We cannot afford to allow I/O + * to start failing when memory pressure kicks in. We can store this in the WU + * because we assert that only one ccb per WU will ever be active. + */ +struct sr_crypto_wu { + TAILQ_ENTRY(sr_crypto_wu) cr_link; + struct uio cr_uio; + struct iovec cr_iov; + struct cryptop *cr_crp; + struct cryptodesc *cr_descs; + struct sr_workunit *cr_wu; + void *cr_dmabuf; +}; + + +struct sr_crypto_wu *sr_crypto_wu_get(struct sr_workunit *, int); +void sr_crypto_wu_put(struct sr_crypto_wu *); +int sr_crypto_create_keys(struct sr_discipline *); +int sr_crypto_get_kdf(struct bioc_createraid *, + struct sr_discipline *); +int sr_crypto_decrypt(u_char *, u_char *, u_char *, size_t, int); +int sr_crypto_encrypt(u_char *, u_char *, u_char *, size_t, int); +int sr_crypto_decrypt_key(struct sr_discipline *); +int sr_crypto_change_maskkey(struct sr_discipline *, + struct sr_crypto_kdfinfo *, struct sr_crypto_kdfinfo *); +int sr_crypto_create(struct sr_discipline *, + struct bioc_createraid *, int, int64_t); +int sr_crypto_assemble(struct sr_discipline *, + struct bioc_createraid *, int, void *); +int sr_crypto_alloc_resources(struct sr_discipline *); +void sr_crypto_free_resources(struct sr_discipline *); +int sr_crypto_ioctl(struct sr_discipline *, + struct bioc_discipline *); +int sr_crypto_meta_opt_handler(struct sr_discipline *, + struct sr_meta_opt_hdr *); +int sr_crypto_write(struct cryptop *); +int sr_crypto_rw(struct sr_workunit *); +int sr_crypto_rw2(struct sr_workunit *, struct sr_crypto_wu *); +void sr_crypto_done(struct sr_workunit *); +int sr_crypto_read(struct cryptop *); +void sr_crypto_finish_io(struct sr_workunit *); +void sr_crypto_calculate_check_hmac_sha1(u_int8_t *, int, + u_int8_t *, int, u_char *); +void sr_crypto_hotplug(struct sr_discipline *, struct disk *, int); + +#ifdef SR_DEBUG0 +void sr_crypto_dumpkeys(struct sr_discipline *); +#endif + +/* Discipline initialisation. */ +void +sr_crypto_discipline_init(struct sr_discipline *sd) +{ + int i; + + /* Fill out discipline members. */ + sd->sd_type = SR_MD_CRYPTO; + strlcpy(sd->sd_name, "CRYPTO", sizeof(sd->sd_name)); + sd->sd_capabilities = SR_CAP_SYSTEM_DISK | SR_CAP_AUTO_ASSEMBLE; + sd->sd_max_wu = SR_CRYPTO_NOWU; + + for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) + sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1; + + /* Setup discipline specific function pointers. */ + sd->sd_alloc_resources = sr_crypto_alloc_resources; + sd->sd_assemble = sr_crypto_assemble; + sd->sd_create = sr_crypto_create; + sd->sd_free_resources = sr_crypto_free_resources; + sd->sd_ioctl_handler = sr_crypto_ioctl; + sd->sd_meta_opt_handler = sr_crypto_meta_opt_handler; + sd->sd_scsi_rw = sr_crypto_rw; + sd->sd_scsi_done = sr_crypto_done; +} + +int +sr_crypto_create(struct sr_discipline *sd, struct bioc_createraid *bc, + int no_chunk, int64_t coerced_size) +{ + struct sr_meta_opt_item *omi; + int rv = EINVAL; + + if (no_chunk != 1) { + sr_error(sd->sd_sc, "%s requires exactly one chunk", + sd->sd_name); + goto done; + } + + /* Create crypto optional metadata. */ + omi = malloc(sizeof(struct sr_meta_opt_item), M_DEVBUF, + M_WAITOK | M_ZERO); + omi->omi_som = malloc(sizeof(struct sr_meta_crypto), M_DEVBUF, + M_WAITOK | M_ZERO); + omi->omi_som->som_type = SR_OPT_CRYPTO; + omi->omi_som->som_length = sizeof(struct sr_meta_crypto); + SLIST_INSERT_HEAD(&sd->sd_meta_opt, omi, omi_link); + sd->mds.mdd_crypto.scr_meta = (struct sr_meta_crypto *)omi->omi_som; + sd->sd_meta->ssdi.ssd_opt_no++; + + sd->mds.mdd_crypto.key_disk = NULL; + + if (bc->bc_key_disk != NODEV) { + + /* Create a key disk. */ + if (sr_crypto_get_kdf(bc, sd)) + goto done; + sd->mds.mdd_crypto.key_disk = + sr_crypto_create_key_disk(sd, bc->bc_key_disk); + if (sd->mds.mdd_crypto.key_disk == NULL) + goto done; + sd->sd_capabilities |= SR_CAP_AUTO_ASSEMBLE; + + } else if (bc->bc_opaque_flags & BIOC_SOOUT) { + + /* No hint available yet. */ + bc->bc_opaque_status = BIOC_SOINOUT_FAILED; + rv = EAGAIN; + goto done; + + } else if (sr_crypto_get_kdf(bc, sd)) + goto done; + + /* Passphrase volumes cannot be automatically assembled. */ + if (!(bc->bc_flags & BIOC_SCNOAUTOASSEMBLE) && bc->bc_key_disk == NODEV) + goto done; + + sd->sd_meta->ssdi.ssd_size = coerced_size; + + sr_crypto_create_keys(sd); + + sd->sd_max_ccb_per_wu = no_chunk; + + rv = 0; +done: + return (rv); +} + +int +sr_crypto_assemble(struct sr_discipline *sd, struct bioc_createraid *bc, + int no_chunk, void *data) +{ + int rv = EINVAL; + + sd->mds.mdd_crypto.key_disk = NULL; + + /* Crypto optional metadata must already exist... */ + if (sd->mds.mdd_crypto.scr_meta == NULL) + goto done; + + if (data != NULL) { + /* Kernel already has mask key. */ + bcopy(data, sd->mds.mdd_crypto.scr_maskkey, + sizeof(sd->mds.mdd_crypto.scr_maskkey)); + } else if (bc->bc_key_disk != NODEV) { + /* Read the mask key from the key disk. */ + sd->mds.mdd_crypto.key_disk = + sr_crypto_read_key_disk(sd, bc->bc_key_disk); + if (sd->mds.mdd_crypto.key_disk == NULL) + goto done; + } else if (bc->bc_opaque_flags & BIOC_SOOUT) { + /* provide userland with kdf hint */ + if (bc->bc_opaque == NULL) + goto done; + + if (sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint) < + bc->bc_opaque_size) + goto done; + + if (copyout(sd->mds.mdd_crypto.scr_meta->scm_kdfhint, + bc->bc_opaque, bc->bc_opaque_size)) + goto done; + + /* we're done */ + bc->bc_opaque_status = BIOC_SOINOUT_OK; + rv = EAGAIN; + goto done; + } else if (bc->bc_opaque_flags & BIOC_SOIN) { + /* get kdf with maskkey from userland */ + if (sr_crypto_get_kdf(bc, sd)) + goto done; + } else + goto done; + + sd->sd_max_ccb_per_wu = sd->sd_meta->ssdi.ssd_chunk_no; + + rv = 0; +done: + return (rv); +} + +struct sr_crypto_wu * +sr_crypto_wu_get(struct sr_workunit *wu, int encrypt) +{ + struct scsi_xfer *xs = wu->swu_xs; + struct sr_discipline *sd = wu->swu_dis; + struct sr_crypto_wu *crwu; + struct cryptodesc *crd; + int flags, i, n; + daddr64_t blk = 0; + u_int keyndx; + + DNPRINTF(SR_D_DIS, "%s: sr_crypto_wu_get wu: %p encrypt: %d\n", + DEVNAME(sd->sd_sc), wu, encrypt); + + mtx_enter(&sd->mds.mdd_crypto.scr_mutex); + if ((crwu = TAILQ_FIRST(&sd->mds.mdd_crypto.scr_wus)) != NULL) + TAILQ_REMOVE(&sd->mds.mdd_crypto.scr_wus, crwu, cr_link); + mtx_leave(&sd->mds.mdd_crypto.scr_mutex); + if (crwu == NULL) + panic("sr_crypto_wu_get: out of wus"); + + crwu->cr_uio.uio_iovcnt = 1; + crwu->cr_uio.uio_iov->iov_len = xs->datalen; + if (xs->flags & SCSI_DATA_OUT) { + crwu->cr_uio.uio_iov->iov_base = crwu->cr_dmabuf; + bcopy(xs->data, crwu->cr_uio.uio_iov->iov_base, xs->datalen); + } else + crwu->cr_uio.uio_iov->iov_base = xs->data; + + if (xs->cmdlen == 10) + blk = _4btol(((struct scsi_rw_big *)xs->cmd)->addr); + else if (xs->cmdlen == 16) + blk = _8btol(((struct scsi_rw_16 *)xs->cmd)->addr); + else if (xs->cmdlen == 6) + blk = _3btol(((struct scsi_rw *)xs->cmd)->addr); + + n = xs->datalen >> DEV_BSHIFT; + + /* + * We preallocated enough crypto descs for up to MAXPHYS of I/O. + * Since there may be less than that we need to tweak the linked list + * of crypto desc structures to be just long enough for our needs. + */ + crd = crwu->cr_descs; + for (i = 0; i < ((MAXPHYS >> DEV_BSHIFT) - n); i++) { + crd = crd->crd_next; + KASSERT(crd); + } + crwu->cr_crp->crp_desc = crd; + flags = (encrypt ? CRD_F_ENCRYPT : 0) | + CRD_F_IV_PRESENT | CRD_F_IV_EXPLICIT; + + /* Select crypto session based on block number */ + keyndx = blk >> SR_CRYPTO_KEY_BLKSHIFT; + if (keyndx >= SR_CRYPTO_MAXKEYS) + goto unwind; + crwu->cr_crp->crp_sid = sd->mds.mdd_crypto.scr_sid[keyndx]; + if (crwu->cr_crp->crp_sid == (u_int64_t)-1) + goto unwind; + + crwu->cr_crp->crp_ilen = xs->datalen; + crwu->cr_crp->crp_alloctype = M_DEVBUF; + crwu->cr_crp->crp_buf = &crwu->cr_uio; + for (i = 0, crd = crwu->cr_crp->crp_desc; crd; + i++, blk++, crd = crd->crd_next) { + crd->crd_skip = i << DEV_BSHIFT; + crd->crd_len = DEV_BSIZE; + crd->crd_inject = 0; + crd->crd_flags = flags; + crd->crd_alg = CRYPTO_AES_XTS; + + switch (sd->mds.mdd_crypto.scr_meta->scm_alg) { + case SR_CRYPTOA_AES_XTS_128: + crd->crd_klen = 256; + break; + case SR_CRYPTOA_AES_XTS_256: + crd->crd_klen = 512; + break; + default: + goto unwind; + } + crd->crd_key = sd->mds.mdd_crypto.scr_key[0]; + bcopy(&blk, crd->crd_iv, sizeof(blk)); + } + crwu->cr_wu = wu; + crwu->cr_crp->crp_opaque = crwu; + + return (crwu); + +unwind: + /* steal the descriptors back from the cryptop */ + crwu->cr_crp->crp_desc = NULL; + + return (NULL); +} + +void +sr_crypto_wu_put(struct sr_crypto_wu *crwu) +{ + struct cryptop *crp = crwu->cr_crp; + struct sr_workunit *wu = crwu->cr_wu; + struct sr_discipline *sd = wu->swu_dis; + + DNPRINTF(SR_D_DIS, "%s: sr_crypto_wu_put crwu: %p\n", + DEVNAME(wu->swu_dis->sd_sc), crwu); + + /* steal the descriptors back from the cryptop */ + crp->crp_desc = NULL; + + mtx_enter(&sd->mds.mdd_crypto.scr_mutex); + TAILQ_INSERT_TAIL(&sd->mds.mdd_crypto.scr_wus, crwu, cr_link); + mtx_leave(&sd->mds.mdd_crypto.scr_mutex); +} + +int +sr_crypto_get_kdf(struct bioc_createraid *bc, struct sr_discipline *sd) +{ + int rv = EINVAL; + struct sr_crypto_kdfinfo *kdfinfo; + + if (!(bc->bc_opaque_flags & BIOC_SOIN)) + return (rv); + if (bc->bc_opaque == NULL) + return (rv); + if (bc->bc_opaque_size != sizeof(*kdfinfo)) + return (rv); + + kdfinfo = malloc(bc->bc_opaque_size, M_DEVBUF, M_WAITOK | M_ZERO); + if (copyin(bc->bc_opaque, kdfinfo, bc->bc_opaque_size)) + goto out; + + if (kdfinfo->len != bc->bc_opaque_size) + goto out; + + /* copy KDF hint to disk meta data */ + if (kdfinfo->flags & SR_CRYPTOKDF_HINT) { + if (sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint) < + kdfinfo->genkdf.len) + goto out; + bcopy(&kdfinfo->genkdf, + sd->mds.mdd_crypto.scr_meta->scm_kdfhint, + kdfinfo->genkdf.len); + } + + /* copy mask key to run-time meta data */ + if ((kdfinfo->flags & SR_CRYPTOKDF_KEY)) { + if (sizeof(sd->mds.mdd_crypto.scr_maskkey) < + sizeof(kdfinfo->maskkey)) + goto out; + bcopy(&kdfinfo->maskkey, sd->mds.mdd_crypto.scr_maskkey, + sizeof(kdfinfo->maskkey)); + } + + bc->bc_opaque_status = BIOC_SOINOUT_OK; + rv = 0; +out: + explicit_bzero(kdfinfo, bc->bc_opaque_size); + free(kdfinfo, M_DEVBUF); + + return (rv); +} + +int +sr_crypto_encrypt(u_char *p, u_char *c, u_char *key, size_t size, int alg) +{ + rijndael_ctx ctx; + int i, rv = 1; + + switch (alg) { + case SR_CRYPTOM_AES_ECB_256: + if (rijndael_set_key_enc_only(&ctx, key, 256) != 0) + goto out; + for (i = 0; i < size; i += RIJNDAEL128_BLOCK_LEN) + rijndael_encrypt(&ctx, &p[i], &c[i]); + rv = 0; + break; + default: + DNPRINTF(SR_D_DIS, "%s: unsupported encryption algorithm %u\n", + "softraid", alg); + rv = -1; + goto out; + } + +out: + explicit_bzero(&ctx, sizeof(ctx)); + return (rv); +} + +int +sr_crypto_decrypt(u_char *c, u_char *p, u_char *key, size_t size, int alg) +{ + rijndael_ctx ctx; + int i, rv = 1; + + switch (alg) { + case SR_CRYPTOM_AES_ECB_256: + if (rijndael_set_key(&ctx, key, 256) != 0) + goto out; + for (i = 0; i < size; i += RIJNDAEL128_BLOCK_LEN) + rijndael_decrypt(&ctx, &c[i], &p[i]); + rv = 0; + break; + default: + DNPRINTF(SR_D_DIS, "%s: unsupported encryption algorithm %u\n", + "softraid", alg); + rv = -1; + goto out; + } + +out: + explicit_bzero(&ctx, sizeof(ctx)); + return (rv); +} + +void +sr_crypto_calculate_check_hmac_sha1(u_int8_t *maskkey, int maskkey_size, + u_int8_t *key, int key_size, u_char *check_digest) +{ + u_char check_key[SHA1_DIGEST_LENGTH]; + HMAC_SHA1_CTX hmacctx; + SHA1_CTX shactx; + + bzero(check_key, sizeof(check_key)); + bzero(&hmacctx, sizeof(hmacctx)); + bzero(&shactx, sizeof(shactx)); + + /* k = SHA1(mask_key) */ + SHA1Init(&shactx); + SHA1Update(&shactx, maskkey, maskkey_size); + SHA1Final(check_key, &shactx); + + /* mac = HMAC_SHA1_k(unencrypted key) */ + HMAC_SHA1_Init(&hmacctx, check_key, sizeof(check_key)); + HMAC_SHA1_Update(&hmacctx, key, key_size); + HMAC_SHA1_Final(check_digest, &hmacctx); + + explicit_bzero(check_key, sizeof(check_key)); + explicit_bzero(&hmacctx, sizeof(hmacctx)); + explicit_bzero(&shactx, sizeof(shactx)); +} + +int +sr_crypto_decrypt_key(struct sr_discipline *sd) +{ + u_char check_digest[SHA1_DIGEST_LENGTH]; + int rv = 1; + + DNPRINTF(SR_D_DIS, "%s: sr_crypto_decrypt_key\n", DEVNAME(sd->sd_sc)); + + if (sd->mds.mdd_crypto.scr_meta->scm_check_alg != SR_CRYPTOC_HMAC_SHA1) + goto out; + + if (sr_crypto_decrypt((u_char *)sd->mds.mdd_crypto.scr_meta->scm_key, + (u_char *)sd->mds.mdd_crypto.scr_key, + sd->mds.mdd_crypto.scr_maskkey, sizeof(sd->mds.mdd_crypto.scr_key), + sd->mds.mdd_crypto.scr_meta->scm_mask_alg) == -1) + goto out; + +#ifdef SR_DEBUG0 + sr_crypto_dumpkeys(sd); +#endif + + /* Check that the key decrypted properly. */ + sr_crypto_calculate_check_hmac_sha1(sd->mds.mdd_crypto.scr_maskkey, + sizeof(sd->mds.mdd_crypto.scr_maskkey), + (u_int8_t *)sd->mds.mdd_crypto.scr_key, + sizeof(sd->mds.mdd_crypto.scr_key), + check_digest); + if (memcmp(sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac, + check_digest, sizeof(check_digest)) != 0) { + explicit_bzero(sd->mds.mdd_crypto.scr_key, + sizeof(sd->mds.mdd_crypto.scr_key)); + goto out; + } + + rv = 0; /* Success */ +out: + /* we don't need the mask key anymore */ + explicit_bzero(&sd->mds.mdd_crypto.scr_maskkey, + sizeof(sd->mds.mdd_crypto.scr_maskkey)); + + explicit_bzero(check_digest, sizeof(check_digest)); + + return rv; +} + +int +sr_crypto_create_keys(struct sr_discipline *sd) +{ + + DNPRINTF(SR_D_DIS, "%s: sr_crypto_create_keys\n", + DEVNAME(sd->sd_sc)); + + if (AES_MAXKEYBYTES < sizeof(sd->mds.mdd_crypto.scr_maskkey)) + return (1); + + /* XXX allow user to specify */ + sd->mds.mdd_crypto.scr_meta->scm_alg = SR_CRYPTOA_AES_XTS_256; + + /* generate crypto keys */ + arc4random_buf(sd->mds.mdd_crypto.scr_key, + sizeof(sd->mds.mdd_crypto.scr_key)); + + /* Mask the disk keys. */ + sd->mds.mdd_crypto.scr_meta->scm_mask_alg = SR_CRYPTOM_AES_ECB_256; + sr_crypto_encrypt((u_char *)sd->mds.mdd_crypto.scr_key, + (u_char *)sd->mds.mdd_crypto.scr_meta->scm_key, + sd->mds.mdd_crypto.scr_maskkey, sizeof(sd->mds.mdd_crypto.scr_key), + sd->mds.mdd_crypto.scr_meta->scm_mask_alg); + + /* Prepare key decryption check code. */ + sd->mds.mdd_crypto.scr_meta->scm_check_alg = SR_CRYPTOC_HMAC_SHA1; + sr_crypto_calculate_check_hmac_sha1(sd->mds.mdd_crypto.scr_maskkey, + sizeof(sd->mds.mdd_crypto.scr_maskkey), + (u_int8_t *)sd->mds.mdd_crypto.scr_key, + sizeof(sd->mds.mdd_crypto.scr_key), + sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac); + + /* Erase the plaintext disk keys */ + explicit_bzero(sd->mds.mdd_crypto.scr_key, + sizeof(sd->mds.mdd_crypto.scr_key)); + +#ifdef SR_DEBUG0 + sr_crypto_dumpkeys(sd); +#endif + + sd->mds.mdd_crypto.scr_meta->scm_flags = SR_CRYPTOF_KEY | + SR_CRYPTOF_KDFHINT; + + return (0); +} + +int +sr_crypto_change_maskkey(struct sr_discipline *sd, + struct sr_crypto_kdfinfo *kdfinfo1, struct sr_crypto_kdfinfo *kdfinfo2) +{ + u_char check_digest[SHA1_DIGEST_LENGTH]; + u_char *c, *p = NULL; + size_t ksz; + int rv = 1; + + DNPRINTF(SR_D_DIS, "%s: sr_crypto_change_maskkey\n", + DEVNAME(sd->sd_sc)); + + if (sd->mds.mdd_crypto.scr_meta->scm_check_alg != SR_CRYPTOC_HMAC_SHA1) + goto out; + + c = (u_char *)sd->mds.mdd_crypto.scr_meta->scm_key; + ksz = sizeof(sd->mds.mdd_crypto.scr_key); + p = malloc(ksz, M_DEVBUF, M_WAITOK | M_CANFAIL | M_ZERO); + if (p == NULL) + goto out; + + if (sr_crypto_decrypt(c, p, kdfinfo1->maskkey, ksz, + sd->mds.mdd_crypto.scr_meta->scm_mask_alg) == -1) + goto out; + +#ifdef SR_DEBUG0 + sr_crypto_dumpkeys(sd); +#endif + + sr_crypto_calculate_check_hmac_sha1(kdfinfo1->maskkey, + sizeof(kdfinfo1->maskkey), p, ksz, check_digest); + if (memcmp(sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac, + check_digest, sizeof(check_digest)) != 0) { + sr_error(sd->sd_sc, "incorrect key or passphrase"); + rv = EPERM; + goto out; + } + + /* Mask the disk keys. */ + c = (u_char *)sd->mds.mdd_crypto.scr_meta->scm_key; + if (sr_crypto_encrypt(p, c, kdfinfo2->maskkey, ksz, + sd->mds.mdd_crypto.scr_meta->scm_mask_alg) == -1) + goto out; + + /* Prepare key decryption check code. */ + sd->mds.mdd_crypto.scr_meta->scm_check_alg = SR_CRYPTOC_HMAC_SHA1; + sr_crypto_calculate_check_hmac_sha1(kdfinfo2->maskkey, + sizeof(kdfinfo2->maskkey), (u_int8_t *)sd->mds.mdd_crypto.scr_key, + sizeof(sd->mds.mdd_crypto.scr_key), check_digest); + + /* Copy new encrypted key and HMAC to metadata. */ + bcopy(check_digest, sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac, + sizeof(sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac)); + + rv = 0; /* Success */ + +out: + if (p) { + explicit_bzero(p, ksz); + free(p, M_DEVBUF); + } + + explicit_bzero(check_digest, sizeof(check_digest)); + explicit_bzero(&kdfinfo1->maskkey, sizeof(kdfinfo1->maskkey)); + explicit_bzero(&kdfinfo2->maskkey, sizeof(kdfinfo2->maskkey)); + + return (rv); +} + +struct sr_chunk * +sr_crypto_create_key_disk(struct sr_discipline *sd, dev_t dev) +{ + struct sr_softc *sc = sd->sd_sc; + struct sr_discipline *fakesd = NULL; + struct sr_metadata *sm = NULL; + struct sr_meta_chunk *km; + struct sr_meta_opt_item *omi = NULL; + struct sr_meta_keydisk *skm; + struct sr_chunk *key_disk = NULL; + struct disklabel label; + struct vnode *vn; + char devname[32]; + int c, part, open = 0; + + /* + * Create a metadata structure on the key disk and store + * keying material in the optional metadata. + */ + + sr_meta_getdevname(sc, dev, devname, sizeof(devname)); + + /* Make sure chunk is not already in use. */ + c = sr_chunk_in_use(sc, dev); + if (c != BIOC_SDINVALID && c != BIOC_SDOFFLINE) { + sr_error(sc, "%s is already in use", devname); + goto done; + } + + /* Open device. */ + if (bdevvp(dev, &vn)) { + sr_error(sc, "cannot open key disk %s", devname); + goto done; + } + if (VOP_OPEN(vn, FREAD | FWRITE, NOCRED, curproc)) { + DNPRINTF(SR_D_META,"%s: sr_crypto_create_key_disk cannot " + "open %s\n", DEVNAME(sc), devname); + vput(vn); + goto fail; + } + open = 1; /* close dev on error */ + + /* Get partition details. */ + part = DISKPART(dev); + if (VOP_IOCTL(vn, DIOCGDINFO, (caddr_t)&label, + FREAD, NOCRED, curproc)) { + DNPRINTF(SR_D_META, "%s: sr_crypto_create_key_disk ioctl " + "failed\n", DEVNAME(sc)); + VOP_CLOSE(vn, FREAD | FWRITE, NOCRED, curproc); + vput(vn); + goto fail; + } + if (label.d_secsize != DEV_BSIZE) { + sr_error(sc, "%s has unsupported sector size (%d)", + devname, label.d_secsize); + goto fail; + } + if (label.d_partitions[part].p_fstype != FS_RAID) { + sr_error(sc, "%s partition not of type RAID (%d)\n", + devname, label.d_partitions[part].p_fstype); + goto fail; + } + + /* + * Create and populate chunk metadata. + */ + + key_disk = malloc(sizeof(struct sr_chunk), M_DEVBUF, M_WAITOK | M_ZERO); + km = &key_disk->src_meta; + + key_disk->src_dev_mm = dev; + key_disk->src_vn = vn; + strlcpy(key_disk->src_devname, devname, sizeof(km->scmi.scm_devname)); + key_disk->src_size = 0; + + km->scmi.scm_volid = sd->sd_meta->ssdi.ssd_level; + km->scmi.scm_chunk_id = 0; + km->scmi.scm_size = 0; + km->scmi.scm_coerced_size = 0; + strlcpy(km->scmi.scm_devname, devname, sizeof(km->scmi.scm_devname)); + bcopy(&sd->sd_meta->ssdi.ssd_uuid, &km->scmi.scm_uuid, + sizeof(struct sr_uuid)); + + sr_checksum(sc, km, &km->scm_checksum, + sizeof(struct sr_meta_chunk_invariant)); + + km->scm_status = BIOC_SDONLINE; + + /* + * Create and populate our own discipline and metadata. + */ + + sm = malloc(sizeof(struct sr_metadata), M_DEVBUF, M_WAITOK | M_ZERO); + sm->ssdi.ssd_magic = SR_MAGIC; + sm->ssdi.ssd_version = SR_META_VERSION; + sm->ssd_ondisk = 0; + sm->ssdi.ssd_vol_flags = 0; + bcopy(&sd->sd_meta->ssdi.ssd_uuid, &sm->ssdi.ssd_uuid, + sizeof(struct sr_uuid)); + sm->ssdi.ssd_chunk_no = 1; + sm->ssdi.ssd_volid = SR_KEYDISK_VOLID; + sm->ssdi.ssd_level = SR_KEYDISK_LEVEL; + sm->ssdi.ssd_size = 0; + strlcpy(sm->ssdi.ssd_vendor, "OPENBSD", sizeof(sm->ssdi.ssd_vendor)); + snprintf(sm->ssdi.ssd_product, sizeof(sm->ssdi.ssd_product), + "SR %s", "KEYDISK"); + snprintf(sm->ssdi.ssd_revision, sizeof(sm->ssdi.ssd_revision), + "%03d", SR_META_VERSION); + + fakesd = malloc(sizeof(struct sr_discipline), M_DEVBUF, + M_WAITOK | M_ZERO); + fakesd->sd_sc = sd->sd_sc; + fakesd->sd_meta = sm; + fakesd->sd_meta_type = SR_META_F_NATIVE; + fakesd->sd_vol_status = BIOC_SVONLINE; + strlcpy(fakesd->sd_name, "KEYDISK", sizeof(fakesd->sd_name)); + SLIST_INIT(&fakesd->sd_meta_opt); + + /* Add chunk to volume. */ + fakesd->sd_vol.sv_chunks = malloc(sizeof(struct sr_chunk *), M_DEVBUF, + M_WAITOK | M_ZERO); + fakesd->sd_vol.sv_chunks[0] = key_disk; + SLIST_INIT(&fakesd->sd_vol.sv_chunk_list); + SLIST_INSERT_HEAD(&fakesd->sd_vol.sv_chunk_list, key_disk, src_link); + + /* Generate mask key. */ + arc4random_buf(sd->mds.mdd_crypto.scr_maskkey, + sizeof(sd->mds.mdd_crypto.scr_maskkey)); + + /* Copy mask key to optional metadata area. */ + omi = malloc(sizeof(struct sr_meta_opt_item), M_DEVBUF, + M_WAITOK | M_ZERO); + omi->omi_som = malloc(sizeof(struct sr_meta_keydisk), M_DEVBUF, + M_WAITOK | M_ZERO); + omi->omi_som->som_type = SR_OPT_KEYDISK; + omi->omi_som->som_length = sizeof(struct sr_meta_keydisk); + skm = (struct sr_meta_keydisk *)omi->omi_som; + bcopy(sd->mds.mdd_crypto.scr_maskkey, &skm->skm_maskkey, + sizeof(skm->skm_maskkey)); + SLIST_INSERT_HEAD(&fakesd->sd_meta_opt, omi, omi_link); + fakesd->sd_meta->ssdi.ssd_opt_no++; + + /* Save metadata. */ + if (sr_meta_save(fakesd, SR_META_DIRTY)) { + sr_error(sc, "could not save metadata to %s", devname); + goto fail; + } + + goto done; + +fail: + if (key_disk) + free(key_disk, M_DEVBUF); + key_disk = NULL; + +done: + if (omi) + free(omi, M_DEVBUF); + if (fakesd && fakesd->sd_vol.sv_chunks) + free(fakesd->sd_vol.sv_chunks, M_DEVBUF); + if (fakesd) + free(fakesd, M_DEVBUF); + if (sm) + free(sm, M_DEVBUF); + if (open) { + VOP_CLOSE(vn, FREAD | FWRITE, NOCRED, curproc); + vput(vn); + } + + return key_disk; +} + +struct sr_chunk * +sr_crypto_read_key_disk(struct sr_discipline *sd, dev_t dev) +{ + struct sr_softc *sc = sd->sd_sc; + struct sr_metadata *sm = NULL; + struct sr_meta_opt_item *omi, *omi_next; + struct sr_meta_opt_hdr *omh; + struct sr_meta_keydisk *skm; + struct sr_meta_opt_head som; + struct sr_chunk *key_disk = NULL; + struct disklabel label; + struct vnode *vn = NULL; + char devname[32]; + int c, part, open = 0; + + /* + * Load a key disk and load keying material into memory. + */ + + SLIST_INIT(&som); + + sr_meta_getdevname(sc, dev, devname, sizeof(devname)); + + /* Make sure chunk is not already in use. */ + c = sr_chunk_in_use(sc, dev); + if (c != BIOC_SDINVALID && c != BIOC_SDOFFLINE) { + sr_error(sc, "%s is already in use", devname); + goto done; + } + + /* Open device. */ + if (bdevvp(dev, &vn)) { + sr_error(sc, "cannot open key disk %s", devname); + goto done; + } + if (VOP_OPEN(vn, FREAD | FWRITE, NOCRED, curproc)) { + DNPRINTF(SR_D_META,"%s: sr_crypto_read_key_disk cannot " + "open %s\n", DEVNAME(sc), devname); + vput(vn); + goto done; + } + open = 1; /* close dev on error */ + + /* Get partition details. */ + part = DISKPART(dev); + if (VOP_IOCTL(vn, DIOCGDINFO, (caddr_t)&label, FREAD, + NOCRED, curproc)) { + DNPRINTF(SR_D_META, "%s: sr_crypto_read_key_disk ioctl " + "failed\n", DEVNAME(sc)); + VOP_CLOSE(vn, FREAD | FWRITE, NOCRED, curproc); + vput(vn); + goto done; + } + if (label.d_secsize != DEV_BSIZE) { + sr_error(sc, "%s has unsupported sector size (%d)", + devname, label.d_secsize); + goto done; + } + if (label.d_partitions[part].p_fstype != FS_RAID) { + sr_error(sc, "%s partition not of type RAID (%d)\n", + devname, label.d_partitions[part].p_fstype); + goto done; + } + + /* + * Read and validate key disk metadata. + */ + sm = malloc(SR_META_SIZE * 512, M_DEVBUF, M_WAITOK | M_ZERO); + if (sr_meta_native_read(sd, dev, sm, NULL)) { + sr_error(sc, "native bootprobe could not read native metadata"); + goto done; + } + + if (sr_meta_validate(sd, dev, sm, NULL)) { + DNPRINTF(SR_D_META, "%s: invalid metadata\n", + DEVNAME(sc)); + goto done; + } + + /* Make sure this is a key disk. */ + if (sm->ssdi.ssd_level != SR_KEYDISK_LEVEL) { + sr_error(sc, "%s is not a key disk", devname); + goto done; + } + + /* Construct key disk chunk. */ + key_disk = malloc(sizeof(struct sr_chunk), M_DEVBUF, M_WAITOK | M_ZERO); + key_disk->src_dev_mm = dev; + key_disk->src_vn = vn; + key_disk->src_size = 0; + + bcopy((struct sr_meta_chunk *)(sm + 1), &key_disk->src_meta, + sizeof(key_disk->src_meta)); + + /* Read mask key from optional metadata. */ + sr_meta_opt_load(sc, sm, &som); + SLIST_FOREACH(omi, &som, omi_link) { + omh = omi->omi_som; + if (omh->som_type == SR_OPT_KEYDISK) { + skm = (struct sr_meta_keydisk *)omh; + bcopy(&skm->skm_maskkey, + sd->mds.mdd_crypto.scr_maskkey, + sizeof(sd->mds.mdd_crypto.scr_maskkey)); + } else if (omh->som_type == SR_OPT_CRYPTO) { + /* Original keydisk format with key in crypto area. */ + bcopy(omh + sizeof(struct sr_meta_opt_hdr), + sd->mds.mdd_crypto.scr_maskkey, + sizeof(sd->mds.mdd_crypto.scr_maskkey)); + } + } + + open = 0; + +done: + for (omi = SLIST_FIRST(&som); omi != SLIST_END(&som); omi = omi_next) { + omi_next = SLIST_NEXT(omi, omi_link); + if (omi->omi_som) + free(omi->omi_som, M_DEVBUF); + free(omi, M_DEVBUF); + } + + if (sm) + free(sm, M_DEVBUF); + + if (vn && open) { + VOP_CLOSE(vn, FREAD, NOCRED, curproc); + vput(vn); + } + + return key_disk; +} + +int +sr_crypto_alloc_resources(struct sr_discipline *sd) +{ + struct cryptoini cri; + struct sr_crypto_wu *crwu; + u_int num_keys, i; + + DNPRINTF(SR_D_DIS, "%s: sr_crypto_alloc_resources\n", + DEVNAME(sd->sd_sc)); + + for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) + sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1; + + if (sr_wu_alloc(sd)) { + sr_error(sd->sd_sc, "unable to allocate work units"); + return (ENOMEM); + } + if (sr_ccb_alloc(sd)) { + sr_error(sd->sd_sc, "unable to allocate CCBs"); + return (ENOMEM); + } + if (sr_crypto_decrypt_key(sd)) { + sr_error(sd->sd_sc, "incorrect key or passphrase"); + return (EPERM); + } + + /* + * For each wu allocate the uio, iovec and crypto structures. + * these have to be allocated now because during runtime we can't + * fail an allocation without failing the io (which can cause real + * problems). + */ + mtx_init(&sd->mds.mdd_crypto.scr_mutex, IPL_BIO); + TAILQ_INIT(&sd->mds.mdd_crypto.scr_wus); + for (i = 0; i < sd->sd_max_wu; i++) { + crwu = malloc(sizeof(*crwu), M_DEVBUF, + M_WAITOK | M_ZERO | M_CANFAIL); + if (crwu == NULL) + return (ENOMEM); + /* put it on the list now so if we fail it'll be freed */ + mtx_enter(&sd->mds.mdd_crypto.scr_mutex); + TAILQ_INSERT_TAIL(&sd->mds.mdd_crypto.scr_wus, crwu, cr_link); + mtx_leave(&sd->mds.mdd_crypto.scr_mutex); + + crwu->cr_uio.uio_iov = &crwu->cr_iov; + crwu->cr_dmabuf = dma_alloc(MAXPHYS, PR_WAITOK); + crwu->cr_crp = crypto_getreq(MAXPHYS >> DEV_BSHIFT); + if (crwu->cr_crp == NULL) + return (ENOMEM); + /* steal the list of cryptodescs */ + crwu->cr_descs = crwu->cr_crp->crp_desc; + crwu->cr_crp->crp_desc = NULL; + } + + bzero(&cri, sizeof(cri)); + cri.cri_alg = CRYPTO_AES_XTS; + switch (sd->mds.mdd_crypto.scr_meta->scm_alg) { + case SR_CRYPTOA_AES_XTS_128: + cri.cri_klen = 256; + break; + case SR_CRYPTOA_AES_XTS_256: + cri.cri_klen = 512; + break; + default: + return (EINVAL); + } + + /* Allocate a session for every 2^SR_CRYPTO_KEY_BLKSHIFT blocks */ + num_keys = sd->sd_meta->ssdi.ssd_size >> SR_CRYPTO_KEY_BLKSHIFT; + if (num_keys >= SR_CRYPTO_MAXKEYS) + return (EFBIG); + for (i = 0; i <= num_keys; i++) { + cri.cri_key = sd->mds.mdd_crypto.scr_key[i]; + if (crypto_newsession(&sd->mds.mdd_crypto.scr_sid[i], + &cri, 0) != 0) { + for (i = 0; + sd->mds.mdd_crypto.scr_sid[i] != (u_int64_t)-1; + i++) { + crypto_freesession( + sd->mds.mdd_crypto.scr_sid[i]); + sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1; + } + return (EINVAL); + } + } + + sr_hotplug_register(sd, sr_crypto_hotplug); + + return (0); +} + +void +sr_crypto_free_resources(struct sr_discipline *sd) +{ + struct sr_crypto_wu *crwu; + u_int i; + + DNPRINTF(SR_D_DIS, "%s: sr_crypto_free_resources\n", + DEVNAME(sd->sd_sc)); + + if (sd->mds.mdd_crypto.key_disk != NULL) { + explicit_bzero(sd->mds.mdd_crypto.key_disk, sizeof + sd->mds.mdd_crypto.key_disk); + free(sd->mds.mdd_crypto.key_disk, M_DEVBUF); + } + + sr_hotplug_unregister(sd, sr_crypto_hotplug); + + for (i = 0; sd->mds.mdd_crypto.scr_sid[i] != (u_int64_t)-1; i++) { + crypto_freesession(sd->mds.mdd_crypto.scr_sid[i]); + sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1; + } + + mtx_enter(&sd->mds.mdd_crypto.scr_mutex); + while ((crwu = TAILQ_FIRST(&sd->mds.mdd_crypto.scr_wus)) != NULL) { + TAILQ_REMOVE(&sd->mds.mdd_crypto.scr_wus, crwu, cr_link); + + if (crwu->cr_dmabuf != NULL) + dma_free(crwu->cr_dmabuf, MAXPHYS); + if (crwu->cr_crp) { + /* twiddle cryptoreq back */ + crwu->cr_crp->crp_desc = crwu->cr_descs; + crypto_freereq(crwu->cr_crp); + } + free(crwu, M_DEVBUF); + } + mtx_leave(&sd->mds.mdd_crypto.scr_mutex); + + sr_wu_free(sd); + sr_ccb_free(sd); +} + +int +sr_crypto_ioctl(struct sr_discipline *sd, struct bioc_discipline *bd) +{ + struct sr_crypto_kdfpair kdfpair; + struct sr_crypto_kdfinfo kdfinfo1, kdfinfo2; + int size, rv = 1; + + DNPRINTF(SR_D_IOCTL, "%s: sr_crypto_ioctl %u\n", + DEVNAME(sd->sd_sc), bd->bd_cmd); + + switch (bd->bd_cmd) { + case SR_IOCTL_GET_KDFHINT: + + /* Get KDF hint for userland. */ + size = sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint); + if (bd->bd_data == NULL || bd->bd_size > size) + goto bad; + if (copyout(sd->mds.mdd_crypto.scr_meta->scm_kdfhint, + bd->bd_data, bd->bd_size)) + goto bad; + + rv = 0; + + break; + + case SR_IOCTL_CHANGE_PASSPHRASE: + + /* Attempt to change passphrase. */ + + size = sizeof(kdfpair); + if (bd->bd_data == NULL || bd->bd_size > size) + goto bad; + if (copyin(bd->bd_data, &kdfpair, size)) + goto bad; + + size = sizeof(kdfinfo1); + if (kdfpair.kdfinfo1 == NULL || kdfpair.kdfsize1 > size) + goto bad; + if (copyin(kdfpair.kdfinfo1, &kdfinfo1, size)) + goto bad; + + size = sizeof(kdfinfo2); + if (kdfpair.kdfinfo2 == NULL || kdfpair.kdfsize2 > size) + goto bad; + if (copyin(kdfpair.kdfinfo2, &kdfinfo2, size)) + goto bad; + + if (sr_crypto_change_maskkey(sd, &kdfinfo1, &kdfinfo2)) + goto bad; + + /* Save metadata to disk. */ + rv = sr_meta_save(sd, SR_META_DIRTY); + + break; + } + +bad: + explicit_bzero(&kdfpair, sizeof(kdfpair)); + explicit_bzero(&kdfinfo1, sizeof(kdfinfo1)); + explicit_bzero(&kdfinfo2, sizeof(kdfinfo2)); + + return (rv); +} + +int +sr_crypto_meta_opt_handler(struct sr_discipline *sd, struct sr_meta_opt_hdr *om) +{ + int rv = EINVAL; + + if (om->som_type == SR_OPT_CRYPTO) { + sd->mds.mdd_crypto.scr_meta = (struct sr_meta_crypto *)om; + rv = 0; + } + + return (rv); +} + +int +sr_crypto_rw(struct sr_workunit *wu) +{ + struct sr_crypto_wu *crwu; + int s, rv = 0; + + DNPRINTF(SR_D_DIS, "%s: sr_crypto_rw wu: %p\n", + DEVNAME(wu->swu_dis->sd_sc), wu); + + if (wu->swu_xs->flags & SCSI_DATA_OUT) { + crwu = sr_crypto_wu_get(wu, 1); + if (crwu == NULL) + return (1); + crwu->cr_crp->crp_callback = sr_crypto_write; + s = splvm(); + if (crypto_invoke(crwu->cr_crp)) + rv = 1; + else + rv = crwu->cr_crp->crp_etype; + splx(s); + } else + rv = sr_crypto_rw2(wu, NULL); + + return (rv); +} + +int +sr_crypto_write(struct cryptop *crp) +{ + struct sr_crypto_wu *crwu = crp->crp_opaque; + struct sr_workunit *wu = crwu->cr_wu; + int s; + + DNPRINTF(SR_D_INTR, "%s: sr_crypto_write: wu %x xs: %x\n", + DEVNAME(wu->swu_dis->sd_sc), wu, wu->swu_xs); + + if (crp->crp_etype) { + /* fail io */ + wu->swu_xs->error = XS_DRIVER_STUFFUP; + s = splbio(); + sr_crypto_finish_io(wu); + splx(s); + } + + return (sr_crypto_rw2(wu, crwu)); +} + +int +sr_crypto_rw2(struct sr_workunit *wu, struct sr_crypto_wu *crwu) +{ + struct sr_discipline *sd = wu->swu_dis; + struct scsi_xfer *xs = wu->swu_xs; + struct sr_ccb *ccb; + struct uio *uio; + int s; + daddr64_t blk; + + if (sr_validate_io(wu, &blk, "sr_crypto_rw2")) + goto bad; + + blk += sd->sd_meta->ssd_data_offset; + + ccb = sr_ccb_rw(sd, 0, blk, xs->datalen, xs->data, xs->flags, 0); + if (!ccb) { + /* should never happen but handle more gracefully */ + printf("%s: %s: too many ccbs queued\n", + DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname); + goto bad; + } + if (!ISSET(xs->flags, SCSI_DATA_IN)) { + uio = crwu->cr_crp->crp_buf; + ccb->ccb_buf.b_data = uio->uio_iov->iov_base; + ccb->ccb_opaque = crwu; + } + sr_wu_enqueue_ccb(wu, ccb); + + s = splbio(); + + if (sr_check_io_collision(wu)) + goto queued; + + sr_raid_startwu(wu); + +queued: + splx(s); + return (0); +bad: + /* wu is unwound by sr_wu_put */ + if (crwu) + crwu->cr_crp->crp_etype = EINVAL; + return (1); +} + +void +sr_crypto_done(struct sr_workunit *wu) +{ + struct scsi_xfer *xs = wu->swu_xs; + struct sr_crypto_wu *crwu; + struct sr_ccb *ccb; + int s; + + /* If this was a successful read, initiate decryption of the data. */ + if (ISSET(xs->flags, SCSI_DATA_IN) && xs->error == XS_NOERROR) { + /* only fails on implementation error */ + crwu = sr_crypto_wu_get(wu, 0); + if (crwu == NULL) + panic("sr_crypto_intr: no wu"); + crwu->cr_crp->crp_callback = sr_crypto_read; + ccb = TAILQ_FIRST(&wu->swu_ccb); + if (ccb == NULL) + panic("sr_crypto_done: no ccbs on workunit"); + ccb->ccb_opaque = crwu; + DNPRINTF(SR_D_INTR, "%s: sr_crypto_intr: crypto_invoke %p\n", + DEVNAME(wu->swu_dis->sd_sc), crwu->cr_crp); + s = splvm(); + crypto_invoke(crwu->cr_crp); + splx(s); + return; + } + + s = splbio(); + sr_crypto_finish_io(wu); + splx(s); +} + +void +sr_crypto_finish_io(struct sr_workunit *wu) +{ + struct sr_discipline *sd = wu->swu_dis; + struct scsi_xfer *xs = wu->swu_xs; + struct sr_ccb *ccb; +#ifdef SR_DEBUG + struct sr_softc *sc = sd->sd_sc; +#endif /* SR_DEBUG */ + + splassert(IPL_BIO); + + DNPRINTF(SR_D_INTR, "%s: sr_crypto_finish_io: wu %x xs: %x\n", + DEVNAME(sc), wu, xs); + + if (wu->swu_cb_active == 1) + panic("%s: sr_crypto_finish_io", DEVNAME(sd->sd_sc)); + TAILQ_FOREACH(ccb, &wu->swu_ccb, ccb_link) { + if (ccb->ccb_opaque == NULL) + continue; + sr_crypto_wu_put(ccb->ccb_opaque); + } + + sr_scsi_done(sd, xs); +} + +int +sr_crypto_read(struct cryptop *crp) +{ + struct sr_crypto_wu *crwu = crp->crp_opaque; + struct sr_workunit *wu = crwu->cr_wu; + int s; + + DNPRINTF(SR_D_INTR, "%s: sr_crypto_read: wu %x xs: %x\n", + DEVNAME(wu->swu_dis->sd_sc), wu, wu->swu_xs); + + if (crp->crp_etype) + wu->swu_xs->error = XS_DRIVER_STUFFUP; + + s = splbio(); + sr_crypto_finish_io(wu); + splx(s); + + return (0); +} + +void +sr_crypto_hotplug(struct sr_discipline *sd, struct disk *diskp, int action) +{ + DNPRINTF(SR_D_MISC, "%s: sr_crypto_hotplug: %s %d\n", + DEVNAME(sd->sd_sc), diskp->dk_name, action); +} + +#ifdef SR_DEBUG0 +void +sr_crypto_dumpkeys(struct sr_discipline *sd) +{ + int i, j; + + printf("sr_crypto_dumpkeys:\n"); + for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) { + printf("\tscm_key[%d]: 0x", i); + for (j = 0; j < SR_CRYPTO_KEYBYTES; j++) { + printf("%02x", + sd->mds.mdd_crypto.scr_meta->scm_key[i][j]); + } + printf("\n"); + } + printf("sr_crypto_dumpkeys: runtime data keys:\n"); + for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) { + printf("\tscr_key[%d]: 0x", i); + for (j = 0; j < SR_CRYPTO_KEYBYTES; j++) { + printf("%02x", + sd->mds.mdd_crypto.scr_key[i][j]); + } + printf("\n"); + } +} +#endif /* SR_DEBUG */ diff --git a/test/test021.right.txt b/test/test021.right.txt new file mode 100644 index 000000000000..7e2cc400cddb --- /dev/null +++ b/test/test021.right.txt @@ -0,0 +1,1251 @@ +/* $OpenBSD: softraid_crypto.c,v 1.139 2020/07/13 00:06:22 kn Exp $ */ +/* + * Copyright (c) 2007 Marco Peereboom + * Copyright (c) 2008 Hans-Joerg Hoexer + * Copyright (c) 2008 Damien Miller + * Copyright (c) 2009 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "bio.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +/* + * The per-I/O data that we need to preallocate. We cannot afford to allow I/O + * to start failing when memory pressure kicks in. We can store this in the WU + * because we assert that only one ccb per WU will ever be active. + */ +struct sr_crypto_wu { + struct sr_workunit cr_wu; /* Must be first. */ + struct uio cr_uio; + struct iovec cr_iov; + struct cryptop *cr_crp; + void *cr_dmabuf; +}; + + +struct sr_crypto_wu *sr_crypto_prepare(struct sr_workunit *, int); +int sr_crypto_create_keys(struct sr_discipline *); +int sr_crypto_get_kdf(struct bioc_createraid *, + struct sr_discipline *); +int sr_crypto_decrypt(u_char *, u_char *, u_char *, size_t, int); +int sr_crypto_encrypt(u_char *, u_char *, u_char *, size_t, int); +int sr_crypto_decrypt_key(struct sr_discipline *); +int sr_crypto_change_maskkey(struct sr_discipline *, + struct sr_crypto_kdfinfo *, struct sr_crypto_kdfinfo *); +int sr_crypto_create(struct sr_discipline *, + struct bioc_createraid *, int, int64_t); +int sr_crypto_assemble(struct sr_discipline *, + struct bioc_createraid *, int, void *); +int sr_crypto_alloc_resources(struct sr_discipline *); +void sr_crypto_free_resources(struct sr_discipline *); +int sr_crypto_ioctl(struct sr_discipline *, + struct bioc_discipline *); +int sr_crypto_meta_opt_handler(struct sr_discipline *, + struct sr_meta_opt_hdr *); +void sr_crypto_write(struct cryptop *); +int sr_crypto_rw(struct sr_workunit *); +int sr_crypto_dev_rw(struct sr_workunit *, struct sr_crypto_wu *); +void sr_crypto_done(struct sr_workunit *); +void sr_crypto_read(struct cryptop *); +void sr_crypto_calculate_check_hmac_sha1(u_int8_t *, int, + u_int8_t *, int, u_char *); +void sr_crypto_hotplug(struct sr_discipline *, struct disk *, int); + +#ifdef SR_DEBUG0 +void sr_crypto_dumpkeys(struct sr_discipline *); +#endif + +/* Discipline initialisation. */ +void +sr_crypto_discipline_init(struct sr_discipline *sd) +{ + int i; + + /* Fill out discipline members. */ + sd->sd_wu_size = sizeof(struct sr_crypto_wu); + sd->sd_type = SR_MD_CRYPTO; + strlcpy(sd->sd_name, "CRYPTO", sizeof(sd->sd_name)); + sd->sd_capabilities = SR_CAP_SYSTEM_DISK | SR_CAP_AUTO_ASSEMBLE; + sd->sd_max_wu = SR_CRYPTO_NOWU; + + for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) + sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1; + + /* Setup discipline specific function pointers. */ + sd->sd_alloc_resources = sr_crypto_alloc_resources; + sd->sd_assemble = sr_crypto_assemble; + sd->sd_create = sr_crypto_create; + sd->sd_free_resources = sr_crypto_free_resources; + sd->sd_ioctl_handler = sr_crypto_ioctl; + sd->sd_meta_opt_handler = sr_crypto_meta_opt_handler; + sd->sd_scsi_rw = sr_crypto_rw; + sd->sd_scsi_done = sr_crypto_done; +} + +int +sr_crypto_create(struct sr_discipline *sd, struct bioc_createraid *bc, + int no_chunk, int64_t coerced_size) +{ + struct sr_meta_opt_item *omi; + int rv = EINVAL; + + if (no_chunk != 1) { + sr_error(sd->sd_sc, "%s requires exactly one chunk", + sd->sd_name); + goto done; + } + + if (coerced_size > SR_CRYPTO_MAXSIZE) { + sr_error(sd->sd_sc, "%s exceeds maximum size (%lli > %llu)", + sd->sd_name, coerced_size, SR_CRYPTO_MAXSIZE); + goto done; + } + + /* Create crypto optional metadata. */ + omi = malloc(sizeof(struct sr_meta_opt_item), M_DEVBUF, + M_WAITOK | M_ZERO); + omi->omi_som = malloc(sizeof(struct sr_meta_crypto), M_DEVBUF, + M_WAITOK | M_ZERO); + omi->omi_som->som_type = SR_OPT_CRYPTO; + omi->omi_som->som_length = sizeof(struct sr_meta_crypto); + SLIST_INSERT_HEAD(&sd->sd_meta_opt, omi, omi_link); + sd->mds.mdd_crypto.scr_meta = (struct sr_meta_crypto *)omi->omi_som; + sd->sd_meta->ssdi.ssd_opt_no++; + + sd->mds.mdd_crypto.key_disk = NULL; + + if (bc->bc_key_disk != NODEV) { + + /* Create a key disk. */ + if (sr_crypto_get_kdf(bc, sd)) + goto done; + sd->mds.mdd_crypto.key_disk = + sr_crypto_create_key_disk(sd, bc->bc_key_disk); + if (sd->mds.mdd_crypto.key_disk == NULL) + goto done; + sd->sd_capabilities |= SR_CAP_AUTO_ASSEMBLE; + + } else if (bc->bc_opaque_flags & BIOC_SOOUT) { + + /* No hint available yet. */ + bc->bc_opaque_status = BIOC_SOINOUT_FAILED; + rv = EAGAIN; + goto done; + + } else if (sr_crypto_get_kdf(bc, sd)) + goto done; + + /* Passphrase volumes cannot be automatically assembled. */ + if (!(bc->bc_flags & BIOC_SCNOAUTOASSEMBLE) && bc->bc_key_disk == NODEV) + goto done; + + sd->sd_meta->ssdi.ssd_size = coerced_size; + + sr_crypto_create_keys(sd); + + sd->sd_max_ccb_per_wu = no_chunk; + + rv = 0; +done: + return (rv); +} + +int +sr_crypto_assemble(struct sr_discipline *sd, struct bioc_createraid *bc, + int no_chunk, void *data) +{ + int rv = EINVAL; + + sd->mds.mdd_crypto.key_disk = NULL; + + /* Crypto optional metadata must already exist... */ + if (sd->mds.mdd_crypto.scr_meta == NULL) + goto done; + + if (data != NULL) { + /* Kernel already has mask key. */ + memcpy(sd->mds.mdd_crypto.scr_maskkey, data, + sizeof(sd->mds.mdd_crypto.scr_maskkey)); + } else if (bc->bc_key_disk != NODEV) { + /* Read the mask key from the key disk. */ + sd->mds.mdd_crypto.key_disk = + sr_crypto_read_key_disk(sd, bc->bc_key_disk); + if (sd->mds.mdd_crypto.key_disk == NULL) + goto done; + } else if (bc->bc_opaque_flags & BIOC_SOOUT) { + /* provide userland with kdf hint */ + if (bc->bc_opaque == NULL) + goto done; + + if (sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint) < + bc->bc_opaque_size) + goto done; + + if (copyout(sd->mds.mdd_crypto.scr_meta->scm_kdfhint, + bc->bc_opaque, bc->bc_opaque_size)) + goto done; + + /* we're done */ + bc->bc_opaque_status = BIOC_SOINOUT_OK; + rv = EAGAIN; + goto done; + } else if (bc->bc_opaque_flags & BIOC_SOIN) { + /* get kdf with maskkey from userland */ + if (sr_crypto_get_kdf(bc, sd)) + goto done; + } else + goto done; + + sd->sd_max_ccb_per_wu = sd->sd_meta->ssdi.ssd_chunk_no; + + rv = 0; +done: + return (rv); +} + +struct sr_crypto_wu * +sr_crypto_prepare(struct sr_workunit *wu, int encrypt) +{ + struct scsi_xfer *xs = wu->swu_xs; + struct sr_discipline *sd = wu->swu_dis; + struct sr_crypto_wu *crwu; + struct cryptodesc *crd; + int flags, i, n; + daddr_t blkno; + u_int keyndx; + + DNPRINTF(SR_D_DIS, "%s: sr_crypto_prepare wu %p encrypt %d\n", + DEVNAME(sd->sd_sc), wu, encrypt); + + crwu = (struct sr_crypto_wu *)wu; + crwu->cr_uio.uio_iovcnt = 1; + crwu->cr_uio.uio_iov->iov_len = xs->datalen; + if (xs->flags & SCSI_DATA_OUT) { + crwu->cr_uio.uio_iov->iov_base = crwu->cr_dmabuf; + memcpy(crwu->cr_uio.uio_iov->iov_base, xs->data, xs->datalen); + } else + crwu->cr_uio.uio_iov->iov_base = xs->data; + + blkno = wu->swu_blk_start; + n = xs->datalen >> DEV_BSHIFT; + + /* + * We preallocated enough crypto descs for up to MAXPHYS of I/O. + * Since there may be less than that we need to tweak the amount + * of crypto desc structures to be just long enough for our needs. + */ + KASSERT(crwu->cr_crp->crp_ndescalloc >= n); + crwu->cr_crp->crp_ndesc = n; + flags = (encrypt ? CRD_F_ENCRYPT : 0) | + CRD_F_IV_PRESENT | CRD_F_IV_EXPLICIT; + + /* + * Select crypto session based on block number. + * + * XXX - this does not handle the case where the read/write spans + * across a different key blocks (e.g. 0.5TB boundary). Currently + * this is already broken by the use of scr_key[0] below. + */ + keyndx = blkno >> SR_CRYPTO_KEY_BLKSHIFT; + crwu->cr_crp->crp_sid = sd->mds.mdd_crypto.scr_sid[keyndx]; + + crwu->cr_crp->crp_opaque = crwu; + crwu->cr_crp->crp_ilen = xs->datalen; + crwu->cr_crp->crp_alloctype = M_DEVBUF; + crwu->cr_crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_NOQUEUE; + crwu->cr_crp->crp_buf = &crwu->cr_uio; + for (i = 0; i < crwu->cr_crp->crp_ndesc; i++, blkno++) { + crd = &crwu->cr_crp->crp_desc[i]; + crd->crd_skip = i << DEV_BSHIFT; + crd->crd_len = DEV_BSIZE; + crd->crd_inject = 0; + crd->crd_flags = flags; + crd->crd_alg = sd->mds.mdd_crypto.scr_alg; + crd->crd_klen = sd->mds.mdd_crypto.scr_klen; + crd->crd_key = sd->mds.mdd_crypto.scr_key[0]; + memcpy(crd->crd_iv, &blkno, sizeof(blkno)); + } + + return (crwu); +} + +int +sr_crypto_get_kdf(struct bioc_createraid *bc, struct sr_discipline *sd) +{ + int rv = EINVAL; + struct sr_crypto_kdfinfo *kdfinfo; + + if (!(bc->bc_opaque_flags & BIOC_SOIN)) + return (rv); + if (bc->bc_opaque == NULL) + return (rv); + if (bc->bc_opaque_size != sizeof(*kdfinfo)) + return (rv); + + kdfinfo = malloc(bc->bc_opaque_size, M_DEVBUF, M_WAITOK | M_ZERO); + if (copyin(bc->bc_opaque, kdfinfo, bc->bc_opaque_size)) + goto out; + + if (kdfinfo->len != bc->bc_opaque_size) + goto out; + + /* copy KDF hint to disk meta data */ + if (kdfinfo->flags & SR_CRYPTOKDF_HINT) { + if (sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint) < + kdfinfo->genkdf.len) + goto out; + memcpy(sd->mds.mdd_crypto.scr_meta->scm_kdfhint, + &kdfinfo->genkdf, kdfinfo->genkdf.len); + } + + /* copy mask key to run-time meta data */ + if ((kdfinfo->flags & SR_CRYPTOKDF_KEY)) { + if (sizeof(sd->mds.mdd_crypto.scr_maskkey) < + sizeof(kdfinfo->maskkey)) + goto out; + memcpy(sd->mds.mdd_crypto.scr_maskkey, &kdfinfo->maskkey, + sizeof(kdfinfo->maskkey)); + } + + bc->bc_opaque_status = BIOC_SOINOUT_OK; + rv = 0; +out: + explicit_bzero(kdfinfo, bc->bc_opaque_size); + free(kdfinfo, M_DEVBUF, bc->bc_opaque_size); + + return (rv); +} + +int +sr_crypto_encrypt(u_char *p, u_char *c, u_char *key, size_t size, int alg) +{ + rijndael_ctx ctx; + int i, rv = 1; + + switch (alg) { + case SR_CRYPTOM_AES_ECB_256: + if (rijndael_set_key_enc_only(&ctx, key, 256) != 0) + goto out; + for (i = 0; i < size; i += RIJNDAEL128_BLOCK_LEN) + rijndael_encrypt(&ctx, &p[i], &c[i]); + rv = 0; + break; + default: + DNPRINTF(SR_D_DIS, "%s: unsupported encryption algorithm %d\n", + "softraid", alg); + rv = -1; + goto out; + } + +out: + explicit_bzero(&ctx, sizeof(ctx)); + return (rv); +} + +int +sr_crypto_decrypt(u_char *c, u_char *p, u_char *key, size_t size, int alg) +{ + rijndael_ctx ctx; + int i, rv = 1; + + switch (alg) { + case SR_CRYPTOM_AES_ECB_256: + if (rijndael_set_key(&ctx, key, 256) != 0) + goto out; + for (i = 0; i < size; i += RIJNDAEL128_BLOCK_LEN) + rijndael_decrypt(&ctx, &c[i], &p[i]); + rv = 0; + break; + default: + DNPRINTF(SR_D_DIS, "%s: unsupported encryption algorithm %d\n", + "softraid", alg); + rv = -1; + goto out; + } + +out: + explicit_bzero(&ctx, sizeof(ctx)); + return (rv); +} + +void +sr_crypto_calculate_check_hmac_sha1(u_int8_t *maskkey, int maskkey_size, + u_int8_t *key, int key_size, u_char *check_digest) +{ + u_char check_key[SHA1_DIGEST_LENGTH]; + HMAC_SHA1_CTX hmacctx; + SHA1_CTX shactx; + + bzero(check_key, sizeof(check_key)); + bzero(&hmacctx, sizeof(hmacctx)); + bzero(&shactx, sizeof(shactx)); + + /* k = SHA1(mask_key) */ + SHA1Init(&shactx); + SHA1Update(&shactx, maskkey, maskkey_size); + SHA1Final(check_key, &shactx); + + /* mac = HMAC_SHA1_k(unencrypted key) */ + HMAC_SHA1_Init(&hmacctx, check_key, sizeof(check_key)); + HMAC_SHA1_Update(&hmacctx, key, key_size); + HMAC_SHA1_Final(check_digest, &hmacctx); + + explicit_bzero(check_key, sizeof(check_key)); + explicit_bzero(&hmacctx, sizeof(hmacctx)); + explicit_bzero(&shactx, sizeof(shactx)); +} + +int +sr_crypto_decrypt_key(struct sr_discipline *sd) +{ + u_char check_digest[SHA1_DIGEST_LENGTH]; + int rv = 1; + + DNPRINTF(SR_D_DIS, "%s: sr_crypto_decrypt_key\n", DEVNAME(sd->sd_sc)); + + if (sd->mds.mdd_crypto.scr_meta->scm_check_alg != SR_CRYPTOC_HMAC_SHA1) + goto out; + + if (sr_crypto_decrypt((u_char *)sd->mds.mdd_crypto.scr_meta->scm_key, + (u_char *)sd->mds.mdd_crypto.scr_key, + sd->mds.mdd_crypto.scr_maskkey, sizeof(sd->mds.mdd_crypto.scr_key), + sd->mds.mdd_crypto.scr_meta->scm_mask_alg) == -1) + goto out; + +#ifdef SR_DEBUG0 + sr_crypto_dumpkeys(sd); +#endif + + /* Check that the key decrypted properly. */ + sr_crypto_calculate_check_hmac_sha1(sd->mds.mdd_crypto.scr_maskkey, + sizeof(sd->mds.mdd_crypto.scr_maskkey), + (u_int8_t *)sd->mds.mdd_crypto.scr_key, + sizeof(sd->mds.mdd_crypto.scr_key), + check_digest); + if (memcmp(sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac, + check_digest, sizeof(check_digest)) != 0) { + explicit_bzero(sd->mds.mdd_crypto.scr_key, + sizeof(sd->mds.mdd_crypto.scr_key)); + goto out; + } + + rv = 0; /* Success */ +out: + /* we don't need the mask key anymore */ + explicit_bzero(&sd->mds.mdd_crypto.scr_maskkey, + sizeof(sd->mds.mdd_crypto.scr_maskkey)); + + explicit_bzero(check_digest, sizeof(check_digest)); + + return rv; +} + +int +sr_crypto_create_keys(struct sr_discipline *sd) +{ + + DNPRINTF(SR_D_DIS, "%s: sr_crypto_create_keys\n", + DEVNAME(sd->sd_sc)); + + if (AES_MAXKEYBYTES < sizeof(sd->mds.mdd_crypto.scr_maskkey)) + return (1); + + /* XXX allow user to specify */ + sd->mds.mdd_crypto.scr_meta->scm_alg = SR_CRYPTOA_AES_XTS_256; + + /* generate crypto keys */ + arc4random_buf(sd->mds.mdd_crypto.scr_key, + sizeof(sd->mds.mdd_crypto.scr_key)); + + /* Mask the disk keys. */ + sd->mds.mdd_crypto.scr_meta->scm_mask_alg = SR_CRYPTOM_AES_ECB_256; + sr_crypto_encrypt((u_char *)sd->mds.mdd_crypto.scr_key, + (u_char *)sd->mds.mdd_crypto.scr_meta->scm_key, + sd->mds.mdd_crypto.scr_maskkey, sizeof(sd->mds.mdd_crypto.scr_key), + sd->mds.mdd_crypto.scr_meta->scm_mask_alg); + + /* Prepare key decryption check code. */ + sd->mds.mdd_crypto.scr_meta->scm_check_alg = SR_CRYPTOC_HMAC_SHA1; + sr_crypto_calculate_check_hmac_sha1(sd->mds.mdd_crypto.scr_maskkey, + sizeof(sd->mds.mdd_crypto.scr_maskkey), + (u_int8_t *)sd->mds.mdd_crypto.scr_key, + sizeof(sd->mds.mdd_crypto.scr_key), + sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac); + + /* Erase the plaintext disk keys */ + explicit_bzero(sd->mds.mdd_crypto.scr_key, + sizeof(sd->mds.mdd_crypto.scr_key)); + +#ifdef SR_DEBUG0 + sr_crypto_dumpkeys(sd); +#endif + + sd->mds.mdd_crypto.scr_meta->scm_flags = SR_CRYPTOF_KEY | + SR_CRYPTOF_KDFHINT; + + return (0); +} + +int +sr_crypto_change_maskkey(struct sr_discipline *sd, + struct sr_crypto_kdfinfo *kdfinfo1, struct sr_crypto_kdfinfo *kdfinfo2) +{ + u_char check_digest[SHA1_DIGEST_LENGTH]; + u_char *c, *p = NULL; + size_t ksz; + int rv = 1; + + DNPRINTF(SR_D_DIS, "%s: sr_crypto_change_maskkey\n", + DEVNAME(sd->sd_sc)); + + if (sd->mds.mdd_crypto.scr_meta->scm_check_alg != SR_CRYPTOC_HMAC_SHA1) + goto out; + + c = (u_char *)sd->mds.mdd_crypto.scr_meta->scm_key; + ksz = sizeof(sd->mds.mdd_crypto.scr_key); + p = malloc(ksz, M_DEVBUF, M_WAITOK | M_CANFAIL | M_ZERO); + if (p == NULL) + goto out; + + if (sr_crypto_decrypt(c, p, kdfinfo1->maskkey, ksz, + sd->mds.mdd_crypto.scr_meta->scm_mask_alg) == -1) + goto out; + +#ifdef SR_DEBUG0 + sr_crypto_dumpkeys(sd); +#endif + + sr_crypto_calculate_check_hmac_sha1(kdfinfo1->maskkey, + sizeof(kdfinfo1->maskkey), p, ksz, check_digest); + if (memcmp(sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac, + check_digest, sizeof(check_digest)) != 0) { + sr_error(sd->sd_sc, "incorrect key or passphrase"); + rv = EPERM; + goto out; + } + + /* Copy new KDF hint to metadata, if supplied. */ + if (kdfinfo2->flags & SR_CRYPTOKDF_HINT) { + if (kdfinfo2->genkdf.len > + sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint)) + goto out; + explicit_bzero(sd->mds.mdd_crypto.scr_meta->scm_kdfhint, + sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint)); + memcpy(sd->mds.mdd_crypto.scr_meta->scm_kdfhint, + &kdfinfo2->genkdf, kdfinfo2->genkdf.len); + } + + /* Mask the disk keys. */ + c = (u_char *)sd->mds.mdd_crypto.scr_meta->scm_key; + if (sr_crypto_encrypt(p, c, kdfinfo2->maskkey, ksz, + sd->mds.mdd_crypto.scr_meta->scm_mask_alg) == -1) + goto out; + + /* Prepare key decryption check code. */ + sd->mds.mdd_crypto.scr_meta->scm_check_alg = SR_CRYPTOC_HMAC_SHA1; + sr_crypto_calculate_check_hmac_sha1(kdfinfo2->maskkey, + sizeof(kdfinfo2->maskkey), (u_int8_t *)sd->mds.mdd_crypto.scr_key, + sizeof(sd->mds.mdd_crypto.scr_key), check_digest); + + /* Copy new encrypted key and HMAC to metadata. */ + memcpy(sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac, check_digest, + sizeof(sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac)); + + rv = 0; /* Success */ + +out: + if (p) { + explicit_bzero(p, ksz); + free(p, M_DEVBUF, ksz); + } + + explicit_bzero(check_digest, sizeof(check_digest)); + explicit_bzero(&kdfinfo1->maskkey, sizeof(kdfinfo1->maskkey)); + explicit_bzero(&kdfinfo2->maskkey, sizeof(kdfinfo2->maskkey)); + + return (rv); +} + +struct sr_chunk * +sr_crypto_create_key_disk(struct sr_discipline *sd, dev_t dev) +{ + struct sr_softc *sc = sd->sd_sc; + struct sr_discipline *fakesd = NULL; + struct sr_metadata *sm = NULL; + struct sr_meta_chunk *km; + struct sr_meta_opt_item *omi = NULL; + struct sr_meta_keydisk *skm; + struct sr_chunk *key_disk = NULL; + struct disklabel label; + struct vnode *vn; + char devname[32]; + int c, part, open = 0; + + /* + * Create a metadata structure on the key disk and store + * keying material in the optional metadata. + */ + + sr_meta_getdevname(sc, dev, devname, sizeof(devname)); + + /* Make sure chunk is not already in use. */ + c = sr_chunk_in_use(sc, dev); + if (c != BIOC_SDINVALID && c != BIOC_SDOFFLINE) { + sr_error(sc, "%s is already in use", devname); + goto done; + } + + /* Open device. */ + if (bdevvp(dev, &vn)) { + sr_error(sc, "cannot open key disk %s", devname); + goto done; + } + if (VOP_OPEN(vn, FREAD | FWRITE, NOCRED, curproc)) { + DNPRINTF(SR_D_META,"%s: sr_crypto_create_key_disk cannot " + "open %s\n", DEVNAME(sc), devname); + vput(vn); + goto done; + } + open = 1; /* close dev on error */ + + /* Get partition details. */ + part = DISKPART(dev); + if (VOP_IOCTL(vn, DIOCGDINFO, (caddr_t)&label, + FREAD, NOCRED, curproc)) { + DNPRINTF(SR_D_META, "%s: sr_crypto_create_key_disk ioctl " + "failed\n", DEVNAME(sc)); + goto done; + } + if (label.d_partitions[part].p_fstype != FS_RAID) { + sr_error(sc, "%s partition not of type RAID (%d)", + devname, label.d_partitions[part].p_fstype); + goto done; + } + + /* + * Create and populate chunk metadata. + */ + + key_disk = malloc(sizeof(struct sr_chunk), M_DEVBUF, M_WAITOK | M_ZERO); + km = &key_disk->src_meta; + + key_disk->src_dev_mm = dev; + key_disk->src_vn = vn; + strlcpy(key_disk->src_devname, devname, sizeof(km->scmi.scm_devname)); + key_disk->src_size = 0; + + km->scmi.scm_volid = sd->sd_meta->ssdi.ssd_level; + km->scmi.scm_chunk_id = 0; + km->scmi.scm_size = 0; + km->scmi.scm_coerced_size = 0; + strlcpy(km->scmi.scm_devname, devname, sizeof(km->scmi.scm_devname)); + memcpy(&km->scmi.scm_uuid, &sd->sd_meta->ssdi.ssd_uuid, + sizeof(struct sr_uuid)); + + sr_checksum(sc, km, &km->scm_checksum, + sizeof(struct sr_meta_chunk_invariant)); + + km->scm_status = BIOC_SDONLINE; + + /* + * Create and populate our own discipline and metadata. + */ + + sm = malloc(sizeof(struct sr_metadata), M_DEVBUF, M_WAITOK | M_ZERO); + sm->ssdi.ssd_magic = SR_MAGIC; + sm->ssdi.ssd_version = SR_META_VERSION; + sm->ssd_ondisk = 0; + sm->ssdi.ssd_vol_flags = 0; + memcpy(&sm->ssdi.ssd_uuid, &sd->sd_meta->ssdi.ssd_uuid, + sizeof(struct sr_uuid)); + sm->ssdi.ssd_chunk_no = 1; + sm->ssdi.ssd_volid = SR_KEYDISK_VOLID; + sm->ssdi.ssd_level = SR_KEYDISK_LEVEL; + sm->ssdi.ssd_size = 0; + strlcpy(sm->ssdi.ssd_vendor, "OPENBSD", sizeof(sm->ssdi.ssd_vendor)); + snprintf(sm->ssdi.ssd_product, sizeof(sm->ssdi.ssd_product), + "SR %s", "KEYDISK"); + snprintf(sm->ssdi.ssd_revision, sizeof(sm->ssdi.ssd_revision), + "%03d", SR_META_VERSION); + + fakesd = malloc(sizeof(struct sr_discipline), M_DEVBUF, + M_WAITOK | M_ZERO); + fakesd->sd_sc = sd->sd_sc; + fakesd->sd_meta = sm; + fakesd->sd_meta_type = SR_META_F_NATIVE; + fakesd->sd_vol_status = BIOC_SVONLINE; + strlcpy(fakesd->sd_name, "KEYDISK", sizeof(fakesd->sd_name)); + SLIST_INIT(&fakesd->sd_meta_opt); + + /* Add chunk to volume. */ + fakesd->sd_vol.sv_chunks = malloc(sizeof(struct sr_chunk *), M_DEVBUF, + M_WAITOK | M_ZERO); + fakesd->sd_vol.sv_chunks[0] = key_disk; + SLIST_INIT(&fakesd->sd_vol.sv_chunk_list); + SLIST_INSERT_HEAD(&fakesd->sd_vol.sv_chunk_list, key_disk, src_link); + + /* Generate mask key. */ + arc4random_buf(sd->mds.mdd_crypto.scr_maskkey, + sizeof(sd->mds.mdd_crypto.scr_maskkey)); + + /* Copy mask key to optional metadata area. */ + omi = malloc(sizeof(struct sr_meta_opt_item), M_DEVBUF, + M_WAITOK | M_ZERO); + omi->omi_som = malloc(sizeof(struct sr_meta_keydisk), M_DEVBUF, + M_WAITOK | M_ZERO); + omi->omi_som->som_type = SR_OPT_KEYDISK; + omi->omi_som->som_length = sizeof(struct sr_meta_keydisk); + skm = (struct sr_meta_keydisk *)omi->omi_som; + memcpy(&skm->skm_maskkey, sd->mds.mdd_crypto.scr_maskkey, + sizeof(skm->skm_maskkey)); + SLIST_INSERT_HEAD(&fakesd->sd_meta_opt, omi, omi_link); + fakesd->sd_meta->ssdi.ssd_opt_no++; + + /* Save metadata. */ + if (sr_meta_save(fakesd, SR_META_DIRTY)) { + sr_error(sc, "could not save metadata to %s", devname); + goto fail; + } + + goto done; + +fail: + free(key_disk, M_DEVBUF, sizeof(struct sr_chunk)); + key_disk = NULL; + +done: + free(omi, M_DEVBUF, sizeof(struct sr_meta_opt_item)); + if (fakesd && fakesd->sd_vol.sv_chunks) + free(fakesd->sd_vol.sv_chunks, M_DEVBUF, + sizeof(struct sr_chunk *)); + free(fakesd, M_DEVBUF, sizeof(struct sr_discipline)); + free(sm, M_DEVBUF, sizeof(struct sr_metadata)); + if (open) { + VOP_CLOSE(vn, FREAD | FWRITE, NOCRED, curproc); + vput(vn); + } + + return key_disk; +} + +struct sr_chunk * +sr_crypto_read_key_disk(struct sr_discipline *sd, dev_t dev) +{ + struct sr_softc *sc = sd->sd_sc; + struct sr_metadata *sm = NULL; + struct sr_meta_opt_item *omi, *omi_next; + struct sr_meta_opt_hdr *omh; + struct sr_meta_keydisk *skm; + struct sr_meta_opt_head som; + struct sr_chunk *key_disk = NULL; + struct disklabel label; + struct vnode *vn = NULL; + char devname[32]; + int c, part, open = 0; + + /* + * Load a key disk and load keying material into memory. + */ + + SLIST_INIT(&som); + + sr_meta_getdevname(sc, dev, devname, sizeof(devname)); + + /* Make sure chunk is not already in use. */ + c = sr_chunk_in_use(sc, dev); + if (c != BIOC_SDINVALID && c != BIOC_SDOFFLINE) { + sr_error(sc, "%s is already in use", devname); + goto done; + } + + /* Open device. */ + if (bdevvp(dev, &vn)) { + sr_error(sc, "cannot open key disk %s", devname); + goto done; + } + if (VOP_OPEN(vn, FREAD, NOCRED, curproc)) { + DNPRINTF(SR_D_META,"%s: sr_crypto_read_key_disk cannot " + "open %s\n", DEVNAME(sc), devname); + vput(vn); + goto done; + } + open = 1; /* close dev on error */ + + /* Get partition details. */ + part = DISKPART(dev); + if (VOP_IOCTL(vn, DIOCGDINFO, (caddr_t)&label, FREAD, + NOCRED, curproc)) { + DNPRINTF(SR_D_META, "%s: sr_crypto_read_key_disk ioctl " + "failed\n", DEVNAME(sc)); + goto done; + } + if (label.d_partitions[part].p_fstype != FS_RAID) { + sr_error(sc, "%s partition not of type RAID (%d)", + devname, label.d_partitions[part].p_fstype); + goto done; + } + + /* + * Read and validate key disk metadata. + */ + sm = malloc(SR_META_SIZE * DEV_BSIZE, M_DEVBUF, M_WAITOK | M_ZERO); + if (sr_meta_native_read(sd, dev, sm, NULL)) { + sr_error(sc, "native bootprobe could not read native metadata"); + goto done; + } + + if (sr_meta_validate(sd, dev, sm, NULL)) { + DNPRINTF(SR_D_META, "%s: invalid metadata\n", + DEVNAME(sc)); + goto done; + } + + /* Make sure this is a key disk. */ + if (sm->ssdi.ssd_level != SR_KEYDISK_LEVEL) { + sr_error(sc, "%s is not a key disk", devname); + goto done; + } + + /* Construct key disk chunk. */ + key_disk = malloc(sizeof(struct sr_chunk), M_DEVBUF, M_WAITOK | M_ZERO); + key_disk->src_dev_mm = dev; + key_disk->src_vn = vn; + key_disk->src_size = 0; + + memcpy(&key_disk->src_meta, (struct sr_meta_chunk *)(sm + 1), + sizeof(key_disk->src_meta)); + + /* Read mask key from optional metadata. */ + sr_meta_opt_load(sc, sm, &som); + SLIST_FOREACH(omi, &som, omi_link) { + omh = omi->omi_som; + if (omh->som_type == SR_OPT_KEYDISK) { + skm = (struct sr_meta_keydisk *)omh; + memcpy(sd->mds.mdd_crypto.scr_maskkey, &skm->skm_maskkey, + sizeof(sd->mds.mdd_crypto.scr_maskkey)); + } else if (omh->som_type == SR_OPT_CRYPTO) { + /* Original keydisk format with key in crypto area. */ + memcpy(sd->mds.mdd_crypto.scr_maskkey, + omh + sizeof(struct sr_meta_opt_hdr), + sizeof(sd->mds.mdd_crypto.scr_maskkey)); + } + } + + open = 0; + +done: + for (omi = SLIST_FIRST(&som); omi != NULL; omi = omi_next) { + omi_next = SLIST_NEXT(omi, omi_link); + free(omi->omi_som, M_DEVBUF, 0); + free(omi, M_DEVBUF, sizeof(struct sr_meta_opt_item)); + } + + free(sm, M_DEVBUF, SR_META_SIZE * DEV_BSIZE); + + if (vn && open) { + VOP_CLOSE(vn, FREAD, NOCRED, curproc); + vput(vn); + } + + return key_disk; +} + +static void +sr_crypto_free_sessions(struct sr_discipline *sd) +{ + u_int i; + + for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) { + if (sd->mds.mdd_crypto.scr_sid[i] != (u_int64_t)-1) { + crypto_freesession(sd->mds.mdd_crypto.scr_sid[i]); + sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1; + } + } +} + +int +sr_crypto_alloc_resources(struct sr_discipline *sd) +{ + struct sr_workunit *wu; + struct sr_crypto_wu *crwu; + struct cryptoini cri; + u_int num_keys, i; + + DNPRINTF(SR_D_DIS, "%s: sr_crypto_alloc_resources\n", + DEVNAME(sd->sd_sc)); + + sd->mds.mdd_crypto.scr_alg = CRYPTO_AES_XTS; + switch (sd->mds.mdd_crypto.scr_meta->scm_alg) { + case SR_CRYPTOA_AES_XTS_128: + sd->mds.mdd_crypto.scr_klen = 256; + break; + case SR_CRYPTOA_AES_XTS_256: + sd->mds.mdd_crypto.scr_klen = 512; + break; + default: + sr_error(sd->sd_sc, "unknown crypto algorithm"); + return (EINVAL); + } + + for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) + sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1; + + if (sr_wu_alloc(sd)) { + sr_error(sd->sd_sc, "unable to allocate work units"); + return (ENOMEM); + } + if (sr_ccb_alloc(sd)) { + sr_error(sd->sd_sc, "unable to allocate CCBs"); + return (ENOMEM); + } + if (sr_crypto_decrypt_key(sd)) { + sr_error(sd->sd_sc, "incorrect key or passphrase"); + return (EPERM); + } + + /* + * For each work unit allocate the uio, iovec and crypto structures. + * These have to be allocated now because during runtime we cannot + * fail an allocation without failing the I/O (which can cause real + * problems). + */ + TAILQ_FOREACH(wu, &sd->sd_wu, swu_next) { + crwu = (struct sr_crypto_wu *)wu; + crwu->cr_uio.uio_iov = &crwu->cr_iov; + crwu->cr_dmabuf = dma_alloc(MAXPHYS, PR_WAITOK); + crwu->cr_crp = crypto_getreq(MAXPHYS >> DEV_BSHIFT); + if (crwu->cr_crp == NULL) + return (ENOMEM); + } + + memset(&cri, 0, sizeof(cri)); + cri.cri_alg = sd->mds.mdd_crypto.scr_alg; + cri.cri_klen = sd->mds.mdd_crypto.scr_klen; + + /* Allocate a session for every 2^SR_CRYPTO_KEY_BLKSHIFT blocks. */ + num_keys = ((sd->sd_meta->ssdi.ssd_size - 1) >> + SR_CRYPTO_KEY_BLKSHIFT) + 1; + if (num_keys > SR_CRYPTO_MAXKEYS) + return (EFBIG); + for (i = 0; i < num_keys; i++) { + cri.cri_key = sd->mds.mdd_crypto.scr_key[i]; + if (crypto_newsession(&sd->mds.mdd_crypto.scr_sid[i], + &cri, 0) != 0) { + sr_crypto_free_sessions(sd); + return (EINVAL); + } + } + + sr_hotplug_register(sd, sr_crypto_hotplug); + + return (0); +} + +void +sr_crypto_free_resources(struct sr_discipline *sd) +{ + struct sr_workunit *wu; + struct sr_crypto_wu *crwu; + + DNPRINTF(SR_D_DIS, "%s: sr_crypto_free_resources\n", + DEVNAME(sd->sd_sc)); + + if (sd->mds.mdd_crypto.key_disk != NULL) { + explicit_bzero(sd->mds.mdd_crypto.key_disk, + sizeof(*sd->mds.mdd_crypto.key_disk)); + free(sd->mds.mdd_crypto.key_disk, M_DEVBUF, + sizeof(*sd->mds.mdd_crypto.key_disk)); + } + + sr_hotplug_unregister(sd, sr_crypto_hotplug); + + sr_crypto_free_sessions(sd); + + TAILQ_FOREACH(wu, &sd->sd_wu, swu_next) { + crwu = (struct sr_crypto_wu *)wu; + if (crwu->cr_dmabuf) + dma_free(crwu->cr_dmabuf, MAXPHYS); + if (crwu->cr_crp) + crypto_freereq(crwu->cr_crp); + } + + sr_wu_free(sd); + sr_ccb_free(sd); +} + +int +sr_crypto_ioctl(struct sr_discipline *sd, struct bioc_discipline *bd) +{ + struct sr_crypto_kdfpair kdfpair; + struct sr_crypto_kdfinfo kdfinfo1, kdfinfo2; + int size, rv = 1; + + DNPRINTF(SR_D_IOCTL, "%s: sr_crypto_ioctl %u\n", + DEVNAME(sd->sd_sc), bd->bd_cmd); + + switch (bd->bd_cmd) { + case SR_IOCTL_GET_KDFHINT: + + /* Get KDF hint for userland. */ + size = sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint); + if (bd->bd_data == NULL || bd->bd_size > size) + goto bad; + if (copyout(sd->mds.mdd_crypto.scr_meta->scm_kdfhint, + bd->bd_data, bd->bd_size)) + goto bad; + + rv = 0; + + break; + + case SR_IOCTL_CHANGE_PASSPHRASE: + + /* Attempt to change passphrase. */ + + size = sizeof(kdfpair); + if (bd->bd_data == NULL || bd->bd_size > size) + goto bad; + if (copyin(bd->bd_data, &kdfpair, size)) + goto bad; + + size = sizeof(kdfinfo1); + if (kdfpair.kdfinfo1 == NULL || kdfpair.kdfsize1 > size) + goto bad; + if (copyin(kdfpair.kdfinfo1, &kdfinfo1, size)) + goto bad; + + size = sizeof(kdfinfo2); + if (kdfpair.kdfinfo2 == NULL || kdfpair.kdfsize2 > size) + goto bad; + if (copyin(kdfpair.kdfinfo2, &kdfinfo2, size)) + goto bad; + + if (sr_crypto_change_maskkey(sd, &kdfinfo1, &kdfinfo2)) + goto bad; + + /* Save metadata to disk. */ + rv = sr_meta_save(sd, SR_META_DIRTY); + + break; + } + +bad: + explicit_bzero(&kdfpair, sizeof(kdfpair)); + explicit_bzero(&kdfinfo1, sizeof(kdfinfo1)); + explicit_bzero(&kdfinfo2, sizeof(kdfinfo2)); + + return (rv); +} + +int +sr_crypto_meta_opt_handler(struct sr_discipline *sd, struct sr_meta_opt_hdr *om) +{ + int rv = EINVAL; + + if (om->som_type == SR_OPT_CRYPTO) { + sd->mds.mdd_crypto.scr_meta = (struct sr_meta_crypto *)om; + rv = 0; + } + + return (rv); +} + +int +sr_crypto_rw(struct sr_workunit *wu) +{ + struct sr_crypto_wu *crwu; + daddr_t blkno; + int rv = 0; + + DNPRINTF(SR_D_DIS, "%s: sr_crypto_rw wu %p\n", + DEVNAME(wu->swu_dis->sd_sc), wu); + + if (sr_validate_io(wu, &blkno, "sr_crypto_rw")) + return (1); + + if (wu->swu_xs->flags & SCSI_DATA_OUT) { + crwu = sr_crypto_prepare(wu, 1); + crwu->cr_crp->crp_callback = sr_crypto_write; + rv = crypto_dispatch(crwu->cr_crp); + if (rv == 0) + rv = crwu->cr_crp->crp_etype; + } else + rv = sr_crypto_dev_rw(wu, NULL); + + return (rv); +} + +void +sr_crypto_write(struct cryptop *crp) +{ + struct sr_crypto_wu *crwu = crp->crp_opaque; + struct sr_workunit *wu = &crwu->cr_wu; + int s; + + DNPRINTF(SR_D_INTR, "%s: sr_crypto_write: wu %p xs: %p\n", + DEVNAME(wu->swu_dis->sd_sc), wu, wu->swu_xs); + + if (crp->crp_etype) { + /* fail io */ + wu->swu_xs->error = XS_DRIVER_STUFFUP; + s = splbio(); + sr_scsi_done(wu->swu_dis, wu->swu_xs); + splx(s); + } + + sr_crypto_dev_rw(wu, crwu); +} + +int +sr_crypto_dev_rw(struct sr_workunit *wu, struct sr_crypto_wu *crwu) +{ + struct sr_discipline *sd = wu->swu_dis; + struct scsi_xfer *xs = wu->swu_xs; + struct sr_ccb *ccb; + struct uio *uio; + daddr_t blkno; + + blkno = wu->swu_blk_start; + + ccb = sr_ccb_rw(sd, 0, blkno, xs->datalen, xs->data, xs->flags, 0); + if (!ccb) { + /* should never happen but handle more gracefully */ + printf("%s: %s: too many ccbs queued\n", + DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname); + goto bad; + } + if (!ISSET(xs->flags, SCSI_DATA_IN)) { + uio = crwu->cr_crp->crp_buf; + ccb->ccb_buf.b_data = uio->uio_iov->iov_base; + ccb->ccb_opaque = crwu; + } + sr_wu_enqueue_ccb(wu, ccb); + sr_schedule_wu(wu); + + return (0); + +bad: + /* wu is unwound by sr_wu_put */ + if (crwu) + crwu->cr_crp->crp_etype = EINVAL; + return (1); +} + +void +sr_crypto_done(struct sr_workunit *wu) +{ + struct scsi_xfer *xs = wu->swu_xs; + struct sr_crypto_wu *crwu; + int s; + + /* If this was a successful read, initiate decryption of the data. */ + if (ISSET(xs->flags, SCSI_DATA_IN) && xs->error == XS_NOERROR) { + crwu = sr_crypto_prepare(wu, 0); + crwu->cr_crp->crp_callback = sr_crypto_read; + DNPRINTF(SR_D_INTR, "%s: sr_crypto_done: crypto_dispatch %p\n", + DEVNAME(wu->swu_dis->sd_sc), crwu->cr_crp); + crypto_dispatch(crwu->cr_crp); + return; + } + + s = splbio(); + sr_scsi_done(wu->swu_dis, wu->swu_xs); + splx(s); +} + +void +sr_crypto_read(struct cryptop *crp) +{ + struct sr_crypto_wu *crwu = crp->crp_opaque; + struct sr_workunit *wu = &crwu->cr_wu; + int s; + + DNPRINTF(SR_D_INTR, "%s: sr_crypto_read: wu %p xs: %p\n", + DEVNAME(wu->swu_dis->sd_sc), wu, wu->swu_xs); + + if (crp->crp_etype) + wu->swu_xs->error = XS_DRIVER_STUFFUP; + + s = splbio(); + sr_scsi_done(wu->swu_dis, wu->swu_xs); + splx(s); +} + +void +sr_crypto_hotplug(struct sr_discipline *sd, struct disk *diskp, int action) +{ + DNPRINTF(SR_D_MISC, "%s: sr_crypto_hotplug: %s %d\n", + DEVNAME(sd->sd_sc), diskp->dk_name, action); +} + +#ifdef SR_DEBUG0 +void +sr_crypto_dumpkeys(struct sr_discipline *sd) +{ + int i, j; + + printf("sr_crypto_dumpkeys:\n"); + for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) { + printf("\tscm_key[%d]: 0x", i); + for (j = 0; j < SR_CRYPTO_KEYBYTES; j++) { + printf("%02x", + sd->mds.mdd_crypto.scr_meta->scm_key[i][j]); + } + printf("\n"); + } + printf("sr_crypto_dumpkeys: runtime data keys:\n"); + for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) { + printf("\tscr_key[%d]: 0x", i); + for (j = 0; j < SR_CRYPTO_KEYBYTES; j++) { + printf("%02x", + sd->mds.mdd_crypto.scr_key[i][j]); + } + printf("\n"); + } +} +#endif /* SR_DEBUG */ diff --git a/test/test101.left-P.txt b/test/test101.left-P.txt new file mode 100644 index 000000000000..fd113b0f7150 --- /dev/null +++ b/test/test101.left-P.txt @@ -0,0 +1,7 @@ +A +B +C +A +B +B +A diff --git a/test/test101.right-P.txt b/test/test101.right-P.txt new file mode 100644 index 000000000000..0075e6d23de0 --- /dev/null +++ b/test/test101.right-P.txt @@ -0,0 +1,6 @@ +C +B +A +B +A +C diff --git a/test/test102.left-P.txt b/test/test102.left-P.txt new file mode 100644 index 000000000000..de77f56f2d47 --- /dev/null +++ b/test/test102.left-P.txt @@ -0,0 +1,10 @@ +A +B +C +A +B +B +A +X +Y +Z diff --git a/test/test102.right-P.txt b/test/test102.right-P.txt new file mode 100644 index 000000000000..a9b4b8b851dd --- /dev/null +++ b/test/test102.right-P.txt @@ -0,0 +1,9 @@ +C +B +A +B +A +C +X +Z +Q diff --git a/test/test103.left-P.txt b/test/test103.left-P.txt new file mode 100644 index 000000000000..940532533944 --- /dev/null +++ b/test/test103.left-P.txt @@ -0,0 +1,5 @@ +a +b +c +d +e diff --git a/test/test103.right-P.txt b/test/test103.right-P.txt new file mode 100644 index 000000000000..d9f266e14574 --- /dev/null +++ b/test/test103.right-P.txt @@ -0,0 +1,4 @@ +x +b +c +y diff --git a/test/test104.left-P.txt b/test/test104.left-P.txt new file mode 100644 index 000000000000..72d95cf6331a --- /dev/null +++ b/test/test104.left-P.txt @@ -0,0 +1,14 @@ +void Chunk_copy(Chunk *src, size_t src_start, Chunk *dst, size_t dst_start, size_t n) +{ + if (!Chunk_bounds_check(src, src_start, n)) return; + if (!Chunk_bounds_check(dst, dst_start, n)) return; + + memcpy(dst->data + dst_start, src->data + src_start, n); +} + +int Chunk_bounds_check(Chunk *chunk, size_t start, size_t n) +{ + if (chunk == NULL) return 0; + + return start <= chunk->length && n <= chunk->length - start; +} diff --git a/test/test104.right-P.txt b/test/test104.right-P.txt new file mode 100644 index 000000000000..cfe8f2ed6be0 --- /dev/null +++ b/test/test104.right-P.txt @@ -0,0 +1,14 @@ +int Chunk_bounds_check(Chunk *chunk, size_t start, size_t n) +{ + if (chunk == NULL) return 0; + + return start <= chunk->length && n <= chunk->length - start; +} + +void Chunk_copy(Chunk *src, size_t src_start, Chunk *dst, size_t dst_start, size_t n) +{ + if (!Chunk_bounds_check(src, src_start, n)) return; + if (!Chunk_bounds_check(dst, dst_start, n)) return; + + memcpy(dst->data + dst_start, src->data + src_start, n); +} diff --git a/test/test105.left-P.txt b/test/test105.left-P.txt new file mode 100644 index 000000000000..b77fc41c4c87 --- /dev/null +++ b/test/test105.left-P.txt @@ -0,0 +1,7 @@ +David Axelrod +Electric Prunes +Gil Scott Heron +The Slits +Faust +The Sonics +The Sonics diff --git a/test/test105.right-P.txt b/test/test105.right-P.txt new file mode 100644 index 000000000000..2480cecfba48 --- /dev/null +++ b/test/test105.right-P.txt @@ -0,0 +1,7 @@ +The Slits +Gil Scott Heron +David Axelrod +Electric Prunes +Faust +The Sonics +The Sonics diff --git a/test/test106.left-P.txt b/test/test106.left-P.txt new file mode 100644 index 000000000000..e01fce04d5ef --- /dev/null +++ b/test/test106.left-P.txt @@ -0,0 +1,25 @@ +Below is an example license to be used for new code in OpenBSD, +modeled after the ISC license. + +It is important to specify the year of the copyright. Additional years +should be separated by a comma, e.g. + Copyright (c) 2003, 2004 + +If you add extra text to the body of the license, be careful not to +add further restrictions. + +/* + * Copyright (c) CCYY YOUR NAME HERE + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/test/test106.right-P.txt b/test/test106.right-P.txt new file mode 100644 index 000000000000..40a0f253dd2e --- /dev/null +++ b/test/test106.right-P.txt @@ -0,0 +1,25 @@ +Below is an example license to be used for new code in OpenBSD, +modeled after the ISC license. + +It is important to specify the year of the copyright. Additional years +should be separated by a comma, e.g. + Copyright (c) 2003, 2004, 2005 + +If you add extra text to the body of the license, be careful not to +add further restrictions. + +/* + * Copyright (c) CCYY YOUR NAME HERE + * + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +An extra line diff --git a/test/test107.left-P.txt b/test/test107.left-P.txt new file mode 100644 index 000000000000..587be6b4c3f9 --- /dev/null +++ b/test/test107.left-P.txt @@ -0,0 +1 @@ +x diff --git a/test/test107.right-P.txt b/test/test107.right-P.txt new file mode 100644 index 000000000000..47b0ccb04734 --- /dev/null +++ b/test/test107.right-P.txt @@ -0,0 +1 @@ +abcdx diff --git a/test/test108.left-P.txt b/test/test108.left-P.txt new file mode 100644 index 000000000000..587be6b4c3f9 --- /dev/null +++ b/test/test108.left-P.txt @@ -0,0 +1 @@ +x diff --git a/test/test108.right-P.txt b/test/test108.right-P.txt new file mode 100644 index 000000000000..70b67eef4500 --- /dev/null +++ b/test/test108.right-P.txt @@ -0,0 +1,6 @@ +x +a +b +c +d +x diff --git a/test/test109.left-P.txt b/test/test109.left-P.txt new file mode 100644 index 000000000000..e4e5238f8e5d --- /dev/null +++ b/test/test109.left-P.txt @@ -0,0 +1,3 @@ +x +a +b diff --git a/test/test109.right-P.txt b/test/test109.right-P.txt new file mode 100644 index 000000000000..3a4386800dba --- /dev/null +++ b/test/test109.right-P.txt @@ -0,0 +1,10 @@ +x +a +b +c +d +e +f +x +a +b diff --git a/test/test110.left-P.txt b/test/test110.left-P.txt new file mode 100644 index 000000000000..f68ae6a8ceaa --- /dev/null +++ b/test/test110.left-P.txt @@ -0,0 +1,14197 @@ +/* $OpenBSD: usbdevs_data.h,v 1.715 2020/01/20 07:09:11 jsg Exp $ */ + +/* + * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. + * + * generated from: + * OpenBSD: usbdevs,v 1.709 2020/01/20 07:08:20 jsg Exp + */ +/* $NetBSD: usbdevs,v 1.322 2003/05/10 17:47:14 hamajima Exp $ */ + +/* + * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Lennart Augustsson (lennart@augustsson.net) at + * Carlstedt Research & Technology. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Descriptions of known vendors and devices ("products"). + */ +struct usb_known_vendor { + u_int16_t vendor; + char *vendorname; +}; + +struct usb_known_product { + u_int16_t vendor; + u_int16_t product; + char *productname; +}; + +const struct usb_known_product usb_known_products[] = { + { + USB_VENDOR_3COM, USB_PRODUCT_3COM_HOMECONN, + "HomeConnect", + }, + { + USB_VENDOR_3COM, USB_PRODUCT_3COM_3CREB96, + "Bluetooth", + }, + { + USB_VENDOR_3COM, USB_PRODUCT_3COM_3C19250, + "3C19250 Ethernet", + }, + { + USB_VENDOR_3COM, USB_PRODUCT_3COM_3CRSHEW696, + "3CRSHEW696", + }, + { + USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460, + "HomeConnect 3C460", + }, + { + USB_VENDOR_3COM, USB_PRODUCT_3COM_USR56K, + "U.S.Robotics 56000", + }, + { + USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460B, + "HomeConnect 3C460B", + }, + { + USB_VENDOR_3COM2, USB_PRODUCT_3COM2_3CRUSB10075, + "3CRUSB10075", + }, + { + USB_VENDOR_3COM3, USB_PRODUCT_3COM3_AR5523_1, + "AR5523", + }, + { + USB_VENDOR_3COM3, USB_PRODUCT_3COM3_AR5523_2, + "AR5523", + }, + { + USB_VENDOR_3COM3, USB_PRODUCT_3COM3_AR5523_3, + "AR5523", + }, + { + USB_VENDOR_3COMUSR, USB_PRODUCT_3COMUSR_OFFICECONN, + "3Com OfficeConnect Analog Modem", + }, + { + USB_VENDOR_3COMUSR, USB_PRODUCT_3COMUSR_USRISDN, + "3Com U.S. Robotics Pro ISDN TA", + }, + { + USB_VENDOR_3COMUSR, USB_PRODUCT_3COMUSR_HOMECONN, + "3Com HomeConnect", + }, + { + USB_VENDOR_3COMUSR, USB_PRODUCT_3COMUSR_USR56K, + "U.S.Robotics 56000", + }, + { + USB_VENDOR_ABBOTT, USB_PRODUCT_ABBOTT_STEREO_PLUG, + "Stereo Plug Cable", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX1, + "XX1", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX2, + "XX2", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2770, + "RT2770", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2870, + "RT2870", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT3070, + "RT3070", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT3071, + "RT3071", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT3072, + "RT3072", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_URE450, + "URE450 Ethernet", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UFE1000, + "UFE1000 Fast Ethernet", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_DSB650TX_PNA, + "1/10/100 Ethernet", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX4, + "XX4", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX5, + "XX5", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX6, + "XX6", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX7, + "XX7", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_LCS8138TX, + "LCS-8138TX", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX8, + "XX8", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX9, + "XX9", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UF200, + "UF200 Ethernet", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_WL54, + "WL54", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8192CU, + "RTL8192CU", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8188EU, + "RTL8188EU", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8188CU_1, + "RTL8188CU", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8188CU_2, + "RTL8188CU", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX10, + "XX10", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_BWU613, + "BWU613", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_HWU54DM, + "HWU54DM", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_2, + "RT2573", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_3, + "RT2573", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_4, + "RT2573", + }, + { + USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_WUG2700, + "WUG2700", + }, + { + USB_VENDOR_ABOCOM2, USB_PRODUCT_ABOCOM2_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_USB320_EC, + "USB320-EC Ethernet", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_2664W, + "2664W", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_111, + "T-Sinus 111 WLAN", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SMCWUSBG, + "SMCWUSB-G", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SMCWUSBTG2, + "SMCWUSBT-G2", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SMCWUSBTG2_NF, + "SMCWUSBT-G2", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_PRISM_GT, + "PrismGT USB 2.0 WLAN", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SS1001, + "SpeedStream Ethernet", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT2870_2, + "RT2870", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070, + "RT3070", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT2770, + "RT2770", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT2870_3, + "RT2870", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT2870_5, + "RT2870", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_4, + "RT3070", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT2870_4, + "RT2870", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_1, + "RT3070", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_2, + "RT3070", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_6, + "RT3070", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_AR9280, + "AR9280+AR7010", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT2870_1, + "RT2870", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RTL8192SU, + "RTL8192SU", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_3, + "RT3070", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RT3070_5, + "RT3070", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_ZD1211B, + "ZD1211B", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_WN4501H_LF_IR, + "WN4501H-LF-IR", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_WUS201, + "WUS-201", + }, + { + USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_WN7512, + "WN7512", + }, + { + USB_VENDOR_ACEECA, USB_PRODUCT_ACEECA_MEZ1000, + "MEZ1000 RDA", + }, + { + USB_VENDOR_ACERCM, USB_PRODUCT_ACERCM_EP1427X2, + "EP-1427X-2 Ethernet", + }, + { + USB_VENDOR_ACERLABS, USB_PRODUCT_ACERLABS_M5632, + "USB 2.0 Data Link", + }, + { + USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_C310U, + "Acerscan C310U", + }, + { + USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_320U, + "Acerscan 320U", + }, + { + USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_640U, + "Acerscan 640U", + }, + { + USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_620U, + "Acerscan 620U", + }, + { + USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ATAPI, + "ATA/ATAPI", + }, + { + USB_VENDOR_ACERP, USB_PRODUCT_ACERP_AWL300, + "AWL300", + }, + { + USB_VENDOR_ACERP, USB_PRODUCT_ACERP_AWL400, + "AWL400", + }, + { + USB_VENDOR_ACERW, USB_PRODUCT_ACERW_WARPLINK, + "Warplink", + }, + { + USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_PRISM_25, + "Prism2.5 WLAN", + }, + { + USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_PRISM_25A, + "Prism2.5 WLAN A", + }, + { + USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_AR9287, + "AR9287+AR7010", + }, + { + USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_FREELAN, + "ROPEX FreeLan 802.11b", + }, + { + USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_802UAT1, + "802UAT1", + }, + { + USB_VENDOR_ACTISYS, USB_PRODUCT_ACTISYS_IR2000U, + "ACT-IR2000U FIR", + }, + { + USB_VENDOR_ACTIVEWIRE, USB_PRODUCT_ACTIVEWIRE_IOBOARD, + "I/O Board", + }, + { + USB_VENDOR_ACTIVEWIRE, USB_PRODUCT_ACTIVEWIRE_IOBOARD_FW1, + "I/O Board, rev. 1", + }, + { + USB_VENDOR_ADAPTEC, USB_PRODUCT_ADAPTEC_AWN8020, + "AWN-8020 WLAN", + }, + { + USB_VENDOR_ADDONICS2, USB_PRODUCT_ADDONICS2_205, + "Cable 205", + }, + { + USB_VENDOR_ADDTRON, USB_PRODUCT_ADDTRON_AWU120, + "AWU-120", + }, + { + USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_4, + "AN986A Ethernet", + }, + { + USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUS, + "AN986 Ethernet", + }, + { + USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII, + "AN8511 Ethernet", + }, + { + USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_2, + "AN8513 Ethernet", + }, + { + USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_3, + "AN8515 Ethernet", + }, + { + USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BT, + "UBS-10BT Ethernet", + }, + { + USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BTX, + "UBS-10BT Ethernet", + }, + { + USB_VENDOR_AEI, USB_PRODUCT_AEI_FASTETHERNET, + "Fast Ethernet", + }, + { + USB_VENDOR_AGATE, USB_PRODUCT_AGATE_QDRIVE, + "Q-Drive", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1212U, + "SnapScan 1212U", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1236U, + "SnapScan 1236U", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANTOUCH, + "SnapScan Touch", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1212U2, + "SnapScan 1212U", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE40, + "SnapScan e40", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE50, + "SnapScan e50", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE20, + "SnapScan e20", + }, + { + USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE25, + "SnapScan e25", + }, + { + USB_V