Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b0d8bfa8 authored by Arumuga Durai A's avatar Arumuga Durai A
Browse files

USB: gadget: ffs: Fix USBCV compliance failure due to adbd



Userspace f_fs client e.g. ADB daemon can re-open ep0 file node
on adb_read/write error (or on bus reset). This results in device
disabling and enabling pull-up on bus reset. USBCV CH9 tests which
perform bus resets also fail due to this.
Fix this by not failing adb_read on bus reset so that adbd client
woudln't attempt ep0-file close. This behavior is not changed for
composition switch or cable disconnect by checking if adb_read
was attempting first transfer after online state or it was in middle
of a session when disconnect happened.

CRs-Fixed: 1083414
Change-Id: I2378f22995b7ddffb17d618df059d8aedb594d97
Signed-off-by: default avatarArumuga Durai A <cadurai@codeaurora.org>
parent da2b3bff
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -715,10 +715,13 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
	ssize_t ret, data_len = -EINVAL;
	int halt;
	size_t extra_buf_alloc = 0;
	bool first_read = false;

	pr_debug("%s: len %zu, read %d\n", __func__, io_data->len,
			io_data->read);

retry:
	first_read = false;
	if (atomic_read(&epfile->error))
		return -ENODEV;

@@ -752,6 +755,11 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
			if (ret < 0)
				goto error;
		}
		/*
		 * set if function eps are not enabled for the first
		 * epfile_read
		 */
		first_read = true;
		if (!ep) {
			ret = -ENODEV;
			goto error;
@@ -941,6 +949,18 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
					ret = ep->status;
				else
					ret = -ENODEV;
				/* do wait again if func eps are not enabled */
				if (io_data->read && first_read && (ret < 0)) {
					pr_debug("%s: waiting for the online state\n",
						 __func__);
					ret = 0;
					kfree(data);
					spin_unlock_irq(&epfile->ffs->eps_lock);
					mutex_unlock(&epfile->mutex);
					atomic_set(&epfile->error, 0);
					goto retry;
				}

				spin_unlock_irq(&epfile->ffs->eps_lock);

				if (io_data->read && ret > 0) {