in master/svc-i3c-master.c [1200:1246]
static int svc_i3c_master_send_direct_ccc_cmd(struct svc_i3c_master *master,
struct i3c_ccc_cmd *ccc)
{
unsigned int xfer_len = ccc->dests[0].payload.len;
unsigned int read_len = ccc->rnw ? xfer_len : 0;
struct svc_i3c_xfer *xfer;
struct svc_i3c_cmd *cmd;
int ret;
xfer = svc_i3c_master_alloc_xfer(master, 2);
if (!xfer)
return -ENOMEM;
xfer->type = SVC_I3C_MCTRL_TYPE_I3C;
/* Broadcasted message */
cmd = &xfer->cmds[0];
cmd->addr = I3C_BROADCAST_ADDR;
cmd->rnw = 0;
cmd->in = NULL;
cmd->out = &ccc->id;
cmd->len = 1;
cmd->read_len = 0;
cmd->continued = true;
/* Directed message */
cmd = &xfer->cmds[1];
cmd->addr = ccc->dests[0].addr;
cmd->rnw = ccc->rnw;
cmd->in = ccc->rnw ? ccc->dests[0].payload.data : NULL;
cmd->out = ccc->rnw ? NULL : ccc->dests[0].payload.data,
cmd->len = xfer_len;
cmd->read_len = read_len;
cmd->continued = false;
svc_i3c_master_enqueue_xfer(master, xfer);
if (!wait_for_completion_timeout(&xfer->comp, msecs_to_jiffies(1000)))
svc_i3c_master_dequeue_xfer(master, xfer);
if (cmd->read_len != xfer_len)
ccc->dests[0].payload.len = cmd->read_len;
ret = xfer->ret;
svc_i3c_master_free_xfer(xfer);
return ret;
}