Re: [PATCH v6] usb: xhci-mtk: fix unreleased bandwidth data
From: Chunfeng Yun <chunfeng.yun@mediatek.com>
Date: 2021-01-29 09:40:02
Also in:
linux-arm-kernel
Hi Ikjoon, On Wed, 2021-01-13 at 18:05 +0800, Ikjoon Jang wrote:
quoted hunk ↗ jump to hunk
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 <redacted> --- Changes in v6: - use xhci overrides instead of quirk functions for {check|reset}_bandwidth(). Changes in v5: - Fix a wrong commit id in Fixes tag Changes in v4: - bugfix in v3, check_bandwidth() return uninitialized value when no new endpoints were added. - change Fixes tag to keep dependency Changes in v3: - drop unrelated code cleanups - change Fixes tag to keep dependency Changes in v2: - fix a 0-day warning from unused variable - split one big patch into three patches - fix wrong offset in mediatek hw flags 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(-)diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index 45c54d56ecbd..a313e75ff1c6 100644 --- 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_sch_ep(struct usb_device *udev, [...] + +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);
This need skip endpoint not allocated bandwidth; e.g. If add 3 eps, the second on is checked fail, only need drop first ep, and skip second & third ones. I'll send out a v7 patch, thanks
+ } + + xhci_reset_bandwidth(hcd, udev); +} +EXPORT_SYMBOL_GPL(xhci_mtk_reset_bandwidth);
[...] _______________________________________________ Linux-mediatek mailing list Linux-mediatek@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-mediatek