* [PATCH v2 00/11] usb: dwc3: gadget: Handle streams
@ 2020-05-06 2:46 Thinh Nguyen
2020-05-06 2:46 ` [PATCH v2 01/11] usb: gadget: Introduce usb_request->is_last Thinh Nguyen
` (11 more replies)
0 siblings, 12 replies; 13+ messages in thread
From: Thinh Nguyen @ 2020-05-06 2:46 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Thinh Nguyen, linux-usb; +Cc: John Youn
Overview of stream transfer requirement:
* A transfer will have a set of TRBs of the same stream ID.
* A transfer is started with a stream ID in START_TRANSFER command.
* A new stream will only start when the previous completes.
Overview of stream events:
* A "prime" from host indicates that its endpoints are active
(buffers prepared and ready to receive/transmit data). The controller
automatically initiates stream if it sees this.
* A "NoStream" rejection event indicates that the host isn't ready.
Host will put the endpoint back to idle state. Device may need to
reinitiate the stream to start transfer again.
* A Stream Found event means host accepted device initiated stream.
Nothing needs to be done from driver.
To initiate a stream, the driver will issue START_TRANSFER command with a
stream ID. To reinitiate the stream, the driver must issue END_TRANSFER and
restart the transfer with START_TRANSFER command with the same stream ID.
This implementation handles device-initated streams (e.g. UASP driver). It
also handles some hosts' quirky behavior where they only prime each endpoint
once.
Prerequisite:
This series requires DWC_usb32 patch series
https://patchwork.kernel.org/project/linux-usb/list/?series=269641
[PATCH 1/2] usb: dwc3: Add support for DWC_usb32 IP
[PATCH 2/2] usb: dwc3: Get MDWIDTH for DWC_usb32
Changes in v2:
- Update cover letter
- Split handling of stream and of transfer completion into smaller patches
- Reword usb_request->is_last to strictly use for streams
- Enforce transfer completion handling to only for stream capable endpoints
Thinh Nguyen (11):
usb: gadget: Introduce usb_request->is_last
usb: gadget: f_tcm: Inform last stream request
usb: dwc3: gadget: Continue to process pending requests
usb: dwc3: gadget: Check for in-progress END_TRANSFER
usb: dwc3: gadget: Refactor TRB completion handler
usb: dwc3: gadget: Enable XferComplete event
usb: dwc3: gadget: Handle XferComplete for streams
usb: dwc3: gadget: Wait for transfer completion
usb: dwc3: gadget: Don't prepare beyond a transfer
usb: dwc3: gadget: Handle stream transfers
usb: dwc3: gadget: Use SET_EP_PRIME for NoStream
drivers/usb/dwc3/core.h | 12 ++
drivers/usb/dwc3/debug.h | 2 +
drivers/usb/dwc3/gadget.c | 225 +++++++++++++++++++++++++++++++-----
drivers/usb/gadget/function/f_tcm.c | 3 +
include/linux/usb/gadget.h | 3 +
5 files changed, 215 insertions(+), 30 deletions(-)
--
2.11.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 01/11] usb: gadget: Introduce usb_request->is_last
2020-05-06 2:46 [PATCH v2 00/11] usb: dwc3: gadget: Handle streams Thinh Nguyen
@ 2020-05-06 2:46 ` Thinh Nguyen
2020-05-06 2:46 ` [PATCH v2 02/11] usb: gadget: f_tcm: Inform last stream request Thinh Nguyen
` (10 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Thinh Nguyen @ 2020-05-06 2:46 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Thinh Nguyen, linux-usb; +Cc: John Youn
To take advantage of DWC3 internal TRB prefetch and cache for
performance, inform the controller the last request with stream_id
before switching to a different stream transfer. This allows the
controller to maintain its transfer burst within the stream ID.
Introduce the usb-request is_last field to help inform the DWC3
controller of this.
Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
---
include/linux/usb/gadget.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index e959c09a97c9..281eabae7f33 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -42,6 +42,8 @@ struct usb_ep;
* @num_mapped_sgs: number of SG entries mapped to DMA (internal)
* @length: Length of that data
* @stream_id: The stream id, when USB3.0 bulk streams are being used
+ * @is_last: Indicates if this is the last request of a stream_id before
+ * switching to a different stream (required for DWC3 controllers).
* @no_interrupt: If true, hints that no completion irq is needed.
* Helpful sometimes with deep request queues that are handled
* directly by DMA controllers.
@@ -104,6 +106,7 @@ struct usb_request {
unsigned num_mapped_sgs;
unsigned stream_id:16;
+ unsigned is_last:1;
unsigned no_interrupt:1;
unsigned zero:1;
unsigned short_not_ok:1;
--
2.11.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 02/11] usb: gadget: f_tcm: Inform last stream request
2020-05-06 2:46 [PATCH v2 00/11] usb: dwc3: gadget: Handle streams Thinh Nguyen
2020-05-06 2:46 ` [PATCH v2 01/11] usb: gadget: Introduce usb_request->is_last Thinh Nguyen
@ 2020-05-06 2:46 ` Thinh Nguyen
2020-05-06 2:46 ` [PATCH v2 03/11] usb: dwc3: gadget: Continue to process pending requests Thinh Nguyen
` (9 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Thinh Nguyen @ 2020-05-06 2:46 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Thinh Nguyen, linux-usb; +Cc: John Youn
Set the request->is_last to each stream request to indicate that the
request is the last stream request of a transfer. The DWC3 controller
needs to know this info to properly switch streams. The current
implementation of f_tcm uses a single request per transfer, so every
stream request is the last of its stream.
Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
---
drivers/usb/gadget/function/f_tcm.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c
index 36504931b2d1..2979cbe4d95f 100644
--- a/drivers/usb/gadget/function/f_tcm.c
+++ b/drivers/usb/gadget/function/f_tcm.c
@@ -531,6 +531,7 @@ static int uasp_prepare_r_request(struct usbg_cmd *cmd)
stream->req_in->sg = se_cmd->t_data_sg;
}
+ stream->req_in->is_last = 1;
stream->req_in->complete = uasp_status_data_cmpl;
stream->req_in->length = se_cmd->data_length;
stream->req_in->context = cmd;
@@ -554,6 +555,7 @@ static void uasp_prepare_status(struct usbg_cmd *cmd)
*/
iu->len = cpu_to_be16(se_cmd->scsi_sense_length);
iu->status = se_cmd->scsi_status;
+ stream->req_status->is_last = 1;
stream->req_status->context = cmd;
stream->req_status->length = se_cmd->scsi_sense_length + 16;
stream->req_status->buf = iu;
@@ -991,6 +993,7 @@ static int usbg_prepare_w_request(struct usbg_cmd *cmd, struct usb_request *req)
req->sg = se_cmd->t_data_sg;
}
+ req->is_last = 1;
req->complete = usbg_data_write_cmpl;
req->length = se_cmd->data_length;
req->context = cmd;
--
2.11.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 03/11] usb: dwc3: gadget: Continue to process pending requests
2020-05-06 2:46 [PATCH v2 00/11] usb: dwc3: gadget: Handle streams Thinh Nguyen
2020-05-06 2:46 ` [PATCH v2 01/11] usb: gadget: Introduce usb_request->is_last Thinh Nguyen
2020-05-06 2:46 ` [PATCH v2 02/11] usb: gadget: f_tcm: Inform last stream request Thinh Nguyen
@ 2020-05-06 2:46 ` Thinh Nguyen
2020-05-06 2:46 ` [PATCH v2 04/11] usb: dwc3: gadget: Check for in-progress END_TRANSFER Thinh Nguyen
` (8 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Thinh Nguyen @ 2020-05-06 2:46 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Thinh Nguyen, linux-usb; +Cc: John Youn
If there are still pending requests because no TRB was available,
prepare more when started requests are completed.
Introduce dwc3_gadget_ep_should_continue() to check for incomplete and
pending requests to resume updating new TRBs to the controller's TRB
cache.
Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
---
drivers/usb/dwc3/gadget.c | 24 +++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 4ca3e197bee4..865e6fbb7360 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2605,10 +2605,8 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep,
req->request.actual = req->request.length - req->remaining;
- if (!dwc3_gadget_ep_request_completed(req)) {
- __dwc3_gadget_kick_transfer(dep);
+ if (!dwc3_gadget_ep_request_completed(req))
goto out;
- }
dwc3_gadget_giveback(dep, req, status);
@@ -2632,6 +2630,24 @@ static void dwc3_gadget_ep_cleanup_completed_requests(struct dwc3_ep *dep,
}
}
+static bool dwc3_gadget_ep_should_continue(struct dwc3_ep *dep)
+{
+ struct dwc3_request *req;
+
+ if (!list_empty(&dep->pending_list))
+ return true;
+
+ /*
+ * We only need to check the first entry of the started list. We can
+ * assume the completed requests are removed from the started list.
+ */
+ req = next_request(&dep->started_list);
+ if (!req)
+ return false;
+
+ return !dwc3_gadget_ep_request_completed(req);
+}
+
static void dwc3_gadget_endpoint_frame_from_event(struct dwc3_ep *dep,
const struct dwc3_event_depevt *event)
{
@@ -2661,6 +2677,8 @@ static void dwc3_gadget_endpoint_transfer_in_progress(struct dwc3_ep *dep,
if (stop)
dwc3_stop_active_transfer(dep, true, true);
+ else if (dwc3_gadget_ep_should_continue(dep))
+ __dwc3_gadget_kick_transfer(dep);
/*
* WORKAROUND: This is the 2nd half of U1/U2 -> U0 workaround.
--
2.11.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 04/11] usb: dwc3: gadget: Check for in-progress END_TRANSFER
2020-05-06 2:46 [PATCH v2 00/11] usb: dwc3: gadget: Handle streams Thinh Nguyen
` (2 preceding siblings ...)
2020-05-06 2:46 ` [PATCH v2 03/11] usb: dwc3: gadget: Continue to process pending requests Thinh Nguyen
@ 2020-05-06 2:46 ` Thinh Nguyen
2020-05-06 2:46 ` [PATCH v2 05/11] usb: dwc3: gadget: Refactor TRB completion handler Thinh Nguyen
` (7 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Thinh Nguyen @ 2020-05-06 2:46 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Thinh Nguyen, linux-usb; +Cc: John Youn
While handling TRBs completion, if a END_TRANSFER command isn't
completed, don't kick new transfer or issue END_TRANSFER command.
Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
---
drivers/usb/dwc3/gadget.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 865e6fbb7360..3bb6f847a865 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2675,11 +2675,15 @@ static void dwc3_gadget_endpoint_transfer_in_progress(struct dwc3_ep *dep,
dwc3_gadget_ep_cleanup_completed_requests(dep, event, status);
+ if (dep->flags & DWC3_EP_END_TRANSFER_PENDING)
+ goto out;
+
if (stop)
dwc3_stop_active_transfer(dep, true, true);
else if (dwc3_gadget_ep_should_continue(dep))
__dwc3_gadget_kick_transfer(dep);
+out:
/*
* WORKAROUND: This is the 2nd half of U1/U2 -> U0 workaround.
* See dwc3_gadget_linksts_change_interrupt() for 1st half.
--
2.11.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 05/11] usb: dwc3: gadget: Refactor TRB completion handler
2020-05-06 2:46 [PATCH v2 00/11] usb: dwc3: gadget: Handle streams Thinh Nguyen
` (3 preceding siblings ...)
2020-05-06 2:46 ` [PATCH v2 04/11] usb: dwc3: gadget: Check for in-progress END_TRANSFER Thinh Nguyen
@ 2020-05-06 2:46 ` Thinh Nguyen
2020-05-06 2:46 ` [PATCH v2 06/11] usb: dwc3: gadget: Enable XferComplete event Thinh Nguyen
` (6 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Thinh Nguyen @ 2020-05-06 2:46 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Thinh Nguyen, linux-usb; +Cc: John Youn
To prepare for handling of XferComplete event, let's refactor and split
up dwc3_gadget_endpoint_transfer_in_progress() to handle TRBs completion
for different events. The handling of TRBs completion will be the same,
but the status of XferComplete event is different than XferInProgress.
No functional change in this commit.
Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
---
drivers/usb/dwc3/gadget.c | 45 ++++++++++++++++++++++++++-------------------
1 file changed, 26 insertions(+), 19 deletions(-)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 3bb6f847a865..5f98b424f20b 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2654,34 +2654,22 @@ static void dwc3_gadget_endpoint_frame_from_event(struct dwc3_ep *dep,
dep->frame_number = event->parameters;
}
-static void dwc3_gadget_endpoint_transfer_in_progress(struct dwc3_ep *dep,
- const struct dwc3_event_depevt *event)
+static bool dwc3_gadget_endpoint_trbs_complete(struct dwc3_ep *dep,
+ const struct dwc3_event_depevt *event, int status)
{
struct dwc3 *dwc = dep->dwc;
- unsigned status = 0;
- bool stop = false;
-
- dwc3_gadget_endpoint_frame_from_event(dep, event);
-
- if (event->status & DEPEVT_STATUS_BUSERR)
- status = -ECONNRESET;
-
- if (event->status & DEPEVT_STATUS_MISSED_ISOC) {
- status = -EXDEV;
-
- if (list_empty(&dep->started_list))
- stop = true;
- }
+ bool no_started_trb = true;
dwc3_gadget_ep_cleanup_completed_requests(dep, event, status);
if (dep->flags & DWC3_EP_END_TRANSFER_PENDING)
goto out;
- if (stop)
+ if (status == -EXDEV && list_empty(&dep->started_list))
dwc3_stop_active_transfer(dep, true, true);
else if (dwc3_gadget_ep_should_continue(dep))
- __dwc3_gadget_kick_transfer(dep);
+ if (__dwc3_gadget_kick_transfer(dep) == 0)
+ no_started_trb = false;
out:
/*
@@ -2699,7 +2687,7 @@ static void dwc3_gadget_endpoint_transfer_in_progress(struct dwc3_ep *dep,
continue;
if (!list_empty(&dep->started_list))
- return;
+ return no_started_trb;
}
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
@@ -2708,6 +2696,25 @@ static void dwc3_gadget_endpoint_transfer_in_progress(struct dwc3_ep *dep,
dwc->u1u2 = 0;
}
+
+ return no_started_trb;
+}
+
+static void dwc3_gadget_endpoint_transfer_in_progress(struct dwc3_ep *dep,
+ const struct dwc3_event_depevt *event)
+{
+ int status = 0;
+
+ if (usb_endpoint_xfer_isoc(dep->endpoint.desc))
+ dwc3_gadget_endpoint_frame_from_event(dep, event);
+
+ if (event->status & DEPEVT_STATUS_BUSERR)
+ status = -ECONNRESET;
+
+ if (event->status & DEPEVT_STATUS_MISSED_ISOC)
+ status = -EXDEV;
+
+ dwc3_gadget_endpoint_trbs_complete(dep, event, status);
}
static void dwc3_gadget_endpoint_transfer_not_ready(struct dwc3_ep *dep,
--
2.11.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 06/11] usb: dwc3: gadget: Enable XferComplete event
2020-05-06 2:46 [PATCH v2 00/11] usb: dwc3: gadget: Handle streams Thinh Nguyen
` (4 preceding siblings ...)
2020-05-06 2:46 ` [PATCH v2 05/11] usb: dwc3: gadget: Refactor TRB completion handler Thinh Nguyen
@ 2020-05-06 2:46 ` Thinh Nguyen
2020-05-06 2:46 ` [PATCH v2 07/11] usb: dwc3: gadget: Handle XferComplete for streams Thinh Nguyen
` (5 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Thinh Nguyen @ 2020-05-06 2:46 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Thinh Nguyen, linux-usb; +Cc: John Youn
To switch from one stream to another, this requires the driver to start
a new transfer with a specific stream ID. For a transfer to complete,
the driver needs to indicate the last TRB of a transfer, and it needs to
enable XferComplete event to handle completed TRBs of a transfer. Let's
enable this event only for stream capable endpoints.
Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
---
drivers/usb/dwc3/gadget.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 5f98b424f20b..81aa7de4cb17 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -579,6 +579,7 @@ static int dwc3_gadget_set_ep_config(struct dwc3_ep *dep, unsigned int action)
if (usb_ss_max_streams(comp_desc) && usb_endpoint_xfer_bulk(desc)) {
params.param1 |= DWC3_DEPCFG_STREAM_CAPABLE
+ | DWC3_DEPCFG_XFER_COMPLETE_EN
| DWC3_DEPCFG_STREAM_EVENT_EN;
dep->stream_capable = true;
}
--
2.11.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 07/11] usb: dwc3: gadget: Handle XferComplete for streams
2020-05-06 2:46 [PATCH v2 00/11] usb: dwc3: gadget: Handle streams Thinh Nguyen
` (5 preceding siblings ...)
2020-05-06 2:46 ` [PATCH v2 06/11] usb: dwc3: gadget: Enable XferComplete event Thinh Nguyen
@ 2020-05-06 2:46 ` Thinh Nguyen
2020-05-06 2:46 ` [PATCH v2 08/11] usb: dwc3: gadget: Wait for transfer completion Thinh Nguyen
` (4 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Thinh Nguyen @ 2020-05-06 2:46 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Thinh Nguyen, linux-usb; +Cc: John Youn
In DWC3, to prepare TRBs for streams, all the TRBs of a transfer will
use the same stream ID. To start a new stream, the driver needs to wait
for the current transfer to complete or ended (by END_TRANFER command).
As a result, inform the controller of the last TRB of a transfer so that
it knows when a transfer completes and start a new transfer of a new
stream.
Even though the transfer completion handling can be applied for other
non-isoc endpoints, only do it for streams due to its requirement.
It's better to keep the controller's TRB cache full than waiting for
transfer completion and starting a new transfer.
Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
---
drivers/usb/dwc3/gadget.c | 34 ++++++++++++++++++++++++++++------
1 file changed, 28 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 81aa7de4cb17..052f6dc52a51 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -919,7 +919,8 @@ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep)
static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb,
dma_addr_t dma, unsigned length, unsigned chain, unsigned node,
- unsigned stream_id, unsigned short_not_ok, unsigned no_interrupt)
+ unsigned stream_id, unsigned short_not_ok,
+ unsigned no_interrupt, unsigned is_last)
{
struct dwc3 *dwc = dep->dwc;
struct usb_gadget *gadget = &dwc->gadget;
@@ -1012,6 +1013,8 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb,
if (chain)
trb->ctrl |= DWC3_TRB_CTRL_CHN;
+ else if (dep->stream_capable && is_last)
+ trb->ctrl |= DWC3_TRB_CTRL_LST;
if (usb_endpoint_xfer_bulk(dep->endpoint.desc) && dep->stream_capable)
trb->ctrl |= DWC3_TRB_CTRL_SID_SOFN(stream_id);
@@ -1039,6 +1042,7 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
unsigned stream_id = req->request.stream_id;
unsigned short_not_ok = req->request.short_not_ok;
unsigned no_interrupt = req->request.no_interrupt;
+ unsigned is_last = req->request.is_last;
if (req->request.num_sgs > 0) {
length = sg_dma_len(req->start_sg);
@@ -1059,7 +1063,7 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
req->num_trbs++;
__dwc3_prepare_one_trb(dep, trb, dma, length, chain, node,
- stream_id, short_not_ok, no_interrupt);
+ stream_id, short_not_ok, no_interrupt, is_last);
}
static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
@@ -1104,7 +1108,8 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
maxp - rem, false, 1,
req->request.stream_id,
req->request.short_not_ok,
- req->request.no_interrupt);
+ req->request.no_interrupt,
+ req->request.is_last);
} else {
dwc3_prepare_one_trb(dep, req, chain, i);
}
@@ -1148,7 +1153,8 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep,
__dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, maxp - rem,
false, 1, req->request.stream_id,
req->request.short_not_ok,
- req->request.no_interrupt);
+ req->request.no_interrupt,
+ req->request.is_last);
} else if (req->request.zero && req->request.length &&
(IS_ALIGNED(req->request.length, maxp))) {
struct dwc3 *dwc = dep->dwc;
@@ -1165,7 +1171,8 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep,
__dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, 0,
false, 1, req->request.stream_id,
req->request.short_not_ok,
- req->request.no_interrupt);
+ req->request.no_interrupt,
+ req->request.is_last);
} else {
dwc3_prepare_one_trb(dep, req, false, 0);
}
@@ -2718,6 +2725,19 @@ static void dwc3_gadget_endpoint_transfer_in_progress(struct dwc3_ep *dep,
dwc3_gadget_endpoint_trbs_complete(dep, event, status);
}
+static void dwc3_gadget_endpoint_transfer_complete(struct dwc3_ep *dep,
+ const struct dwc3_event_depevt *event)
+{
+ int status = 0;
+
+ dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
+
+ if (event->status & DEPEVT_STATUS_BUSERR)
+ status = -ECONNRESET;
+
+ dwc3_gadget_endpoint_trbs_complete(dep, event, status);
+}
+
static void dwc3_gadget_endpoint_transfer_not_ready(struct dwc3_ep *dep,
const struct dwc3_event_depevt *event)
{
@@ -2781,8 +2801,10 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
dep->flags &= ~DWC3_EP_DELAY_START;
}
break;
- case DWC3_DEPEVT_STREAMEVT:
case DWC3_DEPEVT_XFERCOMPLETE:
+ dwc3_gadget_endpoint_transfer_complete(dep, event);
+ break;
+ case DWC3_DEPEVT_STREAMEVT:
case DWC3_DEPEVT_RXTXFIFOEVT:
break;
}
--
2.11.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 08/11] usb: dwc3: gadget: Wait for transfer completion
2020-05-06 2:46 [PATCH v2 00/11] usb: dwc3: gadget: Handle streams Thinh Nguyen
` (6 preceding siblings ...)
2020-05-06 2:46 ` [PATCH v2 07/11] usb: dwc3: gadget: Handle XferComplete for streams Thinh Nguyen
@ 2020-05-06 2:46 ` Thinh Nguyen
2020-05-06 2:47 ` [PATCH v2 09/11] usb: dwc3: gadget: Don't prepare beyond a transfer Thinh Nguyen
` (3 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Thinh Nguyen @ 2020-05-06 2:46 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Thinh Nguyen, linux-usb; +Cc: John Youn
If a transfer is in-progress, any new request should not kick off
another transfer. The driver needs to wait for the current transfer to
complete before starting off the next transfer. Introduce a new flag
DWC3_EP_WAIT_TRANSFER_COMPLETE for this.
Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
---
drivers/usb/dwc3/core.h | 1 +
drivers/usb/dwc3/gadget.c | 9 ++++++++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 7204a838ec06..b11183a715a7 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -701,6 +701,7 @@ struct dwc3_ep {
#define DWC3_EP_END_TRANSFER_PENDING BIT(4)
#define DWC3_EP_PENDING_REQUEST BIT(5)
#define DWC3_EP_DELAY_START BIT(6)
+#define DWC3_EP_WAIT_TRANSFER_COMPLETE BIT(7)
/* This last one is specific to EP0 */
#define DWC3_EP0_DIR_IN BIT(31)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 052f6dc52a51..97c6a5785725 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1292,6 +1292,9 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep)
return ret;
}
+ if (dep->stream_capable && req->request.is_last)
+ dep->flags |= DWC3_EP_WAIT_TRANSFER_COMPLETE;
+
return 0;
}
@@ -1498,6 +1501,9 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
list_add_tail(&req->list, &dep->pending_list);
req->status = DWC3_REQUEST_STATUS_QUEUED;
+ if (dep->flags & DWC3_EP_WAIT_TRANSFER_COMPLETE)
+ return 0;
+
/* Start the transfer only after the END_TRANSFER is completed */
if (dep->flags & DWC3_EP_END_TRANSFER_PENDING) {
dep->flags |= DWC3_EP_DELAY_START;
@@ -2735,7 +2741,8 @@ static void dwc3_gadget_endpoint_transfer_complete(struct dwc3_ep *dep,
if (event->status & DEPEVT_STATUS_BUSERR)
status = -ECONNRESET;
- dwc3_gadget_endpoint_trbs_complete(dep, event, status);
+ if (dwc3_gadget_endpoint_trbs_complete(dep, event, status))
+ dep->flags &= ~DWC3_EP_WAIT_TRANSFER_COMPLETE;
}
static void dwc3_gadget_endpoint_transfer_not_ready(struct dwc3_ep *dep,
--
2.11.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 09/11] usb: dwc3: gadget: Don't prepare beyond a transfer
2020-05-06 2:46 [PATCH v2 00/11] usb: dwc3: gadget: Handle streams Thinh Nguyen
` (7 preceding siblings ...)
2020-05-06 2:46 ` [PATCH v2 08/11] usb: dwc3: gadget: Wait for transfer completion Thinh Nguyen
@ 2020-05-06 2:47 ` Thinh Nguyen
2020-05-06 2:47 ` [PATCH v2 10/11] usb: dwc3: gadget: Handle stream transfers Thinh Nguyen
` (2 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Thinh Nguyen @ 2020-05-06 2:47 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Thinh Nguyen, linux-usb; +Cc: John Youn
Don't prepare TRBs beyond a transfer. In DWC_usb32, its transfer burst
capability may try to read and use TRBs beyond the active transfer. For
other controllers, they don't process the next transfer TRBs until the
current transfer is completed. Explicitly prevent preparing TRBs ahead
for all controllers.
Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
---
drivers/usb/dwc3/gadget.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 97c6a5785725..07824b670440 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1231,6 +1231,14 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep)
if (!dwc3_calc_trbs_left(dep))
return;
+
+ /*
+ * Don't prepare beyond a transfer. In DWC_usb32, its transfer
+ * burst capability may try to read and use TRBs beyond the
+ * active transfer instead of stopping.
+ */
+ if (dep->stream_capable && req->request.is_last)
+ return;
}
}
--
2.11.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 10/11] usb: dwc3: gadget: Handle stream transfers
2020-05-06 2:46 [PATCH v2 00/11] usb: dwc3: gadget: Handle streams Thinh Nguyen
` (8 preceding siblings ...)
2020-05-06 2:47 ` [PATCH v2 09/11] usb: dwc3: gadget: Don't prepare beyond a transfer Thinh Nguyen
@ 2020-05-06 2:47 ` Thinh Nguyen
2020-05-06 2:47 ` [PATCH v2 11/11] usb: dwc3: gadget: Use SET_EP_PRIME for NoStream Thinh Nguyen
2020-05-14 10:43 ` [PATCH v2 00/11] usb: dwc3: gadget: Handle streams Felipe Balbi
11 siblings, 0 replies; 13+ messages in thread
From: Thinh Nguyen @ 2020-05-06 2:47 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Thinh Nguyen, linux-usb; +Cc: John Youn
Overview of stream transfer requirement:
* A transfer will have a set of TRBs of the same stream ID.
* A transfer is started with a stream ID in START_TRANSFER command.
* A new stream will only start when the previous completes.
Overview of stream events:
* A "prime" from host indicates that its endpoints are active
(buffers prepared and ready to receive/transmit data). The controller
automatically initiates stream if it sees this.
* A "NoStream" rejection event indicates that the host isn't ready.
Host will put the endpoint back to idle state. Device may need to
reinitiate the stream to start transfer again.
* A Stream Found event means host accepted device initiated stream.
Nothing needs to be done from driver.
To initiate a stream, the driver will issue START_TRANSFER command with
a stream ID. To reinitiate the stream, the driver must issue
END_TRANSFER and restart the transfer with START_TRANSFER command with
the same stream ID.
This implementation handles device-initated streams (e.g. UASP driver).
It also handles some hosts' quirky behavior where they only prime each
endpoint once.
Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
---
drivers/usb/dwc3/core.h | 8 ++++
drivers/usb/dwc3/debug.h | 2 +
drivers/usb/dwc3/gadget.c | 97 +++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 104 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index b11183a715a7..4def088329c7 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -495,6 +495,7 @@
#define DWC3_DGCMD_SELECTED_FIFO_FLUSH 0x09
#define DWC3_DGCMD_ALL_FIFO_FLUSH 0x0a
#define DWC3_DGCMD_SET_ENDPOINT_NRDY 0x0c
+#define DWC3_DGCMD_SET_ENDPOINT_PRIME 0x0d
#define DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK 0x10
#define DWC3_DGCMD_STATUS(n) (((n) >> 12) & 0x0F)
@@ -702,6 +703,9 @@ struct dwc3_ep {
#define DWC3_EP_PENDING_REQUEST BIT(5)
#define DWC3_EP_DELAY_START BIT(6)
#define DWC3_EP_WAIT_TRANSFER_COMPLETE BIT(7)
+#define DWC3_EP_IGNORE_NEXT_NOSTREAM BIT(8)
+#define DWC3_EP_FORCE_RESTART_STREAM BIT(9)
+#define DWC3_EP_FIRST_STREAM_PRIMED BIT(10)
/* This last one is specific to EP0 */
#define DWC3_EP0_DIR_IN BIT(31)
@@ -1301,6 +1305,10 @@ struct dwc3_event_depevt {
#define DEPEVT_STREAMEVT_FOUND 1
#define DEPEVT_STREAMEVT_NOTFOUND 2
+/* Stream event parameter */
+#define DEPEVT_STREAM_PRIME 0xfffe
+#define DEPEVT_STREAM_NOSTREAM 0x0
+
/* Control-only Status */
#define DEPEVT_STATUS_CONTROL_DATA 1
#define DEPEVT_STATUS_CONTROL_STATUS 2
diff --git a/drivers/usb/dwc3/debug.h b/drivers/usb/dwc3/debug.h
index 0f95656c9622..d8f600e0e88f 100644
--- a/drivers/usb/dwc3/debug.h
+++ b/drivers/usb/dwc3/debug.h
@@ -68,6 +68,8 @@ dwc3_gadget_generic_cmd_string(u8 cmd)
return "All FIFO Flush";
case DWC3_DGCMD_SET_ENDPOINT_NRDY:
return "Set Endpoint NRDY";
+ case DWC3_DGCMD_SET_ENDPOINT_PRIME:
+ return "Set Endpoint Prime";
case DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK:
return "Run SoC Bus Loopback Test";
default:
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 07824b670440..0380f76151a1 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -610,6 +610,9 @@ static int dwc3_gadget_set_ep_config(struct dwc3_ep *dep, unsigned int action)
return dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_SETEPCONFIG, ¶ms);
}
+static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
+ bool interrupt);
+
/**
* __dwc3_gadget_ep_enable - initializes a hw endpoint
* @dep: endpoint to be initialized
@@ -670,7 +673,7 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, unsigned int action)
* Issue StartTransfer here with no-op TRB so we can always rely on No
* Response Update Transfer command.
*/
- if ((usb_endpoint_xfer_bulk(desc) && !dep->stream_capable) ||
+ if (usb_endpoint_xfer_bulk(desc) ||
usb_endpoint_xfer_int(desc)) {
struct dwc3_gadget_ep_cmd_params params;
struct dwc3_trb *trb;
@@ -689,6 +692,29 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, unsigned int action)
ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms);
if (ret < 0)
return ret;
+
+ if (dep->stream_capable) {
+ /*
+ * For streams, at start, there maybe a race where the
+ * host primes the endpoint before the function driver
+ * queues a request to initiate a stream. In that case,
+ * the controller will not see the prime to generate the
+ * ERDY and start stream. To workaround this, issue a
+ * no-op TRB as normal, but end it immediately. As a
+ * result, when the function driver queues the request,
+ * the next START_TRANSFER command will cause the
+ * controller to generate an ERDY to initiate the
+ * stream.
+ */
+ dwc3_stop_active_transfer(dep, true, true);
+
+ /*
+ * All stream eps will reinitiate stream on NoStream
+ * rejection until we can determine that the host can
+ * prime after the first transfer.
+ */
+ dep->flags |= DWC3_EP_FORCE_RESTART_STREAM;
+ }
}
out:
@@ -697,8 +723,6 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, unsigned int action)
return 0;
}
-static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
- bool interrupt);
static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
{
struct dwc3_request *req;
@@ -2772,6 +2796,63 @@ static void dwc3_gadget_endpoint_transfer_not_ready(struct dwc3_ep *dep,
(void) __dwc3_gadget_start_isoc(dep);
}
+static void dwc3_gadget_endpoint_stream_event(struct dwc3_ep *dep,
+ const struct dwc3_event_depevt *event)
+{
+ struct dwc3 *dwc = dep->dwc;
+
+ if (event->status == DEPEVT_STREAMEVT_FOUND) {
+ dep->flags |= DWC3_EP_FIRST_STREAM_PRIMED;
+ goto out;
+ }
+
+ /* Note: NoStream rejection event param value is 0 and not 0xFFFF */
+ switch (event->parameters) {
+ case DEPEVT_STREAM_PRIME:
+ /*
+ * If the host can properly transition the endpoint state from
+ * idle to prime after a NoStream rejection, there's no need to
+ * force restarting the endpoint to reinitiate the stream. To
+ * simplify the check, assume the host follows the USB spec if
+ * it primed the endpoint more than once.
+ */
+ if (dep->flags & DWC3_EP_FORCE_RESTART_STREAM) {
+ if (dep->flags & DWC3_EP_FIRST_STREAM_PRIMED)
+ dep->flags &= ~DWC3_EP_FORCE_RESTART_STREAM;
+ else
+ dep->flags |= DWC3_EP_FIRST_STREAM_PRIMED;
+ }
+
+ break;
+ case DEPEVT_STREAM_NOSTREAM:
+ if ((dep->flags & DWC3_EP_IGNORE_NEXT_NOSTREAM) ||
+ !(dep->flags & DWC3_EP_FORCE_RESTART_STREAM) ||
+ !(dep->flags & DWC3_EP_WAIT_TRANSFER_COMPLETE))
+ break;
+
+ /*
+ * If the host rejects a stream due to no active stream, by the
+ * USB and xHCI spec, the endpoint will be put back to idle
+ * state. When the host is ready (buffer added/updated), it will
+ * prime the endpoint to inform the usb device controller. This
+ * triggers the device controller to issue ERDY to restart the
+ * stream. However, some hosts don't follow this and keep the
+ * endpoint in the idle state. No prime will come despite host
+ * streams are updated, and the device controller will not be
+ * triggered to generate ERDY to move the next stream data. To
+ * workaround this and maintain compatibility with various
+ * hosts, force to reinitate the stream until the host is ready
+ * instead of waiting for the host to prime the endpoint.
+ */
+ dep->flags |= DWC3_EP_DELAY_START;
+ dwc3_stop_active_transfer(dep, true, true);
+ return;
+ }
+
+out:
+ dep->flags &= ~DWC3_EP_IGNORE_NEXT_NOSTREAM;
+}
+
static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
const struct dwc3_event_depevt *event)
{
@@ -2820,6 +2901,8 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
dwc3_gadget_endpoint_transfer_complete(dep, event);
break;
case DWC3_DEPEVT_STREAMEVT:
+ dwc3_gadget_endpoint_stream_event(dep, event);
+ break;
case DWC3_DEPEVT_RXTXFIFOEVT:
break;
}
@@ -2911,6 +2994,14 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
WARN_ON_ONCE(ret);
dep->resource_index = 0;
+ /*
+ * The END_TRANSFER command will cause the controller to generate a
+ * NoStream Event, and it's not due to the host DP NoStream rejection.
+ * Ignore the next NoStream event.
+ */
+ if (dep->stream_capable)
+ dep->flags |= DWC3_EP_IGNORE_NEXT_NOSTREAM;
+
if (!interrupt)
dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
else
--
2.11.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 11/11] usb: dwc3: gadget: Use SET_EP_PRIME for NoStream
2020-05-06 2:46 [PATCH v2 00/11] usb: dwc3: gadget: Handle streams Thinh Nguyen
` (9 preceding siblings ...)
2020-05-06 2:47 ` [PATCH v2 10/11] usb: dwc3: gadget: Handle stream transfers Thinh Nguyen
@ 2020-05-06 2:47 ` Thinh Nguyen
2020-05-14 10:43 ` [PATCH v2 00/11] usb: dwc3: gadget: Handle streams Felipe Balbi
11 siblings, 0 replies; 13+ messages in thread
From: Thinh Nguyen @ 2020-05-06 2:47 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Thinh Nguyen, linux-usb; +Cc: John Youn
DWC_usb32 v1.00a and later can use SET_EP_PRIME command to reinitiate a
stream. Use the command to handle NoStream rejection instead of ending
and restarting the endpoint.
Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
---
drivers/usb/dwc3/core.h | 3 +++
drivers/usb/dwc3/gadget.c | 13 ++++++++++---
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 4def088329c7..013f42a2b5dc 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -1161,6 +1161,9 @@ struct dwc3 {
#define DWC31_REVISION_180A 0x3138302a
#define DWC31_REVISION_190A 0x3139302a
+#define DWC32_REVISION_ANY 0x0
+#define DWC32_REVISION_100A 0x3130302a
+
u32 version_type;
#define DWC31_VERSIONTYPE_ANY 0x0
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 0380f76151a1..fea4fde1b5e3 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2844,9 +2844,16 @@ static void dwc3_gadget_endpoint_stream_event(struct dwc3_ep *dep,
* hosts, force to reinitate the stream until the host is ready
* instead of waiting for the host to prime the endpoint.
*/
- dep->flags |= DWC3_EP_DELAY_START;
- dwc3_stop_active_transfer(dep, true, true);
- return;
+ if (DWC3_VER_IS_WITHIN(DWC32, 100A, ANY)) {
+ unsigned int cmd = DWC3_DGCMD_SET_ENDPOINT_PRIME;
+
+ dwc3_send_gadget_generic_command(dwc, cmd, dep->number);
+ } else {
+ dep->flags |= DWC3_EP_DELAY_START;
+ dwc3_stop_active_transfer(dep, true, true);
+ return;
+ }
+ break;
}
out:
--
2.11.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v2 00/11] usb: dwc3: gadget: Handle streams
2020-05-06 2:46 [PATCH v2 00/11] usb: dwc3: gadget: Handle streams Thinh Nguyen
` (10 preceding siblings ...)
2020-05-06 2:47 ` [PATCH v2 11/11] usb: dwc3: gadget: Use SET_EP_PRIME for NoStream Thinh Nguyen
@ 2020-05-14 10:43 ` Felipe Balbi
11 siblings, 0 replies; 13+ messages in thread
From: Felipe Balbi @ 2020-05-14 10:43 UTC (permalink / raw)
To: Thinh Nguyen, Greg Kroah-Hartman, Thinh Nguyen, linux-usb; +Cc: John Youn
[-- Attachment #1: Type: text/plain, Size: 2538 bytes --]
Hi,
Thinh Nguyen <Thinh.Nguyen@synopsys.com> writes:
> Overview of stream transfer requirement:
> * A transfer will have a set of TRBs of the same stream ID.
> * A transfer is started with a stream ID in START_TRANSFER command.
> * A new stream will only start when the previous completes.
>
> Overview of stream events:
> * A "prime" from host indicates that its endpoints are active
> (buffers prepared and ready to receive/transmit data). The controller
> automatically initiates stream if it sees this.
> * A "NoStream" rejection event indicates that the host isn't ready.
> Host will put the endpoint back to idle state. Device may need to
> reinitiate the stream to start transfer again.
> * A Stream Found event means host accepted device initiated stream.
> Nothing needs to be done from driver.
>
> To initiate a stream, the driver will issue START_TRANSFER command with a
> stream ID. To reinitiate the stream, the driver must issue END_TRANSFER and
> restart the transfer with START_TRANSFER command with the same stream ID.
>
> This implementation handles device-initated streams (e.g. UASP driver). It
> also handles some hosts' quirky behavior where they only prime each endpoint
> once.
>
> Prerequisite:
> This series requires DWC_usb32 patch series
> https://patchwork.kernel.org/project/linux-usb/list/?series=269641
>
> [PATCH 1/2] usb: dwc3: Add support for DWC_usb32 IP
> [PATCH 2/2] usb: dwc3: Get MDWIDTH for DWC_usb32
>
>
> Changes in v2:
> - Update cover letter
> - Split handling of stream and of transfer completion into smaller patches
> - Reword usb_request->is_last to strictly use for streams
> - Enforce transfer completion handling to only for stream capable endpoints
>
>
> Thinh Nguyen (11):
> usb: gadget: Introduce usb_request->is_last
> usb: gadget: f_tcm: Inform last stream request
> usb: dwc3: gadget: Continue to process pending requests
> usb: dwc3: gadget: Check for in-progress END_TRANSFER
> usb: dwc3: gadget: Refactor TRB completion handler
> usb: dwc3: gadget: Enable XferComplete event
> usb: dwc3: gadget: Handle XferComplete for streams
> usb: dwc3: gadget: Wait for transfer completion
> usb: dwc3: gadget: Don't prepare beyond a transfer
> usb: dwc3: gadget: Handle stream transfers
> usb: dwc3: gadget: Use SET_EP_PRIME for NoStream
This seris is now in testing/next. Can you check that everything looks
fine for you? I had to manually apply one patch.
--
balbi
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2020-05-14 10:43 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-06 2:46 [PATCH v2 00/11] usb: dwc3: gadget: Handle streams Thinh Nguyen
2020-05-06 2:46 ` [PATCH v2 01/11] usb: gadget: Introduce usb_request->is_last Thinh Nguyen
2020-05-06 2:46 ` [PATCH v2 02/11] usb: gadget: f_tcm: Inform last stream request Thinh Nguyen
2020-05-06 2:46 ` [PATCH v2 03/11] usb: dwc3: gadget: Continue to process pending requests Thinh Nguyen
2020-05-06 2:46 ` [PATCH v2 04/11] usb: dwc3: gadget: Check for in-progress END_TRANSFER Thinh Nguyen
2020-05-06 2:46 ` [PATCH v2 05/11] usb: dwc3: gadget: Refactor TRB completion handler Thinh Nguyen
2020-05-06 2:46 ` [PATCH v2 06/11] usb: dwc3: gadget: Enable XferComplete event Thinh Nguyen
2020-05-06 2:46 ` [PATCH v2 07/11] usb: dwc3: gadget: Handle XferComplete for streams Thinh Nguyen
2020-05-06 2:46 ` [PATCH v2 08/11] usb: dwc3: gadget: Wait for transfer completion Thinh Nguyen
2020-05-06 2:47 ` [PATCH v2 09/11] usb: dwc3: gadget: Don't prepare beyond a transfer Thinh Nguyen
2020-05-06 2:47 ` [PATCH v2 10/11] usb: dwc3: gadget: Handle stream transfers Thinh Nguyen
2020-05-06 2:47 ` [PATCH v2 11/11] usb: dwc3: gadget: Use SET_EP_PRIME for NoStream Thinh Nguyen
2020-05-14 10:43 ` [PATCH v2 00/11] usb: dwc3: gadget: Handle streams Felipe Balbi
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.