Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

usb: chipidea: udc: improve error recovery for ISO transfer

Impove device mode ISO transfer error tolerant by reprime the corresponding
endpoint.

The recovery steps when error occurs:
- Delete the error dTD from dQH and giveback request to user.
- Do reprime if dQH is not empty.
- Do prime when new dTD is queued if dQH is empty

Acked-by: Peter Chen <peter.chen@kernel.org>
Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
Link: https://lore.kernel.org/r/20240926022906.473319-3-xu.yang_2@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Xu Yang and committed by
Greg Kroah-Hartman
47263478 b8c7f7e1

+9 -4
+9 -4
drivers/usb/chipidea/udc.c
··· 824 824 unsigned remaining_length; 825 825 unsigned actual = hwreq->req.length; 826 826 struct ci_hdrc *ci = hwep->ci; 827 + bool is_isoc = hwep->type == USB_ENDPOINT_XFER_ISOC; 827 828 828 829 if (hwreq->req.status != -EALREADY) 829 830 return -EINVAL; ··· 838 837 int n = hw_ep_bit(hwep->num, hwep->dir); 839 838 840 839 if (ci->rev == CI_REVISION_24 || 841 - ci->rev == CI_REVISION_22) 840 + ci->rev == CI_REVISION_22 || is_isoc) 842 841 if (!hw_read(ci, OP_ENDPTSTAT, BIT(n))) 843 842 reprime_dtd(ci, hwep, node); 844 843 hwreq->req.status = -EALREADY; ··· 857 856 hwreq->req.status = -EPROTO; 858 857 break; 859 858 } else if ((TD_STATUS_TR_ERR & hwreq->req.status)) { 860 - hwreq->req.status = -EILSEQ; 861 - break; 859 + if (is_isoc) { 860 + hwreq->req.status = 0; 861 + } else { 862 + hwreq->req.status = -EILSEQ; 863 + break; 864 + } 862 865 } 863 866 864 - if (remaining_length) { 867 + if (remaining_length && !is_isoc) { 865 868 if (hwep->dir == TX) { 866 869 hwreq->req.status = -EPROTO; 867 870 break;