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 phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9834FC44511 for ; Thu, 16 Jul 2026 16:14:36 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 8F25A84E12; Thu, 16 Jul 2026 18:09:18 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="F54GIlXX"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 5CB9D84CE8; Thu, 16 Jul 2026 15:44:02 +0200 (CEST) Received: from mail-ej1-x633.google.com (mail-ej1-x633.google.com [IPv6:2a00:1450:4864:20::633]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 8EA4D84CEB for ; Thu, 16 Jul 2026 15:43:59 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=anders.roxell@linaro.org Received: by mail-ej1-x633.google.com with SMTP id a640c23a62f3a-c15fc4707f5so65236066b.3 for ; Thu, 16 Jul 2026 06:43:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1784209439; x=1784814239; darn=lists.denx.de; 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=/MESsMKQ30KgDxzc5NxL8qZJAfp43DLczBBx6LPt/yg=; b=F54GIlXXDuK7N6LA1VrtskB2t1BOtCubwsUr1RX8zF4vmO0+7BeOmSUh1FHNQ7kJe6 8IO4k7kcKpGduIDlpdcMoXnP5f1qgYagh794Le2M6opM+Z5PewMTFTbH1YCVKI19hpSu VaWp6yi7/5e4q1NLq54EfRqTx1FI3UwHnwF1WffGGze/9TaWsYiKCVBMcn/sz/rxfGdF bPBBDUo5MILgoopiFyfbFBi/NhU/XPt76/YRZ661bfm3bQP8MWcUrgOc8+EmLP8yFzwL cSGBiovi9ElcXLY1aXxnn+JxieLiGu4KQuNIeNFpIfBOQeLiMX6dGWrqhTmTpGxAQ9CX pO6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784209439; x=1784814239; 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=/MESsMKQ30KgDxzc5NxL8qZJAfp43DLczBBx6LPt/yg=; b=pc8M5dnn+TlYon46i+Qhq/1r7I9fAhg4h+FeU8EPUN0jF8AEayTkYRURLPOqbiodx0 ojdMZmAH6SGfi07rBWP1nPWL6q8Fmg2/tVm2xGR25PxXTAqqRzOSEcqeI/UgTdasR3cp E76v/IBs6UARS/ZpSP2PjLf6eBrjntwf70pz49svDe1gjjaqLI6d5rW00Hw7JiEMHRkc npB243GQsdHaBpnbE2wZ22Jy/JRQL+8k5YPaAa70d0wsbB696cSb57pZkp6oQeDVT4ZK 5Aib6E1yVKwYTAnLlllvtDqt5Ik523bGnlLP7ZSyWLTnWhea6PjcehlnspBWqvxg/hFI 7nIg== X-Gm-Message-State: AOJu0YyMh3iA8od6C6jg1kLRIzzdChmSRjINqv+grEDaYWKcE4L6VFVj Qd7X3TgZeeKa/c4wrWV47XmUvxK5i/m7j9w9y55/50EXKY4Wjgr6d8IcmbB/Gg7ww/17U3RiUN9 uu6b+ X-Gm-Gg: AfdE7cksgtWT3qnWcDsn4Qp5fY4gC88oAFzGqEiRgLEEq9cC204RuwF2SWWuHNkQ9VH L0JD/zmIGuqJCYA1vwgjKw2yxN8Sx2E60ajEtVH9lVQsy5Zhh3Yw0116PFDIIXygtHehLR0bGJB KWKnafmm2zrAbG4dPyTIQytlBa/p7GdLXGR6Zsrwd056UIA671LOiOAFiiZcR9M4woZJmrwPRFa 2dHkLyakUZZRFILyERdTZsyrFo8ElrILJpHAzyCa0dEhp1kBzX2aPXGoxDEMuS+CNSXqRmPOec6 pybkIpnpxkD56boiMzZfMisshzIdmDMpaFt1gAZetYrijH7IbtcDnrDL9Hexb+NHQpP7iBfgzLP XF6y3Ec+CpGnxFGB/rSncxZl1eVstel9XfnOyc4oKOuNprWBYrj/Qp4VxbA763TlLp/BgEhaX1S m6LN3RwWZq/abWO7svDjhAYI7X+W6GabRHOawd8A== X-Received: by 2002:a17:906:ee8c:b0:c15:f4bb:e665 with SMTP id a640c23a62f3a-c161ea8d628mr734653766b.5.1784209438919; Thu, 16 Jul 2026 06:43:58 -0700 (PDT) Received: from localhost (c-85-229-7-191.bbcust.telenor.se. [85.229.7.191]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c168744bd40sm215136066b.43.2026.07.16.06.43.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2026 06:43:58 -0700 (PDT) From: Anders Roxell To: u-boot@lists.denx.de, marex@denx.de Cc: mkorpershoek@kernel.org, ilias.apalodimas@linaro.org, trini@konsulko.com, michal.simek@amd.com, alchark@flipper.net, jerome.forissier@arm.com, Jens Wiklander , Anders Roxell , Lukasz Majewski Subject: [PATCH v5 33/75] usb: dwc3: import from kernel v5.9 Date: Thu, 16 Jul 2026 15:42:03 +0200 Message-ID: <20260716134305.614278-34-anders.roxell@linaro.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260716134305.614278-1-anders.roxell@linaro.org> References: <20260716134305.614278-1-anders.roxell@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Mailman-Approved-At: Thu, 16 Jul 2026 18:09:05 +0200 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean From: Jens Wiklander Sync Linux kernel dwc3 changes from v5.8 to v5.9. The following files are preserved accross the import: Makefile Kconfig dwc3-meson-g12a.c dwc3-meson-gxl.c dwc3-omap.c dwc3-uniphier.c dwc3-generic.h dwc3-generic.c dwc3-generic-sti.c dwc3-layerscape.c ti_usb_phy.c Skipping unused files: debugfs.c drd.c dwc3-exynos.c dwc3-haps.c dwc3-imx8mp.c dwc3-keystone.c dwc3-octeon.c dwc3-of-simple.c dwc3-pci.c dwc3-qcom.c dwc3-qcom-legacy.c dwc3-rtk.c dwc3-st.c dwc3-xilinx.c host.c trace.c trace.h ulpi.c Note that this is a raw import and doesn't build. A fixup commit at the end of the series fixes that. List of commits: git log --oneline v5.8..v5.9 Commits imported: a6498d51821e Revert "usb: dwc3: meson-g12a: fix shared reset control use" df561f6688fe treewide: Use fallthrough pseudo-keyword bc9a2e226ea9 usb: dwc3: gadget: Handle ZLP for sg requests d2ee3ff79e6a usb: dwc3: gadget: Fix handling ZLP 5d187c0454ef usb: dwc3: gadget: Don't setup more than requested db123bea9625 usb: dwc3: convert to devm_platform_ioremap_resource_byname f5e46aa4a124 usb: dwc3: gadget: when the started list is empty stop the active xfer c5a7092f4015 usb: dwc3: gadget: make starting isoc transfers more robust ca14378560db usb: dwc3: gadget: add frame number mask 7a410953d1fb usb: dwc3: meson-g12a: fix shared reset control use 10623b879da3 usb: dwc3: Replace HTTP links with HTTPS ones b789710de583 usb: dwc3: dwc3-qcom: Do not define 'struct acpi_device_id' when !CONFIG_ACPI 26ef796f9306 usb: dwc3: dwc3-of-simple: Function headers are not good candidates for kerneldoc 4d72cf0cb9e2 usb: dwc3: dwc3-haps: Function headers are not suitable for kerneldoc 3c373454a9f2 usb: dwc3: dwc3-omap: Do not read DMA status fb678a5a76a4 usb: dwc3: ulpi: File headers are not doc headers 7679defc3e29 usb: dwc3: drd: File headers are not doc headers 62fb45d317c5 USB: ch9: add "USB_" prefix in front of TEST defines Signed-off-by: Jens Wiklander Signed-off-by: Anders Roxell --- drivers/usb/dwc3/core.c | 7 +- drivers/usb/dwc3/core.h | 2 +- drivers/usb/dwc3/debug.h | 2 +- drivers/usb/dwc3/ep0.c | 12 +-- drivers/usb/dwc3/gadget.c | 149 +++++++++++++++++++++++++++++++------- drivers/usb/dwc3/gadget.h | 4 +- drivers/usb/dwc3/io.h | 2 +- 7 files changed, 137 insertions(+), 41 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 25c686a752b0..2eb34c8b4065 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -2,7 +2,7 @@ /** * core.c - DesignWare USB3 DRD Controller Core file * - * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com * * Authors: Felipe Balbi , * Sebastian Andrzej Siewior @@ -646,9 +646,8 @@ static int dwc3_phy_setup(struct dwc3 *dwc) if (!(reg & DWC3_GUSB2PHYCFG_ULPI_UTMI)) break; } - /* FALLTHROUGH */ + fallthrough; case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI: - /* FALLTHROUGH */ default: break; } @@ -1411,7 +1410,7 @@ static void dwc3_check_params(struct dwc3 *dwc) default: dev_err(dev, "invalid maximum_speed parameter %d\n", dwc->maximum_speed); - /* fall through */ + fallthrough; case USB_SPEED_UNKNOWN: /* default to superspeed */ dwc->maximum_speed = USB_SPEED_SUPER; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 013f42a2b5dc..2f04b3e42bf1 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -2,7 +2,7 @@ /* * core.h - DesignWare USB3 DRD Core Header * - * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com * * Authors: Felipe Balbi , * Sebastian Andrzej Siewior diff --git a/drivers/usb/dwc3/debug.h b/drivers/usb/dwc3/debug.h index d8f600e0e88f..3d16dac4e5cc 100644 --- a/drivers/usb/dwc3/debug.h +++ b/drivers/usb/dwc3/debug.h @@ -2,7 +2,7 @@ /** * debug.h - DesignWare USB3 DRD Controller Debug Header * - * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com * * Authors: Felipe Balbi , * Sebastian Andrzej Siewior diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 6dee4dabc0a4..59f2e8c31bd1 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -2,7 +2,7 @@ /* * ep0.c - DesignWare USB3 DRD Controller Endpoint 0 Handling * - * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com * * Authors: Felipe Balbi , * Sebastian Andrzej Siewior @@ -425,11 +425,11 @@ static int dwc3_ep0_handle_test(struct dwc3 *dwc, enum usb_device_state state, return -EINVAL; switch (wIndex >> 8) { - case TEST_J: - case TEST_K: - case TEST_SE0_NAK: - case TEST_PACKET: - case TEST_FORCE_EN: + case USB_TEST_J: + case USB_TEST_K: + case USB_TEST_SE0_NAK: + case USB_TEST_PACKET: + case USB_TEST_FORCE_ENABLE: dwc->test_mode_nr = wIndex >> 8; dwc->test_mode = true; break; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 80c3ef134e41..c2a0f64f8d1e 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2,7 +2,7 @@ /* * gadget.c - DesignWare USB3 DRD Controller Gadget Framework Link * - * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com * * Authors: Felipe Balbi , * Sebastian Andrzej Siewior @@ -46,11 +46,11 @@ int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode) reg &= ~DWC3_DCTL_TSTCTRL_MASK; switch (mode) { - case TEST_J: - case TEST_K: - case TEST_SE0_NAK: - case TEST_PACKET: - case TEST_FORCE_EN: + case USB_TEST_J: + case USB_TEST_K: + case USB_TEST_SE0_NAK: + case USB_TEST_PACKET: + case USB_TEST_FORCE_ENABLE: reg |= mode << 1; break; default: @@ -1054,27 +1054,25 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb, * dwc3_prepare_one_trb - setup one TRB from one request * @dep: endpoint for which this request is prepared * @req: dwc3_request pointer + * @trb_length: buffer size of the TRB * @chain: should this TRB be chained to the next? * @node: only for isochronous endpoints. First TRB needs different type. */ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, - struct dwc3_request *req, unsigned chain, unsigned node) + struct dwc3_request *req, unsigned int trb_length, + unsigned chain, unsigned node) { struct dwc3_trb *trb; - unsigned int length; dma_addr_t dma; unsigned stream_id = req->request.stream_id; unsigned short_not_ok = req->request.short_not_ok; unsigned no_interrupt = req->request.no_interrupt; unsigned is_last = req->request.is_last; - if (req->request.num_sgs > 0) { - length = sg_dma_len(req->start_sg); + if (req->request.num_sgs > 0) dma = sg_dma_address(req->start_sg); - } else { - length = req->request.length; + else dma = req->request.dma; - } trb = &dep->trb_pool[dep->trb_enqueue]; @@ -1086,7 +1084,7 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, req->num_trbs++; - __dwc3_prepare_one_trb(dep, trb, dma, length, chain, node, + __dwc3_prepare_one_trb(dep, trb, dma, trb_length, chain, node, stream_id, short_not_ok, no_interrupt, is_last); } @@ -1096,16 +1094,27 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, struct scatterlist *sg = req->start_sg; struct scatterlist *s; int i; - + unsigned int length = req->request.length; unsigned int remaining = req->request.num_mapped_sgs - req->num_queued_sgs; + /* + * If we resume preparing the request, then get the remaining length of + * the request and resume where we left off. + */ + for_each_sg(req->request.sg, s, req->num_queued_sgs, i) + length -= sg_dma_len(s); + for_each_sg(sg, s, remaining, i) { - unsigned int length = req->request.length; unsigned int maxp = usb_endpoint_maxp(dep->endpoint.desc); unsigned int rem = length % maxp; + unsigned int trb_length; unsigned chain = true; + trb_length = min_t(unsigned int, length, sg_dma_len(s)); + + length -= trb_length; + /* * IOMMU driver is coalescing the list of sgs which shares a * page boundary into one and giving it to USB driver. With @@ -1113,7 +1122,7 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, * sgs passed. So mark the chain bit to false if it isthe last * mapped sg. */ - if (i == remaining - 1) + if ((i == remaining - 1) || !length) chain = false; if (rem && usb_endpoint_dir_out(dep->endpoint.desc) && !chain) { @@ -1123,7 +1132,7 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, req->needs_extra_trb = true; /* prepare normal TRB */ - dwc3_prepare_one_trb(dep, req, true, i); + dwc3_prepare_one_trb(dep, req, trb_length, true, i); /* Now prepare one extra TRB to align transfer size */ trb = &dep->trb_pool[dep->trb_enqueue]; @@ -1134,8 +1143,39 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, req->request.short_not_ok, req->request.no_interrupt, req->request.is_last); + } else if (req->request.zero && req->request.length && + !usb_endpoint_xfer_isoc(dep->endpoint.desc) && + !rem && !chain) { + struct dwc3 *dwc = dep->dwc; + struct dwc3_trb *trb; + + req->needs_extra_trb = true; + + /* Prepare normal TRB */ + dwc3_prepare_one_trb(dep, req, trb_length, true, i); + + /* Prepare one extra TRB to handle ZLP */ + trb = &dep->trb_pool[dep->trb_enqueue]; + req->num_trbs++; + __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, 0, + !req->direction, 1, + req->request.stream_id, + req->request.short_not_ok, + req->request.no_interrupt, + req->request.is_last); + + /* Prepare one more TRB to handle MPS alignment */ + if (!req->direction) { + trb = &dep->trb_pool[dep->trb_enqueue]; + req->num_trbs++; + __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, maxp, + false, 1, req->request.stream_id, + req->request.short_not_ok, + req->request.no_interrupt, + req->request.is_last); + } } else { - dwc3_prepare_one_trb(dep, req, chain, i); + dwc3_prepare_one_trb(dep, req, trb_length, chain, i); } /* @@ -1150,6 +1190,16 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, req->num_queued_sgs++; + /* + * The number of pending SG entries may not correspond to the + * number of mapped SG entries. If all the data are queued, then + * don't include unused SG entries. + */ + if (length == 0) { + req->num_pending_sgs -= req->request.num_mapped_sgs - req->num_queued_sgs; + break; + } + if (!dwc3_calc_trbs_left(dep)) break; } @@ -1169,7 +1219,7 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, req->needs_extra_trb = true; /* prepare normal TRB */ - dwc3_prepare_one_trb(dep, req, true, 0); + dwc3_prepare_one_trb(dep, req, length, true, 0); /* Now prepare one extra TRB to align transfer size */ trb = &dep->trb_pool[dep->trb_enqueue]; @@ -1180,6 +1230,7 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, req->request.no_interrupt, req->request.is_last); } else if (req->request.zero && req->request.length && + !usb_endpoint_xfer_isoc(dep->endpoint.desc) && (IS_ALIGNED(req->request.length, maxp))) { struct dwc3 *dwc = dep->dwc; struct dwc3_trb *trb; @@ -1187,18 +1238,29 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, req->needs_extra_trb = true; /* prepare normal TRB */ - dwc3_prepare_one_trb(dep, req, true, 0); + dwc3_prepare_one_trb(dep, req, length, true, 0); - /* Now prepare one extra TRB to handle ZLP */ + /* Prepare one extra TRB to handle ZLP */ trb = &dep->trb_pool[dep->trb_enqueue]; req->num_trbs++; __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, 0, - false, 1, req->request.stream_id, + !req->direction, 1, req->request.stream_id, req->request.short_not_ok, req->request.no_interrupt, req->request.is_last); + + /* Prepare one more TRB to handle MPS alignment for OUT */ + if (!req->direction) { + trb = &dep->trb_pool[dep->trb_enqueue]; + req->num_trbs++; + __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, maxp, + false, 1, req->request.stream_id, + req->request.short_not_ok, + req->request.no_interrupt, + req->request.is_last); + } } else { - dwc3_prepare_one_trb(dep, req, false, 0); + dwc3_prepare_one_trb(dep, req, length, false, 0); } } @@ -1403,7 +1465,7 @@ static int dwc3_gadget_start_isoc_quirk(struct dwc3_ep *dep) * Check if we can start isoc transfer on the next interval or * 4 uframes in the future with BIT[15:14] as dep->combo_num */ - test_frame_number = dep->frame_number & 0x3fff; + test_frame_number = dep->frame_number & DWC3_FRNUMBER_MASK; test_frame_number |= dep->combo_num << 14; test_frame_number += max_t(u32, 4, dep->interval); @@ -1450,7 +1512,7 @@ static int dwc3_gadget_start_isoc_quirk(struct dwc3_ep *dep) else if (test0 && test1) dep->combo_num = 0; - dep->frame_number &= 0x3fff; + dep->frame_number &= DWC3_FRNUMBER_MASK; dep->frame_number |= dep->combo_num << 14; dep->frame_number += max_t(u32, 4, dep->interval); @@ -1463,6 +1525,7 @@ static int dwc3_gadget_start_isoc_quirk(struct dwc3_ep *dep) static int __dwc3_gadget_start_isoc(struct dwc3_ep *dep) { + const struct usb_endpoint_descriptor *desc = dep->endpoint.desc; struct dwc3 *dwc = dep->dwc; int ret; int i; @@ -1480,6 +1543,27 @@ static int __dwc3_gadget_start_isoc(struct dwc3_ep *dep) return dwc3_gadget_start_isoc_quirk(dep); } + if (desc->bInterval <= 14 && + dwc->gadget.speed >= USB_SPEED_HIGH) { + u32 frame = __dwc3_gadget_get_frame(dwc); + bool rollover = frame < + (dep->frame_number & DWC3_FRNUMBER_MASK); + + /* + * frame_number is set from XferNotReady and may be already + * out of date. DSTS only provides the lower 14 bit of the + * current frame number. So add the upper two bits of + * frame_number and handle a possible rollover. + * This will provide the correct frame_number unless more than + * rollover has happened since XferNotReady. + */ + + dep->frame_number = (dep->frame_number & ~DWC3_FRNUMBER_MASK) | + frame; + if (rollover) + dep->frame_number += BIT(14); + } + for (i = 0; i < DWC3_ISOC_MAX_RETRIES; i++) { dep->frame_number = DWC3_ALIGN_FRAME(dep, i + 1); @@ -2649,8 +2733,17 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep, status); if (req->needs_extra_trb) { + unsigned int maxp = usb_endpoint_maxp(dep->endpoint.desc); + ret = dwc3_gadget_ep_reclaim_trb_linear(dep, req, event, status); + + /* Reclaim MPS padding TRB for ZLP */ + if (!req->direction && req->request.zero && req->request.length && + !usb_endpoint_xfer_isoc(dep->endpoint.desc) && + (IS_ALIGNED(req->request.length, maxp))) + ret = dwc3_gadget_ep_reclaim_trb_linear(dep, req, event, status); + req->needs_extra_trb = false; } @@ -2716,7 +2809,9 @@ static bool dwc3_gadget_endpoint_trbs_complete(struct dwc3_ep *dep, if (dep->flags & DWC3_EP_END_TRANSFER_PENDING) goto out; - if (status == -EXDEV && list_empty(&dep->started_list)) + if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && + list_empty(&dep->started_list) && + (list_empty(&dep->pending_list) || status == -EXDEV)) dwc3_stop_active_transfer(dep, true, true); else if (dwc3_gadget_ep_should_continue(dep)) if (__dwc3_gadget_kick_transfer(dep) == 0) diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h index 24dca3872022..bd85eb7fa9ef 100644 --- a/drivers/usb/dwc3/gadget.h +++ b/drivers/usb/dwc3/gadget.h @@ -2,7 +2,7 @@ /* * gadget.h - DesignWare USB3 DRD Gadget Header * - * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com * * Authors: Felipe Balbi , * Sebastian Andrzej Siewior @@ -54,6 +54,8 @@ struct dwc3; /* U2 Device exit Latency */ #define DWC3_DEFAULT_U2_DEV_EXIT_LAT 0x1FF /* Less then 511 microsec */ +/* Frame/Microframe Number Mask */ +#define DWC3_FRNUMBER_MASK 0x3fff /* -------------------------------------------------------------------------- */ #define to_dwc3_request(r) (container_of(r, struct dwc3_request, request)) diff --git a/drivers/usb/dwc3/io.h b/drivers/usb/dwc3/io.h index 9bbe5d4bf076..76b73b116862 100644 --- a/drivers/usb/dwc3/io.h +++ b/drivers/usb/dwc3/io.h @@ -2,7 +2,7 @@ /** * io.h - DesignWare USB3 DRD IO Header * - * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com * * Authors: Felipe Balbi , * Sebastian Andrzej Siewior -- 2.53.0