Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144967501
D48974.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D48974.diff
View Options
diff --git a/usr.sbin/usbconfig/dump.h b/usr.sbin/usbconfig/dump.h
--- a/usr.sbin/usbconfig/dump.h
+++ b/usr.sbin/usbconfig/dump.h
@@ -32,10 +32,11 @@
const char *dump_speed(uint8_t value);
const char *dump_power_mode(uint8_t value);
void dump_string_by_index(struct libusb20_device *pdev, uint8_t index);
-void dump_device_info(struct libusb20_device *pdev, uint8_t show_drv);
+void dump_device_info(struct libusb20_device *pdev, uint8_t show_drv,
+ bool list_mode);
void dump_be_quirk_names(struct libusb20_backend *pbe);
void dump_be_dev_quirks(struct libusb20_backend *pbe);
-void dump_device_desc(struct libusb20_device *pdev);
+void dump_device_desc(struct libusb20_device *pdev, bool list_mode);
void dump_device_stats(struct libusb20_device *pdev);
void dump_config(struct libusb20_device *pdev, uint8_t all_cfg);
diff --git a/usr.sbin/usbconfig/dump.c b/usr.sbin/usbconfig/dump.c
--- a/usr.sbin/usbconfig/dump.c
+++ b/usr.sbin/usbconfig/dump.c
@@ -3,6 +3,10 @@
*
* Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
* Copyright (c) 2024 Baptiste Daroussin <bapt@FreeBSD.org>
+ * Copyright (c) 2025 The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Björn Zeeb
+ * under sponsorship from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,22 +32,32 @@
#include <sys/queue.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
+#include <unistd.h>
#include <err.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
#include <ctype.h>
+#include <fcntl.h>
#include <libusb20.h>
#include <libusb20_desc.h>
+#include <dev/usb/usb_ioctl.h>
+
#include "dump.h"
#include "pathnames.h"
+#ifndef IOUSB
+#define IOUSB(a) a
+#endif
+
#define DUMP0(n,type,field,...) dump_field(pdev, " ", #field, n->field);
+#define DUMP0L(n,type,field,...) dump_fieldl(pdev, " ", #field, n->field);
#define DUMP1(n,type,field,...) dump_field(pdev, " ", #field, n->field);
#define DUMP2(n,type,field,...) dump_field(pdev, " ", #field, n->field);
#define DUMP3(n,type,field,...) dump_field(pdev, " ", #field, n->field);
@@ -113,11 +127,21 @@
}
static void
-dump_field(struct libusb20_device *pdev, const char *plevel,
- const char *field, uint32_t value)
+_dump_field(struct libusb20_device *pdev, const char *plevel,
+ const char *field, uint32_t value, bool list_mode)
{
uint8_t temp_string[256];
+ if (list_mode) {
+ /* Skip fields we are not interested in. */
+ if (strcmp(field, "bLength") == 0 ||
+ strcmp(field, "bDescriptorType") == 0 ||
+ strcmp(field, "bMaxPacketSize0") == 0)
+ return;
+
+ printf("%s=%#06x ", field, value);
+ return;
+ }
printf("%s%s = 0x%04x ", plevel, field, value);
if (strlen(plevel) == 8) {
@@ -257,6 +281,20 @@
printf("\n");
}
+static void
+dump_field(struct libusb20_device *pdev, const char *plevel,
+ const char *field, uint32_t value)
+{
+ _dump_field(pdev, plevel, field, value, false);
+}
+
+static void
+dump_fieldl(struct libusb20_device *pdev, const char *plevel,
+ const char *field, uint32_t value)
+{
+ _dump_field(pdev, plevel, field, value, true);
+}
+
static void
dump_extra(struct libusb20_me_struct *str, const char *plevel)
{
@@ -396,16 +434,34 @@
return (usb_vendors);
}
+enum _device_descr_list_type {
+ _DEVICE_DESCR_LIST_TYPE_DEFAULT = 0,
+ _DEVICE_DESCR_LIST_TYPE_UGEN = 1,
+ _DEVICE_DESCR_LIST_TYPE_PRODUCT_VENDOR = 2,
+};
+
static char *
-_device_desc(struct libusb20_device *pdev)
+_device_desc(struct libusb20_device *pdev,
+ enum _device_descr_list_type list_type)
{
static struct usb_vendors *usb_vendors = NULL;
char *desc = NULL;
const char *vendor = NULL, *product = NULL;
- uint16_t vid = libusb20_dev_get_device_desc(pdev)->idVendor;
- uint16_t pid = libusb20_dev_get_device_desc(pdev)->idProduct;
+ uint16_t vid;
+ uint16_t pid;
struct usb_vendor_info *vi;
struct usb_product_info *pi;
+ struct usb_device_info devinfo;
+
+ if (list_type == _DEVICE_DESCR_LIST_TYPE_UGEN) {
+ asprintf(&desc, "ugen%u.%u",
+ libusb20_dev_get_bus_number(pdev),
+ libusb20_dev_get_address(pdev));
+ return (desc);
+ }
+
+ vid = libusb20_dev_get_device_desc(pdev)->idVendor;
+ pid = libusb20_dev_get_device_desc(pdev)->idProduct;
if (usb_vendors == NULL)
usb_vendors = load_vendors();
@@ -424,6 +480,44 @@
}
}
}
+
+ /*
+ * Try to gather the information; libusb2 unfortunately seems to
+ * only build an entire string but not save vendor/product individually.
+ */
+ if (vendor == NULL || product == NULL) {
+ char buf[64];
+ int f;
+
+ snprintf(buf, sizeof(buf), "/dev/" USB_GENERIC_NAME "%u.%u",
+ libusb20_dev_get_bus_number(pdev),
+ libusb20_dev_get_address(pdev));
+
+ f = open(buf, O_RDWR);
+ if (f < 0)
+ goto skip_vp_recovery;
+
+ if (ioctl(f, IOUSB(USB_GET_DEVICEINFO), &devinfo))
+ goto skip_vp_recovery;
+
+
+ if (vendor == NULL)
+ vendor = devinfo.udi_vendor;
+ if (product == NULL)
+ product = devinfo.udi_product;
+
+skip_vp_recovery:
+ if (f >= 0)
+ close(f);
+ }
+
+ if (list_type == _DEVICE_DESCR_LIST_TYPE_PRODUCT_VENDOR) {
+ asprintf(&desc, "vendor='%s' product='%s'",
+ (vendor != NULL) ? vendor : "",
+ (product != NULL) ? product : "");
+ return (desc);
+ }
+
if (vendor == NULL || product == NULL)
return (NULL);
@@ -433,12 +527,12 @@
product, vendor,
libusb20_dev_get_bus_number(pdev));
-
return (desc);
}
void
-dump_device_info(struct libusb20_device *pdev, uint8_t show_ifdrv)
+dump_device_info(struct libusb20_device *pdev, uint8_t show_ifdrv,
+ bool list_mode)
{
char buf[128];
uint8_t n;
@@ -447,18 +541,22 @@
usage = libusb20_dev_get_power_usage(pdev);
- desc = _device_desc(pdev);
-
- printf("%s, cfg=%u md=%s spd=%s pwr=%s (%umA)\n",
- desc ? desc : libusb20_dev_get_desc(pdev),
- libusb20_dev_get_config_index(pdev),
- dump_mode(libusb20_dev_get_mode(pdev)),
- dump_speed(libusb20_dev_get_speed(pdev)),
- dump_power_mode(libusb20_dev_get_power_mode(pdev)),
- usage);
+ desc = _device_desc(pdev, (list_mode) ? _DEVICE_DESCR_LIST_TYPE_UGEN :
+ _DEVICE_DESCR_LIST_TYPE_DEFAULT);
+
+ if (list_mode)
+ printf("%s: ", desc);
+ else
+ printf("%s, cfg=%u md=%s spd=%s pwr=%s (%umA)\n",
+ desc ? desc : libusb20_dev_get_desc(pdev),
+ libusb20_dev_get_config_index(pdev),
+ dump_mode(libusb20_dev_get_mode(pdev)),
+ dump_speed(libusb20_dev_get_speed(pdev)),
+ dump_power_mode(libusb20_dev_get_power_mode(pdev)),
+ usage);
free(desc);
- if (!show_ifdrv)
+ if (list_mode || !show_ifdrv)
return;
for (n = 0; n != 255; n++) {
@@ -531,12 +629,21 @@
}
void
-dump_device_desc(struct libusb20_device *pdev)
+dump_device_desc(struct libusb20_device *pdev, bool list_mode)
{
struct LIBUSB20_DEVICE_DESC_DECODED *ddesc;
ddesc = libusb20_dev_get_device_desc(pdev);
- LIBUSB20_DEVICE_DESC(DUMP0, ddesc);
+ if (list_mode) {
+ char *desc;
+
+ LIBUSB20_DEVICE_DESC(DUMP0L, ddesc);
+ desc = _device_desc(pdev, _DEVICE_DESCR_LIST_TYPE_PRODUCT_VENDOR);
+ printf("%s\n", (desc != NULL) ? desc : "");
+ free(desc);
+ } else {
+ LIBUSB20_DEVICE_DESC(DUMP0, ddesc);
+ }
}
void
diff --git a/usr.sbin/usbconfig/usbconfig.8 b/usr.sbin/usbconfig/usbconfig.8
--- a/usr.sbin/usbconfig/usbconfig.8
+++ b/usr.sbin/usbconfig/usbconfig.8
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd January 29, 2022
+.Dd February 12, 2025
.Dt USBCONFIG 8
.Os
.Sh NAME
@@ -30,6 +30,7 @@
.Nd configure the USB subsystem
.Sh SYNOPSIS
.Nm
+.Op Fl l
.Op Fl v
.Op Fl a Ar addr
.Op Fl i Ar interface_index
@@ -40,6 +41,7 @@
.Sm off
.Oo Oo Cm /dev/ Oc Cm ugen Oc Ar unit Cm \&. Ar addr
.Sm on
+.Op Fl l
.Op Fl v
.Op Fl i Ar interface_index
.Op Ar cmds ...
@@ -70,6 +72,8 @@
Specify interface index as indicated by the command description.
If this argument is not specified
a value of zero will be used for the interface index.
+.It Fl l Cm dump_device_desc
+Show numeral only key=value output as one long line.
.It Fl u Ar unit
Limit device range to USB devices connected to the given USBUS unit.
.It Fl v
diff --git a/usr.sbin/usbconfig/usbconfig.c b/usr.sbin/usbconfig/usbconfig.c
--- a/usr.sbin/usbconfig/usbconfig.c
+++ b/usr.sbin/usbconfig/usbconfig.c
@@ -25,6 +25,7 @@
* SUCH DAMAGE.
*/
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
@@ -91,6 +92,7 @@
uint8_t got_dump_string:1;
uint8_t got_do_request:1;
uint8_t got_detach_kernel_driver:1;
+ uint8_t opt_dump_in_list_mode:1;
};
struct token {
@@ -504,11 +506,13 @@
if (opt->got_list || dump_any) {
dump_device_info(pdev,
- opt->got_show_iface_driver);
+ opt->got_show_iface_driver,
+ opt->opt_dump_in_list_mode && opt->got_dump_device_desc);
}
if (opt->got_dump_device_desc) {
- printf("\n");
- dump_device_desc(pdev);
+ if (!opt->opt_dump_in_list_mode)
+ printf("\n");
+ dump_device_desc(pdev, opt->opt_dump_in_list_mode);
}
if (opt->got_dump_all_config) {
printf("\n");
@@ -518,14 +522,14 @@
dump_config(pdev, 0);
} else if (opt->got_dump_all_desc) {
printf("\n");
- dump_device_desc(pdev);
+ dump_device_desc(pdev, false);
dump_config(pdev, 1);
}
if (opt->got_dump_stats) {
printf("\n");
dump_device_stats(pdev);
}
- if (dump_any) {
+ if (dump_any && !opt->opt_dump_in_list_mode) {
printf("\n");
}
if (libusb20_dev_close(pdev)) {
@@ -559,7 +563,7 @@
if (pbe == NULL)
err(1, "could not access USB backend\n");
- while ((ch = getopt(argc, argv, "a:d:hi:u:v")) != -1) {
+ while ((ch = getopt(argc, argv, "a:d:hi:lu:v")) != -1) {
switch (ch) {
case 'a':
opt->addr = num_id(optarg, "addr");
@@ -596,6 +600,10 @@
opt->iface = num_id(optarg, "iface");
break;
+ case 'l':
+ opt->opt_dump_in_list_mode = 1;
+ break;
+
case 'u':
opt->bus = num_id(optarg, "busnum");
opt->got_bus = 1;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Feb 15, 2:21 PM (6 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28744325
Default Alt Text
D48974.diff (9 KB)
Attached To
Mode
D48974: usbconfig: add -l option to dump_device_desc for single line output
Attached
Detach File
Event Timeline
Log In to Comment