summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHemant Kumar <hemantk@codeaurora.org>2016-05-01 17:35:36 -0700
committerKyle Yan <kyan@codeaurora.org>2016-06-07 16:01:41 -0700
commit1bb8887af8b525e68d9c9e7c828836a3d17ab0b3 (patch)
treec49b464093001131add3424d73a0dc048d5f7187
parentf5bf2e9314b81ec2e24e7ad9a344c58d1304e7af (diff)
USB: gadget: mtp: Add module parameter for Rx transfer length
The Rx request transfer length is 16K bytes by default. The test results indicate that larger transfers improve write speeds. Add provision for specifying Rx transfer length at runtime. echo -n 1048576 > /sys/module/g_android/parameters/mtp_rx_req_len The above command can be used to set Rx transfer length to 1MB. If the memory allocation is failed, fallback to the default length. Change-Id: I74d5da09437c25e9f1772f7cd49aecb8e4fedcf2 Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org> Signed-off-by: Hemant Kumar <hemantk@codeaurora.org>
-rw-r--r--drivers/usb/gadget/function/f_mtp.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/drivers/usb/gadget/function/f_mtp.c b/drivers/usb/gadget/function/f_mtp.c
index 286cb7622870..33c6118bf71d 100644
--- a/drivers/usb/gadget/function/f_mtp.c
+++ b/drivers/usb/gadget/function/f_mtp.c
@@ -73,6 +73,9 @@
#define MTP_RESPONSE_DEVICE_BUSY 0x2019
#define DRIVER_NAME "mtp"
+unsigned int mtp_rx_req_len = MTP_BULK_BUFFER_SIZE;
+module_param(mtp_rx_req_len, uint, S_IRUGO | S_IWUSR);
+
static const char mtp_shortname[] = DRIVER_NAME "_usb";
struct mtp_dev {
@@ -450,10 +453,27 @@ static int mtp_create_bulk_endpoints(struct mtp_dev *dev,
req->complete = mtp_complete_in;
mtp_req_put(dev, &dev->tx_idle, req);
}
+
+ /*
+ * The RX buffer should be aligned to EP max packet for
+ * some controllers. At bind time, we don't know the
+ * operational speed. Hence assuming super speed max
+ * packet size.
+ */
+ if (mtp_rx_req_len % 1024)
+ mtp_rx_req_len = MTP_BULK_BUFFER_SIZE;
+
+retry_rx_alloc:
for (i = 0; i < RX_REQ_MAX; i++) {
- req = mtp_request_new(dev->ep_out, MTP_BULK_BUFFER_SIZE);
- if (!req)
- goto fail;
+ req = mtp_request_new(dev->ep_out, mtp_rx_req_len);
+ if (!req) {
+ if (mtp_rx_req_len <= MTP_BULK_BUFFER_SIZE)
+ goto fail;
+ for (; i > 0; i--)
+ mtp_request_free(dev->rx_req[i], dev->ep_out);
+ mtp_rx_req_len = MTP_BULK_BUFFER_SIZE;
+ goto retry_rx_alloc;
+ }
req->complete = mtp_complete_out;
dev->rx_req[i] = req;
}
@@ -483,7 +503,7 @@ static ssize_t mtp_read(struct file *fp, char __user *buf,
DBG(cdev, "mtp_read(%zu)\n", count);
- if (count > MTP_BULK_BUFFER_SIZE)
+ if (count > mtp_rx_req_len)
return -EINVAL;
if (!IS_ALIGNED(count, dev->ep_out->maxpacket))
@@ -511,7 +531,7 @@ static ssize_t mtp_read(struct file *fp, char __user *buf,
requeue_req:
/* queue a request */
req = dev->rx_req[0];
- req->length = MTP_BULK_BUFFER_SIZE;
+ req->length = mtp_rx_req_len;
dev->rx_done = 0;
ret = usb_ep_queue(dev->ep_out, req, GFP_KERNEL);
if (ret < 0) {
@@ -787,7 +807,7 @@ static void receive_file_work(struct work_struct *data)
cur_buf = (cur_buf + 1) % RX_REQ_MAX;
/* some h/w expects size to be aligned to ep's MTU */
- read_req->length = MTP_BULK_BUFFER_SIZE;
+ read_req->length = mtp_rx_req_len;
dev->rx_done = 0;
ret = usb_ep_queue(dev->ep_out, read_req, GFP_KERNEL);