| From c237566b78ad8c72bc0431c5d6171db8d12e6f94 Mon Sep 17 00:00:00 2001 |
| From: Chunfeng Yun <chunfeng.yun@mediatek.com> |
| Date: Thu, 12 May 2022 14:49:30 +0800 |
| Subject: usb: xhci-mtk: fix fs isoc's transfer error |
| |
| From: Chunfeng Yun <chunfeng.yun@mediatek.com> |
| |
| commit c237566b78ad8c72bc0431c5d6171db8d12e6f94 upstream. |
| |
| Due to the scheduler allocates the optimal bandwidth for FS ISOC endpoints, |
| this may be not enough actually and causes data transfer error, so come up |
| with an estimate that is no less than the worst case bandwidth used for |
| any one mframe, but may be an over-estimate. |
| |
| Fixes: 451d3912586a ("usb: xhci-mtk: update fs bus bandwidth by bw_budget_table") |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> |
| Link: https://lore.kernel.org/r/20220512064931.31670-1-chunfeng.yun@mediatek.com |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/usb/host/xhci-mtk-sch.c | 16 +++++++--------- |
| 1 file changed, 7 insertions(+), 9 deletions(-) |
| |
| --- a/drivers/usb/host/xhci-mtk-sch.c |
| +++ b/drivers/usb/host/xhci-mtk-sch.c |
| @@ -465,7 +465,7 @@ static int check_fs_bus_bw(struct mu3h_s |
| */ |
| for (j = 0; j < sch_ep->num_budget_microframes; j++) { |
| k = XHCI_MTK_BW_INDEX(base + j); |
| - tmp = tt->fs_bus_bw[k] + sch_ep->bw_budget_table[j]; |
| + tmp = tt->fs_bus_bw[k] + sch_ep->bw_cost_per_microframe; |
| if (tmp > FS_PAYLOAD_MAX) |
| return -ESCH_BW_OVERFLOW; |
| } |
| @@ -539,19 +539,17 @@ static int check_sch_tt(struct mu3h_sch_ |
| static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used) |
| { |
| struct mu3h_sch_tt *tt = sch_ep->sch_tt; |
| + int bw_updated; |
| u32 base; |
| - int i, j, k; |
| + int i, j; |
| + |
| + bw_updated = sch_ep->bw_cost_per_microframe * (used ? 1 : -1); |
| |
| for (i = 0; i < sch_ep->num_esit; i++) { |
| base = sch_ep->offset + i * sch_ep->esit; |
| |
| - for (j = 0; j < sch_ep->num_budget_microframes; j++) { |
| - k = XHCI_MTK_BW_INDEX(base + j); |
| - if (used) |
| - tt->fs_bus_bw[k] += sch_ep->bw_budget_table[j]; |
| - else |
| - tt->fs_bus_bw[k] -= sch_ep->bw_budget_table[j]; |
| - } |
| + for (j = 0; j < sch_ep->num_budget_microframes; j++) |
| + tt->fs_bus_bw[XHCI_MTK_BW_INDEX(base + j)] += bw_updated; |
| } |
| |
| if (used) |