mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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



  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®