Commit 04dd6e76 authored by Ray Chi's avatar Ray Chi Committed by Greg Kroah-Hartman

usb: dwc3: add cancelled reasons for dwc3 requests

Currently, when dwc3 handles request cancelled, dwc3 just returns
-ECONNRESET for all requests. It will cause USB function drivers
can't know if the requests are cancelled by other reasons.

This patch will replace DWC3_REQUEST_STATUS_CANCELLED with the
reasons below.
  - DWC3_REQUEST_STATUS_DISCONNECTED
  - DWC3_REQUEST_STATUS_DEQUEUED
  - DWC3_REQUEST_STATUS_STALLED
Reviewed-by: default avatarThinh Nguyen <Thinh.Nguyen@synopsys.com>
Signed-off-by: default avatarRay Chi <raychi@google.com>
Link: https://lore.kernel.org/r/20210327181742.1810969-1-raychi@google.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d1689cd3
...@@ -906,11 +906,13 @@ struct dwc3_request { ...@@ -906,11 +906,13 @@ struct dwc3_request {
unsigned int remaining; unsigned int remaining;
unsigned int status; unsigned int status;
#define DWC3_REQUEST_STATUS_QUEUED 0 #define DWC3_REQUEST_STATUS_QUEUED 0
#define DWC3_REQUEST_STATUS_STARTED 1 #define DWC3_REQUEST_STATUS_STARTED 1
#define DWC3_REQUEST_STATUS_CANCELLED 2 #define DWC3_REQUEST_STATUS_DISCONNECTED 2
#define DWC3_REQUEST_STATUS_COMPLETED 3 #define DWC3_REQUEST_STATUS_DEQUEUED 3
#define DWC3_REQUEST_STATUS_UNKNOWN -1 #define DWC3_REQUEST_STATUS_STALLED 4
#define DWC3_REQUEST_STATUS_COMPLETED 5
#define DWC3_REQUEST_STATUS_UNKNOWN -1
u8 epnum; u8 epnum;
struct dwc3_trb *trb; struct dwc3_trb *trb;
......
...@@ -1402,7 +1402,7 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep) ...@@ -1402,7 +1402,7 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep)
dwc3_stop_active_transfer(dep, true, true); dwc3_stop_active_transfer(dep, true, true);
list_for_each_entry_safe(req, tmp, &dep->started_list, list) list_for_each_entry_safe(req, tmp, &dep->started_list, list)
dwc3_gadget_move_cancelled_request(req); dwc3_gadget_move_cancelled_request(req, DWC3_REQUEST_STATUS_DEQUEUED);
/* If ep isn't started, then there's no end transfer pending */ /* If ep isn't started, then there's no end transfer pending */
if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING)) if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING))
...@@ -1729,10 +1729,25 @@ static void dwc3_gadget_ep_cleanup_cancelled_requests(struct dwc3_ep *dep) ...@@ -1729,10 +1729,25 @@ static void dwc3_gadget_ep_cleanup_cancelled_requests(struct dwc3_ep *dep)
{ {
struct dwc3_request *req; struct dwc3_request *req;
struct dwc3_request *tmp; struct dwc3_request *tmp;
struct dwc3 *dwc = dep->dwc;
list_for_each_entry_safe(req, tmp, &dep->cancelled_list, list) { list_for_each_entry_safe(req, tmp, &dep->cancelled_list, list) {
dwc3_gadget_ep_skip_trbs(dep, req); dwc3_gadget_ep_skip_trbs(dep, req);
dwc3_gadget_giveback(dep, req, -ECONNRESET); switch (req->status) {
case DWC3_REQUEST_STATUS_DISCONNECTED:
dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
break;
case DWC3_REQUEST_STATUS_DEQUEUED:
dwc3_gadget_giveback(dep, req, -ECONNRESET);
break;
case DWC3_REQUEST_STATUS_STALLED:
dwc3_gadget_giveback(dep, req, -EPIPE);
break;
default:
dev_err(dwc->dev, "request cancelled with wrong reason:%d\n", req->status);
dwc3_gadget_giveback(dep, req, -ECONNRESET);
break;
}
} }
} }
...@@ -1776,7 +1791,8 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, ...@@ -1776,7 +1791,8 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
* cancelled. * cancelled.
*/ */
list_for_each_entry_safe(r, t, &dep->started_list, list) list_for_each_entry_safe(r, t, &dep->started_list, list)
dwc3_gadget_move_cancelled_request(r); dwc3_gadget_move_cancelled_request(r,
DWC3_REQUEST_STATUS_DEQUEUED);
dep->flags &= ~DWC3_EP_WAIT_TRANSFER_COMPLETE; dep->flags &= ~DWC3_EP_WAIT_TRANSFER_COMPLETE;
...@@ -1848,7 +1864,7 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol) ...@@ -1848,7 +1864,7 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol)
dwc3_stop_active_transfer(dep, true, true); dwc3_stop_active_transfer(dep, true, true);
list_for_each_entry_safe(req, tmp, &dep->started_list, list) list_for_each_entry_safe(req, tmp, &dep->started_list, list)
dwc3_gadget_move_cancelled_request(req); dwc3_gadget_move_cancelled_request(req, DWC3_REQUEST_STATUS_STALLED);
if (dep->flags & DWC3_EP_END_TRANSFER_PENDING) { if (dep->flags & DWC3_EP_END_TRANSFER_PENDING) {
dep->flags |= DWC3_EP_PENDING_CLEAR_STALL; dep->flags |= DWC3_EP_PENDING_CLEAR_STALL;
......
...@@ -90,15 +90,17 @@ static inline void dwc3_gadget_move_started_request(struct dwc3_request *req) ...@@ -90,15 +90,17 @@ static inline void dwc3_gadget_move_started_request(struct dwc3_request *req)
/** /**
* dwc3_gadget_move_cancelled_request - move @req to the cancelled_list * dwc3_gadget_move_cancelled_request - move @req to the cancelled_list
* @req: the request to be moved * @req: the request to be moved
* @reason: cancelled reason for the dwc3 request
* *
* Caller should take care of locking. This function will move @req from its * Caller should take care of locking. This function will move @req from its
* current list to the endpoint's cancelled_list. * current list to the endpoint's cancelled_list.
*/ */
static inline void dwc3_gadget_move_cancelled_request(struct dwc3_request *req) static inline void dwc3_gadget_move_cancelled_request(struct dwc3_request *req,
unsigned int reason)
{ {
struct dwc3_ep *dep = req->dep; struct dwc3_ep *dep = req->dep;
req->status = DWC3_REQUEST_STATUS_CANCELLED; req->status = reason;
list_move_tail(&req->list, &dep->cancelled_list); list_move_tail(&req->list, &dep->cancelled_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