staticint nfp_ccm_alloc_tag(struct nfp_ccm *ccm)
{ /* CCM is for FW communication which is request-reply. To make sure * we don't reuse the message ID too early after timeout - limit the * number of requests in flight.
*/ if (unlikely(nfp_ccm_all_tags_busy(ccm))) {
ccm_warn(ccm->app, "all FW request contexts busy!\n"); return -EAGAIN;
}
nfp_ctrl_lock(app->ctrl);
skb = __nfp_ccm_reply(ccm, tag); if (!skb)
nfp_ccm_free_tag(ccm, tag);
nfp_ctrl_unlock(app->ctrl);
return skb;
}
staticstruct sk_buff *
nfp_ccm_wait_reply(struct nfp_ccm *ccm, struct nfp_app *app, enum nfp_ccm_type type, int tag)
{ struct sk_buff *skb; int i, err;
for (i = 0; i < 50; i++) {
udelay(4);
skb = nfp_ccm_reply(ccm, app, tag); if (skb) return skb;
}
err = wait_event_interruptible_timeout(ccm->wq,
skb = nfp_ccm_reply(ccm, app,
tag),
msecs_to_jiffies(5000)); /* We didn't get a response - try last time and atomically drop * the tag even if no response is matched.
*/ if (!skb)
skb = nfp_ccm_reply_drop_tag(ccm, app, tag); if (err < 0) {
ccm_warn(app, "%s waiting for response to 0x%02x: %d\n",
err == ERESTARTSYS ? "interrupted" : "error",
type, err); return ERR_PTR(err);
} if (!skb) {
ccm_warn(app, "timeout waiting for response to 0x%02x\n", type); return ERR_PTR(-ETIMEDOUT);
}
if (unlikely(skb->len < sizeof(struct nfp_ccm_hdr))) {
ccm_warn(app, "cmsg drop - too short %d!\n", skb->len); goto err_free;
}
nfp_ctrl_lock(app->ctrl);
tag = nfp_ccm_get_tag(skb); if (unlikely(!test_bit(tag, ccm->tag_allocator))) {
ccm_warn(app, "cmsg drop - no one is waiting for tag %u!\n",
tag); goto err_unlock;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.