From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 05759C5DF81 for ; Mon, 24 Aug 2026 16:45:29 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id C4B7D606F0; Mon, 24 Aug 2026 16:45:28 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id G2EL7X5t35VB; Mon, 24 Aug 2026 16:45:25 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.166.142; helo=lists1.osuosl.org; envelope-from=u-boot-bounces@lists.u-boot-project.org; receiver= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.u-boot-project.org; s=default; t=1787589925; bh=N08ZBrgMsyjx3ftDO7O7GR689tqBX00t5T5ExBAfNHw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=yHwMKNKjeDDQh95qy3h0D5junWHvdPvtKBPEnop7PhQ8KBJHdMfXNFn/Np0QnNJOz XolCdtvArMlD+KMoKT8EuP3RZxb9sNx+CSmIZPHtsAlrqWTgZNzejgA+Hp2gsIK47i 5ChiHMprsesNwCMP0kT/V+4Hh+sPUpAvSTA8xC8lBeYJ5CwswaYkDWOxFUgXFoHT3D UtM7Towcj0+iwh+NDI2MDdy/fPaWwiSshuLEa7PuXQ5bUQ34432Rv+wEknhT0G9mjl gw/5Pi1JNdZ22vzx1GoopggOu614p1AbRo3mqLjpfrM3DKjOGHigP8SUW7q+0U1tLs 6O8qQiOcS1AyA== Received: from lists1.osuosl.org (lists1.osuosl.org [140.211.166.142]) by smtp3.osuosl.org (Postfix) with ESMTP id 6A6B7606C9; Mon, 24 Aug 2026 16:45:25 +0000 (UTC) Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) by lists1.osuosl.org (Postfix) with ESMTP id 999FB3AD for ; Mon, 24 Aug 2026 15:32:48 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 97C10808C1 for ; Mon, 24 Aug 2026 15:32:48 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id V1ovd15TnBh1 for ; Mon, 24 Aug 2026 15:32:47 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=2a00:1450:4864:20::631; helo=mail-ej1-x631.google.com; envelope-from=anders.roxell@linaro.org; receiver= Authentication-Results: smtp1.osuosl.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp1.osuosl.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=s/257mHg Received: from mail-ej1-x631.google.com (mail-ej1-x631.google.com [IPv6:2a00:1450:4864:20::631]) by smtp1.osuosl.org (Postfix) with ESMTPS id 37E94808A9 for ; Mon, 24 Aug 2026 15:32:46 +0000 (UTC) Received: by mail-ej1-x631.google.com with SMTP id a640c23a62f3a-c15f025146dso49271266b.2 for ; Mon, 24 Aug 2026 08:32:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1787585565; x=1788190365; darn=lists.u-boot-project.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=N08ZBrgMsyjx3ftDO7O7GR689tqBX00t5T5ExBAfNHw=; b=s/257mHg/kGTZcwFQXVhQlSzr8fB1sZqmCHIL7HSiiF2QYPmymn3DemQeIMsi6GVKw R0Bu/C/CqfDxum9HlBI3CY64IB54D+u0sEXUNWbKthAp8fuijzfbyif++UlfLa/iRLZy srMv+y/8LJXnmkP4AjYn0aw2k+48RrpEbOoDs8651y1mw9gy+ZFKVn8xPColCHnRgr5w INj5CWbxDkzMQLEM1DUnybwngQNfAdBavTNzei1MUNkld9Ys9dH/EJXIKr4nCy8+Djbd OCUlxh0UeLb2w/cUtmgRFsR1JsQOZiMvcPJAhX7Ko3oY83nhZeDRsqkbY8heLIwWJnCF 0hog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787585565; x=1788190365; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=N08ZBrgMsyjx3ftDO7O7GR689tqBX00t5T5ExBAfNHw=; b=GVfvzoUTnUknh6PC9skuyjlP8bjKUL/6dWc2+K5MzZ4F2qmwUZWR0XbO3o0YC4Wx0c 26WjGN5m8K8TD0Pm4qRtBvvD8JrADA6KUVPn4yM1P1Gd+HZ/1l+nZ54LPg7OaZ3AFQtS hDXkwFvLWGbu8izfsXXX1kQCoXdCEnF9tu6Qq7NrNsx4j4/IIhaJQJxtU7oq+F2ssajJ Lbujk0h4q9OQTx0GsF2tk9tHq5YBMjwhkeXqI6kyx7w0/FE1U+pnr9D9+Z01NGfa8zwz YO1wQTKpZ0CFK70O1TM804y2diZcPUMmVn+OgNAKPyBwdBArQNzFoDMQBZU46Wk6msvW Lnhg== X-Gm-Message-State: AFuF++kR0VMbBR2CSxXviSzIV1pxcuwQGyAbmGSzojPMC7oR/5qOOGLT xjYc15k38bw4ojOq70ndk3vKFJ1m8btM5MwPXQdik5+609fdTFuOFLC3urry3umIKqUtkAquwfw ik0K0 X-Gm-Gg: AR+sD13JOl76qTW4PrtI0izlvet7PbqsBXqhtgh3sHNPdUYISdWZyrTEhQbPCRa3t73 6NEE5il3wNub1zRoxl9e5SJqpdnH0frw6fQ4JaxX7PoV+9GEZH08O2+BKP4a7o95URY0K1qmdK7 l0L5AlGqMvxIO7AByEBdKdAV5Ut5H4shCQ12klbnIF1cVX4pL/jfA/PuuhWi1hfdJmoyEyAN2xl xhvSHwDHbMNVi1Ey2+HvhhKD7oD9rOQ1u/fKzrKMghXBCQxOn9TjyPOk5hxEMWhRte/4tvM08km DTx55U2uiH9+lHzMX7vfe324lrDhLhoUDw4+jFC7rKjcEwmDQY70rkY/erdMl53fxSEQwXKlKLX trIbnO/hJBlQ9XIciFBaQ3AsBlJ4ol+dhqTm73xpUr+fCtILsk2H+y6z9FrQaqYU3waHduiTYOf gEFuO5ETKWWtUE7od3GGM3ajSCIggzjIXAogv6hePZbDV1fF/jb9b3E6pGYfOFRjCo0AdsYrVZQ onHNc/zXeHi0gMgLpEMLA== X-Received: by 2002:a17:906:f59a:b0:c21:7bf1:2c88 with SMTP id a640c23a62f3a-c246a67540dmr1431139666b.2.1787585564869; Mon, 24 Aug 2026 08:32:44 -0700 (PDT) Received: from monster (c-85-229-7-191.bbcust.telenor.se. [85.229.7.191]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c2496295627sm1267430166b.15.2026.08.24.08.32.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Aug 2026 08:32:44 -0700 (PDT) From: Anders Roxell To: u-boot@lists.u-boot-project.org Cc: marek.vasut@mailbox.org, trini@konsulko.com, ilias.apalodimas@linaro.org, michal.simek@amd.com, lukma@denx.de, alchark@flipper.net, jerome.forissier@arm.com, Jerome Forissier , Jens Wiklander , Anders Roxell , Mattijs Korpershoek Subject: [PATCH v7 62/63] usb: gadget: re-import epautoconf.c from kernel v6.16 Date: Mon, 24 Aug 2026 17:27:33 +0200 Message-ID: <20260824152734.159794-63-anders.roxell@linaro.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260824152734.159794-1-anders.roxell@linaro.org> References: <20260824152734.159794-1-anders.roxell@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Mailman-Approved-At: Mon, 24 Aug 2026 16:43:55 +0000 X-BeenThere: u-boot@lists.u-boot-project.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.u-boot-project.org From: Jerome Forissier Replace drivers/usb/gadget/epautoconf.c with the one from the Linux kernel. Fixes will come later. Signed-off-by: Jerome Forissier Signed-off-by: Jens Wiklander Signed-off-by: Anders Roxell Reviewed-by: Mattijs Korpershoek --- drivers/usb/gadget/epautoconf.c | 292 +++++++++++++++----------------- 1 file changed, 133 insertions(+), 159 deletions(-) diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 495460473e9a..4fbea9137240 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -1,172 +1,123 @@ // SPDX-License-Identifier: GPL-2.0+ +/* Imported from Linux v6.16 */ /* * epautoconf.c -- endpoint autoconfiguration for usb gadget drivers * * Copyright (C) 2004 David Brownell - * - * Ported to U-Boot by: Thomas Smits and - * Remy Bohmer */ -#include -#include -#include -#include - -#define isdigit(c) ('0' <= (c) && (c) <= '9') +#include +#include +#include +#include -/* we must assign addresses for configurable endpoints (like net2280) */ -static unsigned epnum; +#include +#include -/* #define MANY_ENDPOINTS */ -#ifdef MANY_ENDPOINTS -/* more than 15 configurable endpoints */ -static unsigned in_epnum; -#endif +#include +#include -/* - * This should work with endpoints from controller drivers sharing the - * same endpoint naming convention. By example: +/** + * usb_ep_autoconfig_ss() - choose an endpoint matching the ep + * descriptor and ep companion descriptor + * @gadget: The device to which the endpoint must belong. + * @desc: Endpoint descriptor, with endpoint direction and transfer mode + * initialized. For periodic transfers, the maximum packet + * size must also be initialized. This is modified on + * success. + * @ep_comp: Endpoint companion descriptor, with the required + * number of streams. Will be modified when the chosen EP + * supports a different number of streams. + * + * This routine replaces the usb_ep_autoconfig when needed + * superspeed enhancments. If such enhancemnets are required, + * the FD should call usb_ep_autoconfig_ss directly and provide + * the additional ep_comp parameter. + * + * By choosing an endpoint to use with the specified descriptor, + * this routine simplifies writing gadget drivers that work with + * multiple USB device controllers. The endpoint would be + * passed later to usb_ep_enable(), along with some descriptor. + * + * That second descriptor won't always be the same as the first one. + * For example, isochronous endpoints can be autoconfigured for high + * bandwidth, and then used in several lower bandwidth altsettings. + * Also, high and full speed descriptors will be different. * - * - ep1, ep2, ... address is fixed, not direction or type - * - ep1in, ep2out, ... address and direction are fixed, not type - * - ep1-bulk, ep2-bulk, ... address and type are fixed, not direction - * - ep1in-bulk, ep2out-iso, ... all three are fixed - * - ep-* ... no functionality restrictions + * Be sure to examine and test the results of autoconfiguration + * on your hardware. This code may not make the best choices + * about how to use the USB controller, and it can't know all + * the restrictions that may apply. Some combinations of driver + * and hardware won't be able to autoconfigure. * - * Type suffixes are "-bulk", "-iso", or "-int". Numbers are decimal. - * Less common restrictions are implied by gadget_is_*(). + * On success, this returns an claimed usb_ep, and modifies the endpoint + * descriptor bEndpointAddress. For bulk endpoints, the wMaxPacket value + * is initialized as if the endpoint were used at full speed and + * the bmAttribute field in the ep companion descriptor is + * updated with the assigned number of streams if it is + * different from the original value. To prevent the endpoint + * from being returned by a later autoconfig call, claims it by + * assigning ep->claimed to true. * - * NOTE: each endpoint is unidirectional, as specified by its USB - * descriptor; and isn't specific to a configuration or altsetting. + * On failure, this returns a null endpoint descriptor. */ -static int ep_matches( +struct usb_ep *usb_ep_autoconfig_ss( struct usb_gadget *gadget, - struct usb_ep *ep, - struct usb_endpoint_descriptor *desc + struct usb_endpoint_descriptor *desc, + struct usb_ss_ep_comp_descriptor *ep_comp ) { - u8 type; - const char *tmp; - u16 max; - - /* endpoint already claimed? */ - if (NULL != ep->driver_data) - return 0; - - /* only support ep0 for portable CONTROL traffic */ - type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; - if (USB_ENDPOINT_XFER_CONTROL == type) - return 0; - - /* some other naming convention */ - if ('e' != ep->name[0]) - return 0; + struct usb_ep *ep; - /* type-restriction: "-iso", "-bulk", or "-int". - * direction-restriction: "in", "out". - */ - if ('-' != ep->name[2]) { - tmp = strrchr(ep->name, '-'); - if (tmp) { - switch (type) { - case USB_ENDPOINT_XFER_INT: - /* bulk endpoints handle interrupt transfers, - * except the toggle-quirky iso-synch kind - */ - if ('s' == tmp[2]) /* == "-iso" */ - return 0; - break; - case USB_ENDPOINT_XFER_BULK: - if ('b' != tmp[1]) /* != "-bulk" */ - return 0; - break; - case USB_ENDPOINT_XFER_ISOC: - if ('s' != tmp[2]) /* != "-iso" */ - return 0; - } - } else { - tmp = ep->name + strlen(ep->name); - } - - /* direction-restriction: "..in-..", "out-.." */ - tmp--; - if (!isdigit(*tmp)) { - if (desc->bEndpointAddress & USB_DIR_IN) { - if ('n' != *tmp) - return 0; - } else { - if ('t' != *tmp) - return 0; - } - } + if (gadget->ops->match_ep) { + ep = gadget->ops->match_ep(gadget, desc, ep_comp); + if (ep) + goto found_ep; } - /* endpoint maxpacket size is an input parameter, except for bulk - * where it's an output parameter representing the full speed limit. - * the usb spec fixes high speed bulk maxpacket at 512 bytes. - */ - max = 0x7ff & le16_to_cpu(get_unaligned(&desc->wMaxPacketSize)); - switch (type) { - case USB_ENDPOINT_XFER_INT: - /* INT: limit 64 bytes full speed, 1024 high speed */ - if (!gadget->is_dualspeed && max > 64) - return 0; - /* FALLTHROUGH */ - - case USB_ENDPOINT_XFER_ISOC: - /* ISO: limit 1023 bytes full speed, 1024 high speed */ - if (ep->maxpacket < max) - return 0; - if (!gadget->is_dualspeed && max > 1023) - return 0; - - /* BOTH: "high bandwidth" works only at high speed */ - if ((get_unaligned(&desc->wMaxPacketSize) & - __constant_cpu_to_le16(3<<11))) { - if (!gadget->is_dualspeed) - return 0; - /* configure your hardware with enough buffering!! */ - } - break; + /* Second, look at endpoints until an unclaimed one looks usable */ + list_for_each_entry (ep, &gadget->ep_list, ep_list) { + if (usb_gadget_ep_match_desc(gadget, ep, desc, ep_comp)) + goto found_ep; } - /* MATCH!! */ + /* Fail */ + return NULL; +found_ep: + + /* + * If the protocol driver hasn't yet decided on wMaxPacketSize + * and wants to know the maximum possible, provide the info. + */ + if (desc->wMaxPacketSize == 0) + desc->wMaxPacketSize = cpu_to_le16(ep->maxpacket_limit); /* report address */ + desc->bEndpointAddress &= USB_DIR_IN; if (isdigit(ep->name[2])) { - u8 num = dectoul(&ep->name[2], NULL); + u8 num = simple_strtoul(&ep->name[2], NULL, 10); desc->bEndpointAddress |= num; -#ifdef MANY_ENDPOINTS } else if (desc->bEndpointAddress & USB_DIR_IN) { - if (++in_epnum > 15) - return 0; - desc->bEndpointAddress = USB_DIR_IN | in_epnum; -#endif + if (++gadget->in_epnum > 15) + return NULL; + desc->bEndpointAddress = USB_DIR_IN | gadget->in_epnum; } else { - if (++epnum > 15) - return 0; - desc->bEndpointAddress |= epnum; + if (++gadget->out_epnum > 15) + return NULL; + desc->bEndpointAddress |= gadget->out_epnum; } - /* report (variable) full speed bulk maxpacket */ - if (USB_ENDPOINT_XFER_BULK == type) { - int size = ep->maxpacket; - - /* min() doesn't work on bitfields with gcc-3.5 */ - if (size > 64) - size = 64; - put_unaligned(cpu_to_le16(size), &desc->wMaxPacketSize); - } - - if (gadget->ops->ep_conf) - return gadget->ops->ep_conf(gadget, ep, desc); - - return 1; + ep->address = desc->bEndpointAddress; + ep->desc = NULL; + ep->comp_desc = NULL; + ep->claimed = true; + return ep; } +EXPORT_SYMBOL_GPL(usb_ep_autoconfig_ss); /** - * usb_ep_autoconfig - choose an endpoint matching the descriptor + * usb_ep_autoconfig() - choose an endpoint matching the + * descriptor * @gadget: The device to which the endpoint must belong. * @desc: Endpoint descriptor, with endpoint direction and transfer mode * initialized. For periodic transfers, the maximum packet @@ -187,11 +138,12 @@ static int ep_matches( * USB controller, and it can't know all the restrictions that may apply. * Some combinations of driver and hardware won't be able to autoconfigure. * - * On success, this returns an un-claimed usb_ep, and modifies the endpoint + * On success, this returns an claimed usb_ep, and modifies the endpoint * descriptor bEndpointAddress. For bulk endpoints, the wMaxPacket value - * is initialized as if the endpoint were used at full speed. To prevent - * the endpoint from being returned by a later autoconfig call, claim it - * by assigning ep->driver_data to some non-null value. + * is initialized as if the endpoint were used at full speed. Because of + * that the users must consider adjusting the autoconfigured descriptor. + * To prevent the endpoint from being returned by a later autoconfig call, + * claims it by assigning ep->claimed to true. * * On failure, this returns a null endpoint descriptor. */ @@ -200,23 +152,45 @@ struct usb_ep *usb_ep_autoconfig( struct usb_endpoint_descriptor *desc ) { - struct usb_ep *ep; + struct usb_ep *ep; + u8 type; - if (gadget->ops->match_ep) { - ep = gadget->ops->match_ep(gadget, desc, NULL); - if (ep && ep_matches(gadget, ep, desc)) - return ep; - } + ep = usb_ep_autoconfig_ss(gadget, desc, NULL); + if (!ep) + return NULL; - /* Second, look at endpoints until an unclaimed one looks usable */ - list_for_each_entry(ep, &gadget->ep_list, ep_list) { - if (ep_matches(gadget, ep, desc)) - return ep; + type = usb_endpoint_type(desc); + + /* report (variable) full speed bulk maxpacket */ + if (type == USB_ENDPOINT_XFER_BULK) { + int size = ep->maxpacket_limit; + + /* min() doesn't work on bitfields with gcc-3.5 */ + if (size > 64) + size = 64; + desc->wMaxPacketSize = cpu_to_le16(size); } - /* Fail */ - return NULL; + return ep; +} +EXPORT_SYMBOL_GPL(usb_ep_autoconfig); + +/** + * usb_ep_autoconfig_release - releases endpoint and set it to initial state + * @ep: endpoint which should be released + * + * This function can be used during function bind for endpoints obtained + * from usb_ep_autoconfig(). It unclaims endpoint claimed by + * usb_ep_autoconfig() to make it available for other functions. Endpoint + * which was released is no longer valid and shouldn't be used in + * context of function which released it. + */ +void usb_ep_autoconfig_release(struct usb_ep *ep) +{ + ep->claimed = false; + ep->driver_data = NULL; } +EXPORT_SYMBOL_GPL(usb_ep_autoconfig_release); /** * usb_ep_autoconfig_reset - reset endpoint autoconfig state @@ -224,18 +198,18 @@ struct usb_ep *usb_ep_autoconfig( * * Use this for devices where one configuration may need to assign * endpoint resources very differently from the next one. It clears - * state such as ep->driver_data and the record of assigned endpoints + * state such as ep->claimed and the record of assigned endpoints * used by usb_ep_autoconfig(). */ -void usb_ep_autoconfig_reset(struct usb_gadget *gadget) +void usb_ep_autoconfig_reset (struct usb_gadget *gadget) { struct usb_ep *ep; - list_for_each_entry(ep, &gadget->ep_list, ep_list) { + list_for_each_entry (ep, &gadget->ep_list, ep_list) { + ep->claimed = false; ep->driver_data = NULL; } -#ifdef MANY_ENDPOINTS - in_epnum = 0; -#endif - epnum = 0; + gadget->in_epnum = 0; + gadget->out_epnum = 0; } +EXPORT_SYMBOL_GPL(usb_ep_autoconfig_reset); -- 2.53.0