In the (very) small print of the REPORT_CURRENT_LATENCY message there is a line that says that the last byte of the message (audio out delay) is only present if the 'audio out compensated' value is 3. I missed this, and so if this message was sent with a total length of 6 (i.e. without the audio out delay byte), then it was rejected by the framework since a minimum length of 7 was expected. Fix this minimum length check and update the wrappers in cec-funcs.h to do the right thing based on the message length.
Showing the changes to include/uapi/linux (1 of 2 files). Show all
Unified · Split
| @@ -1665,14 +1665,15 @@ static inline void cec_msg_report_current_latency(struct cec_msg *msg, · 1664 unmodified lines | |||
| 1665 | __u8 audio_out_compensated, | 1665 | __u8 audio_out_compensated, |
| 1666 | __u8 audio_out_delay) | 1666 | __u8 audio_out_delay) |
| 1667 | { | 1667 | { |
| 1668 | msg->len = 7; | 1668 | msg->len = 6; |
| 1669 | msg->msg[0] |= 0xf; /* broadcast */ | 1669 | msg->msg[0] |= 0xf; /* broadcast */ |
| 1670 | msg->msg[1] = CEC_MSG_REPORT_CURRENT_LATENCY; | 1670 | msg->msg[1] = CEC_MSG_REPORT_CURRENT_LATENCY; |
| 1671 | msg->msg[2] = phys_addr >> 8; | 1671 | msg->msg[2] = phys_addr >> 8; |
| 1672 | msg->msg[3] = phys_addr & 0xff; | 1672 | msg->msg[3] = phys_addr & 0xff; |
| 1673 | msg->msg[4] = video_latency; | 1673 | msg->msg[4] = video_latency; |
| 1674 | msg->msg[5] = (low_latency_mode << 2) | audio_out_compensated; | 1674 | msg->msg[5] = (low_latency_mode << 2) | audio_out_compensated; |
| 1675 | msg->msg[6] = audio_out_delay; | 1675 | if (audio_out_compensated == 3) |
| 1676 | msg->msg[msg->len++] = audio_out_delay; | ||
| 1676 | } | 1677 | } |
| 1677 | 1678 | ||
| 1678 | static inline void cec_ops_report_current_latency(const struct cec_msg *msg, | 1679 | static inline void cec_ops_report_current_latency(const struct cec_msg *msg, |
| @@ -1686,7 +1687,10 @@ static inline void cec_ops_report_current_latency(const struct cec_msg *msg, · 7 unmodified lines | |||
| 1686 | *video_latency = msg->msg[4]; | 1687 | *video_latency = msg->msg[4]; |
| 1687 | *low_latency_mode = (msg->msg[5] >> 2) & 1; | 1688 | *low_latency_mode = (msg->msg[5] >> 2) & 1; |
| 1688 | *audio_out_compensated = msg->msg[5] & 3; | 1689 | *audio_out_compensated = msg->msg[5] & 3; |
| 1689 | *audio_out_delay = msg->msg[6]; | 1690 | if (*audio_out_compensated == 3 && msg->len >= 7) |
| 1691 | *audio_out_delay = msg->msg[6]; | ||
| 1692 | else | ||
| 1693 | *audio_out_delay = 0; | ||
| 1690 | } | 1694 | } |
| 1691 | 1695 | ||
| 1692 | static inline void cec_msg_request_current_latency(struct cec_msg *msg, | 1696 | static inline void cec_msg_request_current_latency(struct cec_msg *msg, |