]> git.baikalelectronics.ru Git - kernel.git/commitdiff
usb: xhci-mtk: fix fs isoc's transfer error
authorChunfeng Yun <chunfeng.yun@mediatek.com>
Thu, 12 May 2022 06:49:30 +0000 (14:49 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 12 May 2022 16:35:38 +0000 (18:35 +0200)
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: 2160a2d9e4ff ("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

index f3139ce7b0a93df35d7bae8145247fbc15abb507..953d2cd1d4cc1ef400404b08c23cf431100ff9c1 100644 (file)
@@ -464,7 +464,7 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
                 */
                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;
                }
@@ -538,19 +538,17 @@ static int check_sch_tt(struct mu3h_sch_ep_info *sch_ep, u32 offset)
 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)