/** * Setup any additional SG pages needed.Inline SG element is setup * at queuing time. */ static bfa_boolean_t bfa_ioim_sge_setup(struct bfa_ioim_s *ioim) { u16 nsgpgs; bfa_assert(ioim->nsges > BFI_SGE_INLINE); /** * allocate SG pages needed */ nsgpgs = BFA_SGPG_NPAGE(ioim->nsges); if (!nsgpgs) return BFA_TRUE; if (bfa_sgpg_malloc(ioim->bfa, &ioim->sgpg_q, nsgpgs) != BFA_STATUS_OK) { bfa_sgpg_wait(ioim->bfa, &ioim->iosp->sgpg_wqe, nsgpgs); return BFA_FALSE; } ioim->nsgpgs = nsgpgs; bfa_ioim_sgpg_setup(ioim); return BFA_TRUE; }
void bfa_sgpg_mfree(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpg) { struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); struct bfa_sgpg_wqe_s *wqe; bfa_trc_fp(bfa, nsgpg); mod->free_sgpgs += nsgpg; bfa_assert(mod->free_sgpgs <= mod->num_sgpgs); bfa_q_enq_q(&mod->sgpg_q, sgpg_q); if (list_empty(&mod->sgpg_wait_q)) return; /** * satisfy as many waiting requests as possible */ do { wqe = bfa_q_first(&mod->sgpg_wait_q); if (mod->free_sgpgs < wqe->nsgpg) nsgpg = mod->free_sgpgs; else nsgpg = wqe->nsgpg; bfa_sgpg_malloc(bfa, &wqe->sgpg_q, nsgpg); wqe->nsgpg -= nsgpg; if (wqe->nsgpg == 0) { list_del(&wqe->qe); wqe->cbfn(wqe->cbarg); } } while (mod->free_sgpgs && !list_empty(&mod->sgpg_wait_q)); }