On 4/1/2019 2:51 PM, Andrzej Pietrasiewicz wrote: > 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) > Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@xxxxxxxxxxxxx> Acked-by: Minas Harutyunyan <hminas@xxxxxxxxxxxx> > --- > 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 6812a8a3a98b..e76b2e040b4c 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 */ > @@ -2028,12 +2031,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), >