From c3aa4eac38752d25e58a27113a33f9a48caabce0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 8 Feb 2021 11:09:33 +0100 Subject: [PATCH] 5.10-stable patches added patches: usb-dwc2-fix-endpoint-direction-check-in-ep_from_windex.patch usb-dwc3-fix-clock-issue-during-resume-in-otg-mode.patch usb-gadget-aspeed-add-missing-of_node_put.patch usb-gadget-legacy-fix-an-error-code-in-eth_bind.patch usb-renesas_usbhs-clear-pipe-running-flag-in-usbhs_pkt_pop.patch usb-usblp-don-t-call-usb_set_interface-if-there-s-a-single-alt.patch usb-xhci-mtk-break-loop-when-find-the-endpoint-to-drop.patch usb-xhci-mtk-fix-unreleased-bandwidth-data.patch usb-xhci-mtk-skip-dropping-bandwidth-of-unchecked-endpoints.patch --- queue-5.10/series | 10 +- ...nt-direction-check-in-ep_from_windex.patch | 74 ++++ ...lock-issue-during-resume-in-otg-mode.patch | 41 +++ ...adget-aspeed-add-missing-of_node_put.patch | 40 +++ ...legacy-fix-an-error-code-in-eth_bind.patch | 35 ++ ...ebu-make-usb-3.0-phy-optional-for-ar.patch | 206 ----------- ...r-pipe-running-flag-in-usbhs_pkt_pop.patch | 33 ++ ...et_interface-if-there-s-a-single-alt.patch | 51 +++ ...-loop-when-find-the-endpoint-to-drop.patch | 36 ++ ...ci-mtk-fix-unreleased-bandwidth-data.patch | 321 ++++++++++++++++++ ...ing-bandwidth-of-unchecked-endpoints.patch | 189 +++++++++++ 11 files changed, 829 insertions(+), 207 deletions(-) create mode 100644 queue-5.10/usb-dwc2-fix-endpoint-direction-check-in-ep_from_windex.patch create mode 100644 queue-5.10/usb-dwc3-fix-clock-issue-during-resume-in-otg-mode.patch create mode 100644 queue-5.10/usb-gadget-aspeed-add-missing-of_node_put.patch create mode 100644 queue-5.10/usb-gadget-legacy-fix-an-error-code-in-eth_bind.patch delete mode 100644 queue-5.10/usb-host-xhci-mvebu-make-usb-3.0-phy-optional-for-ar.patch create mode 100644 queue-5.10/usb-renesas_usbhs-clear-pipe-running-flag-in-usbhs_pkt_pop.patch create mode 100644 queue-5.10/usb-usblp-don-t-call-usb_set_interface-if-there-s-a-single-alt.patch create mode 100644 queue-5.10/usb-xhci-mtk-break-loop-when-find-the-endpoint-to-drop.patch create mode 100644 queue-5.10/usb-xhci-mtk-fix-unreleased-bandwidth-data.patch create mode 100644 queue-5.10/usb-xhci-mtk-skip-dropping-bandwidth-of-unchecked-endpoints.patch diff --git a/queue-5.10/series b/queue-5.10/series index 79f39753657..6514a3f4b5f 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -2,7 +2,15 @@ usb-serial-cp210x-add-pid-vid-for-wsda-200-usb.patch usb-serial-cp210x-add-new-vid-pid-for-supporting-teraoka-ad2000.patch usb-serial-option-adding-support-for-cinterion-mv31.patch usb-host-xhci-mvebu-make-usb-3.0-phy-optional-for-armada-3720.patch -usb-host-xhci-mvebu-make-usb-3.0-phy-optional-for-ar.patch +usb-gadget-legacy-fix-an-error-code-in-eth_bind.patch +usb-gadget-aspeed-add-missing-of_node_put.patch +usb-usblp-don-t-call-usb_set_interface-if-there-s-a-single-alt.patch +usb-renesas_usbhs-clear-pipe-running-flag-in-usbhs_pkt_pop.patch +usb-dwc2-fix-endpoint-direction-check-in-ep_from_windex.patch +usb-dwc3-fix-clock-issue-during-resume-in-otg-mode.patch +usb-xhci-mtk-fix-unreleased-bandwidth-data.patch +usb-xhci-mtk-skip-dropping-bandwidth-of-unchecked-endpoints.patch +usb-xhci-mtk-break-loop-when-find-the-endpoint-to-drop.patch arm-omap1-osk-fix-ohci-omap-breakage.patch arm64-dts-qcom-c630-keep-both-touchpad-devices-enabl.patch input-i8042-unbreak-pegatron-c15b.patch diff --git a/queue-5.10/usb-dwc2-fix-endpoint-direction-check-in-ep_from_windex.patch b/queue-5.10/usb-dwc2-fix-endpoint-direction-check-in-ep_from_windex.patch new file mode 100644 index 00000000000..e5418f49fe5 --- /dev/null +++ b/queue-5.10/usb-dwc2-fix-endpoint-direction-check-in-ep_from_windex.patch @@ -0,0 +1,74 @@ +From f670e9f9c8cac716c3506c6bac9e997b27ad441a Mon Sep 17 00:00:00 2001 +From: Heiko Stuebner +Date: Wed, 27 Jan 2021 11:39:19 +0100 +Subject: usb: dwc2: Fix endpoint direction check in ep_from_windex + +From: Heiko Stuebner + +commit f670e9f9c8cac716c3506c6bac9e997b27ad441a upstream. + +dwc2_hsotg_process_req_status uses ep_from_windex() to retrieve +the endpoint for the index provided in the wIndex request param. + +In a test-case with a rndis gadget running and sending a malformed +packet to it like: + dev.ctrl_transfer( + 0x82, # bmRequestType + 0x00, # bRequest + 0x0000, # wValue + 0x0001, # wIndex + 0x00 # wLength + ) +it is possible to cause a crash: + +[ 217.533022] dwc2 ff300000.usb: dwc2_hsotg_process_req_status: USB_REQ_GET_STATUS +[ 217.559003] Unable to handle kernel read from unreadable memory at virtual address 0000000000000088 +... +[ 218.313189] Call trace: +[ 218.330217] ep_from_windex+0x3c/0x54 +[ 218.348565] usb_gadget_giveback_request+0x10/0x20 +[ 218.368056] dwc2_hsotg_complete_request+0x144/0x184 + +This happens because ep_from_windex wants to compare the endpoint +direction even if index_to_ep() didn't return an endpoint due to +the direction not matching. + +The fix is easy insofar that the actual direction check is already +happening when calling index_to_ep() which will return NULL if there +is no endpoint for the targeted direction, so the offending check +can go away completely. + +Fixes: c6f5c050e2a7 ("usb: dwc2: gadget: add bi-directional endpoint support") +Cc: stable@vger.kernel.org +Reported-by: Gerhard Klostermeier +Signed-off-by: Heiko Stuebner +Link: https://lore.kernel.org/r/20210127103919.58215-1-heiko@sntech.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc2/gadget.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +--- a/drivers/usb/dwc2/gadget.c ++++ b/drivers/usb/dwc2/gadget.c +@@ -1543,7 +1543,6 @@ static void dwc2_hsotg_complete_oursetup + static struct dwc2_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg, + u32 windex) + { +- struct dwc2_hsotg_ep *ep; + int dir = (windex & USB_DIR_IN) ? 1 : 0; + int idx = windex & 0x7F; + +@@ -1553,12 +1552,7 @@ static struct dwc2_hsotg_ep *ep_from_win + if (idx > hsotg->num_of_eps) + return NULL; + +- ep = index_to_ep(hsotg, idx, dir); +- +- if (idx && ep->dir_in != dir) +- return NULL; +- +- return ep; ++ return index_to_ep(hsotg, idx, dir); + } + + /** diff --git a/queue-5.10/usb-dwc3-fix-clock-issue-during-resume-in-otg-mode.patch b/queue-5.10/usb-dwc3-fix-clock-issue-during-resume-in-otg-mode.patch new file mode 100644 index 00000000000..783220e3e24 --- /dev/null +++ b/queue-5.10/usb-dwc3-fix-clock-issue-during-resume-in-otg-mode.patch @@ -0,0 +1,41 @@ +From 0e5a3c8284a30f4c43fd81d7285528ece74563b5 Mon Sep 17 00:00:00 2001 +From: Gary Bisson +Date: Mon, 25 Jan 2021 17:19:34 +0100 +Subject: usb: dwc3: fix clock issue during resume in OTG mode + +From: Gary Bisson + +commit 0e5a3c8284a30f4c43fd81d7285528ece74563b5 upstream. + +Commit fe8abf332b8f ("usb: dwc3: support clocks and resets for DWC3 +core") introduced clock support and a new function named +dwc3_core_init_for_resume() which enables the clock before calling +dwc3_core_init() during resume as clocks get disabled during suspend. + +Unfortunately in this commit the DWC3_GCTL_PRTCAP_OTG case was forgotten +and therefore during resume, a platform could call dwc3_core_init() +without re-enabling the clocks first, preventing to resume properly. + +So update the resume path to call dwc3_core_init_for_resume() as it +should. + +Fixes: fe8abf332b8f ("usb: dwc3: support clocks and resets for DWC3 core") +Cc: stable@vger.kernel.org +Signed-off-by: Gary Bisson +Link: https://lore.kernel.org/r/20210125161934.527820-1-gary.bisson@boundarydevices.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -1758,7 +1758,7 @@ static int dwc3_resume_common(struct dwc + if (PMSG_IS_AUTO(msg)) + break; + +- ret = dwc3_core_init(dwc); ++ ret = dwc3_core_init_for_resume(dwc); + if (ret) + return ret; + diff --git a/queue-5.10/usb-gadget-aspeed-add-missing-of_node_put.patch b/queue-5.10/usb-gadget-aspeed-add-missing-of_node_put.patch new file mode 100644 index 00000000000..72c05d209e5 --- /dev/null +++ b/queue-5.10/usb-gadget-aspeed-add-missing-of_node_put.patch @@ -0,0 +1,40 @@ +From a55a9a4c5c6253f6e4dea268af728664ac997790 Mon Sep 17 00:00:00 2001 +From: kernel test robot +Date: Thu, 21 Jan 2021 19:12:54 +0100 +Subject: usb: gadget: aspeed: add missing of_node_put + +From: kernel test robot + +commit a55a9a4c5c6253f6e4dea268af728664ac997790 upstream. + +Breaking out of for_each_child_of_node requires a put on the +child value. + +Generated by: scripts/coccinelle/iterators/for_each_child.cocci + +Fixes: 82c2d81361ec ("coccinelle: iterators: Add for_each_child.cocci script") +CC: Sumera Priyadarsini +Reported-by: kernel test robot +Signed-off-by: kernel test robot +Signed-off-by: Julia Lawall +Cc: stable +Link: https://lore.kernel.org/r/alpine.DEB.2.22.394.2101211907060.14700@hadrien +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/aspeed-vhub/hub.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/udc/aspeed-vhub/hub.c ++++ b/drivers/usb/gadget/udc/aspeed-vhub/hub.c +@@ -999,8 +999,10 @@ static int ast_vhub_of_parse_str_desc(st + str_array[offset].s = NULL; + + ret = ast_vhub_str_alloc_add(vhub, &lang_str); +- if (ret) ++ if (ret) { ++ of_node_put(child); + break; ++ } + } + + return ret; diff --git a/queue-5.10/usb-gadget-legacy-fix-an-error-code-in-eth_bind.patch b/queue-5.10/usb-gadget-legacy-fix-an-error-code-in-eth_bind.patch new file mode 100644 index 00000000000..b17f71a998c --- /dev/null +++ b/queue-5.10/usb-gadget-legacy-fix-an-error-code-in-eth_bind.patch @@ -0,0 +1,35 @@ +From 3e1f4a2e1184ae6ad7f4caf682ced9554141a0f4 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 28 Jan 2021 12:33:42 +0300 +Subject: USB: gadget: legacy: fix an error code in eth_bind() + +From: Dan Carpenter + +commit 3e1f4a2e1184ae6ad7f4caf682ced9554141a0f4 upstream. + +This code should return -ENOMEM if the allocation fails but it currently +returns success. + +Fixes: 9b95236eebdb ("usb: gadget: ether: allocate and init otg descriptor by otg capabilities") +Signed-off-by: Dan Carpenter +Link: https://lore.kernel.org/r/YBKE9rqVuJEOUWpW@mwanda +Cc: stable +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/legacy/ether.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/legacy/ether.c ++++ b/drivers/usb/gadget/legacy/ether.c +@@ -403,8 +403,10 @@ static int eth_bind(struct usb_composite + struct usb_descriptor_header *usb_desc; + + usb_desc = usb_otg_descriptor_alloc(gadget); +- if (!usb_desc) ++ if (!usb_desc) { ++ status = -ENOMEM; + goto fail1; ++ } + usb_otg_descriptor_init(gadget, usb_desc); + otg_desc[0] = usb_desc; + otg_desc[1] = NULL; diff --git a/queue-5.10/usb-host-xhci-mvebu-make-usb-3.0-phy-optional-for-ar.patch b/queue-5.10/usb-host-xhci-mvebu-make-usb-3.0-phy-optional-for-ar.patch deleted file mode 100644 index 31c0cd2990c..00000000000 --- a/queue-5.10/usb-host-xhci-mvebu-make-usb-3.0-phy-optional-for-ar.patch +++ /dev/null @@ -1,206 +0,0 @@ -From bec5fbb439c63738153b186dea9e487db9b5259b Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 1 Feb 2021 16:08:03 +0100 -Subject: usb: host: xhci: mvebu: make USB 3.0 PHY optional for Armada 3720 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -From: Pali Rohár - -commit 3241929b67d28c83945d3191c6816a3271fd6b85 upstream. - -Older ATF does not provide SMC call for USB 3.0 phy power on functionality -and therefore initialization of xhci-hcd is failing when older version of -ATF is used. In this case phy_power_on() function returns -EOPNOTSUPP. - -[ 3.108467] mvebu-a3700-comphy d0018300.phy: unsupported SMC call, try updating your firmware -[ 3.117250] phy phy-d0018300.phy.0: phy poweron failed --> -95 -[ 3.123465] xhci-hcd: probe of d0058000.usb failed with error -95 - -This patch introduces a new plat_setup callback for xhci platform drivers -which is called prior calling usb_add_hcd() function. This function at its -beginning skips PHY init if hcd->skip_phy_initialization is set. - -Current init_quirk callback for xhci platform drivers is called from -xhci_plat_setup() function which is called after chip reset completes. -It happens in the middle of the usb_add_hcd() function and therefore this -callback cannot be used for setting if PHY init should be skipped or not. - -For Armada 3720 this patch introduce a new xhci_mvebu_a3700_plat_setup() -function configured as a xhci platform plat_setup callback. This new -function calls phy_power_on() and in case it returns -EOPNOTSUPP then -XHCI_SKIP_PHY_INIT quirk is set to instruct xhci-plat to skip PHY -initialization. - -This patch fixes above failure by ignoring 'not supported' error in -xhci-hcd driver. In this case it is expected that phy is already power on. - -It fixes initialization of xhci-hcd on Espressobin boards where is older -Marvell's Arm Trusted Firmware without SMC call for USB 3.0 phy power. - -This is regression introduced in commit bd3d25b07342 ("arm64: dts: marvell: -armada-37xx: link USB hosts with their PHYs") where USB 3.0 phy was defined -and therefore xhci-hcd on Espressobin with older ATF started failing. - -Fixes: bd3d25b07342 ("arm64: dts: marvell: armada-37xx: link USB hosts with their PHYs") -Cc: # 5.1+: ea17a0f153af: phy: marvell: comphy: Convert internal SMCC firmware return codes to errno -Cc: # 5.1+: f768e718911e: usb: host: xhci-plat: add priv quirk for skip PHY initialization -Tested-by: Tomasz Maciej Nowak -Tested-by: Yoshihiro Shimoda # On R-Car -Reviewed-by: Yoshihiro Shimoda # xhci-plat -Acked-by: Mathias Nyman -Signed-off-by: Pali Rohár -Link: https://lore.kernel.org/r/20210201150803.7305-1-pali@kernel.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/usb/host/xhci-mvebu.c | 42 +++++++++++++++++++++++++++++++++++ - drivers/usb/host/xhci-mvebu.h | 6 +++++ - drivers/usb/host/xhci-plat.c | 20 ++++++++++++++++- - drivers/usb/host/xhci-plat.h | 1 + - 4 files changed, 68 insertions(+), 1 deletion(-) - -diff --git a/drivers/usb/host/xhci-mvebu.c b/drivers/usb/host/xhci-mvebu.c -index 60651a50770f9..8ca1a235d1645 100644 ---- a/drivers/usb/host/xhci-mvebu.c -+++ b/drivers/usb/host/xhci-mvebu.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -74,6 +75,47 @@ int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd) - return 0; - } - -+int xhci_mvebu_a3700_plat_setup(struct usb_hcd *hcd) -+{ -+ struct xhci_hcd *xhci = hcd_to_xhci(hcd); -+ struct device *dev = hcd->self.controller; -+ struct phy *phy; -+ int ret; -+ -+ /* Old bindings miss the PHY handle */ -+ phy = of_phy_get(dev->of_node, "usb3-phy"); -+ if (IS_ERR(phy) && PTR_ERR(phy) == -EPROBE_DEFER) -+ return -EPROBE_DEFER; -+ else if (IS_ERR(phy)) -+ goto phy_out; -+ -+ ret = phy_init(phy); -+ if (ret) -+ goto phy_put; -+ -+ ret = phy_set_mode(phy, PHY_MODE_USB_HOST_SS); -+ if (ret) -+ goto phy_exit; -+ -+ ret = phy_power_on(phy); -+ if (ret == -EOPNOTSUPP) { -+ /* Skip initializatin of XHCI PHY when it is unsupported by firmware */ -+ dev_warn(dev, "PHY unsupported by firmware\n"); -+ xhci->quirks |= XHCI_SKIP_PHY_INIT; -+ } -+ if (ret) -+ goto phy_exit; -+ -+ phy_power_off(phy); -+phy_exit: -+ phy_exit(phy); -+phy_put: -+ of_phy_put(phy); -+phy_out: -+ -+ return 0; -+} -+ - int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd) - { - struct xhci_hcd *xhci = hcd_to_xhci(hcd); -diff --git a/drivers/usb/host/xhci-mvebu.h b/drivers/usb/host/xhci-mvebu.h -index 3be021793cc8b..01bf3fcb3eca5 100644 ---- a/drivers/usb/host/xhci-mvebu.h -+++ b/drivers/usb/host/xhci-mvebu.h -@@ -12,6 +12,7 @@ struct usb_hcd; - - #if IS_ENABLED(CONFIG_USB_XHCI_MVEBU) - int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd); -+int xhci_mvebu_a3700_plat_setup(struct usb_hcd *hcd); - int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd); - #else - static inline int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd) -@@ -19,6 +20,11 @@ static inline int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd) - return 0; - } - -+static inline int xhci_mvebu_a3700_plat_setup(struct usb_hcd *hcd) -+{ -+ return 0; -+} -+ - static inline int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd) - { - return 0; -diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c -index 4d34f6005381e..c1edcc9b13cec 100644 ---- a/drivers/usb/host/xhci-plat.c -+++ b/drivers/usb/host/xhci-plat.c -@@ -44,6 +44,16 @@ static void xhci_priv_plat_start(struct usb_hcd *hcd) - priv->plat_start(hcd); - } - -+static int xhci_priv_plat_setup(struct usb_hcd *hcd) -+{ -+ struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd); -+ -+ if (!priv->plat_setup) -+ return 0; -+ -+ return priv->plat_setup(hcd); -+} -+ - static int xhci_priv_init_quirk(struct usb_hcd *hcd) - { - struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd); -@@ -111,6 +121,7 @@ static const struct xhci_plat_priv xhci_plat_marvell_armada = { - }; - - static const struct xhci_plat_priv xhci_plat_marvell_armada3700 = { -+ .plat_setup = xhci_mvebu_a3700_plat_setup, - .init_quirk = xhci_mvebu_a3700_init_quirk, - }; - -@@ -330,7 +341,14 @@ static int xhci_plat_probe(struct platform_device *pdev) - - hcd->tpl_support = of_usb_host_tpl_support(sysdev->of_node); - xhci->shared_hcd->tpl_support = hcd->tpl_support; -- if (priv && (priv->quirks & XHCI_SKIP_PHY_INIT)) -+ -+ if (priv) { -+ ret = xhci_priv_plat_setup(hcd); -+ if (ret) -+ goto disable_usb_phy; -+ } -+ -+ if ((xhci->quirks & XHCI_SKIP_PHY_INIT) || (priv && (priv->quirks & XHCI_SKIP_PHY_INIT))) - hcd->skip_phy_initialization = 1; - - if (priv && (priv->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK)) -diff --git a/drivers/usb/host/xhci-plat.h b/drivers/usb/host/xhci-plat.h -index 1fb149d1fbcea..561d0b7bce098 100644 ---- a/drivers/usb/host/xhci-plat.h -+++ b/drivers/usb/host/xhci-plat.h -@@ -13,6 +13,7 @@ - struct xhci_plat_priv { - const char *firmware_name; - unsigned long long quirks; -+ int (*plat_setup)(struct usb_hcd *); - void (*plat_start)(struct usb_hcd *); - int (*init_quirk)(struct usb_hcd *); - int (*suspend_quirk)(struct usb_hcd *); --- -2.27.0 - diff --git a/queue-5.10/usb-renesas_usbhs-clear-pipe-running-flag-in-usbhs_pkt_pop.patch b/queue-5.10/usb-renesas_usbhs-clear-pipe-running-flag-in-usbhs_pkt_pop.patch new file mode 100644 index 00000000000..92aa805b53c --- /dev/null +++ b/queue-5.10/usb-renesas_usbhs-clear-pipe-running-flag-in-usbhs_pkt_pop.patch @@ -0,0 +1,33 @@ +From 9917f0e3cdba7b9f1a23f70e3f70b1a106be54a8 Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda +Date: Mon, 1 Feb 2021 21:47:20 +0900 +Subject: usb: renesas_usbhs: Clear pipe running flag in usbhs_pkt_pop() + +From: Yoshihiro Shimoda + +commit 9917f0e3cdba7b9f1a23f70e3f70b1a106be54a8 upstream. + +Should clear the pipe running flag in usbhs_pkt_pop(). Otherwise, +we cannot use this pipe after dequeue was called while the pipe was +running. + +Fixes: 8355b2b3082d ("usb: renesas_usbhs: fix the behavior of some usbhs_pkt_handle") +Reported-by: Tho Vu +Signed-off-by: Yoshihiro Shimoda +Link: https://lore.kernel.org/r/1612183640-8898-1-git-send-email-yoshihiro.shimoda.uh@renesas.com +Cc: stable +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/renesas_usbhs/fifo.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/renesas_usbhs/fifo.c ++++ b/drivers/usb/renesas_usbhs/fifo.c +@@ -126,6 +126,7 @@ struct usbhs_pkt *usbhs_pkt_pop(struct u + } + + usbhs_pipe_clear_without_sequence(pipe, 0, 0); ++ usbhs_pipe_running(pipe, 0); + + __usbhsf_pkt_del(pkt); + } diff --git a/queue-5.10/usb-usblp-don-t-call-usb_set_interface-if-there-s-a-single-alt.patch b/queue-5.10/usb-usblp-don-t-call-usb_set_interface-if-there-s-a-single-alt.patch new file mode 100644 index 00000000000..0af5510d1da --- /dev/null +++ b/queue-5.10/usb-usblp-don-t-call-usb_set_interface-if-there-s-a-single-alt.patch @@ -0,0 +1,51 @@ +From d8c6edfa3f4ee0d45d7ce5ef18d1245b78774b9d Mon Sep 17 00:00:00 2001 +From: Jeremy Figgins +Date: Sat, 23 Jan 2021 18:21:36 -0600 +Subject: USB: usblp: don't call usb_set_interface if there's a single alt + +From: Jeremy Figgins + +commit d8c6edfa3f4ee0d45d7ce5ef18d1245b78774b9d upstream. + +Some devices, such as the Winbond Electronics Corp. Virtual Com Port +(Vendor=0416, ProdId=5011), lockup when usb_set_interface() or +usb_clear_halt() are called. This device has only a single +altsetting, so it should not be necessary to call usb_set_interface(). + +Acked-by: Pete Zaitcev +Signed-off-by: Jeremy Figgins +Link: https://lore.kernel.org/r/YAy9kJhM/rG8EQXC@watson +Cc: stable +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/class/usblp.c | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +--- a/drivers/usb/class/usblp.c ++++ b/drivers/usb/class/usblp.c +@@ -1329,14 +1329,17 @@ static int usblp_set_protocol(struct usb + if (protocol < USBLP_FIRST_PROTOCOL || protocol > USBLP_LAST_PROTOCOL) + return -EINVAL; + +- alts = usblp->protocol[protocol].alt_setting; +- if (alts < 0) +- return -EINVAL; +- r = usb_set_interface(usblp->dev, usblp->ifnum, alts); +- if (r < 0) { +- printk(KERN_ERR "usblp: can't set desired altsetting %d on interface %d\n", +- alts, usblp->ifnum); +- return r; ++ /* Don't unnecessarily set the interface if there's a single alt. */ ++ if (usblp->intf->num_altsetting > 1) { ++ alts = usblp->protocol[protocol].alt_setting; ++ if (alts < 0) ++ return -EINVAL; ++ r = usb_set_interface(usblp->dev, usblp->ifnum, alts); ++ if (r < 0) { ++ printk(KERN_ERR "usblp: can't set desired altsetting %d on interface %d\n", ++ alts, usblp->ifnum); ++ return r; ++ } + } + + usblp->bidir = (usblp->protocol[protocol].epread != NULL); diff --git a/queue-5.10/usb-xhci-mtk-break-loop-when-find-the-endpoint-to-drop.patch b/queue-5.10/usb-xhci-mtk-break-loop-when-find-the-endpoint-to-drop.patch new file mode 100644 index 00000000000..2c84e360497 --- /dev/null +++ b/queue-5.10/usb-xhci-mtk-break-loop-when-find-the-endpoint-to-drop.patch @@ -0,0 +1,36 @@ +From a50ea34d6dd00a12c9cd29cf7b0fa72816bffbcb Mon Sep 17 00:00:00 2001 +From: Chunfeng Yun +Date: Tue, 2 Feb 2021 16:38:24 +0800 +Subject: usb: xhci-mtk: break loop when find the endpoint to drop + +From: Chunfeng Yun + +commit a50ea34d6dd00a12c9cd29cf7b0fa72816bffbcb upstream. + +No need to check the following endpoints after finding the endpoint +wanted to drop. + +Fixes: 54f6a8af3722 ("usb: xhci-mtk: skip dropping bandwidth of unchecked endpoints") +Cc: stable +Reported-by: Ikjoon Jang +Signed-off-by: Chunfeng Yun +Link: https://lore.kernel.org/r/1612255104-5363-1-git-send-email-chunfeng.yun@mediatek.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-mtk-sch.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci-mtk-sch.c ++++ b/drivers/usb/host/xhci-mtk-sch.c +@@ -689,8 +689,10 @@ void xhci_mtk_drop_ep_quirk(struct usb_h + sch_bw = &sch_array[bw_index]; + + list_for_each_entry_safe(sch_ep, tmp, &sch_bw->bw_ep_list, endpoint) { +- if (sch_ep->ep == ep) ++ if (sch_ep->ep == ep) { + destroy_sch_ep(udev, sch_bw, sch_ep); ++ break; ++ } + } + } + EXPORT_SYMBOL_GPL(xhci_mtk_drop_ep_quirk); diff --git a/queue-5.10/usb-xhci-mtk-fix-unreleased-bandwidth-data.patch b/queue-5.10/usb-xhci-mtk-fix-unreleased-bandwidth-data.patch new file mode 100644 index 00000000000..1896cea44f6 --- /dev/null +++ b/queue-5.10/usb-xhci-mtk-fix-unreleased-bandwidth-data.patch @@ -0,0 +1,321 @@ +From 1d69f9d901ef14d81c3b004e3282b8cc7b456280 Mon Sep 17 00:00:00 2001 +From: Ikjoon Jang +Date: Wed, 13 Jan 2021 18:05:11 +0800 +Subject: usb: xhci-mtk: fix unreleased bandwidth data + +From: Ikjoon Jang + +commit 1d69f9d901ef14d81c3b004e3282b8cc7b456280 upstream. + +xhci-mtk needs XHCI_MTK_HOST quirk functions in add_endpoint() and +drop_endpoint() to handle its own sw bandwidth management. + +It stores bandwidth data into an internal table every time +add_endpoint() is called, and drops those in drop_endpoint(). +But when bandwidth allocation fails at one endpoint, all earlier +allocation from the same interface could still remain at the table. + +This patch moves bandwidth management codes to check_bandwidth() and +reset_bandwidth() path. To do so, this patch also adds those functions +to xhci_driver_overrides and lets mtk-xhci to release all failed +endpoints in reset_bandwidth() path. + +Fixes: 08e469de87a2 ("usb: xhci-mtk: supports bandwidth scheduling with multi-TT") +Signed-off-by: Ikjoon Jang +Link: https://lore.kernel.org/r/20210113180444.v6.1.Id0d31b5f3ddf5e734d2ab11161ac5821921b1e1e@changeid +Cc: stable +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-mtk-sch.c | 123 +++++++++++++++++++++++++++------------- + drivers/usb/host/xhci-mtk.c | 2 + drivers/usb/host/xhci-mtk.h | 13 ++++ + drivers/usb/host/xhci.c | 8 +- + drivers/usb/host/xhci.h | 4 + + 5 files changed, 111 insertions(+), 39 deletions(-) + +--- a/drivers/usb/host/xhci-mtk-sch.c ++++ b/drivers/usb/host/xhci-mtk-sch.c +@@ -200,6 +200,7 @@ static struct mu3h_sch_ep_info *create_s + + sch_ep->sch_tt = tt; + sch_ep->ep = ep; ++ INIT_LIST_HEAD(&sch_ep->tt_endpoint); + + return sch_ep; + } +@@ -583,6 +584,8 @@ int xhci_mtk_sch_init(struct xhci_hcd_mt + + mtk->sch_array = sch_array; + ++ INIT_LIST_HEAD(&mtk->bw_ep_list_new); ++ + return 0; + } + EXPORT_SYMBOL_GPL(xhci_mtk_sch_init); +@@ -601,19 +604,14 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd + struct xhci_ep_ctx *ep_ctx; + struct xhci_slot_ctx *slot_ctx; + struct xhci_virt_device *virt_dev; +- struct mu3h_sch_bw_info *sch_bw; + struct mu3h_sch_ep_info *sch_ep; +- struct mu3h_sch_bw_info *sch_array; + unsigned int ep_index; +- int bw_index; +- int ret = 0; + + xhci = hcd_to_xhci(hcd); + virt_dev = xhci->devs[udev->slot_id]; + ep_index = xhci_get_endpoint_index(&ep->desc); + slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); + ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); +- sch_array = mtk->sch_array; + + xhci_dbg(xhci, "%s() type:%d, speed:%d, mpkt:%d, dir:%d, ep:%p\n", + __func__, usb_endpoint_type(&ep->desc), udev->speed, +@@ -632,39 +630,34 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd + return 0; + } + +- bw_index = get_bw_index(xhci, udev, ep); +- sch_bw = &sch_array[bw_index]; +- + sch_ep = create_sch_ep(udev, ep, ep_ctx); + if (IS_ERR_OR_NULL(sch_ep)) + return -ENOMEM; + + setup_sch_info(udev, ep_ctx, sch_ep); + +- ret = check_sch_bw(udev, sch_bw, sch_ep); +- if (ret) { +- xhci_err(xhci, "Not enough bandwidth!\n"); +- if (is_fs_or_ls(udev->speed)) +- drop_tt(udev); +- +- kfree(sch_ep); +- return -ENOSPC; +- } ++ list_add_tail(&sch_ep->endpoint, &mtk->bw_ep_list_new); + +- list_add_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list); ++ return 0; ++} ++EXPORT_SYMBOL_GPL(xhci_mtk_add_ep_quirk); + +- ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts) +- | EP_BCSCOUNT(sch_ep->cs_count) | EP_BBM(sch_ep->burst_mode)); +- ep_ctx->reserved[1] |= cpu_to_le32(EP_BOFFSET(sch_ep->offset) +- | EP_BREPEAT(sch_ep->repeat)); ++static void xhci_mtk_drop_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev, ++ struct mu3h_sch_ep_info *sch_ep) ++{ ++ struct xhci_hcd *xhci = hcd_to_xhci(mtk->hcd); ++ int bw_index = get_bw_index(xhci, udev, sch_ep->ep); ++ struct mu3h_sch_bw_info *sch_bw = &mtk->sch_array[bw_index]; + +- xhci_dbg(xhci, " PKTS:%x, CSCOUNT:%x, BM:%x, OFFSET:%x, REPEAT:%x\n", +- sch_ep->pkts, sch_ep->cs_count, sch_ep->burst_mode, +- sch_ep->offset, sch_ep->repeat); ++ update_bus_bw(sch_bw, sch_ep, 0); ++ list_del(&sch_ep->endpoint); + +- return 0; ++ if (sch_ep->sch_tt) { ++ list_del(&sch_ep->tt_endpoint); ++ drop_tt(udev); ++ } ++ kfree(sch_ep); + } +-EXPORT_SYMBOL_GPL(xhci_mtk_add_ep_quirk); + + void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, + struct usb_host_endpoint *ep) +@@ -675,7 +668,7 @@ void xhci_mtk_drop_ep_quirk(struct usb_h + struct xhci_virt_device *virt_dev; + struct mu3h_sch_bw_info *sch_array; + struct mu3h_sch_bw_info *sch_bw; +- struct mu3h_sch_ep_info *sch_ep; ++ struct mu3h_sch_ep_info *sch_ep, *tmp; + int bw_index; + + xhci = hcd_to_xhci(hcd); +@@ -694,17 +687,73 @@ void xhci_mtk_drop_ep_quirk(struct usb_h + bw_index = get_bw_index(xhci, udev, ep); + sch_bw = &sch_array[bw_index]; + +- list_for_each_entry(sch_ep, &sch_bw->bw_ep_list, endpoint) { ++ list_for_each_entry_safe(sch_ep, tmp, &sch_bw->bw_ep_list, endpoint) { + if (sch_ep->ep == ep) { +- update_bus_bw(sch_bw, sch_ep, 0); +- list_del(&sch_ep->endpoint); +- if (is_fs_or_ls(udev->speed)) { +- list_del(&sch_ep->tt_endpoint); +- drop_tt(udev); +- } +- kfree(sch_ep); +- break; ++ xhci_mtk_drop_ep(mtk, udev, sch_ep); + } + } + } + EXPORT_SYMBOL_GPL(xhci_mtk_drop_ep_quirk); ++ ++int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) ++{ ++ struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); ++ struct xhci_hcd *xhci = hcd_to_xhci(hcd); ++ struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id]; ++ struct mu3h_sch_bw_info *sch_bw; ++ struct mu3h_sch_ep_info *sch_ep, *tmp; ++ int bw_index, ret; ++ ++ dev_dbg(&udev->dev, "%s\n", __func__); ++ ++ list_for_each_entry(sch_ep, &mtk->bw_ep_list_new, endpoint) { ++ bw_index = get_bw_index(xhci, udev, sch_ep->ep); ++ sch_bw = &mtk->sch_array[bw_index]; ++ ++ ret = check_sch_bw(udev, sch_bw, sch_ep); ++ if (ret) { ++ xhci_err(xhci, "Not enough bandwidth!\n"); ++ return -ENOSPC; ++ } ++ } ++ ++ list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_list_new, endpoint) { ++ struct xhci_ep_ctx *ep_ctx; ++ struct usb_host_endpoint *ep = sch_ep->ep; ++ unsigned int ep_index = xhci_get_endpoint_index(&ep->desc); ++ ++ bw_index = get_bw_index(xhci, udev, ep); ++ sch_bw = &mtk->sch_array[bw_index]; ++ ++ list_move_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list); ++ ++ ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); ++ ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts) ++ | EP_BCSCOUNT(sch_ep->cs_count) ++ | EP_BBM(sch_ep->burst_mode)); ++ ep_ctx->reserved[1] |= cpu_to_le32(EP_BOFFSET(sch_ep->offset) ++ | EP_BREPEAT(sch_ep->repeat)); ++ ++ xhci_dbg(xhci, " PKTS:%x, CSCOUNT:%x, BM:%x, OFFSET:%x, REPEAT:%x\n", ++ sch_ep->pkts, sch_ep->cs_count, sch_ep->burst_mode, ++ sch_ep->offset, sch_ep->repeat); ++ } ++ ++ return xhci_check_bandwidth(hcd, udev); ++} ++EXPORT_SYMBOL_GPL(xhci_mtk_check_bandwidth); ++ ++void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) ++{ ++ struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); ++ struct mu3h_sch_ep_info *sch_ep, *tmp; ++ ++ dev_dbg(&udev->dev, "%s\n", __func__); ++ ++ list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_list_new, endpoint) { ++ xhci_mtk_drop_ep(mtk, udev, sch_ep); ++ } ++ ++ xhci_reset_bandwidth(hcd, udev); ++} ++EXPORT_SYMBOL_GPL(xhci_mtk_reset_bandwidth); +--- a/drivers/usb/host/xhci-mtk.c ++++ b/drivers/usb/host/xhci-mtk.c +@@ -347,6 +347,8 @@ static void usb_wakeup_set(struct xhci_h + static int xhci_mtk_setup(struct usb_hcd *hcd); + static const struct xhci_driver_overrides xhci_mtk_overrides __initconst = { + .reset = xhci_mtk_setup, ++ .check_bandwidth = xhci_mtk_check_bandwidth, ++ .reset_bandwidth = xhci_mtk_reset_bandwidth, + }; + + static struct hc_driver __read_mostly xhci_mtk_hc_driver; +--- a/drivers/usb/host/xhci-mtk.h ++++ b/drivers/usb/host/xhci-mtk.h +@@ -130,6 +130,7 @@ struct mu3c_ippc_regs { + struct xhci_hcd_mtk { + struct device *dev; + struct usb_hcd *hcd; ++ struct list_head bw_ep_list_new; + struct mu3h_sch_bw_info *sch_array; + struct mu3c_ippc_regs __iomem *ippc_regs; + bool has_ippc; +@@ -166,6 +167,8 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd + struct usb_host_endpoint *ep); + void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, + struct usb_host_endpoint *ep); ++int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); ++void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); + + #else + static inline int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, +@@ -179,6 +182,16 @@ static inline void xhci_mtk_drop_ep_quir + { + } + ++static inline int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, ++ struct usb_device *udev) ++{ ++ return 0; ++} ++ ++static inline void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, ++ struct usb_device *udev) ++{ ++} + #endif + + #endif /* _XHCI_MTK_H_ */ +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -2861,7 +2861,7 @@ static void xhci_check_bw_drop_ep_stream + * else should be touching the xhci->devs[slot_id] structure, so we + * don't need to take the xhci->lock for manipulating that. + */ +-static int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) ++int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) + { + int i; + int ret = 0; +@@ -2959,7 +2959,7 @@ command_cleanup: + return ret; + } + +-static void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) ++void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) + { + struct xhci_hcd *xhci; + struct xhci_virt_device *virt_dev; +@@ -5385,6 +5385,10 @@ void xhci_init_driver(struct hc_driver * + drv->reset = over->reset; + if (over->start) + drv->start = over->start; ++ if (over->check_bandwidth) ++ drv->check_bandwidth = over->check_bandwidth; ++ if (over->reset_bandwidth) ++ drv->reset_bandwidth = over->reset_bandwidth; + } + } + EXPORT_SYMBOL_GPL(xhci_init_driver); +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1916,6 +1916,8 @@ struct xhci_driver_overrides { + size_t extra_priv_size; + int (*reset)(struct usb_hcd *hcd); + int (*start)(struct usb_hcd *hcd); ++ int (*check_bandwidth)(struct usb_hcd *, struct usb_device *); ++ void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *); + }; + + #define XHCI_CFC_DELAY 10 +@@ -2070,6 +2072,8 @@ int xhci_gen_setup(struct usb_hcd *hcd, + void xhci_shutdown(struct usb_hcd *hcd); + void xhci_init_driver(struct hc_driver *drv, + const struct xhci_driver_overrides *over); ++int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); ++void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); + int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id); + int xhci_ext_cap_init(struct xhci_hcd *xhci); + diff --git a/queue-5.10/usb-xhci-mtk-skip-dropping-bandwidth-of-unchecked-endpoints.patch b/queue-5.10/usb-xhci-mtk-skip-dropping-bandwidth-of-unchecked-endpoints.patch new file mode 100644 index 00000000000..01f02d226dc --- /dev/null +++ b/queue-5.10/usb-xhci-mtk-skip-dropping-bandwidth-of-unchecked-endpoints.patch @@ -0,0 +1,189 @@ +From 54f6a8af372213a254af6609758d99f7c0b6b5ad Mon Sep 17 00:00:00 2001 +From: Chunfeng Yun +Date: Mon, 1 Feb 2021 13:57:44 +0800 +Subject: usb: xhci-mtk: skip dropping bandwidth of unchecked endpoints + +From: Chunfeng Yun + +commit 54f6a8af372213a254af6609758d99f7c0b6b5ad upstream. + +For those unchecked endpoints, we don't allocate bandwidth for +them, so no need free the bandwidth, otherwise will decrease +the allocated bandwidth. +Meanwhile use xhci_dbg() instead of dev_dbg() to print logs and +rename bw_ep_list_new as bw_ep_chk_list. + +Fixes: 1d69f9d901ef ("usb: xhci-mtk: fix unreleased bandwidth data") +Cc: stable +Reviewed-and-tested-by: Ikjoon Jang +Signed-off-by: Chunfeng Yun +Link: https://lore.kernel.org/r/1612159064-28413-1-git-send-email-chunfeng.yun@mediatek.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-mtk-sch.c | 61 +++++++++++++++++++++------------------- + drivers/usb/host/xhci-mtk.h | 4 +- + 2 files changed, 36 insertions(+), 29 deletions(-) + +--- a/drivers/usb/host/xhci-mtk-sch.c ++++ b/drivers/usb/host/xhci-mtk-sch.c +@@ -200,6 +200,7 @@ static struct mu3h_sch_ep_info *create_s + + sch_ep->sch_tt = tt; + sch_ep->ep = ep; ++ INIT_LIST_HEAD(&sch_ep->endpoint); + INIT_LIST_HEAD(&sch_ep->tt_endpoint); + + return sch_ep; +@@ -374,6 +375,7 @@ static void update_bus_bw(struct mu3h_sc + sch_ep->bw_budget_table[j]; + } + } ++ sch_ep->allocated = used; + } + + static int check_sch_tt(struct usb_device *udev, +@@ -542,6 +544,22 @@ static int check_sch_bw(struct usb_devic + return 0; + } + ++static void destroy_sch_ep(struct usb_device *udev, ++ struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep) ++{ ++ /* only release ep bw check passed by check_sch_bw() */ ++ if (sch_ep->allocated) ++ update_bus_bw(sch_bw, sch_ep, 0); ++ ++ list_del(&sch_ep->endpoint); ++ ++ if (sch_ep->sch_tt) { ++ list_del(&sch_ep->tt_endpoint); ++ drop_tt(udev); ++ } ++ kfree(sch_ep); ++} ++ + static bool need_bw_sch(struct usb_host_endpoint *ep, + enum usb_device_speed speed, int has_tt) + { +@@ -584,7 +602,7 @@ int xhci_mtk_sch_init(struct xhci_hcd_mt + + mtk->sch_array = sch_array; + +- INIT_LIST_HEAD(&mtk->bw_ep_list_new); ++ INIT_LIST_HEAD(&mtk->bw_ep_chk_list); + + return 0; + } +@@ -636,29 +654,12 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd + + setup_sch_info(udev, ep_ctx, sch_ep); + +- list_add_tail(&sch_ep->endpoint, &mtk->bw_ep_list_new); ++ list_add_tail(&sch_ep->endpoint, &mtk->bw_ep_chk_list); + + return 0; + } + EXPORT_SYMBOL_GPL(xhci_mtk_add_ep_quirk); + +-static void xhci_mtk_drop_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev, +- struct mu3h_sch_ep_info *sch_ep) +-{ +- struct xhci_hcd *xhci = hcd_to_xhci(mtk->hcd); +- int bw_index = get_bw_index(xhci, udev, sch_ep->ep); +- struct mu3h_sch_bw_info *sch_bw = &mtk->sch_array[bw_index]; +- +- update_bus_bw(sch_bw, sch_ep, 0); +- list_del(&sch_ep->endpoint); +- +- if (sch_ep->sch_tt) { +- list_del(&sch_ep->tt_endpoint); +- drop_tt(udev); +- } +- kfree(sch_ep); +-} +- + void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, + struct usb_host_endpoint *ep) + { +@@ -688,9 +689,8 @@ void xhci_mtk_drop_ep_quirk(struct usb_h + sch_bw = &sch_array[bw_index]; + + list_for_each_entry_safe(sch_ep, tmp, &sch_bw->bw_ep_list, endpoint) { +- if (sch_ep->ep == ep) { +- xhci_mtk_drop_ep(mtk, udev, sch_ep); +- } ++ if (sch_ep->ep == ep) ++ destroy_sch_ep(udev, sch_bw, sch_ep); + } + } + EXPORT_SYMBOL_GPL(xhci_mtk_drop_ep_quirk); +@@ -704,9 +704,9 @@ int xhci_mtk_check_bandwidth(struct usb_ + struct mu3h_sch_ep_info *sch_ep, *tmp; + int bw_index, ret; + +- dev_dbg(&udev->dev, "%s\n", __func__); ++ xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev)); + +- list_for_each_entry(sch_ep, &mtk->bw_ep_list_new, endpoint) { ++ list_for_each_entry(sch_ep, &mtk->bw_ep_chk_list, endpoint) { + bw_index = get_bw_index(xhci, udev, sch_ep->ep); + sch_bw = &mtk->sch_array[bw_index]; + +@@ -717,7 +717,7 @@ int xhci_mtk_check_bandwidth(struct usb_ + } + } + +- list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_list_new, endpoint) { ++ list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) { + struct xhci_ep_ctx *ep_ctx; + struct usb_host_endpoint *ep = sch_ep->ep; + unsigned int ep_index = xhci_get_endpoint_index(&ep->desc); +@@ -746,12 +746,17 @@ EXPORT_SYMBOL_GPL(xhci_mtk_check_bandwid + void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) + { + struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); ++ struct xhci_hcd *xhci = hcd_to_xhci(hcd); ++ struct mu3h_sch_bw_info *sch_bw; + struct mu3h_sch_ep_info *sch_ep, *tmp; ++ int bw_index; + +- dev_dbg(&udev->dev, "%s\n", __func__); ++ xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev)); + +- list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_list_new, endpoint) { +- xhci_mtk_drop_ep(mtk, udev, sch_ep); ++ list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) { ++ bw_index = get_bw_index(xhci, udev, sch_ep->ep); ++ sch_bw = &mtk->sch_array[bw_index]; ++ destroy_sch_ep(udev, sch_bw, sch_ep); + } + + xhci_reset_bandwidth(hcd, udev); +--- a/drivers/usb/host/xhci-mtk.h ++++ b/drivers/usb/host/xhci-mtk.h +@@ -59,6 +59,7 @@ struct mu3h_sch_bw_info { + * @ep_type: endpoint type + * @maxpkt: max packet size of endpoint + * @ep: address of usb_host_endpoint struct ++ * @allocated: the bandwidth is aready allocated from bus_bw + * @offset: which uframe of the interval that transfer should be + * scheduled first time within the interval + * @repeat: the time gap between two uframes that transfers are +@@ -86,6 +87,7 @@ struct mu3h_sch_ep_info { + u32 ep_type; + u32 maxpkt; + void *ep; ++ bool allocated; + /* + * mtk xHCI scheduling information put into reserved DWs + * in ep context +@@ -130,8 +132,8 @@ struct mu3c_ippc_regs { + struct xhci_hcd_mtk { + struct device *dev; + struct usb_hcd *hcd; +- struct list_head bw_ep_list_new; + struct mu3h_sch_bw_info *sch_array; ++ struct list_head bw_ep_chk_list; + struct mu3c_ippc_regs __iomem *ippc_regs; + bool has_ippc; + int num_u2_ports; -- 2.47.3