list_del_init(&data->list);
/* Mark it as an error */
- data->msg.ts = ktime_get_ns();
+ data->msg.tx_ts = ktime_get_ns();
data->msg.tx_status = CEC_TX_STATUS_ERROR |
CEC_TX_STATUS_MAX_RETRIES;
data->attempts = 0;
{
struct cec_data *data;
struct cec_msg *msg;
+ u64 ts = ktime_get_ns();
dprintk(2, "cec_transmit_done %02x\n", status);
mutex_lock(&adap->lock);
/* Drivers must fill in the status! */
WARN_ON(status == 0);
- msg->ts = ktime_get_ns();
+ msg->tx_ts = ts;
msg->tx_status |= status;
msg->tx_arb_lost_cnt += arb_lost_cnt;
msg->tx_nack_cnt += nack_cnt;
/* Mark the message as timed out */
list_del_init(&data->list);
- data->msg.ts = ktime_get_ns();
+ data->msg.rx_ts = ktime_get_ns();
data->msg.rx_status = CEC_RX_STATUS_TIMEOUT;
cec_data_completed(data);
unlock:
if (WARN_ON(!msg->len || msg->len > CEC_MAX_MSG_SIZE))
return;
- mutex_lock(&adap->lock);
- msg->ts = ktime_get_ns();
+ msg->rx_ts = ktime_get_ns();
msg->rx_status = CEC_RX_STATUS_OK;
- msg->tx_status = 0;
msg->sequence = msg->reply = msg->timeout = 0;
+ msg->tx_status = 0;
+ msg->tx_ts = 0;
msg->flags = 0;
+ mutex_lock(&adap->lock);
dprintk(2, "cec_received_msg: %*ph\n", msg->len, msg->msg);
/* Check if this message was for us (directed or broadcast). */
*/
list_for_each_entry(data, &adap->wait_queue, list) {
struct cec_msg *dst = &data->msg;
- u8 dst_reply;
/* Does the command match? */
if ((abort && cmd != dst->msg[1]) ||
continue;
/* We got a reply */
- msg->sequence = dst->sequence;
- msg->tx_status = dst->tx_status;
- dst_reply = dst->reply;
- *dst = *msg;
- dst->reply = dst_reply;
+ memcpy(dst->msg, msg->msg, msg->len);
+ dst->len = msg->len;
+ dst->rx_ts = msg->rx_ts;
+ dst->rx_status = msg->rx_status;
if (abort) {
dst->reply = 0;
dst->rx_status |= CEC_RX_STATUS_FEATURE_ABORT;
/**
* struct cec_msg - CEC message structure.
- * @ts: Timestamp in nanoseconds using CLOCK_MONOTONIC. Set by the
- * driver. It is set when the message transmission has finished
- * and it is set when a message was received.
+ * @tx_ts: Timestamp in nanoseconds using CLOCK_MONOTONIC. Set by the
+ * driver when the message transmission has finished.
+ * @rx_ts: Timestamp in nanoseconds using CLOCK_MONOTONIC. Set by the
+ * driver when the message was received.
* @len: Length in bytes of the message.
* @timeout: The timeout (in ms) that is used to timeout CEC_RECEIVE.
* Set to 0 if you want to wait forever. This timeout can also be
* sent. This can be used to track replies to previously sent
* messages.
* @flags: Set to 0.
- * @rx_status: The message receive status bits. Set by the driver.
- * @tx_status: The message transmit status bits. Set by the driver.
* @msg: The message payload.
* @reply: This field is ignored with CEC_RECEIVE and is only used by
* CEC_TRANSMIT. If non-zero, then wait for a reply with this
* broadcast, then -EINVAL is returned.
* if reply is non-zero, then timeout is set to 1000 (the required
* maximum response time).
+ * @rx_status: The message receive status bits. Set by the driver.
+ * @tx_status: The message transmit status bits. Set by the driver.
* @tx_arb_lost_cnt: The number of 'Arbitration Lost' events. Set by the driver.
* @tx_nack_cnt: The number of 'Not Acknowledged' events. Set by the driver.
* @tx_low_drive_cnt: The number of 'Low Drive Detected' events. Set by the
* @tx_error_cnt: The number of 'Error' events. Set by the driver.
*/
struct cec_msg {
- __u64 ts;
+ __u64 tx_ts;
+ __u64 rx_ts;
__u32 len;
__u32 timeout;
__u32 sequence;
__u32 flags;
- __u8 rx_status;
- __u8 tx_status;
__u8 msg[CEC_MAX_MSG_SIZE];
__u8 reply;
+ __u8 rx_status;
+ __u8 tx_status;
__u8 tx_arb_lost_cnt;
__u8 tx_nack_cnt;
__u8 tx_low_drive_cnt;