diff options
author | Vamsi Krishna <vskrishn@codeaurora.org> | 2015-11-10 14:38:23 -0800 |
---|---|---|
committer | David Pursell <dpursell@google.com> | 2015-11-12 16:31:21 -0800 |
commit | d1ce38d6f959b18bb6241d6fae18fb38a273f0ab (patch) | |
tree | 2793c82604c6e2256304ce24f08e175e96076854 | |
parent | f734b14939da6975995db807d1160b53a27c98c3 (diff) | |
download | qcom-d1ce38d6f959b18bb6241d6fae18fb38a273f0ab.tar.gz |
usb: gadget: ffs: limit write buffer to 16K
USB CI (chipidea) controller driver cannot handle
more than 16K and new ADB version supports buffer
length upto 256KB breaking the adb protocol whenever
adb daemon tries to send more than 16K to PC. Fix
it by limiting buffer length to 16K in ffs driver.
It will not break ADB functionality as ADB daemon
will retry.
Bug: http://b/25193669
Change-Id: I65243cf874ca2a8999fb0601d329405a814cb426
Signed-off-by: Vamsi Krishna <vskrishn@codeaurora.org>
Signed-off-by: Anu Ramanathan <anur@codeaurora.org>
-rw-r--r-- | drivers/usb/gadget/f_fs.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 3609b24c62a..6a5fb202cbe 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -765,7 +765,11 @@ static void ffs_epfile_io_complete(struct usb_ep *_ep, struct usb_request *req) } } -#define MAX_BUF_LEN 4096 +#define MAX_BUF_LEN 16384 +/*USB CI (chipidea) controller driver cannot handle more than 16K and +new ADB version supports buffer sizes upto 256KB.This is fixed by limiting +maximum buffer length to 16K to ffs driver. */ + static ssize_t ffs_epfile_io(struct file *file, char __user *buf, size_t len, int read) { @@ -777,7 +781,7 @@ static ssize_t ffs_epfile_io(struct file *file, int halt; int buffer_len = 0; - pr_debug("%s: len %zu, read %d\n", __func__, len, read); + pr_debug("%s: len %zu, read %s\n", __func__, len, read ? "read" : "write"); if (atomic_read(&epfile->error)) return -ENODEV; @@ -881,9 +885,11 @@ first_try: req->length = buffer_len; if (read) { + pr_debug("%s: out completion\n", __func__); INIT_COMPLETION(ffs->epout_completion); req->context = done = &ffs->epout_completion; } else { + pr_debug("%s: in completion\n", __func__); INIT_COMPLETION(ffs->epin_completion); req->context = done = &ffs->epin_completion; } @@ -946,6 +952,13 @@ ffs_epfile_write(struct file *file, const char __user *buf, size_t len, { ENTER(); + pr_debug("%s: len:%u\n", __func__, len); + + if (len > MAX_BUF_LEN) { + len = MAX_BUF_LEN; + pr_debug("%s: new_len:%u\n", __func__, len); + } + return ffs_epfile_io(file, (char __user *)buf, len, 0); } @@ -954,6 +967,7 @@ ffs_epfile_read(struct file *file, char __user *buf, size_t len, loff_t *ptr) { ENTER(); + pr_debug("%s: len:%u\n", __func__, len); return ffs_epfile_io(file, buf, len, 1); } |