* Re: [PATCH v4 1/3] usb: xhci: Add support for eUSB2v2 1024-byte bulk packet size
2026-10-09 6:49 ` [PATCH v4 1/3] usb: xhci: Add support for eUSB2v2 1024-byte bulk packet size Pawel Laszczak via B4 Relay
@ 2026-10-09 6:38 ` sashiko-bot
0 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-10-09 6:38 UTC (permalink / raw)
To: Pawel Laszczak; +Cc: linux-usb
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] usb: xhci: eUSB2v2 1KB mode erroneously enabled for Full-Speed devices
- [High] usb: class drivers under-allocate RX buffers due to unmodified wMaxPacketSize
- [Medium] usb: xhci: incorrect URB_ZERO_PACKET evaluation for 1KB bulk OUT endpoints
--
commit 54ae7d8065840029212e7f3efbe68ad6defca543
Author: Pawel Laszczak <pawell@cadence.com>
Subject: usb: xhci: Add support for eUSB2v2 1024-byte bulk packet size
This commit introduces support for 1024-byte maximum packet sizes for Bulk
endpoints in High-Speed mode on eUSB2v2 capable hosts. It introduces an
is_eusb2v2 flag and issues a SET_FEATURE request to switch compatible
peripherals to 1024-byte packet mode.
> diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
> index 0cd6dd2b6334b..311b8fd3bf44f 100644
> --- a/drivers/usb/core/message.c
> +++ b/drivers/usb/core/message.c
[ ... ]
> @@ -2013,6 +2013,69 @@ int usb_set_wireless_status(struct usb_interface *iface,
> }
> EXPORT_SYMBOL_GPL(usb_set_wireless_status);
>
> +/*
> + * eusb_update_max_packet - enable 1024-byte bulk mode for eUSB2v2 device
> + * @udev: target device
> + * @cp: configuration to be checked and enabled
> + *
> + * Per eUSB2v2 spec section 5.2, an eUSB2v2 peripheral will revert the
> + * maximum packet size to 512 for bulk endpoints after bus reset, disconnect,
> + * or deconfiguration.
> + * This function sends the BULK_MAX_PACKET_UPDATE request to restore the
> + * 1024-byte mode. It is valid only if the configuration has bulk endpoints.
> + */
> +int eusb_update_max_packet(struct usb_device *udev, struct usb_host_config *cp)
> +{
> + struct usb_host_config *config = cp ? cp : udev->actconfig;
> + struct usb_hcd *hcd = bus_to_hcd(udev->bus);
> + struct usb_interface_cache *intfc;
> + struct usb_host_interface *alt;
> + struct usb_host_endpoint *ep;
> + int i, j, a;
> + int ret;
> +
> + udev->eusb2v2_mps_active = 0;
> +
> + if (le16_to_cpu(udev->descriptor.bcdUSB) != 0x0230 ||
> + !hcd->self.is_eusb2v2)
> + return -EOPNOTSUPP;
[Severity: High]
Does this need to check udev->speed == USB_SPEED_HIGH? If an eUSB2v2-compliant
device is connected but enumerates at Full-Speed, eusb_update_max_packet()
could send the feature request and set udev->eusb2v2_mps_active to 1.
If this happens, xhci_usb_endpoint_maxp() will unconditionally return 1024 for
the Full-Speed bulk endpoint, leading to a conflict in xhci_endpoint_init()
where the hardware endpoint context is clamped to 64 bytes:
drivers/usb/host/xhci-mem.c:xhci_endpoint_init() {
if (udev->speed == USB_SPEED_FULL) {
max_packet = rounddown_pow_of_two(max_packet);
max_packet = clamp_val(max_packet, 8, 64);
}
}
Can this discrepancy between the 64-byte hardware context and the 1024-byte
TRBs generated by software lead to malformed TRBs and transfer failures?
> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index a9e47e178c280..8e630d323c6fb 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
[ ... ]
> @@ -2949,6 +2949,11 @@ int xhci_usb_endpoint_maxp(struct usb_device *udev,
> {
> if (usb_endpoint_is_hs_isoc_double(udev, host_ep))
> return le16_to_cpu(host_ep->eusb2_isoc_ep_comp.wMaxPacketSize);
> +
> + if (udev->eusb2v2_mps_active &&
> + usb_endpoint_xfer_bulk(&host_ep->desc))
> + return 1024;
> +
> return usb_endpoint_maxp(&host_ep->desc);
> }
[Severity: High]
By dynamically overriding the packet size to 1024 bytes here for xHCI, while
leaving ep->desc.wMaxPacketSize as 512 bytes, could this cause higher-level
USB class drivers to under-allocate their transfer buffers?
Class drivers (like CDC NCM) rely entirely on usb_endpoint_maxp(&ep->desc) to
determine the size of incoming packets and pre-allocate their buffers. If they
allocate 512 bytes based on the unmodified descriptor, an incoming 1024-byte
packet could overflow the buffer and abort the transfer.
[Severity: Medium]
Additionally, does leaving the descriptor at 512 bytes cause an incorrect
URB_ZERO_PACKET evaluation for Bulk OUT transfers?
In xhci_urb_enqueue(), the need for a Zero-Length Packet is evaluated as:
!(urb->transfer_buffer_length % usb_endpoint_maxp(&urb->ep->desc))
Since usb_endpoint_maxp() reads the unadjusted descriptor value of 512, an OUT
transfer length that is a multiple of 512 but not 1024 (e.g., 1536 bytes)
might incorrectly satisfy this condition and append an unnecessary Zero-Length
Packet, violating the bulk protocol.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261009-eusb2v2-packet-size-v4-0-a505ee17b460@cadence.com?part=1
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v4 3/3] usb: cdns3: cdnsp: Enable eUSB2v2 1KB bulk packet capability
2026-10-09 6:49 ` [PATCH v4 3/3] usb: cdns3: cdnsp: Enable eUSB2v2 1KB bulk packet capability Pawel Laszczak via B4 Relay
@ 2026-10-09 6:41 ` sashiko-bot
0 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-10-09 6:41 UTC (permalink / raw)
To: Pawel Laszczak; +Cc: linux-usb
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] usb: cdns3: TRB logic uses incorrect 512-byte maxp for 1024-byte eUSB2v2 endpoints
- [High] usb: cdns3: Missing hardware capability check for eUSB2v2 MPS update
--
commit 5efa1eec93f4abee65d86f70cca3c1177b04dfda
Author: Pawel Laszczak <pawell@cadence.com>
usb: cdns3: cdnsp: Enable eUSB2v2 1KB bulk packet capability
This commit implements peripheral-side changes in the Cadence (cdnsp) driver
to support eUSB2v2 1024-byte Bulk MaxPacketSize. It checks for eUSB2v2
capability in the HCCPARAMS2 register, delegates bulk max packet update
requests to the composite layer, and dynamically configures the hardware
endpoint for a 1024-byte packet size when the feature is active.
> diff --git a/drivers/usb/cdns3/cdnsp-ep0.c b/drivers/usb/cdns3/cdnsp-ep0.c
> index 5cd9b898ce971..090d20b307ee2 100644
> --- a/drivers/usb/cdns3/cdnsp-ep0.c
> +++ b/drivers/usb/cdns3/cdnsp-ep0.c
> @@ -253,6 +253,8 @@ static int cdnsp_ep0_handle_feature_device(struct cdnsp_device *pdev,
> */
> cdnsp_enter_test_mode(pdev);
> break;
> + case USB_DEVICE_BULK_MAX_PACKET_UPDATE:
> + return cdnsp_ep0_delegate_req(pdev, ctrl);
[Severity: High]
Does this code need to verify that the controller is actually eUSB2v2 capable
(pdev->gadget.is_eusb2v2) before delegating the request?
The composite gadget framework unconditionally sets gadget->eusb2v2_mps_active = 1
when it receives USB_DEVICE_BULK_MAX_PACKET_UPDATE without checking
gadget->is_eusb2v2:
drivers/usb/gadget/composite.c:composite_setup() {
...
case USB_DEVICE_BULK_MAX_PACKET_UPDATE:
if (ctrl->bRequestType != (USB_DIR_OUT | USB_RECIP_DEVICE))
goto unknown;
if (ctrl->bRequest != USB_REQ_SET_FEATURE)
goto unknown;
gadget->eusb2v2_mps_active = 1;
...
}
If a malicious or improperly configured USB host sends this request to a
non-eUSB2v2 capable device, this delegation allows the flag to be set, leading
to cdnsp_endpoint_init() configuring a 1024-byte maximum packet size on
unsupported hardware.
> default:
> return -EINVAL;
> }
[ ... ]
> diff --git a/drivers/usb/cdns3/cdnsp-mem.c b/drivers/usb/cdns3/cdnsp-mem.c
> index 419309c8439e3..a499887ed5618 100644
> --- a/drivers/usb/cdns3/cdnsp-mem.c
> +++ b/drivers/usb/cdns3/cdnsp-mem.c
> @@ -976,8 +976,13 @@ int cdnsp_endpoint_init(struct cdnsp_device *pdev,
> if (!usb_endpoint_xfer_isoc(pep->endpoint.desc))
> err_count = 3;
> if (usb_endpoint_xfer_bulk(pep->endpoint.desc) &&
> - pdev->gadget.speed == USB_SPEED_HIGH)
> - max_packet = 512;
> + pdev->gadget.speed == USB_SPEED_HIGH) {
> + if (pdev->gadget.eusb2v2_mps_active)
> + max_packet = 1024;
[Severity: High]
Does the TRB generation logic in drivers/usb/cdns3/cdnsp-ring.c need to be
updated to handle the 1024-byte max packet size?
While the hardware endpoint context is correctly programmed to 1024 bytes here,
functions in cdnsp-ring.c still rely on usb_endpoint_maxp(ep->desc), which
evaluates to 512 bytes.
For example, calculating ZLP boundaries:
drivers/usb/cdns3/cdnsp-ring.c:cdnsp_queue_bulk_tx() {
...
if (preq->request.zero && preq->request.length &&
IS_ALIGNED(full_len, usb_endpoint_maxp(pep->endpoint.desc))) {
need_zero_pkt = true;
num_trbs++;
}
...
}
Calculating bounce buffer alignment:
drivers/usb/cdns3/cdnsp-ring.c:cdnsp_align_td() {
...
max_pkt = usb_endpoint_maxp(preq->pep->endpoint.desc);
unalign = (enqd_len + *trb_buff_len) % max_pkt;
...
}
Calculating TRB TD size:
drivers/usb/cdns3/cdnsp-ring.c:cdnsp_td_remainder() {
...
maxp = usb_endpoint_maxp(preq->pep->endpoint.desc);
total_packet_count = DIV_ROUND_UP(td_total_len, maxp);
...
}
This causes the driver to incorrectly calculate ZLP boundaries on 512-byte
boundaries instead of 1024, fragment TRBs into 512-byte bounce buffers, and
provide wrong TRB_TD_SIZE metrics to the hardware scheduler.
> + else
> + max_packet = 512;
> + }
> +
> /* Controller spec indicates that ctrl ep avg TRB Length should be 8. */
> if (usb_endpoint_xfer_control(pep->endpoint.desc))
> avg_trb_len = 8;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261009-eusb2v2-packet-size-v4-0-a505ee17b460@cadence.com?part=3
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v4 2/3] usb: gadget: composite: Support eUSB2v2 bulk MPS update
2026-10-09 6:49 ` [PATCH v4 2/3] usb: gadget: composite: Support eUSB2v2 bulk MPS update Pawel Laszczak via B4 Relay
@ 2026-10-09 6:43 ` sashiko-bot
0 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-10-09 6:43 UTC (permalink / raw)
To: Pawel Laszczak; +Cc: linux-usb
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] usb: composite: Data race on bitfields in struct usb_gadget
- [High] usb: composite: eUSB2v2 capability check breaks SuperSpeed device descriptors
- [Medium] usb: composite: Missing capability check before accepting eUSB2v2 feature
- [Medium] usb: composite: Missing fallback for unhandled SET_FEATURE requests breaks delegation
--
commit 6017c856bde8d3fefac3ad153909a02705baae1f
Author: Pawel Laszczak <pawell@cadence.com>
usb: gadget: composite: Support eUSB2v2 bulk MPS update
This commit adds support for eUSB2v2 1024-byte Bulk MPS negotiation to the
Gadget Composite framework.
> diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
> --- a/drivers/usb/gadget/composite.c
> +++ b/drivers/usb/gadget/composite.c
[ ... ]
> @@ -1807,7 +1808,11 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
> count_configs(cdev, USB_DT_DEVICE);
> cdev->desc.bMaxPacketSize0 =
> cdev->gadget->ep0->maxpacket;
> - if (gadget_is_superspeed(gadget)) {
> +
> + if (gadget->is_eusb2v2) {
> + cdev->desc.bcdUSB = cpu_to_le16(0x0230);
> + cdev->desc.bMaxPacketSize0 = 64;
> + } else if (gadget_is_superspeed(gadget)) {
[Severity: High]
Does this static capability check unconditionally override the descriptor
fields and ignore the current negotiated link speed?
is_eusb2v2 is a static capability flag set by dual-speed UDC drivers at
probe time. If a dual-speed device is plugged into a USB 3.0 port and
enumerates at SuperSpeed:
composite_setup()
switch (w_value >> 8) {
case USB_DT_DEVICE:
if (gadget->is_eusb2v2) {
...
} else if (gadget_is_superspeed(gadget)) {
...
}
The code will incorrectly report bMaxPacketSize0 = 64 instead of the
strictly required value of 9 (representing 2^9 = 512 bytes for SuperSpeed).
Can this break USB 3.x host enumeration for any UDC supporting eUSB2v2?
[ ... ]
> @@ -2006,12 +2011,20 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
> */
> case USB_REQ_CLEAR_FEATURE:
> case USB_REQ_SET_FEATURE:
> - if (!gadget_is_superspeed(gadget))
> - goto unknown;
> - if (ctrl->bRequestType != (USB_DIR_OUT | USB_RECIP_INTERFACE))
> - goto unknown;
> switch (w_value) {
[Severity: Medium]
Does this switch block miss a fallback for unhandled SET_FEATURE requests?
Standard requests with w_value that are not explicitly handled in the
switch (for example USB_DEVICE_REMOTE_WAKEUP, USB_DEVICE_TEST_MODE, or
USB_DEVICE_U1_ENABLE) will fall through the switch, hit the outer break,
and return -EOPNOTSUPP directly.
Could this bypass the goto unknown delegation block entirely, breaking
userspace gadget drivers like FunctionFS that rely on intercepting
device-level feature requests by setting the FUNCTIONFS_ALL_CTRL_RECIP flag?
> + case USB_DEVICE_BULK_MAX_PACKET_UPDATE:
> + if (ctrl->bRequestType != (USB_DIR_OUT | USB_RECIP_DEVICE))
> + goto unknown;
> + if (ctrl->bRequest != USB_REQ_SET_FEATURE)
> + goto unknown;
[Severity: Medium]
Is a capability check missing before accepting the eUSB2v2 feature?
If a host incorrectly sends this eUSB2-specific feature to a standard
USB 2.0 or 3.0 gadget, the gadget will inappropriately ACK the feature
here instead of STALLing it, because there is no verification of
if (gadget->is_eusb2v2).
Can this cause the host to incorrectly assume 1024-byte bulk packets are
supported and transmit them, leading to hardware babble errors or DMA
overflows on standard UDCs configured for 512-byte max packet sizes?
> + gadget->eusb2v2_mps_active = 1;
> + value = 0;
> + break;
[Severity: High]
Does this bitfield write in interrupt context introduce a data race?
composite_setup() runs in the UDC endpoint 0 interrupt context, and
gadget->eusb2v2_mps_active = 1 is written here without taking a lock that
serializes with process-context writers.
In include/linux/usb/gadget.h, eusb2v2_mps_active shares a bitfield word
with other flags like connected and deactivated:
struct usb_gadget {
...
unsigned connected:1;
...
unsigned is_eusb2v2:1;
unsigned eusb2v2_mps_active:1;
};
Those other fields are written in process context (for example, in
usb_gadget_connect()) while holding the connect_lock mutex, which does
not disable interrupts.
Since bitfield updates compile down to non-atomic Read-Modify-Write (RMW)
operations on the full word, an interrupt occurring during a process-context
RMW will cause the interrupt's bitfield write to be silently overwritten and
lost, or vice versa. Can this randomly drop the gadget's fundamental
connection state?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261009-eusb2v2-packet-size-v4-0-a505ee17b460@cadence.com?part=2
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v4 0/3] usb: Add support for eUSB2v2 1024-byte Bulk MaxPacketSize
@ 2026-10-09 6:49 Pawel Laszczak via B4 Relay
2026-10-09 6:49 ` [PATCH v4 1/3] usb: xhci: Add support for eUSB2v2 1024-byte bulk packet size Pawel Laszczak via B4 Relay
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Pawel Laszczak via B4 Relay @ 2026-10-09 6:49 UTC (permalink / raw)
To: Greg Kroah-Hartman, Mathias Nyman; +Cc: linux-usb, linux-kernel, Pawel Laszczak
The Embedded USB2 (eUSB2) v2 specification (bcdUSB 0x0230) introduces a
mechanism that allows High-Speed Bulk endpoints to support a maximum
packet size (MPS) of 1024 bytes, expanding it from the traditional
512-byte limit defined in the standard USB 2.0 specification.
This capability is highly beneficial for Mass Storage Class (MSC)
devices, significantly improving overall throughput.
Per the eUSB2v2 specification, a peripheral device will revert its
internal Bulk MPS back to 512 bytes after major bus events, including a
bus reset, disconnect, or deconfiguration. To establish and maintain
the 1024-byte mode, the host controller must explicitly issue
a device-recipient SET_FEATURE request called
USB_DEVICE_BULK_MAX_PACKET_UPDATE. This must occur after the device enters
the ADDRESSED state, but strictly before it transitions to the CONFIGURED
state.
This patch series implements the required infrastructure on both the host
and gadget sides, and enables it for the Cadence (cdnsp) controller.
Structure of the series:
- Patch 1: Introduces host-side core support in usb_set_configuration() to
detect eUSB2v2 devices and issue the SET_FEATURE update request prior to
activating the device configuration. Adds eusb2v2_mps_active flag to
struct usb_device to track negotiation state. Extends hub.c to re-issue
SET_FEATURE after bus reset in usb_reset_and_verify_device(); on failure
triggers re-enumeration to prevent driver from operating with
inconsistent MPS state. Also updates xHCI endpoint initialization
to allow 1024-byte packets for High-Speed Bulk endpoints when HCC2_E2V2C
is present.
- Patch 2: Extends the USB Gadget Composite framework to advertise bcdUSB
0x0230 when eUSB2v2 is supported, intercept the incoming feature
request, and dynamically update the wMaxPacketSize fields across all
High-Speed Bulk descriptors before configuration is completed.
- Patch 3: Implements peripheral-specific handling in the Cadence (cdnsp)
driver, reading HCCPARAMS2 to discover the hardware capability and
adapting cdnsp_endpoint_init() boundaries to allow for the larger
packet size.
Testing:
The flow has been validated using the Cadence eUSB2v2 Host and Device
controllers, ensuring seamless transition to 1024-byte mode during early
enumeration stages and successful verification under USB-IF Compliance
Verification (CV) tooling.
Signed-off-by: Pawel Laszczak <pawell@cadence.com>
---
Changes in v4:
- [Patch 1/3] Removed redundant code and simplified conditions based on
community feedback:
- Eliminated duplicate error logging in eusb_update_max_packet().
- Cleaned up control flow in eusb_update_max_packet() by dropping the
redundant `has_bulk` variable.
- Made eusb_update_max_packet() return -EOPNOTSUPP, which simplified
the active flag assignment in usb_set_configuration().
- Moved eusb2v2_mps_active flag management entirely inside
eusb_update_max_packet().
- Dropped a redundant defensive USB_SPEED_HIGH check in xhci_usb_endpoint_maxp().
- [Patch 2/3] and [Patch 3/3] No changes.
- Link to v3: https://patch.msgid.link/20261005-eusb2v2-packet-size-v3-0-fde610a3c47a@cadence.com
Changes in v3:
- message.c: Add check for bulk endpoint existence before sending
BULK_MAX_PACKET_UPDATE. This avoids sending the request to devices that
only use isochronous endpoints, as they do not support it.
- host & gadget: Do not overwrite ep->desc.wMaxPacketSize to 1024.
According to eUSB2v2 spec section 5.2, the endpoint descriptor must
always report 512 bytes regardless of the current operating mode.
- host: Rely on the eusb2v2_mps_active flag in xhci_usb_endpoint_maxp()
to dynamically return 1024 for HS bulk endpoints when the 1KB mode
is active.
- gadget: Introduce gadget->eusb2v2_mps_active flag to let the composite
framework report 512 bytes while the UDC dynamically sets 1KB max packet
size in hardware.
- Link to v2: https://patch.msgid.link/20260826-eusb2v2-packet-size-v2-0-950f19f38ef0@cadence.com
Changes in v2:
- Removed config.c change: per eUSB2v2 spec section 5.2, conformant devices
always report wMaxPacketSize=512 in their descriptor regardless of operating
mode, so the warning suppression was unnecessary.
- eusb_update_max_packet(): changed from void to int; added error propagation
and eusb2v2_mps_active state tracking.
- Added hub.c handling to restore 1KB mode after bus reset, with re-enumeration
on failure (addresses Oliver Neukum's review comments).
- xhci-mem.c: simplified HS bulk clamp logic.
- xhci.c: moved is_eusb2v2 assignment into xhci_hcd_init_usb2_data().
- composite.c: stall CLEAR_FEATURE(BULK_MAX_PACKET_UPDATE) as it is not
defined by the eUSB2v2 spec.
- cdnsp-mem.c: simplified HS bulk clamp logic, consistent with xhci-mem.c.
- Link to v1: https://patch.msgid.link/20260717-eusb2v2-packet-size-v1-0-67c611bd0c5b@cadence.com
---
Pawel Laszczak (3):
usb: xhci: Add support for eUSB2v2 1024-byte bulk packet size
usb: gadget: composite: Support eUSB2v2 bulk MPS update
usb: cdns3: cdnsp: Enable eUSB2v2 1KB bulk packet capability
drivers/usb/cdns3/cdnsp-ep0.c | 2 ++
drivers/usb/cdns3/cdnsp-gadget.c | 4 +++
drivers/usb/cdns3/cdnsp-gadget.h | 8 +++++
drivers/usb/cdns3/cdnsp-mem.c | 9 ++++--
drivers/usb/common/debug.c | 2 ++
drivers/usb/core/hub.c | 16 ++++++++++
drivers/usb/core/message.c | 67 ++++++++++++++++++++++++++++++++++++++++
drivers/usb/core/usb.h | 2 ++
drivers/usb/gadget/composite.c | 28 ++++++++++++-----
drivers/usb/host/xhci-mem.c | 15 +++++++--
drivers/usb/host/xhci.c | 9 ++++++
include/linux/usb.h | 7 +++++
include/linux/usb/gadget.h | 4 +++
13 files changed, 161 insertions(+), 12 deletions(-)
---
base-commit: 1d52b92ce8748624f84eca7eaea3ac31ed7b09a5
change-id: 20260609-eusb2v2-packet-size-4cb668455465
Best regards,
--
Pawel Laszczak <pawell@cadence.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v4 1/3] usb: xhci: Add support for eUSB2v2 1024-byte bulk packet size
2026-10-09 6:49 [PATCH v4 0/3] usb: Add support for eUSB2v2 1024-byte Bulk MaxPacketSize Pawel Laszczak via B4 Relay
@ 2026-10-09 6:49 ` Pawel Laszczak via B4 Relay
2026-10-09 6:38 ` sashiko-bot
2026-10-09 6:49 ` [PATCH v4 2/3] usb: gadget: composite: Support eUSB2v2 bulk MPS update Pawel Laszczak via B4 Relay
2026-10-09 6:49 ` [PATCH v4 3/3] usb: cdns3: cdnsp: Enable eUSB2v2 1KB bulk packet capability Pawel Laszczak via B4 Relay
2 siblings, 1 reply; 7+ messages in thread
From: Pawel Laszczak via B4 Relay @ 2026-10-09 6:49 UTC (permalink / raw)
To: Greg Kroah-Hartman, Mathias Nyman; +Cc: linux-usb, linux-kernel, Pawel Laszczak
From: Pawel Laszczak <pawell@cadence.com>
The eUSB2 v2 specification (bcdUSB 0x0230) introduces support for
1024-byte maximum packet sizes for Bulk endpoints in High-Speed mode.
However, an eUSB2v2 peripheral will revert its internal maximum packet
size back to 512 bytes after events like a bus reset, disconnect, or
deconfiguration.
To support 1024-byte bulk transfers on capable hosts, add a new
is_eusb2v2 flag to the usb_bus structure, populated via the HCCPARAMS2
E2V2C capability bit in the xHCI driver.
When an eUSB2v2 host configures an eUSB2v2 device, issue a specific
SET_FEATURE (USB_DEVICE_BULK_MAX_PACKET_UPDATE) request during device
configuration to switch the peripheral to 1024-byte packet mode, and
allow the xHCI endpoint initialization to accept up to 1024 bytes for
HS bulk endpoints.
Signed-off-by: Pawel Laszczak <pawell@cadence.com>
---
Changes in v4:
- Removed duplicate dev_warn logging inside eusb_update_max_packet()
as errors are handled and logged by the caller.
- Removed redundant `has_bulk` variable in eusb_update_max_packet().
- Modified eusb_update_max_packet() to return -EOPNOTSUPP for non-eUSB2
devices, simplifying the condition logic in usb_set_configuration().
- Removed unnecessary udev->speed == USB_SPEED_HIGH check from
xhci_usb_endpoint_maxp().
- Moved eusb2v2_mps_active flag management entirely inside
eusb_update_max_packet()
Changes in v3:
- Add check for bulk endpoint existence before sending
BULK_MAX_PACKET_UPDATE. This avoids sending the request to devices that
only use isochronous endpoints, as they do not support it.
- Do not overwrite ep->desc.wMaxPacketSize to 1024. According to eUSB2v2
spec section 5.2, the endpoint descriptor must always report 512 bytes
regardless of the current operating mode.
- Rely on the eusb2v2_mps_active flag in xhci_usb_endpoint_maxp() and
xhci-mem.c to dynamically return 1024 for HS bulk endpoints when the 1KB
mode is active.
Changes in v2:
- Removed change in config.c: per eUSB2v2 spec section 5.2, conformant
devices always report wMaxPacketSize=512 in their descriptor regardless
of operating mode, so the warning suppression was unnecessary.
- xhci-mem.c: simplified HS bulk clamp
- xhci.c: moved is_eusb2v2 assignment into xhci_hcd_init_usb2_data()
- eusb_update_max_packet(): changed from void to int; returns error on
SET_FEATURE failure.
- Added eusb2v2_mps_active flag to struct usb_device to track whether
SET_FEATURE(BULK_MAX_PACKET_UPDATE) succeeded.
- Added hub.c: usb_reset_and_verify_device() now re-issues SET_FEATURE
after bus reset to restore 1KB mode. Failure triggers re-enumeration
to prevent a driver from operating with inconsistent MPS state.
---
drivers/usb/core/hub.c | 16 +++++++++++
drivers/usb/core/message.c | 67 +++++++++++++++++++++++++++++++++++++++++++++
drivers/usb/core/usb.h | 2 ++
drivers/usb/host/xhci-mem.c | 15 ++++++++--
drivers/usb/host/xhci.c | 9 ++++++
include/linux/usb.h | 7 +++++
6 files changed, 113 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 24960ba9caa9..34cfc44c5df8 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -6252,6 +6252,22 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
mutex_unlock(hcd->bandwidth_mutex);
goto re_enumerate;
}
+
+ /*
+ * Restore eUSB2v2 1KB bulk mode after reset (device reverts to 512
+ * after any bus reset per eUSB2v2 spec section 5.2).
+ * Only retry if the initial SET_FEATURE had succeeded.
+ */
+ if (udev->eusb2v2_mps_active) {
+ ret = eusb_update_max_packet(udev, udev->actconfig);
+ if (ret < 0) {
+ dev_err(&udev->dev,
+ "eUSB2v2: failed to restore 1KB mode after reset (%d)\n", ret);
+ mutex_unlock(hcd->bandwidth_mutex);
+ goto re_enumerate;
+ }
+ }
+
ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
USB_REQ_SET_CONFIGURATION, 0,
udev->actconfig->desc.bConfigurationValue, 0,
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 75e2bfd744a9..027e7c85524e 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -2007,6 +2007,69 @@ int usb_set_wireless_status(struct usb_interface *iface,
}
EXPORT_SYMBOL_GPL(usb_set_wireless_status);
+/*
+ * eusb_update_max_packet - enable 1024-byte bulk mode for eUSB2v2 device
+ * @udev: target device
+ * @cp: configuration to be checked and enabled
+ *
+ * Per eUSB2v2 spec section 5.2, an eUSB2v2 peripheral will revert the
+ * maximum packet size to 512 for bulk endpoints after bus reset, disconnect,
+ * or deconfiguration.
+ * This function sends the BULK_MAX_PACKET_UPDATE request to restore the
+ * 1024-byte mode. It is valid only if the configuration has bulk endpoints.
+ */
+int eusb_update_max_packet(struct usb_device *udev, struct usb_host_config *cp)
+{
+ struct usb_host_config *config = cp ? cp : udev->actconfig;
+ struct usb_hcd *hcd = bus_to_hcd(udev->bus);
+ struct usb_interface_cache *intfc;
+ struct usb_host_interface *alt;
+ struct usb_host_endpoint *ep;
+ int i, j, a;
+ int ret;
+
+ udev->eusb2v2_mps_active = 0;
+
+ if (le16_to_cpu(udev->descriptor.bcdUSB) != 0x0230 ||
+ !hcd->self.is_eusb2v2)
+ return -EOPNOTSUPP;
+
+ if (!config)
+ return 0;
+
+ for (i = 0; i < config->desc.bNumInterfaces; i++) {
+ intfc = config->intf_cache[i];
+
+ if (!intfc)
+ continue;
+
+ for (a = 0; a < intfc->num_altsetting; a++) {
+ alt = &intfc->altsetting[a];
+
+ for (j = 0; j < alt->desc.bNumEndpoints; j++) {
+ ep = &alt->endpoint[j];
+
+ if (usb_endpoint_xfer_bulk(&ep->desc))
+ goto found_bulk;
+ }
+ }
+ }
+
+ return 0;
+
+found_bulk:
+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ USB_REQ_SET_FEATURE, USB_RECIP_DEVICE,
+ USB_DEVICE_BULK_MAX_PACKET_UPDATE, 0, NULL, 0,
+ USB_CTRL_SET_TIMEOUT);
+ if (ret < 0)
+ return ret;
+
+ udev->eusb2v2_mps_active = 1;
+
+ return 0;
+}
+
/*
* usb_set_configuration - Makes a particular device setting be current
* @dev: the device whose configuration is being updated
@@ -2123,6 +2186,10 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
if (dev->state != USB_STATE_ADDRESS)
usb_disable_device(dev, 1); /* Skip ep0 */
+ ret = eusb_update_max_packet(dev, cp);
+ if (ret < 0 && ret != -EOPNOTSUPP)
+ dev_err(&dev->dev, "eUSB2v2 1KB update failed: %d\n", ret);
+
/* Get rid of pending async Set-Config requests for this device */
cancel_async_set_config(dev);
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index a9b37aeb515b..c51e4261085c 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -89,6 +89,8 @@ extern int usb_major_init(void);
extern void usb_major_cleanup(void);
extern int usb_device_supports_lpm(struct usb_device *udev);
extern int usb_port_disable(struct usb_device *udev);
+int eusb_update_max_packet(struct usb_device *udev,
+ struct usb_host_config *cp);
#ifdef CONFIG_PM
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 997fe90f54e5..37a5f9e9bd6d 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1479,10 +1479,19 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
/* Allow 3 retries for everything but isoc, set CErr = 3 */
if (!usb_endpoint_xfer_isoc(&ep->desc))
err_count = 3;
- /* HS bulk max packet should be 512, FS bulk supports 8, 16, 32 or 64 */
+
+ /*
+ * HS bulk max packet should be 512 (or 1024 for eUSB2v2),
+ * FS bulk supports 8, 16, 32 or 64.
+ */
if (usb_endpoint_xfer_bulk(&ep->desc)) {
- if (udev->speed == USB_SPEED_HIGH)
- max_packet = 512;
+ if (udev->speed == USB_SPEED_HIGH) {
+ if (udev->eusb2v2_mps_active)
+ max_packet = 1024;
+ else
+ max_packet = 512;
+ }
+
if (udev->speed == USB_SPEED_FULL) {
max_packet = rounddown_pow_of_two(max_packet);
max_packet = clamp_val(max_packet, 8, 64);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index a54f5b57f205..4ce98fd7e4b7 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -2951,6 +2951,11 @@ int xhci_usb_endpoint_maxp(struct usb_device *udev,
{
if (usb_endpoint_is_hs_isoc_double(udev, host_ep))
return le16_to_cpu(host_ep->eusb2_isoc_ep_comp.wMaxPacketSize);
+
+ if (udev->eusb2v2_mps_active &&
+ usb_endpoint_xfer_bulk(&host_ep->desc))
+ return 1024;
+
return usb_endpoint_maxp(&host_ep->desc);
}
@@ -5371,6 +5376,10 @@ static void xhci_hcd_init_usb2_data(struct xhci_hcd *xhci, struct usb_hcd *hcd)
xhci->usb2_rhub.hcd = hcd;
hcd->speed = HCD_USB2;
hcd->self.root_hub->speed = USB_SPEED_HIGH;
+
+ if (xhci->hcc_params2 & HCC2_E2V2C)
+ hcd->self.is_eusb2v2 = 1;
+
/*
* USB 2.0 roothub under xHCI has an integrated TT,
* (rate matching hub) as opposed to having an OHCI/UHCI
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 25a203ac7a7e..57fb4c552740 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -464,6 +464,10 @@ struct usb_bus {
* the ep queue on a short transfer
* with the URB_SHORT_NOT_OK flag set.
*/
+ unsigned is_eusb2v2:1; /*
+ * true when HC controller supports
+ * eusb2v2
+ */
unsigned no_sg_constraint:1; /* no sg constraint */
unsigned sg_tablesize; /* 0 or largest number of sg list entries */
@@ -625,6 +629,8 @@ struct usb3_lpm_parameters {
* @usb2_hw_lpm_allowed: Userspace allows USB 2.0 LPM to be enabled
* @usb3_lpm_u1_enabled: USB3 hardware U1 LPM enabled
* @usb3_lpm_u2_enabled: USB3 hardware U2 LPM enabled
+ * @eusb2v2_mps_active: 1024-byte bulk mode is active and must be restored
+ * after bus reset.
* @string_langid: language ID for strings
* @product: iProduct string, if present (static)
* @manufacturer: iManufacturer string, if present (static)
@@ -708,6 +714,7 @@ struct usb_device {
unsigned usb2_hw_lpm_allowed:1;
unsigned usb3_lpm_u1_enabled:1;
unsigned usb3_lpm_u2_enabled:1;
+ unsigned eusb2v2_mps_active:1;
int string_langid;
/* static strings from the device */
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v4 2/3] usb: gadget: composite: Support eUSB2v2 bulk MPS update
2026-10-09 6:49 [PATCH v4 0/3] usb: Add support for eUSB2v2 1024-byte Bulk MaxPacketSize Pawel Laszczak via B4 Relay
2026-10-09 6:49 ` [PATCH v4 1/3] usb: xhci: Add support for eUSB2v2 1024-byte bulk packet size Pawel Laszczak via B4 Relay
@ 2026-10-09 6:49 ` Pawel Laszczak via B4 Relay
2026-10-09 6:43 ` sashiko-bot
2026-10-09 6:49 ` [PATCH v4 3/3] usb: cdns3: cdnsp: Enable eUSB2v2 1KB bulk packet capability Pawel Laszczak via B4 Relay
2 siblings, 1 reply; 7+ messages in thread
From: Pawel Laszczak via B4 Relay @ 2026-10-09 6:49 UTC (permalink / raw)
To: Greg Kroah-Hartman, Mathias Nyman; +Cc: linux-usb, linux-kernel, Pawel Laszczak
From: Pawel Laszczak <pawell@cadence.com>
Add support for eUSB2v2 1024-byte Bulk MPS negotiation to the Gadget
Composite framework.
If 'gadget->is_eusb2v2' is set, force bcdUSB to 0x0230 and bMaxPacketSize0
to 64 bytes. Handle the USB_DEVICE_BULK_MAX_PACKET_UPDATE Feature Selector
request by activating the new 'eusb2v2_mps_active' gadget flag.
This flag allows the UDC (USB Device Controller) driver to dynamically
configure its hardware endpoints for 1024-byte packet mode, while the
Composite framework continues to report 512 bytes in the Configuration
Descriptor, ensuring strict compliance with eUSB2v2 specification
section 5.2. The flag is cleared upon device reset or disconnect.
Signed-off-by: Pawel Laszczak <pawell@cadence.com>
---
Changes in v4:
- No changes.
Changes in v3:
- composite.c: Do not overwrite ep->desc.wMaxPacketSize to 1024, as the eUSB2v2
spec section 5.2 mandates that the endpoint descriptor always reports 512 bytes
to the host. Instead, introduce gadget->eusb2v2_mps_active flag.
- gadget.h: Add eusb2v2_mps_active to struct usb_gadget.
Changes in v2:
- composite.c: CLEAR_FEATURE(BULK_MAX_PACKET_UPDATE) is not defined in the
eUSB2v2 spec; stall it instead of incorrectly setting 1024-byte mode.
- restore MPS in __composite_disconnect
---
drivers/usb/gadget/composite.c | 28 +++++++++++++++++++++-------
include/linux/usb/gadget.h | 4 ++++
2 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index dc3664374596..9678ed4e4aee 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -924,7 +924,6 @@ static void device_qual(struct usb_composite_dev *cdev)
}
/*-------------------------------------------------------------------------*/
-
static void reset_config(struct usb_composite_dev *cdev)
{
struct usb_function *f;
@@ -971,8 +970,10 @@ static int set_config(struct usb_composite_dev *cdev,
if (result < 0)
goto done;
} else { /* Zero configuration value - need to reset the config */
- if (cdev->config)
+ if (cdev->config) {
reset_config(cdev);
+ cdev->gadget->eusb2v2_mps_active = 0;
+ }
result = 0;
}
@@ -1807,7 +1808,11 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
count_configs(cdev, USB_DT_DEVICE);
cdev->desc.bMaxPacketSize0 =
cdev->gadget->ep0->maxpacket;
- if (gadget_is_superspeed(gadget)) {
+
+ if (gadget->is_eusb2v2) {
+ cdev->desc.bcdUSB = cpu_to_le16(0x0230);
+ cdev->desc.bMaxPacketSize0 = 64;
+ } else if (gadget_is_superspeed(gadget)) {
if (gadget->speed >= USB_SPEED_SUPER) {
cdev->desc.bcdUSB = cpu_to_le16(0x0320);
cdev->desc.bMaxPacketSize0 = 9;
@@ -2005,12 +2010,20 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
*/
case USB_REQ_CLEAR_FEATURE:
case USB_REQ_SET_FEATURE:
- if (!gadget_is_superspeed(gadget))
- goto unknown;
- if (ctrl->bRequestType != (USB_DIR_OUT | USB_RECIP_INTERFACE))
- goto unknown;
switch (w_value) {
+ case USB_DEVICE_BULK_MAX_PACKET_UPDATE:
+ if (ctrl->bRequestType != (USB_DIR_OUT | USB_RECIP_DEVICE))
+ goto unknown;
+ if (ctrl->bRequest != USB_REQ_SET_FEATURE)
+ goto unknown;
+ gadget->eusb2v2_mps_active = 1;
+ value = 0;
+ break;
case USB_INTRF_FUNC_SUSPEND:
+ if (!gadget_is_superspeed(gadget))
+ goto unknown;
+ if (ctrl->bRequestType != (USB_DIR_OUT | USB_RECIP_INTERFACE))
+ goto unknown;
if (!cdev->config || intf >= MAX_CONFIG_INTERFACES)
break;
f = cdev->config->interface[intf];
@@ -2293,6 +2306,7 @@ static void __composite_disconnect(struct usb_gadget *gadget)
* disconnect callbacks?
*/
spin_lock_irqsave(&cdev->lock, flags);
+ cdev->gadget->eusb2v2_mps_active = 0;
cdev->suspended = 0;
if (cdev->config)
reset_config(cdev);
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 8285b19a25e0..5f691f80fd68 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -420,6 +420,8 @@ struct usb_gadget_ops {
* @wakeup_armed: True if gadget is armed by the host for remote wakeup.
* @irq: the interrupt number for device controller.
* @id_number: a unique ID number for ensuring that gadget names are distinct
+ * @is_eusb2v2: True if controller is Embedded usb2.
+ * @eusb2v2_mps_active: 1024-byte bulk mode is active.
*
* Gadgets have a mostly-portable "gadget driver" implementing device
* functions, handling all usb configurations and interfaces. Gadget
@@ -483,6 +485,8 @@ struct usb_gadget {
unsigned lpm_capable:1;
unsigned wakeup_capable:1;
unsigned wakeup_armed:1;
+ unsigned is_eusb2v2:1;
+ unsigned eusb2v2_mps_active:1;
int irq;
int id_number;
};
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v4 3/3] usb: cdns3: cdnsp: Enable eUSB2v2 1KB bulk packet capability
2026-10-09 6:49 [PATCH v4 0/3] usb: Add support for eUSB2v2 1024-byte Bulk MaxPacketSize Pawel Laszczak via B4 Relay
2026-10-09 6:49 ` [PATCH v4 1/3] usb: xhci: Add support for eUSB2v2 1024-byte bulk packet size Pawel Laszczak via B4 Relay
2026-10-09 6:49 ` [PATCH v4 2/3] usb: gadget: composite: Support eUSB2v2 bulk MPS update Pawel Laszczak via B4 Relay
@ 2026-10-09 6:49 ` Pawel Laszczak via B4 Relay
2026-10-09 6:41 ` sashiko-bot
2 siblings, 1 reply; 7+ messages in thread
From: Pawel Laszczak via B4 Relay @ 2026-10-09 6:49 UTC (permalink / raw)
To: Greg Kroah-Hartman, Mathias Nyman; +Cc: linux-usb, linux-kernel, Pawel Laszczak
From: Pawel Laszczak <pawell@cadence.com>
Implement peripheral-side changes in the Cadence (cdnsp) driver
to support eUSB2v2 1024-byte Bulk MaxPacketSize.
Check the HCC2_E2V2C bit in HCCPARAMS2 during setup and set
'pdev->gadget.is_eusb2v2 = 1' if supported. Delegate the incoming
USB_DEVICE_BULK_MAX_PACKET_UPDATE setup request from ep0 to the
composite layer.
Update cdnsp_endpoint_init() to check the 'eusb2v2_mps_active' flag
set by the gadget framework. If active, dynamically configure the
hardware endpoint for 1024-byte maximum packet size, overriding
the 512-byte value reported in the endpoint descriptor.
Signed-off-by: Pawel Laszczak <pawell@cadence.com>
---
Changes in v4:
- No changes.
Changes in v3:
- cdnsp-mem.c: Use the new gadget->eusb2v2_mps_active flag instead of modifying
ep->desc.wMaxPacketSize. This allows the UDC to determine the correct HS bulk
maximum packet size while letting the composite framework report 512 bytes in
the endpoint descriptor per eUSB2v2 spec section 5.2.
Changes in v2:
- cdnsp-mem.c: simplified HS bulk clamp logic to: if (max_packet != 1024)
max_packet = 512, consistent with xhci-mem.c.
---
drivers/usb/cdns3/cdnsp-ep0.c | 2 ++
drivers/usb/cdns3/cdnsp-gadget.c | 4 ++++
drivers/usb/cdns3/cdnsp-gadget.h | 8 ++++++++
drivers/usb/cdns3/cdnsp-mem.c | 9 +++++++--
drivers/usb/common/debug.c | 2 ++
5 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/cdns3/cdnsp-ep0.c b/drivers/usb/cdns3/cdnsp-ep0.c
index 5cd9b898ce97..090d20b307ee 100644
--- a/drivers/usb/cdns3/cdnsp-ep0.c
+++ b/drivers/usb/cdns3/cdnsp-ep0.c
@@ -253,6 +253,8 @@ static int cdnsp_ep0_handle_feature_device(struct cdnsp_device *pdev,
*/
cdnsp_enter_test_mode(pdev);
break;
+ case USB_DEVICE_BULK_MAX_PACKET_UPDATE:
+ return cdnsp_ep0_delegate_req(pdev, ctrl);
default:
return -EINVAL;
}
diff --git a/drivers/usb/cdns3/cdnsp-gadget.c b/drivers/usb/cdns3/cdnsp-gadget.c
index a5275c2fb43b..ac1dde43ce1d 100644
--- a/drivers/usb/cdns3/cdnsp-gadget.c
+++ b/drivers/usb/cdns3/cdnsp-gadget.c
@@ -1853,6 +1853,10 @@ static int cdnsp_gen_setup(struct cdnsp_device *pdev)
pdev->hcc_params = readl(&pdev->cap_regs->hc_capbase);
pdev->hci_version = HC_VERSION(pdev->hcc_params);
pdev->hcc_params = readl(&pdev->cap_regs->hcc_params);
+ pdev->hcc_params2 = readl(&pdev->cap_regs->hcc_params2);
+
+ if (pdev->hcc_params2 & HCC2_E2V2C)
+ pdev->gadget.is_eusb2v2 = 1;
/*
* Override the APB timeout value to give the controller more time for
diff --git a/drivers/usb/cdns3/cdnsp-gadget.h b/drivers/usb/cdns3/cdnsp-gadget.h
index c44bca348a41..75bc3f15bde5 100644
--- a/drivers/usb/cdns3/cdnsp-gadget.h
+++ b/drivers/usb/cdns3/cdnsp-gadget.h
@@ -89,6 +89,12 @@ struct cdnsp_cap_regs {
#define CTX_SIZE(_hcc) (HCC_64BYTE_CONTEXT(_hcc) ? 64 : 32)
+/* HCCPARAMS2 - hcc_params2 - bitmasks */
+/* bit 11 - DC support Double BW on a eUSB2 HS ISOC EP */
+#define HCC2_EUSB2_DIC BIT(11)
+/* bit 12 - DC support eUSB2V2 capability */
+#define HCC2_E2V2C BIT(12)
+
/* db_off bitmask - bits 0:1 reserved. */
#define DBOFF_MASK GENMASK(31, 2)
@@ -1370,6 +1376,7 @@ struct cdnsp_port {
* @rev_cap: Controller Capabilities Registers.
* @hcs_params1: Cached register copies of read-only HCSPARAMS1
* @hcc_params: Cached register copies of read-only HCCPARAMS1
+ * @hcc_params2: Cached register copies of read-only HCCPARAMS2
* @rtl_revision: Cached controller rtl revision.
* @setup: Temporary buffer for setup packet.
* @ep0_preq: Internal allocated request used during enumeration.
@@ -1425,6 +1432,7 @@ struct cdnsp_device {
__u32 hcs_params1;
__u32 hcs_params3;
__u32 hcc_params;
+ __u32 hcc_params2;
#define RTL_REVISION_NEW_LPM 0x2700
__u32 rtl_revision;
/* Lock used in interrupt thread context. */
diff --git a/drivers/usb/cdns3/cdnsp-mem.c b/drivers/usb/cdns3/cdnsp-mem.c
index 5d8cdc91927d..8892767942a7 100644
--- a/drivers/usb/cdns3/cdnsp-mem.c
+++ b/drivers/usb/cdns3/cdnsp-mem.c
@@ -978,8 +978,13 @@ int cdnsp_endpoint_init(struct cdnsp_device *pdev,
if (!usb_endpoint_xfer_isoc(pep->endpoint.desc))
err_count = 3;
if (usb_endpoint_xfer_bulk(pep->endpoint.desc) &&
- pdev->gadget.speed == USB_SPEED_HIGH)
- max_packet = 512;
+ pdev->gadget.speed == USB_SPEED_HIGH) {
+ if (pdev->gadget.eusb2v2_mps_active)
+ max_packet = 1024;
+ else
+ max_packet = 512;
+ }
+
/* Controller spec indicates that ctrl ep avg TRB Length should be 8. */
if (usb_endpoint_xfer_control(pep->endpoint.desc))
avg_trb_len = 8;
diff --git a/drivers/usb/common/debug.c b/drivers/usb/common/debug.c
index f204cec8d380..b9696fae7ef5 100644
--- a/drivers/usb/common/debug.c
+++ b/drivers/usb/common/debug.c
@@ -46,6 +46,8 @@ static const char *usb_decode_device_feature(u16 wValue)
return "U2 Enable";
case USB_DEVICE_LTM_ENABLE:
return "LTM Enable";
+ case USB_DEVICE_BULK_MAX_PACKET_UPDATE:
+ return "Bulk mps update";
default:
return "UNKNOWN";
}
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-10-09 6:43 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-09 6:49 [PATCH v4 0/3] usb: Add support for eUSB2v2 1024-byte Bulk MaxPacketSize Pawel Laszczak via B4 Relay
2026-10-09 6:49 ` [PATCH v4 1/3] usb: xhci: Add support for eUSB2v2 1024-byte bulk packet size Pawel Laszczak via B4 Relay
2026-10-09 6:38 ` sashiko-bot
2026-10-09 6:49 ` [PATCH v4 2/3] usb: gadget: composite: Support eUSB2v2 bulk MPS update Pawel Laszczak via B4 Relay
2026-10-09 6:43 ` sashiko-bot
2026-10-09 6:49 ` [PATCH v4 3/3] usb: cdns3: cdnsp: Enable eUSB2v2 1KB bulk packet capability Pawel Laszczak via B4 Relay
2026-10-09 6:41 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox