summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVamsi Krishna <vskrishn@codeaurora.org>2015-11-10 14:38:23 -0800
committerDavid Pursell <dpursell@google.com>2015-11-12 16:31:21 -0800
commitd1ce38d6f959b18bb6241d6fae18fb38a273f0ab (patch)
tree2793c82604c6e2256304ce24f08e175e96076854
parentf734b14939da6975995db807d1160b53a27c98c3 (diff)
downloadqcom-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.c18
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);
}