lsusb: add fallback names for 'lsusb -v' output

Previously the -v output would not show the vendor/product names if they
were not in the hwdb.  Change that to look in sysfs as well if the
database does not have a string, as that's what the non-v version does.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Greg Kroah-Hartman 2023-10-30 12:26:33 +01:00
parent a8044d965c
commit 0cc65720ad
4 changed files with 41 additions and 35 deletions

View File

@ -11,6 +11,7 @@
#include <unistd.h>
#include <stddef.h>
#include <libusb.h>
#include "list.h"
#include "lsusb.h"
#include "names.h"

37
lsusb.c
View File

@ -274,9 +274,8 @@ static void dump_device(
char mfg[128] = {0}, prod[128] = {0}, serial[128] = {0};
char sysfs_name[PATH_MAX];
get_vendor_string(vendor, sizeof(vendor), descriptor->idVendor);
get_product_string(product, sizeof(product),
descriptor->idVendor, descriptor->idProduct);
get_vendor_product_with_fallback(vendor, sizeof(vendor),
product, sizeof(product), dev);
get_class_string(cls, sizeof(cls), descriptor->bDeviceClass);
get_subclass_string(subcls, sizeof(subcls),
descriptor->bDeviceClass, descriptor->bDeviceSubClass);
@ -3599,38 +3598,6 @@ static void dumpdev(libusb_device *dev)
/* ---------------------------------------------------------------------- */
/*
* Attempt to get friendly vendor and product names from the udev hwdb. If
* either or both are not present, instead populate those from the device's
* own string descriptors.
*/
static void get_vendor_product_with_fallback(char *vendor, int vendor_len,
char *product, int product_len,
libusb_device *dev)
{
struct libusb_device_descriptor desc;
char sysfs_name[PATH_MAX];
bool have_vendor, have_product;
libusb_get_device_descriptor(dev, &desc);
have_vendor = !!get_vendor_string(vendor, vendor_len, desc.idVendor);
have_product = !!get_product_string(product, product_len,
desc.idVendor, desc.idProduct);
if (have_vendor && have_product)
return;
if (get_sysfs_name(sysfs_name, sizeof(sysfs_name), dev) >= 0) {
if (!have_vendor)
if (!read_sysfs_prop(vendor, vendor_len, sysfs_name, "manufacturer"))
strncpy(vendor, "[unknown]", vendor_len);
if (!have_product)
if (!read_sysfs_prop(product, product_len, sysfs_name, "product"))
strncpy(product, "[unknown]", product_len);
}
}
static int dump_one_device(libusb_context *ctx, const char *path)
{
libusb_device *dev;

35
names.c
View File

@ -20,11 +20,14 @@
#include <unistd.h>
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
#include <libusb.h>
#include <libudev.h>
#include "usb-spec.h"
#include "names.h"
#include "sysfs.h"
#define HASH1 0x10
@ -232,6 +235,38 @@ int get_subclass_string(char *buf, size_t size, uint8_t cls, uint8_t subcls)
return snprintf(buf, size, "%s", cp);
}
/*
* Attempt to get friendly vendor and product names from the udev hwdb. If
* either or both are not present, instead populate those from the device's
* own string descriptors.
*/
void get_vendor_product_with_fallback(char *vendor, int vendor_len,
char *product, int product_len,
libusb_device *dev)
{
struct libusb_device_descriptor desc;
char sysfs_name[PATH_MAX];
bool have_vendor, have_product;
libusb_get_device_descriptor(dev, &desc);
have_vendor = !!get_vendor_string(vendor, vendor_len, desc.idVendor);
have_product = !!get_product_string(product, product_len,
desc.idVendor, desc.idProduct);
if (have_vendor && have_product)
return;
if (get_sysfs_name(sysfs_name, sizeof(sysfs_name), dev) >= 0) {
if (!have_vendor)
if (!read_sysfs_prop(vendor, vendor_len, sysfs_name, "manufacturer"))
strncpy(vendor, "[unknown]", vendor_len);
if (!have_product)
if (!read_sysfs_prop(product, product_len, sysfs_name, "product"))
strncpy(product, "[unknown]", product_len);
}
}
/* ---------------------------------------------------------------------- */
static int hash_audioterminal(struct audioterminal *at)

View File

@ -31,6 +31,9 @@ extern int get_vendor_string(char *buf, size_t size, uint16_t vid);
extern int get_product_string(char *buf, size_t size, uint16_t vid, uint16_t pid);
extern int get_class_string(char *buf, size_t size, uint8_t cls);
extern int get_subclass_string(char *buf, size_t size, uint8_t cls, uint8_t subcls);
extern void get_vendor_product_with_fallback(char *vendor, int vendor_len,
char *product, int product_len,
libusb_device *dev);
extern int names_init(void);
extern void names_exit(void);