in stm/p_sys-t.c [287:356]
static ssize_t sys_t_write(struct stm_data *data, struct stm_output *output,
unsigned int chan, const char *buf, size_t count)
{
struct sys_t_output *op = output->pdrv_private;
unsigned int c = output->channel + chan;
unsigned int m = output->master;
const unsigned char nil = 0;
u32 header = DATA_HEADER;
u8 uuid[UUID_SIZE];
ssize_t sz;
/* We require an existing policy node to proceed */
if (!op)
return -EINVAL;
if (sys_t_need_clock_sync(op)) {
sz = sys_t_clock_sync(data, m, c);
if (sz <= 0)
return sz;
}
if (op->node.do_len)
header |= MIPI_SYST_OPT_LEN;
if (sys_t_need_ts(op))
header |= MIPI_SYST_OPT_TS;
/*
* STP framing rules for SyS-T frames:
* * the first packet of the SyS-T frame is timestamped;
* * the last packet is a FLAG.
*/
/* Message layout: HEADER / GUID / [LENGTH /][TIMESTAMP /] DATA */
/* HEADER */
sz = data->packet(data, m, c, STP_PACKET_DATA, STP_PACKET_TIMESTAMPED,
4, (u8 *)&header);
if (sz <= 0)
return sz;
/* GUID */
export_uuid(uuid, &op->node.uuid);
sz = stm_data_write(data, m, c, false, uuid, sizeof(op->node.uuid));
if (sz <= 0)
return sz;
/* [LENGTH] */
if (op->node.do_len) {
u16 length = count;
sz = data->packet(data, m, c, STP_PACKET_DATA, 0, 2,
(u8 *)&length);
if (sz <= 0)
return sz;
}
/* [TIMESTAMP] */
if (header & MIPI_SYST_OPT_TS) {
u64 ts = ktime_get_real_ns();
sz = stm_data_write(data, m, c, false, &ts, sizeof(ts));
if (sz <= 0)
return sz;
}
/* DATA */
sz = stm_data_write(data, m, c, false, buf, count);
if (sz > 0)
data->packet(data, m, c, STP_PACKET_FLAG, 0, 0, &nil);
return sz;
}