void mthca_pd_free(struct mthca_dev *dev, struct mthca_pd *pd) { might_sleep(); if (pd->privileged) mthca_free_mr(dev, &pd->ntmr); mthca_free(&dev->pd_table.alloc, pd->pd_num); }
int mthca_destroy_ah(struct mthca_dev *dev, struct mthca_ah *ah) { if (ah->on_hca) mthca_free(&dev->av_table.alloc, (ah->avdma - dev->av_table.ddr_av_base) / MTHCA_AV_SIZE); else pci_pool_free(dev->av_table.pool, ah->av, ah->avdma); return 0; }
void mthca_free_qp(struct mthca_dev *dev, struct mthca_qp *qp) { u8 status; int size; int i; spin_lock_irq(&dev->qp_table.lock); mthca_array_clear(&dev->qp_table.qp, qp->qpn & (dev->limits.num_qps - 1)); spin_unlock_irq(&dev->qp_table.lock); atomic_dec(&qp->refcount); wait_event(qp->wait, !atomic_read(&qp->refcount)); if (qp->state != IB_QPS_RESET) mthca_MODIFY_QP(dev, MTHCA_TRANS_ANY2RST, qp->qpn, 0, NULL, 0, &status); mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq)->cqn, qp->qpn); if (qp->ibqp.send_cq != qp->ibqp.recv_cq) mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq)->cqn, qp->qpn); mthca_free_mr(dev, &qp->mr); size = PAGE_ALIGN(qp->send_wqe_offset + (qp->sq.max << qp->sq.wqe_shift)); if (qp->is_direct) { pci_free_consistent(dev->pdev, size, qp->queue.direct.buf, pci_unmap_addr(&qp->queue.direct, mapping)); } else { for (i = 0; i < size / PAGE_SIZE; ++i) { pci_free_consistent(dev->pdev, PAGE_SIZE, qp->queue.page_list[i].buf, pci_unmap_addr(&qp->queue.page_list[i], mapping)); } } kfree(qp->wrid); if (is_sqp(dev, qp)) { atomic_dec(&(to_mpd(qp->ibqp.pd)->sqp_count)); dma_free_coherent(&dev->pdev->dev, to_msqp(qp)->header_buf_size, to_msqp(qp)->header_buf, to_msqp(qp)->header_dma); } else mthca_free(&dev->qp_table.alloc, qp->qpn); }
int mthca_destroy_ah(struct mthca_dev *dev, struct mthca_ah *ah) { switch (ah->type) { case MTHCA_AH_ON_HCA: mthca_free(&dev->av_table.alloc, (ah->avdma - dev->av_table.ddr_av_base) / MTHCA_AV_SIZE); break; case MTHCA_AH_PCI_POOL: pci_pool_free(dev->av_table.pool, ah->av, ah->avdma); break; case MTHCA_AH_KMALLOC: kfree(ah->av); break; } return 0; }
int mthca_pd_alloc(struct mthca_dev *dev, int privileged, struct mthca_pd *pd) { int err = 0; pd->privileged = privileged; atomic_set(&pd->sqp_count, 0); pd->pd_num = mthca_alloc(&dev->pd_table.alloc); if (pd->pd_num == -1) return -ENOMEM; if (privileged) { err = mthca_mr_alloc_notrans(dev, pd->pd_num, MTHCA_MPT_FLAG_LOCAL_READ | MTHCA_MPT_FLAG_LOCAL_WRITE, &pd->ntmr); if (err) mthca_free(&dev->pd_table.alloc, pd->pd_num); } return err; }
int mthca_alloc_qp(struct mthca_dev *dev, struct mthca_pd *pd, struct mthca_cq *send_cq, struct mthca_cq *recv_cq, enum ib_qp_type type, enum ib_sig_type send_policy, enum ib_sig_type recv_policy, struct mthca_qp *qp) { int err; switch (type) { case IB_QPT_RC: qp->transport = RC; break; case IB_QPT_UC: qp->transport = UC; break; case IB_QPT_UD: qp->transport = UD; break; default: return -EINVAL; } qp->qpn = mthca_alloc(&dev->qp_table.alloc); if (qp->qpn == -1) return -ENOMEM; err = mthca_alloc_qp_common(dev, pd, send_cq, recv_cq, send_policy, recv_policy, qp); if (err) { mthca_free(&dev->qp_table.alloc, qp->qpn); return err; } spin_lock_irq(&dev->qp_table.lock); mthca_array_set(&dev->qp_table.qp, qp->qpn & (dev->limits.num_qps - 1), qp); spin_unlock_irq(&dev->qp_table.lock); return 0; }
void mthca_uar_free(struct mthca_dev *dev, struct mthca_uar *uar) { mthca_free(&dev->uar_table.alloc, uar->index); }