1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2 /* Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. */ 3 4 #include <linux/export.h> 5 #include <rdma/iter.h> 6 7 void __rdma_block_iter_start(struct ib_block_iter *biter, 8 struct scatterlist *sglist, unsigned int nents, 9 unsigned long pgsz) 10 { 11 memset(biter, 0, sizeof(struct ib_block_iter)); 12 biter->__sg = sglist; 13 biter->__sg_nents = nents; 14 15 /* Driver provides best block size to use */ 16 biter->__pg_bit = __fls(pgsz); 17 } 18 EXPORT_SYMBOL(__rdma_block_iter_start); 19 20 bool __rdma_block_iter_next(struct ib_block_iter *biter) 21 { 22 unsigned int block_offset; 23 unsigned int delta; 24 25 if (!biter->__sg_nents || !biter->__sg) 26 return false; 27 28 biter->__dma_addr = sg_dma_address(biter->__sg) + biter->__sg_advance; 29 block_offset = biter->__dma_addr & (BIT_ULL(biter->__pg_bit) - 1); 30 delta = BIT_ULL(biter->__pg_bit) - block_offset; 31 32 while (biter->__sg_nents && biter->__sg && 33 sg_dma_len(biter->__sg) - biter->__sg_advance <= delta) { 34 delta -= sg_dma_len(biter->__sg) - biter->__sg_advance; 35 biter->__sg_advance = 0; 36 biter->__sg = sg_next(biter->__sg); 37 biter->__sg_nents--; 38 } 39 biter->__sg_advance += delta; 40 41 return true; 42 } 43 EXPORT_SYMBOL(__rdma_block_iter_next); 44