IB/core: Add passing an offset into the SG to ib_map_mr_sg
[cascardo/linux.git] / drivers / infiniband / core / verbs.c
index b65b354..73fa9da 100644 (file)
@@ -1597,6 +1597,7 @@ EXPORT_SYMBOL(ib_set_vf_guid);
  * @mr:            memory region
  * @sg:            dma mapped scatterlist
  * @sg_nents:      number of entries in sg
+ * @sg_offset:     offset in bytes into sg
  * @page_size:     page vector desired page size
  *
  * Constraints:
@@ -1615,17 +1616,15 @@ EXPORT_SYMBOL(ib_set_vf_guid);
  * After this completes successfully, the  memory region
  * is ready for registration.
  */
-int ib_map_mr_sg(struct ib_mr *mr,
-                struct scatterlist *sg,
-                int sg_nents,
-                unsigned int page_size)
+int ib_map_mr_sg(struct ib_mr *mr, struct scatterlist *sg, int sg_nents,
+               unsigned int sg_offset, unsigned int page_size)
 {
        if (unlikely(!mr->device->map_mr_sg))
                return -ENOSYS;
 
        mr->page_size = page_size;
 
-       return mr->device->map_mr_sg(mr, sg, sg_nents);
+       return mr->device->map_mr_sg(mr, sg, sg_nents, sg_offset);
 }
 EXPORT_SYMBOL(ib_map_mr_sg);
 
@@ -1635,6 +1634,7 @@ EXPORT_SYMBOL(ib_map_mr_sg);
  * @mr:            memory region
  * @sgl:           dma mapped scatterlist
  * @sg_nents:      number of entries in sg
+ * @sg_offset:     offset in bytes into sg
  * @set_page:      driver page assignment function pointer
  *
  * Core service helper for drivers to convert the largest
@@ -1645,10 +1645,8 @@ EXPORT_SYMBOL(ib_map_mr_sg);
  * Returns the number of sg elements that were assigned to
  * a page vector.
  */
-int ib_sg_to_pages(struct ib_mr *mr,
-                  struct scatterlist *sgl,
-                  int sg_nents,
-                  int (*set_page)(struct ib_mr *, u64))
+int ib_sg_to_pages(struct ib_mr *mr, struct scatterlist *sgl, int sg_nents,
+               unsigned int sg_offset, int (*set_page)(struct ib_mr *, u64))
 {
        struct scatterlist *sg;
        u64 last_end_dma_addr = 0;
@@ -1656,12 +1654,12 @@ int ib_sg_to_pages(struct ib_mr *mr,
        u64 page_mask = ~((u64)mr->page_size - 1);
        int i, ret;
 
-       mr->iova = sg_dma_address(&sgl[0]);
+       mr->iova = sg_dma_address(&sgl[0]) + sg_offset;
        mr->length = 0;
 
        for_each_sg(sgl, sg, sg_nents, i) {
-               u64 dma_addr = sg_dma_address(sg);
-               unsigned int dma_len = sg_dma_len(sg);
+               u64 dma_addr = sg_dma_address(sg) + sg_offset;
+               unsigned int dma_len = sg_dma_len(sg) - sg_offset;
                u64 end_dma_addr = dma_addr + dma_len;
                u64 page_addr = dma_addr & page_mask;
 
@@ -1694,6 +1692,8 @@ next_page:
                mr->length += dma_len;
                last_end_dma_addr = end_dma_addr;
                last_page_off = end_dma_addr & ~page_mask;
+
+               sg_offset = 0;
        }
 
        return i;