aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@android.com>2011-02-07 11:51:07 -0500
committerMike Lockwood <lockwood@android.com>2011-02-07 11:59:43 -0500
commit7fe4e995ccc36f56acc51ee3a1c392ac23d2a122 (patch)
tree93f4c104c6612ce3b842b5c2e234ba9787831269
parent23b6f13927416ced600e5a27f4d17ba54d857ad9 (diff)
downloadqemu-7fe4e995ccc36f56acc51ee3a1c392ac23d2a122.tar.gz
USB: gadget: f_mtp: Fix problems transferring files from device to host
Exit from send_file_work immediately when a cancel request is received. Only busy status if there is a cancel pending that has not been repoorted to userspace. This avoids a race condition that can occur when mtp_read resets the state to STATE_BUSY before we report status OK back to the host. Signed-off-by: Mike Lockwood <lockwood@android.com>
-rw-r--r--drivers/usb/gadget/f_mtp.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c
index e07224fd9f8..d560fbcf4f5 100644
--- a/drivers/usb/gadget/f_mtp.c
+++ b/drivers/usb/gadget/f_mtp.c
@@ -662,6 +662,10 @@ static void send_file_work(struct work_struct *data) {
ret = wait_event_interruptible(dev->write_wq,
(req = req_get(dev, &dev->tx_idle))
|| dev->state != STATE_BUSY);
+ if (dev->state == STATE_CANCELED) {
+ r = -ECANCELED;
+ break;
+ }
if (!req) {
r = ret;
break;
@@ -1098,14 +1102,13 @@ static int mtp_function_setup(struct usb_function *f,
/* device status is "busy" until we report
* the cancelation to userspace
*/
- if (dev->state == STATE_BUSY
- || dev->state == STATE_CANCELED)
+ if (dev->state == STATE_CANCELED)
status->wCode =
__cpu_to_le16(MTP_RESPONSE_DEVICE_BUSY);
else
status->wCode =
__cpu_to_le16(MTP_RESPONSE_OK);
- spin_unlock_irqrestore(&dev->lock, flags);
+ spin_unlock_irqrestore(&dev->lock, flags);
value = sizeof(*status);
}
}
@@ -1185,7 +1188,7 @@ static void mtp_function_disable(struct usb_function *f)
static int mtp_bind_config(struct usb_configuration *c)
{
struct mtp_dev *dev;
- int ret;
+ int ret = 0;
printk(KERN_INFO "mtp_bind_config\n");