Commit 61d2cf0d authored by Chunfeng Yun's avatar Chunfeng Yun Committed by Greg Kroah-Hartman

usb: xhci-mtk: fix in-ep's start-split check failure

It's wrong to use the data length in a CS (in uframe x) to check whether
there is a SS (in uframe x-2), because for a isoc-in ep, it may need some
CS to receive data;
Save the count of SS in a uframe for isoc/intr in-eps to fix the issue.

Fixes: 5c954e03 ("usb: xhci-mtk: improve split scheduling by separate IN/OUT budget")
Signed-off-by: default avatarChunfeng Yun <chunfeng.yun@mediatek.com>
Link: https://lore.kernel.org/r/20231118033011.22033-1-chunfeng.yun@mediatek.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 8bbae288
...@@ -650,9 +650,8 @@ static int check_isoc_ss_overlap(struct mu3h_sch_ep_info *sch_ep, u32 offset) ...@@ -650,9 +650,8 @@ static int check_isoc_ss_overlap(struct mu3h_sch_ep_info *sch_ep, u32 offset)
if (sch_ep->ep_type == ISOC_OUT_EP) { if (sch_ep->ep_type == ISOC_OUT_EP) {
for (j = 0; j < sch_ep->num_budget_microframes; j++) { for (j = 0; j < sch_ep->num_budget_microframes; j++) {
k = XHCI_MTK_BW_INDEX(base + j + CS_OFFSET); k = XHCI_MTK_BW_INDEX(base + j);
/* use cs to indicate existence of in-ss @(base+j) */ if (tt->in_ss_cnt[k])
if (tt->fs_bus_bw_in[k])
return -ESCH_SS_OVERLAP; return -ESCH_SS_OVERLAP;
} }
} else if (sch_ep->ep_type == ISOC_IN_EP || sch_ep->ep_type == INT_IN_EP) { } else if (sch_ep->ep_type == ISOC_IN_EP || sch_ep->ep_type == INT_IN_EP) {
...@@ -769,6 +768,14 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used) ...@@ -769,6 +768,14 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
tt->fs_frame_bw[f] -= (u16)sch_ep->bw_budget_table[j]; tt->fs_frame_bw[f] -= (u16)sch_ep->bw_budget_table[j];
} }
} }
if (sch_ep->ep_type == ISOC_IN_EP || sch_ep->ep_type == INT_IN_EP) {
k = XHCI_MTK_BW_INDEX(base);
if (used)
tt->in_ss_cnt[k]++;
else
tt->in_ss_cnt[k]--;
}
} }
if (used) if (used)
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
* @fs_bus_bw_in: save bandwidth used by FS/LS IN eps in each uframes * @fs_bus_bw_in: save bandwidth used by FS/LS IN eps in each uframes
* @ls_bus_bw: save bandwidth used by LS eps in each uframes * @ls_bus_bw: save bandwidth used by LS eps in each uframes
* @fs_frame_bw: save bandwidth used by FS/LS eps in each FS frames * @fs_frame_bw: save bandwidth used by FS/LS eps in each FS frames
* @in_ss_cnt: the count of Start-Split for IN eps
* @ep_list: Endpoints using this TT * @ep_list: Endpoints using this TT
*/ */
struct mu3h_sch_tt { struct mu3h_sch_tt {
...@@ -45,6 +46,7 @@ struct mu3h_sch_tt { ...@@ -45,6 +46,7 @@ struct mu3h_sch_tt {
u16 fs_bus_bw_in[XHCI_MTK_MAX_ESIT]; u16 fs_bus_bw_in[XHCI_MTK_MAX_ESIT];
u8 ls_bus_bw[XHCI_MTK_MAX_ESIT]; u8 ls_bus_bw[XHCI_MTK_MAX_ESIT];
u16 fs_frame_bw[XHCI_MTK_FRAMES_CNT]; u16 fs_frame_bw[XHCI_MTK_FRAMES_CNT];
u8 in_ss_cnt[XHCI_MTK_MAX_ESIT];
struct list_head ep_list; struct list_head ep_list;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment