media: cec: core: avoid confusing "transmit timed out" message

If, when waiting for a transmit to finish, the wait is interrupted,
then you might get a "transmit timed out" message, even though the
transmit was interrupted and did not actually time out.

Set transmit_in_progress_aborted to true if the
wait_for_completion_killable() call was interrupted and ensure
that the transmit is properly marked as ABORTED.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Reported-by: Yang, Chenyuan <cy54@illinois.edu>
Closes: https://lore.kernel.org/linux-media/PH7PR11MB57688E64ADE4FE82E658D86DA09EA@PH7PR11MB5768.namprd11.prod.outlook.com/
Fixes: 590a8e564c ("media: cec: abort if the current transmit was canceled")
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
This commit is contained in:
Hans Verkuil 2024-04-30 11:13:47 +01:00 committed by Mauro Carvalho Chehab
parent 47c82aac10
commit cbe499977b

View File

@ -490,6 +490,15 @@ int cec_thread_func(void *_adap)
goto unlock; goto unlock;
} }
if (adap->transmit_in_progress &&
adap->transmit_in_progress_aborted) {
if (adap->transmitting)
cec_data_cancel(adap->transmitting,
CEC_TX_STATUS_ABORTED, 0);
adap->transmit_in_progress = false;
adap->transmit_in_progress_aborted = false;
goto unlock;
}
if (adap->transmit_in_progress && timeout) { if (adap->transmit_in_progress && timeout) {
/* /*
* If we timeout, then log that. Normally this does * If we timeout, then log that. Normally this does
@ -771,6 +780,7 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
{ {
struct cec_data *data; struct cec_data *data;
bool is_raw = msg_is_raw(msg); bool is_raw = msg_is_raw(msg);
int err;
if (adap->devnode.unregistered) if (adap->devnode.unregistered)
return -ENODEV; return -ENODEV;
@ -935,10 +945,13 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
* Release the lock and wait, retake the lock afterwards. * Release the lock and wait, retake the lock afterwards.
*/ */
mutex_unlock(&adap->lock); mutex_unlock(&adap->lock);
wait_for_completion_killable(&data->c); err = wait_for_completion_killable(&data->c);
cancel_delayed_work_sync(&data->work); cancel_delayed_work_sync(&data->work);
mutex_lock(&adap->lock); mutex_lock(&adap->lock);
if (err)
adap->transmit_in_progress_aborted = true;
/* Cancel the transmit if it was interrupted */ /* Cancel the transmit if it was interrupted */
if (!data->completed) { if (!data->completed) {
if (data->msg.tx_status & CEC_TX_STATUS_OK) if (data->msg.tx_status & CEC_TX_STATUS_OK)