~~~~~~
Please pick something while reading :)
-- Implement streaming support for BULK endpoints
- Tatyana's patch "usb: Add streams support to the gadget framework"
- introduces streaming support for the gadget driver.
- Every usb_request has new field called stream_id which holds its id.
- Every usb_ep has a field num_supported_strms which describes the max
- number of streams supported (for this ep).
- UAS is AFAIK the only gadget with streaming support.
-
- Convert interrupt handler to per-ep-thread-irq
As it turns out some DWC3-commands ~1ms to complete. Currently we spin
* @interval: the intervall on which the ISOC transfer is started
* @name: a human readable name e.g. ep1out-bulk
* @direction: true for TX, false for RX
+ * @stream_capable: true when streams are enabled
*/
struct dwc3_ep {
struct usb_ep endpoint;
char name[20];
unsigned direction:1;
+ unsigned stream_capable:1;
};
enum dwc3_phy {
#define DEPEVT_STATUS_IOC (1 << 2)
#define DEPEVT_STATUS_LST (1 << 3)
+/* Stream event only */
+#define DEPEVT_STREAMEVT_FOUND 1
+#define DEPEVT_STREAMEVT_NOTFOUND 2
+
/* Control-only Status */
#define DEPEVT_STATUS_CONTROL_SETUP 0
#define DEPEVT_STATUS_CONTROL_DATA 1
params.param1.depcfg.xfer_complete_enable = true;
params.param1.depcfg.xfer_not_ready_enable = true;
+ if (usb_endpoint_xfer_bulk(desc) && dep->endpoint.max_streams) {
+ params.param1.depcfg.stream_capable = true;
+ params.param1.depcfg.stream_event_enable = true;
+ dep->stream_capable = true;
+ }
+
if (usb_endpoint_xfer_isoc(desc))
params.param1.depcfg.xfer_in_progress_enable = true;
struct dwc3 *dwc = dep->dwc;
u32 reg;
- dep->flags &= ~DWC3_EP_ENABLED;
dwc3_remove_requests(dwc, dep);
reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);
reg &= ~DWC3_DALEPENA_EP(dep->number);
dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
+ dep->stream_capable = false;
dep->desc = NULL;
dep->type = 0;
+ dep->flags = 0;
return 0;
}
trb.lst = last_one;
}
+ if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable)
+ trb.sid_sofn = req->request.stream_id;
+
switch (usb_endpoint_type(dep->desc)) {
case USB_ENDPOINT_XFER_CONTROL:
trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP;
dep->name);
}
+ break;
+ case DWC3_DEPEVT_STREAMEVT:
+ if (!usb_endpoint_xfer_bulk(dep->desc)) {
+ dev_err(dwc->dev, "Stream event for non-Bulk %s\n",
+ dep->name);
+ return;
+ }
+
+ switch (event->status) {
+ case DEPEVT_STREAMEVT_FOUND:
+ dev_vdbg(dwc->dev, "Stream %d found and started\n",
+ event->parameters);
+
+ break;
+ case DEPEVT_STREAMEVT_NOTFOUND:
+ /* FALLTHROUGH */
+ default:
+ dev_dbg(dwc->dev, "Couldn't find suitable stream\n");
+ }
break;
case DWC3_DEPEVT_RXTXFIFOEVT:
dev_dbg(dwc->dev, "%s FIFO Overrun\n", dep->name);
break;
- case DWC3_DEPEVT_STREAMEVT:
- dev_dbg(dwc->dev, "%s Stream Event\n", dep->name);
- break;
case DWC3_DEPEVT_EPCMDCMPLT:
dwc3_ep_cmd_compl(dep, event);
break;