diff options
-rw-r--r-- | drivers/infiniband/core/umem.c | 34 | ||||
-rw-r--r-- | include/rdma/ib_umem.h | 2 |
2 files changed, 36 insertions, 0 deletions
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index e0f883292374..6f152628e0d2 100644 --- a/drivers/infiniband/core/umem.c +++ b/drivers/infiniband/core/umem.c | |||
@@ -292,3 +292,37 @@ int ib_umem_page_count(struct ib_umem *umem) | |||
292 | return n; | 292 | return n; |
293 | } | 293 | } |
294 | EXPORT_SYMBOL(ib_umem_page_count); | 294 | EXPORT_SYMBOL(ib_umem_page_count); |
295 | |||
296 | /* | ||
297 | * Copy from the given ib_umem's pages to the given buffer. | ||
298 | * | ||
299 | * umem - the umem to copy from | ||
300 | * offset - offset to start copying from | ||
301 | * dst - destination buffer | ||
302 | * length - buffer length | ||
303 | * | ||
304 | * Returns 0 on success, or an error code. | ||
305 | */ | ||
306 | int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offset, | ||
307 | size_t length) | ||
308 | { | ||
309 | size_t end = offset + length; | ||
310 | int ret; | ||
311 | |||
312 | if (offset > umem->length || length > umem->length - offset) { | ||
313 | pr_err("ib_umem_copy_from not in range. offset: %zd umem length: %zd end: %zd\n", | ||
314 | offset, umem->length, end); | ||
315 | return -EINVAL; | ||
316 | } | ||
317 | |||
318 | ret = sg_pcopy_to_buffer(umem->sg_head.sgl, umem->nmap, dst, length, | ||
319 | offset + ib_umem_offset(umem)); | ||
320 | |||
321 | if (ret < 0) | ||
322 | return ret; | ||
323 | else if (ret != length) | ||
324 | return -EINVAL; | ||
325 | else | ||
326 | return 0; | ||
327 | } | ||
328 | EXPORT_SYMBOL(ib_umem_copy_from); | ||
diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h index 7ed6d4ff58dc..45bb04bc88cd 100644 --- a/include/rdma/ib_umem.h +++ b/include/rdma/ib_umem.h | |||
@@ -84,6 +84,8 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, | |||
84 | size_t size, int access, int dmasync); | 84 | size_t size, int access, int dmasync); |
85 | void ib_umem_release(struct ib_umem *umem); | 85 | void ib_umem_release(struct ib_umem *umem); |
86 | int ib_umem_page_count(struct ib_umem *umem); | 86 | int ib_umem_page_count(struct ib_umem *umem); |
87 | int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offset, | ||
88 | size_t length); | ||
87 | 89 | ||
88 | #else /* CONFIG_INFINIBAND_USER_MEM */ | 90 | #else /* CONFIG_INFINIBAND_USER_MEM */ |
89 | 91 | ||