From: Pawel Laszczak via B4 Relay <devnull+pawell.cadence.com@kernel.org>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Mathias Nyman <mathias.nyman@intel.com>
Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
Pawel Laszczak <pawell@cadence.com>
Subject: [PATCH v2 2/3] usb: gadget: composite: Support eUSB2v2 bulk MPS update request
Date: Wed, 26 Aug 2026 13:24:37 +0200 [thread overview]
Message-ID: <20260826-eusb2v2-packet-size-v2-2-950f19f38ef0@cadence.com> (raw)
In-Reply-To: <20260826-eusb2v2-packet-size-v2-0-950f19f38ef0@cadence.com>
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 request
by introducing eusb2_update_mps_bulk(), which dynamically updates the
wMaxPacketSize of all HS Bulk endpoint descriptors to 1024 bytes before
the device is configured.
Signed-off-by: Pawel Laszczak <pawell@cadence.com>
---
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 | 68 ++++++++++++++++++++++++++++++++++++++----
include/linux/usb/gadget.h | 2 ++
2 files changed, 64 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index dc3664374596..f0246e25f2b5 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -924,6 +924,48 @@ static void device_qual(struct usb_composite_dev *cdev)
}
/*-------------------------------------------------------------------------*/
+static void eusb2_update_ep_mps(struct usb_descriptor_header *header, __le16 mps)
+{
+ struct usb_endpoint_descriptor *epd;
+
+ if (header->bDescriptorType != USB_DT_ENDPOINT)
+ return;
+
+ epd = (void *)header;
+ if (usb_endpoint_xfer_bulk(epd))
+ epd->wMaxPacketSize = mps;
+}
+
+static int eusb2_update_mps_bulk(struct usb_composite_dev *cdev, bool set)
+{
+ __le16 mps = cpu_to_le16(set ? 1024 : 512);
+ struct usb_gadget *gadget = cdev->gadget;
+ struct usb_configuration *config;
+ struct usb_function *f;
+
+ if (!gadget->is_eusb2v2)
+ return -EINVAL;
+
+ if (set && gadget->state >= USB_STATE_CONFIGURED)
+ return -EINVAL;
+
+ list_for_each_entry(config, &cdev->configs, list) {
+ if (!config->highspeed)
+ continue;
+
+ list_for_each_entry(f, &config->functions, list) {
+ struct usb_descriptor_header **desc = f->hs_descriptors;
+
+ if (!desc)
+ continue;
+
+ for (; *desc; desc++)
+ eusb2_update_ep_mps(*desc, mps);
+ }
+ }
+
+ return 0;
+}
static void reset_config(struct usb_composite_dev *cdev)
{
@@ -971,8 +1013,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);
+ eusb2_update_mps_bulk(cdev, false);
+ }
result = 0;
}
@@ -1807,7 +1851,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 +2053,19 @@ 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;
+ value = eusb2_update_mps_bulk(cdev, true);
+ 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 +2348,7 @@ static void __composite_disconnect(struct usb_gadget *gadget)
* disconnect callbacks?
*/
spin_lock_irqsave(&cdev->lock, flags);
+ eusb2_update_mps_bulk(cdev, false);
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..3c554fe95f87 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -420,6 +420,7 @@ 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.
*
* Gadgets have a mostly-portable "gadget driver" implementing device
* functions, handling all usb configurations and interfaces. Gadget
@@ -483,6 +484,7 @@ struct usb_gadget {
unsigned lpm_capable:1;
unsigned wakeup_capable:1;
unsigned wakeup_armed:1;
+ unsigned is_eusb2v2:1;
int irq;
int id_number;
};
--
2.43.0
next prev parent reply other threads:[~2026-08-26 11:05 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-26 11:24 [PATCH v2 0/3] usb: Add support for eUSB2v2 1024-byte Bulk MaxPacketSize Pawel Laszczak via B4 Relay
2026-08-26 11:24 ` [PATCH v2 1/3] usb: xhci: Add support for eUSB2v2 1024-byte bulk packet size Pawel Laszczak via B4 Relay
2026-09-23 9:32 ` Mathias Nyman
2026-08-26 11:24 ` Pawel Laszczak via B4 Relay [this message]
2026-09-10 11:54 ` [PATCH v2 2/3] usb: gadget: composite: Support eUSB2v2 bulk MPS update request Selvarasu Ganesan
2026-09-22 8:16 ` Pawel Laszczak
2026-09-22 9:15 ` Selvarasu Ganesan
2026-08-26 11:24 ` [PATCH v2 3/3] usb: cdns3: cdnsp: Enable eUSB2v2 1KB bulk packet capability Pawel Laszczak via B4 Relay
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260826-eusb2v2-packet-size-v2-2-950f19f38ef0@cadence.com \
--to=devnull+pawell.cadence.com@kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=mathias.nyman@intel.com \
--cc=pawell@cadence.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®