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.

CRs-Fixed: 360409
Signed-off-by: Vijayavardhan Vennapusa <vvreddy@codeaurora.org>
Change-Id: Ia8cbd1cd8c81b90389900b83744b2bed89068db5
This commit is contained in:
Vijayavardhan Vennapusa 2012-05-18 11:18:40 +05:30 committed by Stephen Boyd
parent 925c40c1e6
commit 4c2551325e

View file

@ -710,7 +710,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;
}
@ -763,7 +764,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;
}
}
@ -775,7 +777,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;