Message ID | 20240920094056.2680590-3-xu.yang_2@nxp.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | [v2,1/3] usb: chipidea: udc: handle USB Error Interrupt if IOC not set | expand |
On 24-09-20 17:40:56, Xu Yang wrote: > 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 > > Signed-off-by: Xu Yang <xu.yang_2@nxp.com> Acked-by: Peter Chen <peter.chen@kernel.org> > > --- > Changes in v2: > - modify commit message > - keep "hwreq->req.status = tmptoken & TD_STATUS" > - giveback status 0 to user for isoc error case > --- > drivers/usb/chipidea/udc.c | 13 +++++++++---- > 1 file changed, 9 insertions(+), 4 deletions(-) > > diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c > index c0b8745234c6..e1121db0aea0 100644 > --- a/drivers/usb/chipidea/udc.c > +++ b/drivers/usb/chipidea/udc.c > @@ -823,6 +823,7 @@ static int _hardware_dequeue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) > unsigned remaining_length; > unsigned actual = hwreq->req.length; > struct ci_hdrc *ci = hwep->ci; > + bool is_isoc = hwep->type == USB_ENDPOINT_XFER_ISOC; > > if (hwreq->req.status != -EALREADY) > return -EINVAL; > @@ -836,7 +837,7 @@ static int _hardware_dequeue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) > int n = hw_ep_bit(hwep->num, hwep->dir); > > if (ci->rev == CI_REVISION_24 || > - ci->rev == CI_REVISION_22) > + ci->rev == CI_REVISION_22 || is_isoc) > if (!hw_read(ci, OP_ENDPTSTAT, BIT(n))) > reprime_dtd(ci, hwep, node); > hwreq->req.status = -EALREADY; > @@ -855,11 +856,15 @@ static int _hardware_dequeue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) > hwreq->req.status = -EPROTO; > break; > } else if ((TD_STATUS_TR_ERR & hwreq->req.status)) { > - hwreq->req.status = -EILSEQ; > - break; > + if (is_isoc) { > + hwreq->req.status = 0; > + } else { > + hwreq->req.status = -EILSEQ; > + break; > + } > } > > - if (remaining_length) { > + if (remaining_length && !is_isoc) { > if (hwep->dir == TX) { > hwreq->req.status = -EPROTO; > break; > -- > 2.34.1 >
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index c0b8745234c6..e1121db0aea0 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -823,6 +823,7 @@ static int _hardware_dequeue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) unsigned remaining_length; unsigned actual = hwreq->req.length; struct ci_hdrc *ci = hwep->ci; + bool is_isoc = hwep->type == USB_ENDPOINT_XFER_ISOC; if (hwreq->req.status != -EALREADY) return -EINVAL; @@ -836,7 +837,7 @@ static int _hardware_dequeue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) int n = hw_ep_bit(hwep->num, hwep->dir); if (ci->rev == CI_REVISION_24 || - ci->rev == CI_REVISION_22) + ci->rev == CI_REVISION_22 || is_isoc) if (!hw_read(ci, OP_ENDPTSTAT, BIT(n))) reprime_dtd(ci, hwep, node); hwreq->req.status = -EALREADY; @@ -855,11 +856,15 @@ static int _hardware_dequeue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) hwreq->req.status = -EPROTO; break; } else if ((TD_STATUS_TR_ERR & hwreq->req.status)) { - hwreq->req.status = -EILSEQ; - break; + if (is_isoc) { + hwreq->req.status = 0; + } else { + hwreq->req.status = -EILSEQ; + break; + } } - if (remaining_length) { + if (remaining_length && !is_isoc) { if (hwep->dir == TX) { hwreq->req.status = -EPROTO; break;
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 Signed-off-by: Xu Yang <xu.yang_2@nxp.com> --- Changes in v2: - modify commit message - keep "hwreq->req.status = tmptoken & TD_STATUS" - giveback status 0 to user for isoc error case --- drivers/usb/chipidea/udc.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)