Re: [PATCH] usb: gadget: core: unmap request from DMA only if previously mapped

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

 



Hi Felipe,

Do you have any comments on this?

Thanks,
Jack

On Tue, Aug 01, 2017 at 02:00:56AM -0700, Jack Pham wrote:
> In the SG case this is already handled since a non-zero
> request->num_mapped_sgs is a clear indicator that dma_map_sg()
> had been called. While it would be nice to do the same for the
> singly mapped case by simply checking for non-zero request->dma,
> it's conceivable that 0 is a valid dma_addr_t handle. Hence add
> a flag 'dma_mapped' to struct usb_request and use this to
> determine the need to call dma_unmap_single(). Otherwise, if a
> request is not DMA mapped then the result of calling
> usb_request_unmap_request() would safely be a no-op.
> 
> Signed-off-by: Jack Pham <jackp@xxxxxxxxxxxxxx>
> ---
> Hi Felipe,
> 
> Here's what I came up with after our discussion back in [1]. It
> turned out to be pretty dead-simple and hopefully doesn't need to
> approach the number of URB flags that the host core uses.
> 
> I did a quick survey of all callers of usb_gadget_{map,unmap}_request
> and besides the instance I reported & patched in dwc3, from what I
> can tell it looks like all the other gadget drivers seem to be calling
> these APIs sanely--i.e. a request is only queued after being
> successfully mapped, and unmap only ever gets called on requests that
> had been queued.
> 
> Although in one instance (renesas_usb3.c), there is a 'used' flag as
> part of struct renesas_usb3_dma that looks like it's tracking the
> status of whether a request is mapped or not, but it's not obvious from
> cursory glance whether it has a use besides that or if it would be
> sufficient to just rely on this new flag in struct usb_gadget.
> Maybe Yoshihiro-san can comment.
> 
> [1] http://marc.info/?l=linux-usb&m=149872369422476&w=2
> 
> Thanks,
> Jack
> 
>  drivers/usb/gadget/udc/core.c | 5 ++++-
>  include/linux/usb/gadget.h    | 2 ++
>  2 files changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
> index e6f04ee..c1cef6a 100644
> --- a/drivers/usb/gadget/udc/core.c
> +++ b/drivers/usb/gadget/udc/core.c
> @@ -812,6 +812,8 @@ int usb_gadget_map_request_by_dev(struct device *dev,
>  			dev_err(dev, "failed to map buffer\n");
>  			return -EFAULT;
>  		}
> +
> +		req->dma_mapped = 1;
>  	}
>  
>  	return 0;
> @@ -836,9 +838,10 @@ void usb_gadget_unmap_request_by_dev(struct device *dev,
>  				is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
>  
>  		req->num_mapped_sgs = 0;
> -	} else {
> +	} else if (req->dma_mapped) {
>  		dma_unmap_single(dev, req->dma, req->length,
>  				is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
> +		req->dma_mapped = 0;
>  	}
>  }
>  EXPORT_SYMBOL_GPL(usb_gadget_unmap_request_by_dev);
> diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
> index 1a4a4ba..21468a7 100644
> --- a/include/linux/usb/gadget.h
> +++ b/include/linux/usb/gadget.h
> @@ -48,6 +48,7 @@ struct usb_ep;
>   *     by adding a zero length packet as needed;
>   * @short_not_ok: When reading data, makes short packets be
>   *     treated as errors (queue stops advancing till cleanup).
> + * @dma_mapped: Indicates if request has been mapped to DMA (internal)
>   * @complete: Function called when request completes, so this request and
>   *	its buffer may be re-used.  The function will always be called with
>   *	interrupts disabled, and it must not sleep.
> @@ -103,6 +104,7 @@ struct usb_request {
>  	unsigned		no_interrupt:1;
>  	unsigned		zero:1;
>  	unsigned		short_not_ok:1;
> +	unsigned		dma_mapped:1;
>  
>  	void			(*complete)(struct usb_ep *ep,
>  					struct usb_request *req);

-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



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

  Powered by Linux