lkml.org 
[lkml]   [2020]   [Jul]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 38/58] usb: core: Add a helper function to check the validity of EP type in URB
    Date
    From: Takashi Iwai <tiwai@suse.de>

    commit e901b9873876ca30a09253731bd3a6b00c44b5b0 upstream.

    This patch adds a new helper function to perform a sanity check of the
    given URB to see whether it contains a valid endpoint. It's a light-
    weight version of what usb_submit_urb() does, but without the kernel
    warning followed by the stack trace, just returns an error code.

    Especially for a driver that doesn't parse the descriptor but fills
    the URB with the fixed endpoint (e.g. some quirks for non-compliant
    devices), this kind of check is preferable at the probe phase before
    actually submitting the urb.

    Tested-by: Andrey Konovalov <andreyknvl@google.com>
    Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Signed-off-by: Takashi Iwai <tiwai@suse.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/usb/core/urb.c | 30 ++++++++++++++++++++++++++----
    include/linux/usb.h | 2 ++
    2 files changed, 28 insertions(+), 4 deletions(-)

    --- a/drivers/usb/core/urb.c
    +++ b/drivers/usb/core/urb.c
    @@ -185,6 +185,31 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb);

    /*-------------------------------------------------------------------*/

    +static const int pipetypes[4] = {
    + PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT
    +};
    +
    +/**
    + * usb_urb_ep_type_check - sanity check of endpoint in the given urb
    + * @urb: urb to be checked
    + *
    + * This performs a light-weight sanity check for the endpoint in the
    + * given urb. It returns 0 if the urb contains a valid endpoint, otherwise
    + * a negative error code.
    + */
    +int usb_urb_ep_type_check(const struct urb *urb)
    +{
    + const struct usb_host_endpoint *ep;
    +
    + ep = usb_pipe_endpoint(urb->dev, urb->pipe);
    + if (!ep)
    + return -EINVAL;
    + if (usb_pipetype(urb->pipe) != pipetypes[usb_endpoint_type(&ep->desc)])
    + return -EINVAL;
    + return 0;
    +}
    +EXPORT_SYMBOL_GPL(usb_urb_ep_type_check);
    +
    /**
    * usb_submit_urb - issue an asynchronous transfer request for an endpoint
    * @urb: pointer to the urb describing the request
    @@ -324,9 +349,6 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb);
    */
    int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
    {
    - static int pipetypes[4] = {
    - PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT
    - };
    int xfertype, max;
    struct usb_device *dev;
    struct usb_host_endpoint *ep;
    @@ -445,7 +467,7 @@ int usb_submit_urb(struct urb *urb, gfp_
    */

    /* Check that the pipe's type matches the endpoint's type */
    - if (usb_pipetype(urb->pipe) != pipetypes[xfertype])
    + if (usb_urb_ep_type_check(urb))
    dev_WARN(&dev->dev, "BOGUS urb xfer, pipe %x != type %x\n",
    usb_pipetype(urb->pipe), pipetypes[xfertype]);

    --- a/include/linux/usb.h
    +++ b/include/linux/usb.h
    @@ -1655,6 +1655,8 @@ static inline int usb_urb_dir_out(struct
    return (urb->transfer_flags & URB_DIR_MASK) == URB_DIR_OUT;
    }

    +int usb_urb_ep_type_check(const struct urb *urb);
    +
    void *usb_alloc_coherent(struct usb_device *dev, size_t size,
    gfp_t mem_flags, dma_addr_t *dma);
    void usb_free_coherent(struct usb_device *dev, size_t size,

    \
     
     \ /
      Last update: 2020-07-20 17:39    [W:2.662 / U:0.296 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site