Re: [PATCH] usb: gadget: dwc2: fix zlp handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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),
> 





[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux