mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-15 23:14:31 +08:00
usb: dwc3: gadget: Return proper request status
commitc7428dbddc
upstream. If the user sets the usb_request's no_interrupt, then there will be no completion event for the request. Currently the driver incorrectly uses the event status of a different request to report the status for a request with no_interrupt. The dwc3 driver needs to check the TRB status associated with the request when reporting its status. Note: this is only applicable to missed_isoc TRB completion status, but the other status are also listed for completeness/documentation. Fixes:6d8a019614
("usb: dwc3: gadget: check for Missed Isoc from event status") Cc: <stable@vger.kernel.org> Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/db2c80108286cfd108adb05bad52138b78d7c3a7.1650673655.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
7d14c96bff
commit
0d1c407b1a
@ -3199,6 +3199,7 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep,
|
|||||||
const struct dwc3_event_depevt *event,
|
const struct dwc3_event_depevt *event,
|
||||||
struct dwc3_request *req, int status)
|
struct dwc3_request *req, int status)
|
||||||
{
|
{
|
||||||
|
int request_status;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (req->request.num_mapped_sgs)
|
if (req->request.num_mapped_sgs)
|
||||||
@ -3219,7 +3220,35 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep,
|
|||||||
req->needs_extra_trb = false;
|
req->needs_extra_trb = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
dwc3_gadget_giveback(dep, req, status);
|
/*
|
||||||
|
* The event status only reflects the status of the TRB with IOC set.
|
||||||
|
* For the requests that don't set interrupt on completion, the driver
|
||||||
|
* needs to check and return the status of the completed TRBs associated
|
||||||
|
* with the request. Use the status of the last TRB of the request.
|
||||||
|
*/
|
||||||
|
if (req->request.no_interrupt) {
|
||||||
|
struct dwc3_trb *trb;
|
||||||
|
|
||||||
|
trb = dwc3_ep_prev_trb(dep, dep->trb_dequeue);
|
||||||
|
switch (DWC3_TRB_SIZE_TRBSTS(trb->size)) {
|
||||||
|
case DWC3_TRBSTS_MISSED_ISOC:
|
||||||
|
/* Isoc endpoint only */
|
||||||
|
request_status = -EXDEV;
|
||||||
|
break;
|
||||||
|
case DWC3_TRB_STS_XFER_IN_PROG:
|
||||||
|
/* Applicable when End Transfer with ForceRM=0 */
|
||||||
|
case DWC3_TRBSTS_SETUP_PENDING:
|
||||||
|
/* Control endpoint only */
|
||||||
|
case DWC3_TRBSTS_OK:
|
||||||
|
default:
|
||||||
|
request_status = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
request_status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
dwc3_gadget_giveback(dep, req, request_status);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
|
Loading…
Reference in New Issue
Block a user