linux-usb.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/4] Enable to set DbC strings through sysfs
@ 2025-11-12 23:15 Łukasz Bartosik
  2025-11-12 23:15 ` [PATCH v3 1/4] xhci: dbc: prepare to expose " Łukasz Bartosik
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Łukasz Bartosik @ 2025-11-12 23:15 UTC (permalink / raw)
  To: Mathias Nyman, Greg Kroah-Hartman
  Cc: Alan Stern, linux-usb, Łukasz Bartosik

From: Łukasz Bartosik <ukaszb@chromium.org>

This patchset enables setting DbC serial number,
product name and manufacturer name through sysfs.

Testing performed with this patchset:

1.DbC is enabled and enumerates on host side with the following
default values of product, manufactuer and serial values:
"
[496803.112431] usb 2-4: new SuperSpeed USB device number 106 using xhci_hcd
[496803.128540] usb 2-4: LPM exit latency is zeroed, disabling LPM.
[496803.129387] usb 2-4: New USB device found, idVendor=18d1, idProduct=0010, bcdDevice= 0.10
[496803.130173] usb 2-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[496803.130858] usb 2-4: Product: Linux USB Debug Target
[496803.131343] usb 2-4: Manufacturer: Linux Foundation
[496803.131821] usb 2-4: SerialNumber: 0001
```

View default DbC values in sysfs:
"
cat /sys/bus/pci/devices/0000:00:14.0/dbc_product
Linux USB Debug Target
cat /sys/bus/pci/devices/0000:00:14.0/dbc_manufacturer
Linux Foundation
cat /sys/bus/pci/devices/0000:00:14.0/dbc_serial
0001
"

2. Try to set product, manufacturer and serial to empty:

echo disable > /sys/bus/pci/devices/0000:00:14.0/dbc
echo "" > /sys/bus/pci/devices/0000:00:14.0/dbc_product
echo "" > /sys/bus/pci/devices/0000:00:14.0/dbc_manufacturer
echo "" > /sys/bus/pci/devices/0000:00:14.0/dbc_serial  
echo enable > /sys/bus/pci/devices/0000:00:14.0/dbc

Verify through sysfs empty values were not set:
"
cat /sys/bus/pci/devices/0000:00:14.0/dbc_product
Linux USB Debug Target
cat /sys/bus/pci/devices/0000:00:14.0/dbc_manufacturer
Linux Foundation
cat /sys/bus/pci/devices/0000:00:14.0/dbc_serial
0001
"

Verify DbC enumerates with default values:
"
[206723.036606] usb 2-3: new SuperSpeed USB device number 52 using xhci_hcd
[206723.056594] usb 2-3: LPM exit latency is zeroed, disabling LPM.
[206723.057795] usb 2-3: New USB device found, idVendor=18d1, idProduct=0010, bcdDevice= 0.10
[206723.058592] usb 2-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[206723.059289] usb 2-3: Product: Linux USB Debug Target
[206723.059796] usb 2-3: Manufacturer: Linux Foundation
[206723.060284] usb 2-3: SerialNumber: 0001
"


3. Update product, manufacturer and serial values:

echo disable > /sys/bus/pci/devices/0000:00:14.0/dbc
echo "A" > /sys/bus/pci/devices/0000:00:14.0/dbc_product
echo "B" > /sys/bus/pci/devices/0000:00:14.0/dbc_manufacturer
echo "C" > /sys/bus/pci/devices/0000:00:14.0/dbc_serial
echo enable > /sys/bus/pci/devices/0000:00:14.0/dbc

Verify through sysfs new values were set:
"
cat /sys/bus/pci/devices/0000:00:14.0/dbc_product
A
cat /sys/bus/pci/devices/0000:00:14.0/dbc_manufacturer
B
cat /sys/bus/pci/devices/0000:00:14.0/dbc_serial
C
"

Verify DbC enumerates with new values:
"
[222501.763069] usb 2-3: new SuperSpeed USB device number 66 using xhci_hcd
[222501.786948] usb 2-3: LPM exit latency is zeroed, disabling LPM.
[222501.801052] usb 2-3: New USB device found, idVendor=18d1, idProduct=0010, bcdDevice= 0.10
[222501.801857] usb 2-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[222501.802556] usb 2-3: Product: A
[222501.802958] usb 2-3: Manufacturer: B
[222501.803329] usb 2-3: SerialNumber: C
"



4. Update product, manufacturer and serial values:

echo disable > /sys/bus/pci/devices/0000:00:14.0/dbc
echo "New_product_name" > /sys/bus/pci/devices/0000:00:14.0/dbc_product
echo "New_manufacturer_name" > /sys/bus/pci/devices/0000:00:14.0/dbc_manufacturer
echo "ABCDEF123456" > /sys/bus/pci/devices/0000:00:14.0/dbc_serial
echo enable > /sys/bus/pci/devices/0000:00:14.0/dbc

Verify through sysfs new values were set:
"
cat /sys/bus/pci/devices/0000:00:14.0/dbc_product
New_product_name
cat /sys/bus/pci/devices/0000:00:14.0/dbc_manufacturer
New_manufacturer_name
cat /sys/bus/pci/devices/0000:00:14.0/dbc_serial
ABCDEF123456
"

Verify DbC enumerates with new values:
"
[222740.958461] usb 2-3: new SuperSpeed USB device number 67 using xhci_hcd
[222740.974545] usb 2-3: LPM exit latency is zeroed, disabling LPM.
[222740.975442] usb 2-3: New USB device found, idVendor=18d1, idProduct=0010, bcdDevice= 0.10
[222740.976236] usb 2-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[222740.976929] usb 2-3: Product: New_product_name
[222740.977372] usb 2-3: Manufacturer: New_manufacturer_name
[222740.977896] usb 2-3: SerialNumber: ABCDEF123456
"


5. Try to update product, manufacturer and serial values with new values longer
than maximum 126 characters (USB_MAX_STRING_LEN):

echo disable > /sys/bus/pci/devices/0000:00:14.0/dbc
echo "AAAAAAAAA_BBBBBBBBB_CCCCCCCCC_DDDDDDDDD_EEEEEEEEE_FFFFFFFFF_GGGGGGGGG_HHHHHHHHH_IIIIIIIII_JJJJJJJJJ_KKKKKKKKK_LLLLLLLLL_MMMMMMM" > /sys/bus/pci/devices/0000:00:14.0/dbc_product                   
echo "NNNNNNNNN_OOOOOOOOO_PPPPPPPPP_RRRRRRRRR_SSSSSSSSS_TTTTTTTTT_UUUUUUUUU_WWWWWWWWW_XXXXXXXXX_YYYYYYYYY_ZZZZZZZZZ_AAAAAAAAA_BBBBBBB" > /sys/bus/pci/devices/0000:00:14.0/dbc_manufacturer              
echo "CCCCCCCCC_DDDDDDDDD_EEEEEEEEE_GGGGGGGGG_HHHHHHHHH_IIIIIIIII_JJJJJJJJJ_KKKKKKKKK_LLLLLLLLL_MMMMMMMMM_NNNNNNNNN_OOOOOOOOO_PPPPPPP" > /sys/bus/pci/devices/0000:00:14.0/dbc_serial  
echo enable > /sys/bus/pci/devices/0000:00:14.0/dbc

Verify through sysfs new values were not set:
"
cat /sys/bus/pci/devices/0000:00:14.0/dbc_product
New_product_name
cat /sys/bus/pci/devices/0000:00:14.0/dbc_manufacturer
New_manufacturer_name
cat /sys/bus/pci/devices/0000:00:14.0/dbc_serial
ABCDEF123456
"

Verify DbC enumerates with previous values:
"
[497908.814834] usb 2-4: new SuperSpeed USB device number 108 using xhci_hcd
[497908.831057] usb 2-4: LPM exit latency is zeroed, disabling LPM.
[497908.844994] usb 2-4: New USB device found, idVendor=18d1, idProduct=0010, bcdDevice= 0.10
[497908.845797] usb 2-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[497908.846482] usb 2-4: Product: New_product_name
[497908.846965] usb 2-4: Manufacturer: New_manufacturer_name
[497908.847505] usb 2-4: SerialNumber: ABCDEF123456
"


6. Update product, manufacturer and serial values with new values
whose length is maximum 126 characters (USB_MAX_STRING_LEN):

echo disable > /sys/bus/pci/devices/0000:00:14.0/dbc
echo "AAAAAAAAA_BBBBBBBBB_CCCCCCCCC_DDDDDDDDD_EEEEEEEEE_FFFFFFFFF_GGGGGGGGG_HHHHHHHHH_IIIIIIIII_JJJJJJJJJ_KKKKKKKKK_LLLLLLLLL_MMMMMM" > /sys/bus/pci/devices/0000:00:14.0/dbc_product                   
echo "NNNNNNNNN_OOOOOOOOO_PPPPPPPPP_RRRRRRRRR_SSSSSSSSS_TTTTTTTTT_UUUUUUUUU_WWWWWWWWW_XXXXXXXXX_YYYYYYYYY_ZZZZZZZZZ_AAAAAAAAA_BBBBBB" > /sys/bus/pci/devices/0000:00:14.0/dbc_manufacturer              
echo "CCCCCCCCC_DDDDDDDDD_EEEEEEEEE_GGGGGGGGG_HHHHHHHHH_IIIIIIIII_JJJJJJJJJ_KKKKKKKKK_LLLLLLLLL_MMMMMMMMM_NNNNNNNNN_OOOOOOOOO_PPPPPP" > /sys/bus/pci/devices/0000:00:14.0/dbc_serial  
echo enable > /sys/bus/pci/devices/0000:00:14.0/dbc

Verify through sysfs new values were set:
"
cat /sys/bus/pci/devices/0000:00:14.0/dbc_product
AAAAAAAAA_BBBBBBBBB_CCCCCCCCC_DDDDDDDDD_EEEEEEEEE_FFFFFFFFF_GGGGGGGGG_HHHHHHHHH_IIIIIIIII_JJJJJJJJJ_KKKKKKKKK_LLLLLLLLL_MMMMMM
cat /sys/bus/pci/devices/0000:00:14.0/dbc_manufacturer
NNNNNNNNN_OOOOOOOOO_PPPPPPPPP_RRRRRRRRR_SSSSSSSSS_TTTTTTTTT_UUUUUUUUU_WWWWWWWWW_XXXXXXXXX_YYYYYYYYY_ZZZZZZZZZ_AAAAAAAAA_BBBBBB
cat /sys/bus/pci/devices/0000:00:14.0/dbc_serial
CCCCCCCCC_DDDDDDDDD_EEEEEEEEE_GGGGGGGGG_HHHHHHHHH_IIIIIIIII_JJJJJJJJJ_KKKKKKKKK_LLLLLLLLL_MMMMMMMMM_NNNNNNNNN_OOOOOOOOO_PPPPPP
"

Verify DbC enumerates with new values:
"
[83206.326166] usb 2-4: new SuperSpeed USB device number 111 using xhci_hcd
[83206.342150] usb 2-4: LPM exit latency is zeroed, disabling LPM.
[83206.343022] usb 2-4: New USB device found, idVendor=18d1, idProduct=0010, bcdDevice= 0.10
[83206.343798] usb 2-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[83206.344475] usb 2-4: Product: AAAAAAAAA_BBBBBBBBB_CCCCCCCCC_DDDDDDDDD_EEEEEEEEE_FFFFFFFFF_GGGGGGGGG_HHHHHHHHH_IIIIIIIII_JJJJJJJJJ_KKKKKKKKK_LLLLLLLLL_MMMMMM
[83206.345783] usb 2-4: Manufacturer: NNNNNNNNN_OOOOOOOOO_PPPPPPPPP_RRRRRRRRR_SSSSSSSSS_TTTTTTTTT_UUUUUUUUU_WWWWWWWWW_XXXXXXXXX_YYYYYYYYY_ZZZZZZZZZ_AAAAAAAAA_BBBBBB
[83206.347156] usb 2-4: SerialNumber: CCCCCCCCC_DDDDDDDDD_EEEEEEEEE_GGGGGGGGG_HHHHHHHHH_IIIIIIIII_JJJJJJJJJ_KKKKKKKKK_LLLLLLLLL_MMMMMMMMM_NNNNNNNNN_OOOOOOOOO_PPPPPP
"



7. Repeat steps 2-6 with passing -n option to each echo command to prevent outputting the trailing newline



Changes in V3:
- Renamed prepare_len() to dbc_prepare_info_context_str_len()
- Simplified initialization of default manufacturer, product and serial values by 
defininig "static const struct dbc_str dbc_str_default", removed DBC_STRING_MANUFACTURER
DBC_STRING_PRODUCT and DBC_STRING_SERIAL defines
- Updated USB_MAX_STRING_DESC_LEN to 254 and added Alan's comment
- Updated max output length in xhci_dbc_populate_str_desc() to 2*USB_MAX_STRING_LEN
- Renamed utf16_len->len and added comment
- Renamed dbc_iSerial->dbc_serial, dbc_iProduct->dbc_product and dbc_iManufacturer->dbc_manufacturer
- Added comment for struct dbc_str

Changes in V2:
- Documented new sysfs entries
- Fixed *_store functions to handle correctly case when there
is no trailing newline

Łukasz Bartosik (4):
  xhci: dbc: prepare to expose strings through sysfs
  xhci: dbc: allow to set serial number through sysfs
  xhci: dbc: allow to set product name through sysfs
  xhci: dbc: allow to set manufacturer name through sysfs

 .../testing/sysfs-bus-pci-drivers-xhci_hcd    |  36 +++
 drivers/usb/host/xhci-dbgcap.c                | 258 +++++++++++++-----
 drivers/usb/host/xhci-dbgcap.h                |  37 ++-
 3 files changed, 253 insertions(+), 78 deletions(-)

-- 
2.51.2.1041.gc1ab5b90ca-goog


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v3 1/4] xhci: dbc: prepare to expose strings through sysfs
  2025-11-12 23:15 [PATCH v3 0/4] Enable to set DbC strings through sysfs Łukasz Bartosik
@ 2025-11-12 23:15 ` Łukasz Bartosik
  2025-11-12 23:15 ` [PATCH v3 2/4] xhci: dbc: allow to set serial number " Łukasz Bartosik
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Łukasz Bartosik @ 2025-11-12 23:15 UTC (permalink / raw)
  To: Mathias Nyman, Greg Kroah-Hartman
  Cc: Alan Stern, linux-usb, Łukasz Bartosik

From: Łukasz Bartosik <ukaszb@chromium.org>

Reorganize the code to prepare ground for setting serial number,
product and manufacturer names through sysfs. This commit:
1. Introduces new buffers for storing serial number, product and
   manufacturer name in utf8. The buffers will be used by sysfs
   *_show and *_store functions.
2. Increases USB string descriptor data maximum length to the
   value from USB specification (126 bytes of data).
3. Adds new helper functions get_str_desc_len, prepare_len
   and xhci_dbc_populate_str_desc.

Signed-off-by: Łukasz Bartosik <ukaszb@chromium.org>
---
 drivers/usb/host/xhci-dbgcap.c | 150 ++++++++++++++++++---------------
 drivers/usb/host/xhci-dbgcap.h |  37 +++++---
 2 files changed, 109 insertions(+), 78 deletions(-)

diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
index cc5e7325af4f..6605833f807d 100644
--- a/drivers/usb/host/xhci-dbgcap.c
+++ b/drivers/usb/host/xhci-dbgcap.c
@@ -29,6 +29,12 @@
 #include "xhci-trace.h"
 #include "xhci-dbgcap.h"
 
+static const struct dbc_str dbc_str_default = {
+	.manufacturer = "Linux Foundation",
+	.product = "Linux USB Debug Target",
+	.serial = "0001",
+};
+
 static void dbc_free_ctx(struct device *dev, struct xhci_container_ctx *ctx)
 {
 	if (!ctx)
@@ -52,55 +58,6 @@ static void dbc_ring_free(struct device *dev, struct xhci_ring *ring)
 	kfree(ring);
 }
 
-static u32 xhci_dbc_populate_strings(struct dbc_str_descs *strings)
-{
-	struct usb_string_descriptor	*s_desc;
-	u32				string_length;
-
-	/* Serial string: */
-	s_desc = (struct usb_string_descriptor *)strings->serial;
-	utf8s_to_utf16s(DBC_STRING_SERIAL, strlen(DBC_STRING_SERIAL),
-			UTF16_LITTLE_ENDIAN, (wchar_t *)s_desc->wData,
-			DBC_MAX_STRING_LENGTH);
-
-	s_desc->bLength		= (strlen(DBC_STRING_SERIAL) + 1) * 2;
-	s_desc->bDescriptorType	= USB_DT_STRING;
-	string_length		= s_desc->bLength;
-	string_length		<<= 8;
-
-	/* Product string: */
-	s_desc = (struct usb_string_descriptor *)strings->product;
-	utf8s_to_utf16s(DBC_STRING_PRODUCT, strlen(DBC_STRING_PRODUCT),
-			UTF16_LITTLE_ENDIAN, (wchar_t *)s_desc->wData,
-			DBC_MAX_STRING_LENGTH);
-
-	s_desc->bLength		= (strlen(DBC_STRING_PRODUCT) + 1) * 2;
-	s_desc->bDescriptorType	= USB_DT_STRING;
-	string_length		+= s_desc->bLength;
-	string_length		<<= 8;
-
-	/* Manufacture string: */
-	s_desc = (struct usb_string_descriptor *)strings->manufacturer;
-	utf8s_to_utf16s(DBC_STRING_MANUFACTURER,
-			strlen(DBC_STRING_MANUFACTURER),
-			UTF16_LITTLE_ENDIAN, (wchar_t *)s_desc->wData,
-			DBC_MAX_STRING_LENGTH);
-
-	s_desc->bLength		= (strlen(DBC_STRING_MANUFACTURER) + 1) * 2;
-	s_desc->bDescriptorType	= USB_DT_STRING;
-	string_length		+= s_desc->bLength;
-	string_length		<<= 8;
-
-	/* String0: */
-	strings->string0[0]	= 4;
-	strings->string0[1]	= USB_DT_STRING;
-	strings->string0[2]	= 0x09;
-	strings->string0[3]	= 0x04;
-	string_length		+= 4;
-
-	return string_length;
-}
-
 static void xhci_dbc_init_ep_contexts(struct xhci_dbc *dbc)
 {
 	struct xhci_ep_ctx      *ep_ctx;
@@ -124,7 +81,64 @@ static void xhci_dbc_init_ep_contexts(struct xhci_dbc *dbc)
 	ep_ctx->deq             = cpu_to_le64(deq | dbc->ring_in->cycle_state);
 }
 
-static void xhci_dbc_init_contexts(struct xhci_dbc *dbc, u32 string_length)
+static u8 get_str_desc_len(const char *desc)
+{
+	return ((struct usb_string_descriptor *)desc)->bLength;
+}
+
+static u32 dbc_prepare_info_context_str_len(struct dbc_str_descs *descs)
+{
+	u32 len;
+
+	len = get_str_desc_len(descs->serial);
+	len <<= 8;
+	len += get_str_desc_len(descs->product);
+	len <<= 8;
+	len += get_str_desc_len(descs->manufacturer);
+	len <<= 8;
+	len += get_str_desc_len(descs->string0);
+
+	return len;
+}
+
+static int xhci_dbc_populate_str_desc(char *desc, const char *src)
+{
+	struct usb_string_descriptor	*s_desc;
+	int				len;
+
+	s_desc = (struct usb_string_descriptor *)desc;
+	/* len holds number of 2 byte UTF-16 characters */
+	len = utf8s_to_utf16s(src, strlen(src), UTF16_LITTLE_ENDIAN,
+			      (wchar_t *)s_desc->wData, 2*USB_MAX_STRING_LEN);
+	if (len < 0)
+		return len;
+
+	s_desc->bLength		= len * 2 + 2;
+	s_desc->bDescriptorType	= USB_DT_STRING;
+
+	return s_desc->bLength;
+}
+
+static void xhci_dbc_populate_str_descs(struct dbc_str_descs *str_descs,
+					struct dbc_str *str)
+{
+	/* Serial string: */
+	xhci_dbc_populate_str_desc(str_descs->serial, str->serial);
+
+	/* Product string: */
+	xhci_dbc_populate_str_desc(str_descs->product, str->product);
+
+	/* Manufacturer string: */
+	xhci_dbc_populate_str_desc(str_descs->manufacturer, str->manufacturer);
+
+	/* String0: */
+	str_descs->string0[0]	= 4;
+	str_descs->string0[1]	= USB_DT_STRING;
+	str_descs->string0[2]	= 0x09;
+	str_descs->string0[3]	= 0x04;
+}
+
+static void xhci_dbc_init_contexts(struct xhci_dbc *dbc)
 {
 	struct dbc_info_context	*info;
 	u32			dev_info;
@@ -135,12 +149,12 @@ static void xhci_dbc_init_contexts(struct xhci_dbc *dbc, u32 string_length)
 
 	/* Populate info Context: */
 	info			= (struct dbc_info_context *)dbc->ctx->bytes;
-	dma			= dbc->string_dma;
+	dma			= dbc->str_descs_dma;
 	info->string0		= cpu_to_le64(dma);
-	info->manufacturer	= cpu_to_le64(dma + DBC_MAX_STRING_LENGTH);
-	info->product		= cpu_to_le64(dma + DBC_MAX_STRING_LENGTH * 2);
-	info->serial		= cpu_to_le64(dma + DBC_MAX_STRING_LENGTH * 3);
-	info->length		= cpu_to_le32(string_length);
+	info->manufacturer	= cpu_to_le64(dma + USB_MAX_STRING_DESC_LEN);
+	info->product		= cpu_to_le64(dma + USB_MAX_STRING_DESC_LEN*2);
+	info->serial		= cpu_to_le64(dma + USB_MAX_STRING_DESC_LEN*3);
+	info->length		= cpu_to_le32(dbc_prepare_info_context_str_len(dbc->str_descs));
 
 	/* Populate bulk in and out endpoint contexts: */
 	xhci_dbc_init_ep_contexts(dbc);
@@ -524,7 +538,6 @@ static int xhci_dbc_mem_init(struct xhci_dbc *dbc, gfp_t flags)
 {
 	int			ret;
 	dma_addr_t		deq;
-	u32			string_length;
 	struct device		*dev = dbc->dev;
 
 	/* Allocate various rings for events and transfers: */
@@ -551,11 +564,11 @@ static int xhci_dbc_mem_init(struct xhci_dbc *dbc, gfp_t flags)
 		goto ctx_fail;
 
 	/* Allocate the string table: */
-	dbc->string_size = sizeof(*dbc->string);
-	dbc->string = dma_alloc_coherent(dev, dbc->string_size,
-					 &dbc->string_dma, flags);
-	if (!dbc->string)
-		goto string_fail;
+	dbc->str_descs_size = sizeof(*dbc->str_descs);
+	dbc->str_descs = dma_alloc_coherent(dev, dbc->str_descs_size,
+					    &dbc->str_descs_dma, flags);
+	if (!dbc->str_descs)
+		goto str_descs_fail;
 
 	/* Setup ERST register: */
 	writel(dbc->erst.num_entries, &dbc->regs->ersts);
@@ -565,16 +578,16 @@ static int xhci_dbc_mem_init(struct xhci_dbc *dbc, gfp_t flags)
 				   dbc->ring_evt->dequeue);
 	lo_hi_writeq(deq, &dbc->regs->erdp);
 
-	/* Setup strings and contexts: */
-	string_length = xhci_dbc_populate_strings(dbc->string);
-	xhci_dbc_init_contexts(dbc, string_length);
+	/* Setup string descriptors and contexts: */
+	xhci_dbc_populate_str_descs(dbc->str_descs, &dbc->str);
+	xhci_dbc_init_contexts(dbc);
 
 	xhci_dbc_eps_init(dbc);
 	dbc->state = DS_INITIALIZED;
 
 	return 0;
 
-string_fail:
+str_descs_fail:
 	dbc_free_ctx(dev, dbc->ctx);
 	dbc->ctx = NULL;
 ctx_fail:
@@ -599,8 +612,8 @@ static void xhci_dbc_mem_cleanup(struct xhci_dbc *dbc)
 
 	xhci_dbc_eps_exit(dbc);
 
-	dma_free_coherent(dbc->dev, dbc->string_size, dbc->string, dbc->string_dma);
-	dbc->string = NULL;
+	dma_free_coherent(dbc->dev, dbc->str_descs_size, dbc->str_descs, dbc->str_descs_dma);
+	dbc->str_descs = NULL;
 
 	dbc_free_ctx(dbc->dev, dbc->ctx);
 	dbc->ctx = NULL;
@@ -1313,6 +1326,9 @@ xhci_alloc_dbc(struct device *dev, void __iomem *base, const struct dbc_driver *
 	dbc->bInterfaceProtocol = DBC_PROTOCOL;
 	dbc->poll_interval = DBC_POLL_INTERVAL_DEFAULT;
 
+	/* initialize serial, product and manufacturer with default values */
+	dbc->str = dbc_str_default;
+
 	if (readl(&dbc->regs->control) & DBC_CTRL_DBC_ENABLE)
 		goto err;
 
diff --git a/drivers/usb/host/xhci-dbgcap.h b/drivers/usb/host/xhci-dbgcap.h
index 47ac72c2286d..07ce9c159b91 100644
--- a/drivers/usb/host/xhci-dbgcap.h
+++ b/drivers/usb/host/xhci-dbgcap.h
@@ -47,10 +47,6 @@ struct dbc_info_context {
 #define DBC_DOOR_BELL_TARGET(p)		(((p) & 0xff) << 8)
 
 #define DBC_MAX_PACKET			1024
-#define DBC_MAX_STRING_LENGTH		64
-#define DBC_STRING_MANUFACTURER		"Linux Foundation"
-#define DBC_STRING_PRODUCT		"Linux USB Debug Target"
-#define DBC_STRING_SERIAL		"0001"
 #define	DBC_CONTEXT_SIZE		64
 
 /*
@@ -63,11 +59,29 @@ struct dbc_info_context {
 #define DBC_PORTSC_LINK_CHANGE		BIT(22)
 #define DBC_PORTSC_CONFIG_CHANGE	BIT(23)
 
+/* The maximum length of a string descriptor is 255, because the bLength
+ * field in the usb_string_descriptor struct is __u8.  In practice the
+ * maximum length is 254, because a string descriptor consists of a 2 byte
+ * header followed by UTF-16 characters (2 bytes each). This allows for
+ * only 126 characters (code points) in the string, which is where
+ * USB_MAX_STRING_LEN comes from.
+ */
+#define USB_MAX_STRING_DESC_LEN		254
+
 struct dbc_str_descs {
-	char	string0[DBC_MAX_STRING_LENGTH];
-	char	manufacturer[DBC_MAX_STRING_LENGTH];
-	char	product[DBC_MAX_STRING_LENGTH];
-	char	serial[DBC_MAX_STRING_LENGTH];
+	char	string0[USB_MAX_STRING_DESC_LEN];
+	char	manufacturer[USB_MAX_STRING_DESC_LEN];
+	char	product[USB_MAX_STRING_DESC_LEN];
+	char	serial[USB_MAX_STRING_DESC_LEN];
+};
+
+/* NULL terminated UTF-8 strings used to create UTF-16 strings
+ * (with maxiumum USB_MAX_STRING_LEN 2 byte characters).
+ */
+struct dbc_str {
+	char	manufacturer[USB_MAX_STRING_LEN+1];
+	char	product[USB_MAX_STRING_LEN+1];
+	char	serial[USB_MAX_STRING_LEN+1];
 };
 
 #define DBC_PROTOCOL			1	/* GNU Remote Debug Command */
@@ -132,9 +146,10 @@ struct xhci_dbc {
 	struct xhci_erst		erst;
 	struct xhci_container_ctx	*ctx;
 
-	struct dbc_str_descs		*string;
-	dma_addr_t			string_dma;
-	size_t				string_size;
+	struct dbc_str_descs		*str_descs;
+	dma_addr_t			str_descs_dma;
+	size_t				str_descs_size;
+	struct dbc_str			str;
 	u16				idVendor;
 	u16				idProduct;
 	u16				bcdDevice;
-- 
2.51.2.1041.gc1ab5b90ca-goog


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v3 2/4] xhci: dbc: allow to set serial number through sysfs
  2025-11-12 23:15 [PATCH v3 0/4] Enable to set DbC strings through sysfs Łukasz Bartosik
  2025-11-12 23:15 ` [PATCH v3 1/4] xhci: dbc: prepare to expose " Łukasz Bartosik
@ 2025-11-12 23:15 ` Łukasz Bartosik
  2025-11-12 23:15 ` [PATCH v3 3/4] xhci: dbc: allow to set product name " Łukasz Bartosik
  2025-11-12 23:15 ` [PATCH v3 4/4] xhci: dbc: allow to set manufacturer " Łukasz Bartosik
  3 siblings, 0 replies; 5+ messages in thread
From: Łukasz Bartosik @ 2025-11-12 23:15 UTC (permalink / raw)
  To: Mathias Nyman, Greg Kroah-Hartman
  Cc: Alan Stern, linux-usb, Łukasz Bartosik

From: Łukasz Bartosik <ukaszb@chromium.org>

Add code which allows to set serial number of a DbC
device through sysfs.

Signed-off-by: Łukasz Bartosik <ukaszb@chromium.org>
---
 .../testing/sysfs-bus-pci-drivers-xhci_hcd    | 13 +++++++
 drivers/usb/host/xhci-dbgcap.c                | 36 +++++++++++++++++++
 2 files changed, 49 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd b/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd
index fc82aa4e54b0..071688dbd969 100644
--- a/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd
+++ b/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd
@@ -85,3 +85,16 @@ Description:
 		up to 5000. The default value is 64 ms.
 		This polling interval is used while DbC is enabled but has no
 		active data transfers.
+
+What:          /sys/bus/pci/drivers/xhci_hcd/.../dbc_iSerial
+Date:          October 2025
+Contact:       Łukasz Bartosik <ukaszb@chromium.org>
+Description:
+               The dbc_iSerial attribute allows to change the iSerial field
+               presented in the USB device descriptor by xhci debug device.
+               Value can only be changed while debug capability (DbC) is in
+               disabled state to prevent USB device descriptor change while
+               connected to a USB host.
+               The default value is "0001".
+               The field length can be from 1 to 63 characters.
+
diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
index 6605833f807d..c5bfd40bd496 100644
--- a/drivers/usb/host/xhci-dbgcap.c
+++ b/drivers/usb/host/xhci-dbgcap.c
@@ -1206,6 +1206,40 @@ static ssize_t dbc_bcdDevice_store(struct device *dev,
 	return size;
 }
 
+static ssize_t dbc_serial_show(struct device *dev,
+			    struct device_attribute *attr,
+			    char *buf)
+{
+	struct xhci_hcd	*xhci = hcd_to_xhci(dev_get_drvdata(dev));
+	struct xhci_dbc	*dbc = xhci->dbc;
+
+	return sysfs_emit(buf, "%s\n", dbc->str.serial);
+}
+
+static ssize_t dbc_serial_store(struct device *dev,
+			     struct device_attribute *attr,
+			     const char *buf, size_t size)
+{
+	struct xhci_hcd	*xhci = hcd_to_xhci(dev_get_drvdata(dev));
+	struct xhci_dbc	*dbc = xhci->dbc;
+	size_t len;
+
+	if (dbc->state != DS_DISABLED)
+		return -EBUSY;
+
+	len = strcspn(buf, "\n");
+	if (!len)
+		return -EINVAL;
+
+	if (len > USB_MAX_STRING_LEN)
+		return -E2BIG;
+
+	memcpy(dbc->str.serial, buf, len);
+	dbc->str.serial[len] = '\0';
+
+	return size;
+}
+
 static ssize_t dbc_bInterfaceProtocol_show(struct device *dev,
 				 struct device_attribute *attr,
 				 char *buf)
@@ -1293,6 +1327,7 @@ static DEVICE_ATTR_RW(dbc);
 static DEVICE_ATTR_RW(dbc_idVendor);
 static DEVICE_ATTR_RW(dbc_idProduct);
 static DEVICE_ATTR_RW(dbc_bcdDevice);
+static DEVICE_ATTR_RW(dbc_serial);
 static DEVICE_ATTR_RW(dbc_bInterfaceProtocol);
 static DEVICE_ATTR_RW(dbc_poll_interval_ms);
 
@@ -1301,6 +1336,7 @@ static struct attribute *dbc_dev_attrs[] = {
 	&dev_attr_dbc_idVendor.attr,
 	&dev_attr_dbc_idProduct.attr,
 	&dev_attr_dbc_bcdDevice.attr,
+	&dev_attr_dbc_serial.attr,
 	&dev_attr_dbc_bInterfaceProtocol.attr,
 	&dev_attr_dbc_poll_interval_ms.attr,
 	NULL
-- 
2.51.2.1041.gc1ab5b90ca-goog


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v3 3/4] xhci: dbc: allow to set product name through sysfs
  2025-11-12 23:15 [PATCH v3 0/4] Enable to set DbC strings through sysfs Łukasz Bartosik
  2025-11-12 23:15 ` [PATCH v3 1/4] xhci: dbc: prepare to expose " Łukasz Bartosik
  2025-11-12 23:15 ` [PATCH v3 2/4] xhci: dbc: allow to set serial number " Łukasz Bartosik
@ 2025-11-12 23:15 ` Łukasz Bartosik
  2025-11-12 23:15 ` [PATCH v3 4/4] xhci: dbc: allow to set manufacturer " Łukasz Bartosik
  3 siblings, 0 replies; 5+ messages in thread
From: Łukasz Bartosik @ 2025-11-12 23:15 UTC (permalink / raw)
  To: Mathias Nyman, Greg Kroah-Hartman
  Cc: Alan Stern, linux-usb, Łukasz Bartosik

From: Łukasz Bartosik <ukaszb@chromium.org>

Add code which allows to set product name of a DbC
device through sysfs.

Signed-off-by: Łukasz Bartosik <ukaszb@chromium.org>
---
 .../testing/sysfs-bus-pci-drivers-xhci_hcd    | 11 ++++++
 drivers/usb/host/xhci-dbgcap.c                | 36 +++++++++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd b/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd
index 071688dbd969..57ba37606f79 100644
--- a/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd
+++ b/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd
@@ -98,3 +98,14 @@ Description:
                The default value is "0001".
                The field length can be from 1 to 63 characters.
 
+What:          /sys/bus/pci/drivers/xhci_hcd/.../dbc_iProduct
+Date:          October 2025
+Contact:       Łukasz Bartosik <ukaszb@chromium.org>
+Description:
+               The dbc_iProduct attribute allows to change the iProduct field
+               presented in the USB device descriptor by xhci debug device.
+               Value can only be changed while debug capability (DbC) is in
+               disabled state to prevent USB device descriptor change while
+               connected to a USB host.
+               The default value is "Linux USB Debug Target".
+               The field length can be from 1 to 63 characters.
diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
index c5bfd40bd496..d2f64a9a389b 100644
--- a/drivers/usb/host/xhci-dbgcap.c
+++ b/drivers/usb/host/xhci-dbgcap.c
@@ -1206,6 +1206,40 @@ static ssize_t dbc_bcdDevice_store(struct device *dev,
 	return size;
 }
 
+static ssize_t dbc_product_show(struct device *dev,
+				 struct device_attribute *attr,
+				 char *buf)
+{
+	struct xhci_hcd	*xhci = hcd_to_xhci(dev_get_drvdata(dev));
+	struct xhci_dbc	*dbc = xhci->dbc;
+
+	return sysfs_emit(buf, "%s\n", dbc->str.product);
+}
+
+static ssize_t dbc_product_store(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t size)
+{
+	struct xhci_hcd	*xhci = hcd_to_xhci(dev_get_drvdata(dev));
+	struct xhci_dbc	*dbc = xhci->dbc;
+	size_t len;
+
+	if (dbc->state != DS_DISABLED)
+		return -EBUSY;
+
+	len = strcspn(buf, "\n");
+	if (!len)
+		return -EINVAL;
+
+	if (len > USB_MAX_STRING_LEN)
+		return -E2BIG;
+
+	memcpy(dbc->str.product, buf, len);
+	dbc->str.product[len] = '\0';
+
+	return size;
+}
+
 static ssize_t dbc_serial_show(struct device *dev,
 			    struct device_attribute *attr,
 			    char *buf)
@@ -1328,6 +1362,7 @@ static DEVICE_ATTR_RW(dbc_idVendor);
 static DEVICE_ATTR_RW(dbc_idProduct);
 static DEVICE_ATTR_RW(dbc_bcdDevice);
 static DEVICE_ATTR_RW(dbc_serial);
+static DEVICE_ATTR_RW(dbc_product);
 static DEVICE_ATTR_RW(dbc_bInterfaceProtocol);
 static DEVICE_ATTR_RW(dbc_poll_interval_ms);
 
@@ -1337,6 +1372,7 @@ static struct attribute *dbc_dev_attrs[] = {
 	&dev_attr_dbc_idProduct.attr,
 	&dev_attr_dbc_bcdDevice.attr,
 	&dev_attr_dbc_serial.attr,
+	&dev_attr_dbc_product.attr,
 	&dev_attr_dbc_bInterfaceProtocol.attr,
 	&dev_attr_dbc_poll_interval_ms.attr,
 	NULL
-- 
2.51.2.1041.gc1ab5b90ca-goog


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v3 4/4] xhci: dbc: allow to set manufacturer name through sysfs
  2025-11-12 23:15 [PATCH v3 0/4] Enable to set DbC strings through sysfs Łukasz Bartosik
                   ` (2 preceding siblings ...)
  2025-11-12 23:15 ` [PATCH v3 3/4] xhci: dbc: allow to set product name " Łukasz Bartosik
@ 2025-11-12 23:15 ` Łukasz Bartosik
  3 siblings, 0 replies; 5+ messages in thread
From: Łukasz Bartosik @ 2025-11-12 23:15 UTC (permalink / raw)
  To: Mathias Nyman, Greg Kroah-Hartman
  Cc: Alan Stern, linux-usb, Łukasz Bartosik

From: Łukasz Bartosik <ukaszb@chromium.org>

Add code which allows to set manufacturer name of a DbC
device through sysfs.

Signed-off-by: Łukasz Bartosik <ukaszb@chromium.org>
---
 .../testing/sysfs-bus-pci-drivers-xhci_hcd    | 12 +++++++
 drivers/usb/host/xhci-dbgcap.c                | 36 +++++++++++++++++++
 2 files changed, 48 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd b/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd
index 57ba37606f79..26ca6a870e44 100644
--- a/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd
+++ b/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd
@@ -109,3 +109,15 @@ Description:
                connected to a USB host.
                The default value is "Linux USB Debug Target".
                The field length can be from 1 to 63 characters.
+
+What:          /sys/bus/pci/drivers/xhci_hcd/.../dbc_Manufacturer
+Date:          October 2025
+Contact:       Łukasz Bartosik <ukaszb@chromium.org>
+Description:
+               The dbc_iManufacturer attribute allows to change the iManufacturer
+               field presented in the USB device descriptor by xhci debug device.
+               Value can only be changed while debug capability (DbC) is in
+               disabled state to prevent USB device descriptor change while
+               connected to a USB host.
+               The default value is "Linux Foundation".
+               The field length can be from 1 to 63 characters.
diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
index d2f64a9a389b..384c5ab400e4 100644
--- a/drivers/usb/host/xhci-dbgcap.c
+++ b/drivers/usb/host/xhci-dbgcap.c
@@ -1206,6 +1206,40 @@ static ssize_t dbc_bcdDevice_store(struct device *dev,
 	return size;
 }
 
+static ssize_t dbc_manufacturer_show(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf)
+{
+	struct xhci_hcd	*xhci = hcd_to_xhci(dev_get_drvdata(dev));
+	struct xhci_dbc	*dbc = xhci->dbc;
+
+	return sysfs_emit(buf, "%s\n", dbc->str.manufacturer);
+}
+
+static ssize_t dbc_manufacturer_store(struct device *dev,
+				       struct device_attribute *attr,
+				       const char *buf, size_t size)
+{
+	struct xhci_hcd	*xhci = hcd_to_xhci(dev_get_drvdata(dev));
+	struct xhci_dbc	*dbc = xhci->dbc;
+	size_t len;
+
+	if (dbc->state != DS_DISABLED)
+		return -EBUSY;
+
+	len = strcspn(buf, "\n");
+	if (!len)
+		return -EINVAL;
+
+	if (len > USB_MAX_STRING_LEN)
+		return -E2BIG;
+
+	memcpy(dbc->str.manufacturer, buf, len);
+	dbc->str.manufacturer[len] = '\0';
+
+	return size;
+}
+
 static ssize_t dbc_product_show(struct device *dev,
 				 struct device_attribute *attr,
 				 char *buf)
@@ -1363,6 +1397,7 @@ static DEVICE_ATTR_RW(dbc_idProduct);
 static DEVICE_ATTR_RW(dbc_bcdDevice);
 static DEVICE_ATTR_RW(dbc_serial);
 static DEVICE_ATTR_RW(dbc_product);
+static DEVICE_ATTR_RW(dbc_manufacturer);
 static DEVICE_ATTR_RW(dbc_bInterfaceProtocol);
 static DEVICE_ATTR_RW(dbc_poll_interval_ms);
 
@@ -1373,6 +1408,7 @@ static struct attribute *dbc_dev_attrs[] = {
 	&dev_attr_dbc_bcdDevice.attr,
 	&dev_attr_dbc_serial.attr,
 	&dev_attr_dbc_product.attr,
+	&dev_attr_dbc_manufacturer.attr,
 	&dev_attr_dbc_bInterfaceProtocol.attr,
 	&dev_attr_dbc_poll_interval_ms.attr,
 	NULL
-- 
2.51.2.1041.gc1ab5b90ca-goog


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2025-11-12 23:16 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-12 23:15 [PATCH v3 0/4] Enable to set DbC strings through sysfs Łukasz Bartosik
2025-11-12 23:15 ` [PATCH v3 1/4] xhci: dbc: prepare to expose " Łukasz Bartosik
2025-11-12 23:15 ` [PATCH v3 2/4] xhci: dbc: allow to set serial number " Łukasz Bartosik
2025-11-12 23:15 ` [PATCH v3 3/4] xhci: dbc: allow to set product name " Łukasz Bartosik
2025-11-12 23:15 ` [PATCH v3 4/4] xhci: dbc: allow to set manufacturer " Łukasz Bartosik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).