X-Git-Url: http://git.ipfire.org/?p=people%2Fms%2Flinux.git;a=blobdiff_plain;f=drivers%2Finfiniband%2Fhw%2Fqib%2Fqib_mr.c;h=dcabf1b2e263467ca617f846fbe9cf878c2ab7df;hp=19220dcb9a3b2a1ea00e4aed2d87eef09269a92d;hb=38071a461f0a;hpb=8376b86de7d35d43cf1a33a1f43bc015b5a095d9 diff --git a/drivers/infiniband/hw/qib/qib_mr.c b/drivers/infiniband/hw/qib/qib_mr.c index 19220dcb9a3b..dcabf1b2e263 100644 --- a/drivers/infiniband/hw/qib/qib_mr.c +++ b/drivers/infiniband/hw/qib/qib_mr.c @@ -303,6 +303,7 @@ int qib_dereg_mr(struct ib_mr *ibmr) int ret = 0; unsigned long timeout; + kfree(mr->pages); qib_free_lkey(&mr->mr); qib_put_mr(&mr->mr); /* will set completion if last */ @@ -340,7 +341,38 @@ struct ib_mr *qib_alloc_mr(struct ib_pd *pd, if (IS_ERR(mr)) return (struct ib_mr *)mr; + mr->pages = kcalloc(max_num_sg, sizeof(u64), GFP_KERNEL); + if (!mr->pages) + goto err; + return &mr->ibmr; + +err: + qib_dereg_mr(&mr->ibmr); + return ERR_PTR(-ENOMEM); +} + +static int qib_set_page(struct ib_mr *ibmr, u64 addr) +{ + struct qib_mr *mr = to_imr(ibmr); + + if (unlikely(mr->npages == mr->mr.max_segs)) + return -ENOMEM; + + mr->pages[mr->npages++] = addr; + + return 0; +} + +int qib_map_mr_sg(struct ib_mr *ibmr, + struct scatterlist *sg, + int sg_nents) +{ + struct qib_mr *mr = to_imr(ibmr); + + mr->npages = 0; + + return ib_sg_to_pages(ibmr, sg, sg_nents, qib_set_page); } struct ib_fast_reg_page_list *