in qcom-ctrl.c [325:387]
static int qcom_xfer_msg(struct slim_controller *sctrl,
struct slim_msg_txn *txn)
{
struct qcom_slim_ctrl *ctrl = dev_get_drvdata(sctrl->dev);
DECLARE_COMPLETION_ONSTACK(done);
void *pbuf = slim_alloc_txbuf(ctrl, txn, &done);
unsigned long ms = txn->rl + HZ;
u8 *puc;
int ret = 0, timeout, retries = QCOM_BUF_ALLOC_RETRIES;
u8 la = txn->la;
u32 *head;
/* HW expects length field to be excluded */
txn->rl--;
/* spin till buffer is made available */
if (!pbuf) {
while (retries--) {
usleep_range(10000, 15000);
pbuf = slim_alloc_txbuf(ctrl, txn, &done);
if (pbuf)
break;
}
}
if (retries < 0 && !pbuf)
return -ENOMEM;
puc = (u8 *)pbuf;
head = (u32 *)pbuf;
if (txn->dt == SLIM_MSG_DEST_LOGICALADDR) {
*head = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt,
txn->mc, 0, la);
puc += 3;
} else {
*head = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt,
txn->mc, 1, la);
puc += 2;
}
if (slim_tid_txn(txn->mt, txn->mc))
*(puc++) = txn->tid;
if (slim_ec_txn(txn->mt, txn->mc)) {
*(puc++) = (txn->ec & 0xFF);
*(puc++) = (txn->ec >> 8) & 0xFF;
}
if (txn->msg && txn->msg->wbuf)
memcpy(puc, txn->msg->wbuf, txn->msg->num_bytes);
qcom_slim_queue_tx(ctrl, head, txn->rl, MGR_TX_MSG);
timeout = wait_for_completion_timeout(&done, msecs_to_jiffies(ms));
if (!timeout) {
dev_err(ctrl->dev, "TX timed out:MC:0x%x,mt:0x%x", txn->mc,
txn->mt);
ret = -ETIMEDOUT;
}
return ret;
}