USB: f_mtp: Fix corner cases in MTP driver while syncing

Currently if USB composition switch happens while file transfer is
happening either from/to device, ep_queue fails and sets device state
to ERROR even if device state is already set to OFFLINE in function
disable call.

As part of ioctl call, if the state is not offline, moving the device
state to READY and returning the error. Since the device state is marked
as READY, the next write call tries to queue the request to hardware and
is blocked and due to this, userspace is not calling the release function.
Hence next mtp open fails even after cable reconnection.

Signed-off-by: Vijayavardhan Vennapusa <vvreddy@codeaurora.org>
Change-Id: Ia8cbd1cd8c81b90389900b83744b2bed89068db5
Signed-off-by: Hemant Kumar <hemantk@codeaurora.org>
This commit is contained in:
Hemant Kumar 2016-05-01 22:15:04 -07:00 committed by Kyle Yan
parent ac86aea5ab
commit 3f0f67e028

View file

@ -780,7 +780,8 @@ static void send_file_work(struct work_struct *data)
ret = usb_ep_queue(dev->ep_in, req, GFP_KERNEL);
if (ret < 0) {
DBG(cdev, "send_file_work: xfer error %d\n", ret);
dev->state = STATE_ERROR;
if (dev->state != STATE_OFFLINE)
dev->state = STATE_ERROR;
r = -EIO;
break;
}
@ -837,7 +838,8 @@ static void receive_file_work(struct work_struct *data)
ret = usb_ep_queue(dev->ep_out, read_req, GFP_KERNEL);
if (ret < 0) {
r = -EIO;
dev->state = STATE_ERROR;
if (dev->state != STATE_OFFLINE)
dev->state = STATE_ERROR;
break;
}
}
@ -849,7 +851,8 @@ static void receive_file_work(struct work_struct *data)
DBG(cdev, "vfs_write %d\n", ret);
if (ret != write_req->actual) {
r = -EIO;
dev->state = STATE_ERROR;
if (dev->state != STATE_OFFLINE)
dev->state = STATE_ERROR;
break;
}
write_req = NULL;