From 55623b4169056d7bb493d1c6f715991f8db67302 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 10 Oct 2018 07:12:15 -0400 Subject: media: cec: check for non-OK/NACK conditions while claiming a LA During the configuration phase of a CEC adapter it is trying to claim a free logical address by polling. However, the code doesn't check if there were errors other than OK or NACK, those are just treated as if the poll was NACKed. Instead check for such errors and retry the poll. And if the problem persists then don't claim this LA since there is something weird going on. Signed-off-by: Hans Verkuil Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-adap.c | 47 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 10 deletions(-) (limited to 'drivers/media/cec/cec-adap.c') diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index 31d1f4ab915e..6fcd575e1b88 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -1180,6 +1180,8 @@ static int cec_config_log_addr(struct cec_adapter *adap, { struct cec_log_addrs *las = &adap->log_addrs; struct cec_msg msg = { }; + const unsigned int max_retries = 2; + unsigned int i; int err; if (cec_has_log_addr(adap, log_addr)) @@ -1188,19 +1190,44 @@ static int cec_config_log_addr(struct cec_adapter *adap, /* Send poll message */ msg.len = 1; msg.msg[0] = (log_addr << 4) | log_addr; - err = cec_transmit_msg_fh(adap, &msg, NULL, true); - /* - * While trying to poll the physical address was reset - * and the adapter was unconfigured, so bail out. - */ - if (!adap->is_configuring) - return -EINTR; + for (i = 0; i < max_retries; i++) { + err = cec_transmit_msg_fh(adap, &msg, NULL, true); - if (err) - return err; + /* + * While trying to poll the physical address was reset + * and the adapter was unconfigured, so bail out. + */ + if (!adap->is_configuring) + return -EINTR; + + if (err) + return err; - if (msg.tx_status & CEC_TX_STATUS_OK) + /* + * The message was aborted due to a disconnect or + * unconfigure, just bail out. + */ + if (msg.tx_status & CEC_TX_STATUS_ABORTED) + return -EINTR; + if (msg.tx_status & CEC_TX_STATUS_OK) + return 0; + if (msg.tx_status & CEC_TX_STATUS_NACK) + break; + /* + * Retry up to max_retries times if the message was neither + * OKed or NACKed. This can happen due to e.g. a Lost + * Arbitration condition. + */ + } + + /* + * If we are unable to get an OK or a NACK after max_retries attempts + * (and note that each attempt already consists of four polls), then + * then we assume that something is really weird and that it is not a + * good idea to try and claim this logical address. + */ + if (i == max_retries) return 0; /* -- cgit v1.2.3 From 2efaf6ebb34fe66c613e94c6e97ae95879455bc3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 11 Oct 2018 06:38:27 -0400 Subject: media: cec: increase debug level for 'queue full' The "transmit queue full" message doesn't warrant debug level 1 since it is already clear from the error code what's going on. Bump to level 2. Signed-off-by: Hans Verkuil Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-adap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/cec/cec-adap.c') diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index 6fcd575e1b88..65a933a21e68 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -807,7 +807,7 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, } if (adap->transmit_queue_sz >= CEC_MAX_MSG_TX_QUEUE_SZ) { - dprintk(1, "%s: transmit queue full\n", __func__); + dprintk(2, "%s: transmit queue full\n", __func__); return -EBUSY; } -- cgit v1.2.3