89 lines
3.1 KiB
Diff
89 lines
3.1 KiB
Diff
![]() |
From 066cfd0770aba8a9ac79b59d99530653885d919d Mon Sep 17 00:00:00 2001
|
||
|
From: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
|
||
|
Date: Mon, 1 Apr 2019 12:50:45 +0200
|
||
|
Subject: [PATCH 48/53] usb: gadget: dwc2: fix zlp handling
|
||
|
|
||
|
The patch 10209abe87f5ebfd482a00323f5236d6094d0865
|
||
|
usb: dwc2: gadget: Add scatter-gather mode
|
||
|
|
||
|
avoided a NULL pointer dereference (hs_ep->req == NULL) by
|
||
|
calling dwc2_gadget_fill_nonisoc_xfer_dma_one() directly instead of through
|
||
|
the dwc2_gadget_config_nonisoc_xfer_ddma() wrapper, which unconditionally
|
||
|
dereferenced the said pointer.
|
||
|
|
||
|
However, this was based on an incorrect assumption that in the context of
|
||
|
dwc2_hsotg_program_zlp() the pointer is always NULL, which is not the case.
|
||
|
The result were SB CV MSC tests failing starting from Test Case 6.
|
||
|
|
||
|
Instead, this patch reverts to calling the wrapper and adds a check for
|
||
|
the pointer being NULL inside the wrapper.
|
||
|
|
||
|
Fixes: 10209abe87f5 (usb: dwc2: gadget: Add scatter-gather mode)
|
||
|
Acked-by: Minas Harutyunyan <hminas@synopsys.com>
|
||
|
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
|
||
|
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
|
||
|
---
|
||
|
drivers/usb/dwc2/gadget.c | 20 ++++++++++++--------
|
||
|
1 file changed, 12 insertions(+), 8 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
|
||
|
index 1d4aef8d4137..bff48a8a1984 100644
|
||
|
--- a/drivers/usb/dwc2/gadget.c
|
||
|
+++ b/drivers/usb/dwc2/gadget.c
|
||
|
@@ -835,19 +835,22 @@ static void dwc2_gadget_fill_nonisoc_xfer_ddma_one(struct dwc2_hsotg_ep *hs_ep,
|
||
|
* with corresponding information based on transfer data.
|
||
|
*/
|
||
|
static void dwc2_gadget_config_nonisoc_xfer_ddma(struct dwc2_hsotg_ep *hs_ep,
|
||
|
- struct usb_request *ureq,
|
||
|
- unsigned int offset,
|
||
|
+ dma_addr_t dma_buff,
|
||
|
unsigned int len)
|
||
|
{
|
||
|
+ struct usb_request *ureq = NULL;
|
||
|
struct dwc2_dma_desc *desc = hs_ep->desc_list;
|
||
|
struct scatterlist *sg;
|
||
|
int i;
|
||
|
u8 desc_count = 0;
|
||
|
|
||
|
+ if (hs_ep->req)
|
||
|
+ ureq = &hs_ep->req->req;
|
||
|
+
|
||
|
/* non-DMA sg buffer */
|
||
|
- if (!ureq->num_sgs) {
|
||
|
+ if (!ureq || !ureq->num_sgs) {
|
||
|
dwc2_gadget_fill_nonisoc_xfer_ddma_one(hs_ep, &desc,
|
||
|
- ureq->dma + offset, len, true);
|
||
|
+ dma_buff, len, true);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
@@ -1135,7 +1138,7 @@ static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg,
|
||
|
offset = ureq->actual;
|
||
|
|
||
|
/* Fill DDMA chain entries */
|
||
|
- dwc2_gadget_config_nonisoc_xfer_ddma(hs_ep, ureq, offset,
|
||
|
+ dwc2_gadget_config_nonisoc_xfer_ddma(hs_ep, ureq->dma + offset,
|
||
|
length);
|
||
|
|
||
|
/* write descriptor chain address to control register */
|
||
|
@@ -2037,12 +2040,13 @@ static void dwc2_hsotg_program_zlp(struct dwc2_hsotg *hsotg,
|
||
|
dev_dbg(hsotg->dev, "Receiving zero-length packet on ep%d\n",
|
||
|
index);
|
||
|
if (using_desc_dma(hsotg)) {
|
||
|
+ /* Not specific buffer needed for ep0 ZLP */
|
||
|
+ dma_addr_t dma = hs_ep->desc_list_dma;
|
||
|
+
|
||
|
if (!index)
|
||
|
dwc2_gadget_set_ep0_desc_chain(hsotg, hs_ep);
|
||
|
|
||
|
- /* Not specific buffer needed for ep0 ZLP */
|
||
|
- dwc2_gadget_fill_nonisoc_xfer_ddma_one(hs_ep, &hs_ep->desc_list,
|
||
|
- hs_ep->desc_list_dma, 0, true);
|
||
|
+ dwc2_gadget_config_nonisoc_xfer_ddma(hs_ep, dma, 0);
|
||
|
} else {
|
||
|
dwc2_writel(hsotg, DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) |
|
||
|
DXEPTSIZ_XFERSIZE(0),
|
||
|
--
|
||
|
2.11.0
|
||
|
|