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 <andrze...@collabora.com>

Acked-by: Minas Harutyunyan <hmi...@synopsys.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 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),
> 

Reply via email to