USB: gadget: Add module parameter for Rx transfer length
authorPavankumar Kondeti <pkondeti@codeaurora.org>
Tue, 19 Feb 2019 11:37:06 +0000 (11:37 +0000)
committerDanny Wood <danwood76@gmail.com>
Tue, 19 Feb 2019 13:07:30 +0000 (13:07 +0000)
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.

CRs-Fixed: 429212
Change-Id: I7bed5aeefabf1a50c08a9a8e5b876e0cf59515fd
Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org>
drivers/usb/gadget/f_mtp.c

index 9dc1cc9e37a923447f8d43f608a646ffaf3b36da..7a697f757382a388aa5be6fd964b168fcbde85d5 100644 (file)
@@ -67,6 +67,9 @@
 #define MTP_RESPONSE_OK             0x2001
 #define MTP_RESPONSE_DEVICE_BUSY    0x2019
 
+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[] = "mtp_usb";
 
 struct mtp_dev {
@@ -504,10 +507,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;
        }
@@ -553,7 +573,7 @@ static ssize_t mtp_read(struct file *fp, char __user *buf,
        spin_lock_irq(&dev->lock);
        if (dev->ep_out->desc) {
                len = usb_ep_align_maybe(cdev->gadget, dev->ep_out, count);
-               if (len > MTP_BULK_BUFFER_SIZE) {
+               if (len > mtp_rx_req_len) {
                        spin_unlock_irq(&dev->lock);
                        return -EINVAL;
                }
@@ -846,8 +866,8 @@ static void receive_file_work(struct work_struct *data)
                        read_req = dev->rx_req[cur_buf];
                        cur_buf = (cur_buf + 1) % RX_REQ_MAX;
 
-                       read_req->length = (count > MTP_BULK_BUFFER_SIZE
-                                       ? MTP_BULK_BUFFER_SIZE : count);
+                       read_req->length = (count > mtp_rx_req_len
+                                       ? mtp_rx_req_len : count);
                        dev->rx_done = 0;
 
                        set_read_req_length(read_req);