diff options
author | Konrad Leszczynski <konrad.leszczynski@intel.com> | 2016-02-12 15:21:46 +0000 |
---|---|---|
committer | Felipe Balbi <felipe.balbi@linux.intel.com> | 2016-04-28 09:02:00 +0300 |
commit | 7b9cc7a2b101cc73f6abe3468441381c98817e54 (patch) | |
tree | eb7f1313f50c5139287b3d6e692b06a06215a92e | |
parent | 0878263b68df372e6389b050fc2bd4f6d5b9f332 (diff) | |
download | linux-7b9cc7a2b101cc73f6abe3468441381c98817e54.tar.bz2 |
usb: dwc3: gadget: give better command return code
if Start Transfer command fails, let's try a little
harder to figure out why the command failed and give
slightly better return codes. This will be usefulf
or isochronous endpoints, at least, which could
decide to retry a given request.
Signed-off-by: Konrad Leszczynski <konrad.leszczynski@intel.com>
Signed-off-by: Rafal Redzimski <rafal.f.redzimski@intel.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
-rw-r--r-- | drivers/usb/dwc3/core.h | 4 | ||||
-rw-r--r-- | drivers/usb/dwc3/gadget.c | 33 |
2 files changed, 34 insertions, 3 deletions
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index bbbd1789596e..87df6dd20d23 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -970,6 +970,10 @@ struct dwc3_event_depevt { #define DEPEVT_STATUS_CONTROL_DATA 1 #define DEPEVT_STATUS_CONTROL_STATUS 2 +/* In response to Start Transfer */ +#define DEPEVT_TRANSFER_NO_RESOURCE 1 +#define DEPEVT_TRANSFER_BUS_EXPIRY 2 + u32 parameters:16; } __packed; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 88fd30bf0c46..43efb627d1cf 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -287,12 +287,39 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, do { reg = dwc3_readl(dwc->regs, DWC3_DEPCMD(ep)); if (!(reg & DWC3_DEPCMD_CMDACT)) { + int cmd_status = DWC3_DEPCMD_STATUS(reg); + dwc3_trace(trace_dwc3_gadget, "Command Complete --> %d", - DWC3_DEPCMD_STATUS(reg)); - if (DWC3_DEPCMD_STATUS(reg)) + cmd_status); + + switch (cmd_status) { + case 0: + ret = 0; + break; + case DEPEVT_TRANSFER_NO_RESOURCE: + dwc3_trace(trace_dwc3_gadget, "%s: no resource available"); + ret = -EINVAL; break; - ret = 0; + case DEPEVT_TRANSFER_BUS_EXPIRY: + /* + * SW issues START TRANSFER command to + * isochronous ep with future frame interval. If + * future interval time has already passed when + * core receives the command, it will respond + * with an error status of 'Bus Expiry'. + * + * Instead of always returning -EINVAL, let's + * give a hint to the gadget driver that this is + * the case by returning -EAGAIN. + */ + dwc3_trace(trace_dwc3_gadget, "%s: bus expiry"); + ret = -EAGAIN; + break; + default: + dev_WARN(dwc->dev, "UNKNOWN cmd status\n"); + } + break; } |