summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaoran Wang <b50027@freescale.com>2015-04-23 09:52:38 +0800
committerguoyin.chen <guoyin.chen@freescale.com>2015-05-08 17:26:44 +0800
commit2e81c6850fc189134b59be2b0b369ec64c70bf26 (patch)
tree82c1cca11cfc2e03e4c184699dd68cf7f902a3f7
parentec844786c252379e343c8af04959fa0cb71d7102 (diff)
MA-6546 Fix PTP transport failure
USB: gadget: mtp: Fix hang in ioctl(MTP_RECEIVE_FILE) for WritePartialObject In receive_file_work, we now queue reads with length rounded up to max packet size rather than mtp_rx_req_len. Otherwise the read request will never complete. Bug: 12195339 Cherry-picked from 0373636d110d37aedfc5d71ea56af61f6bb3b65e Mike Lockwood <lockwood@google.com> Signed-off-by: Haoran Wang <b50027@freescale.com>
-rw-r--r--drivers/usb/gadget/f_mtp.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c
index 620aeaaf2d72..c1c1c748d65e 100644
--- a/drivers/usb/gadget/f_mtp.c
+++ b/drivers/usb/gadget/f_mtp.c
@@ -2,6 +2,7 @@
* Gadget Function Driver for MTP
*
* Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
* Author: Mike Lockwood <lockwood@android.com>
*
* This software is licensed under the terms of the GNU General Public
@@ -68,6 +69,7 @@
#define MTP_RESPONSE_DEVICE_BUSY 0x2019
static const char mtp_shortname[] = "mtp_usb";
+bool isPtp;
struct mtp_dev {
struct usb_function function;
@@ -745,6 +747,7 @@ static void receive_file_work(struct work_struct *data)
int64_t count;
int ret, cur_buf = 0;
int r = 0;
+ int len = 0;
/* read our parameters */
smp_rmb();
@@ -760,8 +763,16 @@ 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);
+ if (isPtp) {
+ len = (count > dev->ep_out->maxpacket ?
+ dev->ep_out->maxpacket : count);
+ if (len > MTP_BULK_BUFFER_SIZE)
+ len = MTP_BULK_BUFFER_SIZE;
+ read_req->length = len;
+ } else {
+ read_req->length = (count > MTP_BULK_BUFFER_SIZE
+ ? MTP_BULK_BUFFER_SIZE : count);
+ }
dev->rx_done = 0;
ret = usb_ep_queue(dev->ep_out, read_req, GFP_KERNEL);
if (ret < 0) {
@@ -789,7 +800,7 @@ static void receive_file_work(struct work_struct *data)
ret = wait_event_interruptible(dev->read_wq,
dev->rx_done || dev->state != STATE_BUSY);
if (dev->state == STATE_CANCELED) {
- r = -ECANCELED;
+ r = -ECANCELED;
if (!dev->rx_done)
usb_ep_dequeue(dev->ep_out, read_req);
break;
@@ -1211,6 +1222,7 @@ static int mtp_bind_config(struct usb_configuration *c, bool ptp_config)
mtp_string_defs[INTERFACE_STRING_INDEX].id = ret;
mtp_interface_desc.iInterface = ret;
}
+ isPtp = ptp_config;
dev->cdev = c->cdev;
dev->function.name = "mtp";