UPSTREAM: usb: dwc3: gadget: give better command return code
authorKonrad Leszczynski <konrad.leszczynski@intel.com>
Fri, 12 Feb 2016 15:21:46 +0000 (15:21 +0000)
committerHuang, Tao <huangtao@rock-chips.com>
Tue, 16 Aug 2016 12:48:19 +0000 (20:48 +0800)
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.

Change-Id: Id3ce609ba9149235dc8c9203798dc19cb2fae4bd
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>
Signed-off-by: Wu Liang feng <wulf@rock-chips.com>
(cherry picked from commit 7b9cc7a2b101cc73f6abe3468441381c98817e54)

drivers/usb/dwc3/core.h
drivers/usb/dwc3/gadget.c

index 85256ba70c1e134cd00fd0f31c7b12fbbb9fcaad..4ea20a254dd8ac09f2e89d529e60832dd5db57d8 100644 (file)
@@ -968,6 +968,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;
 
index d7668e7bc61a9069e3ea5a229c1bdf8b01d53667..c285b34af0c5f472a244e9f7d98b0305775af61f 100644 (file)
@@ -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;
                }