lkml.org 
[lkml]   [2013]   [Nov]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 2/2] check quirk to pad epout buf size when not aligned to maxpacketsize
    Date
    From: Michal Nazarewicz <mina86@mina86.com>

    Check gadget.quirk_ep_out_aligned_size to decide if buffer size requires
    to be aligned to maxpacketsize of an out endpoint. ffs_epfile_io() needs
    to pad epout buffer to match above condition if quirk is found.

    Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
    ---
    I'm wondering whether the len should be aligned down rather then up.
    This would have it's own problems, but maybe better then
    a possibility of silently dropping data.

    drivers/usb/gadget/f_fs.c | 21 ++++++++++++++++++---
    1 file changed, 18 insertions(+), 3 deletions(-)

    diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
    index f875f26..ea0b8ba 100644
    --- a/drivers/usb/gadget/f_fs.c
    +++ b/drivers/usb/gadget/f_fs.c
    @@ -753,8 +753,9 @@ static ssize_t ffs_epfile_io(struct file *file,
    char __user *buf, size_t len, int read)
    {
    struct ffs_epfile *epfile = file->private_data;
    + struct usb_gadget *gadget = epfile->ffs->gadget;
    struct ffs_ep *ep;
    - ssize_t ret;
    + ssize_t ret, data_len;
    char *data;
    int halt;

    @@ -787,6 +788,13 @@ static ssize_t ffs_epfile_io(struct file *file,

    /* Allocate & copy */
    if (!halt) {
    + /*
    + * Controller requires buffer size to be aligned to
    + * maxpacketsize of an out endpoint.
    + */
    + data_len = read && gadget->quirk_ep_out_aligned_size ?
    + usb_ep_align_maxpacketsize(ep->ep, len) : len;
    +
    data = kmalloc(len, GFP_KERNEL);
    if (unlikely(!data))
    return -ENOMEM;
    @@ -824,7 +832,7 @@ static ssize_t ffs_epfile_io(struct file *file,
    req->context = &done;
    req->complete = ffs_epfile_io_complete;
    req->buf = data;
    - req->length = len;
    + req->length = data_len;

    ret = usb_ep_queue(ep->ep, req, GFP_ATOMIC);

    @@ -836,9 +844,16 @@ static ssize_t ffs_epfile_io(struct file *file,
    ret = -EINTR;
    usb_ep_dequeue(ep->ep, req);
    } else {
    + /*
    + * XXX We may end up silently droping data here.
    + * Since data_len (i.e. req->length) may be bigger
    + * than len (after being rounded up to maxpacketsize),
    + * we may end up with more data then user space has
    + * space for.
    + */
    ret = ep->status;
    if (read && ret > 0 &&
    - unlikely(copy_to_user(buf, data, ret)))
    + unlikely(copy_to_user(buf, data, min(ret, len))))
    ret = -EFAULT;
    }
    }
    --
    1.8.3.2


    \
     
     \ /
      Last update: 2013-11-10 18:01    [W:4.746 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site