in qcom_glink_native.c [322:368]
static int qcom_glink_tx(struct qcom_glink *glink,
const void *hdr, size_t hlen,
const void *data, size_t dlen, bool wait)
{
unsigned int tlen = hlen + dlen;
unsigned long flags;
int ret = 0;
/* Reject packets that are too big */
if (tlen >= glink->tx_pipe->length)
return -EINVAL;
spin_lock_irqsave(&glink->tx_lock, flags);
while (qcom_glink_tx_avail(glink) < tlen) {
if (!wait) {
ret = -EAGAIN;
goto out;
}
if (!glink->sent_read_notify) {
glink->sent_read_notify = true;
qcom_glink_send_read_notify(glink);
}
/* Wait without holding the tx_lock */
spin_unlock_irqrestore(&glink->tx_lock, flags);
wait_event_timeout(glink->tx_avail_notify,
qcom_glink_tx_avail(glink) >= tlen, 10 * HZ);
spin_lock_irqsave(&glink->tx_lock, flags);
if (qcom_glink_tx_avail(glink) >= tlen)
glink->sent_read_notify = false;
}
qcom_glink_tx_write(glink, hdr, hlen, data, dlen);
mbox_send_message(glink->mbox_chan, NULL);
mbox_client_txdone(glink->mbox_chan, 0);
out:
spin_unlock_irqrestore(&glink->tx_lock, flags);
return ret;
}