Skip to content

Commit

Permalink
media: cec: core: count low-drive, error and arb-lost conditions
Browse files Browse the repository at this point in the history
Count how many Low Drive, Error and Arbitration Lost transmit
status errors occurred, and expose that in debugfs.

Also log the first 8 transmits that result in Low Drive or Error
conditions. That really should not happen with well-behaved CEC devices
and good HDMI cables.

This is useful to detect and debug HDMI cable issues.

Signed-off-by: Hans Verkuil <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
  • Loading branch information
Hans Verkuil authored and mchehab committed Nov 23, 2023
1 parent bbd267d commit 632b8b0
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 7 deletions.
54 changes: 49 additions & 5 deletions drivers/media/cec/core/cec-adap.c
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ int cec_thread_func(void *_adap)
pr_warn("cec-%s: transmit timed out\n", adap->name);
}
adap->transmit_in_progress = false;
adap->tx_timeouts++;
adap->tx_timeout_cnt++;
goto unlock;
}

Expand Down Expand Up @@ -625,6 +625,33 @@ void cec_transmit_done_ts(struct cec_adapter *adap, u8 status,
msg->tx_low_drive_cnt += low_drive_cnt;
msg->tx_error_cnt += error_cnt;

adap->tx_arb_lost_cnt += arb_lost_cnt;
adap->tx_low_drive_cnt += low_drive_cnt;
adap->tx_error_cnt += error_cnt;

/*
* Low Drive transmission errors should really not happen for
* well-behaved CEC devices and proper HDMI cables.
*
* Ditto for the 'Error' status.
*
* For the first few times that this happens, log this.
* Stop logging after that, since that will not add any more
* useful information and instead it will just flood the kernel log.
*/
if (done && adap->tx_low_drive_log_cnt < 8 && msg->tx_low_drive_cnt) {
adap->tx_low_drive_log_cnt++;
dprintk(0, "low drive counter: %u (seq %u: %*ph)\n",
msg->tx_low_drive_cnt, msg->sequence,
msg->len, msg->msg);
}
if (done && adap->tx_error_log_cnt < 8 && msg->tx_error_cnt) {
adap->tx_error_log_cnt++;
dprintk(0, "error counter: %u (seq %u: %*ph)\n",
msg->tx_error_cnt, msg->sequence,
msg->len, msg->msg);
}

/* Mark that we're done with this transmit */
adap->transmitting = NULL;

Expand Down Expand Up @@ -1607,6 +1634,8 @@ int cec_adap_enable(struct cec_adapter *adap)
if (enable) {
adap->last_initiator = 0xff;
adap->transmit_in_progress = false;
adap->tx_low_drive_log_cnt = 0;
adap->tx_error_log_cnt = 0;
ret = adap->ops->adap_enable(adap, true);
if (!ret) {
/*
Expand Down Expand Up @@ -2265,10 +2294,25 @@ int cec_adap_status(struct seq_file *file, void *priv)
if (adap->monitor_pin_cnt)
seq_printf(file, "file handles in Monitor Pin mode: %u\n",
adap->monitor_pin_cnt);
if (adap->tx_timeouts) {
seq_printf(file, "transmit timeouts: %u\n",
adap->tx_timeouts);
adap->tx_timeouts = 0;
if (adap->tx_timeout_cnt) {
seq_printf(file, "transmit timeout count: %u\n",
adap->tx_timeout_cnt);
adap->tx_timeout_cnt = 0;
}
if (adap->tx_low_drive_cnt) {
seq_printf(file, "transmit low drive count: %u\n",
adap->tx_low_drive_cnt);
adap->tx_low_drive_cnt = 0;
}
if (adap->tx_arb_lost_cnt) {
seq_printf(file, "transmit arbitration lost count: %u\n",
adap->tx_arb_lost_cnt);
adap->tx_arb_lost_cnt = 0;
}
if (adap->tx_error_cnt) {
seq_printf(file, "transmit error count: %u\n",
adap->tx_error_cnt);
adap->tx_error_cnt = 0;
}
data = adap->transmitting;
if (data)
Expand Down
22 changes: 20 additions & 2 deletions include/media/cec.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,20 @@ struct cec_adap_ops {
* passthrough mode.
* @log_addrs: current logical addresses
* @conn_info: current connector info
* @tx_timeouts: number of transmit timeouts
* @tx_timeout_cnt: count the number of Timed Out transmits.
* Reset to 0 when this is reported in cec_adap_status().
* @tx_low_drive_cnt: count the number of Low Drive transmits.
* Reset to 0 when this is reported in cec_adap_status().
* @tx_error_cnt: count the number of Error transmits.
* Reset to 0 when this is reported in cec_adap_status().
* @tx_arb_lost_cnt: count the number of Arb Lost transmits.
* Reset to 0 when this is reported in cec_adap_status().
* @tx_low_drive_log_cnt: number of logged Low Drive transmits since the
* adapter was enabled. Used to avoid flooding the kernel
* log if this happens a lot.
* @tx_error_log_cnt: number of logged Error transmits since the adapter was
* enabled. Used to avoid flooding the kernel log if this
* happens a lot.
* @notifier: CEC notifier
* @pin: CEC pin status struct
* @cec_dir: debugfs cec directory
Expand Down Expand Up @@ -262,7 +275,12 @@ struct cec_adapter {
struct cec_log_addrs log_addrs;
struct cec_connector_info conn_info;

u32 tx_timeouts;
u32 tx_timeout_cnt;
u32 tx_low_drive_cnt;
u32 tx_error_cnt;
u32 tx_arb_lost_cnt;
u32 tx_low_drive_log_cnt;
u32 tx_error_log_cnt;

#ifdef CONFIG_CEC_NOTIFIER
struct cec_notifier *notifier;
Expand Down

0 comments on commit 632b8b0

Please sign in to comment.