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

Commit 67fb4943 authored by Hans Verkuil's avatar Hans Verkuil Committed by Greg Kroah-Hartman
Browse files

media: cec-adap.c: fix is_configuring state



[ Upstream commit 59267fc34f4900dcd2ec3295f6be04b79aee2186 ]

If an adapter is trying to claim a free logical address then it is
in the 'is_configuring' state. If during that process the cable is
disconnected (HPD goes low, which in turn invalidates the physical
address), then cec_adap_unconfigure() is called, and that set the
is_configuring boolean to false, even though the thread that's
trying to claim an LA is still running.

Don't touch the is_configuring bool in cec_adap_unconfigure(), it
will eventually be cleared by the thread. By making that change
the cec_config_log_addr() function also had to change: it was
aborting if is_configuring became false (since that is what
cec_adap_unconfigure() did), but that no longer works. Instead
check if the physical address is invalid. That is a much
more appropriate check anyway.

This fixes a bug where the the adapter could be disabled even
though the device was still configuring. This could cause POLL
transmits to time out.

Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 4172a34e
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -1263,7 +1263,7 @@ static int cec_config_log_addr(struct cec_adapter *adap,
		 * While trying to poll the physical address was reset
		 * and the adapter was unconfigured, so bail out.
		 */
		if (!adap->is_configuring)
		if (adap->phys_addr == CEC_PHYS_ADDR_INVALID)
			return -EINTR;

		if (err)
@@ -1321,7 +1321,6 @@ static void cec_adap_unconfigure(struct cec_adapter *adap)
	    adap->phys_addr != CEC_PHYS_ADDR_INVALID)
		WARN_ON(adap->ops->adap_log_addr(adap, CEC_LOG_ADDR_INVALID));
	adap->log_addrs.log_addr_mask = 0;
	adap->is_configuring = false;
	adap->is_configured = false;
	memset(adap->phys_addrs, 0xff, sizeof(adap->phys_addrs));
	cec_flush(adap);
@@ -1514,9 +1513,10 @@ static int cec_config_thread_func(void *arg)
	for (i = 0; i < las->num_log_addrs; i++)
		las->log_addr[i] = CEC_LOG_ADDR_INVALID;
	cec_adap_unconfigure(adap);
	adap->is_configuring = false;
	adap->kthread_config = NULL;
	mutex_unlock(&adap->lock);
	complete(&adap->config_completion);
	mutex_unlock(&adap->lock);
	return 0;
}