1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (C) 2021 Intel Corporation.
3 * All rights reserved.
4 */
5
6 #ifndef __SGL_INTERNAL_H__
7 #define __SGL_INTERNAL_H__
8
9 #include "spdk/stdinc.h"
10
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14
15 struct spdk_iov_sgl {
16 struct iovec *iov;
17 int iovcnt;
18 uint32_t iov_offset;
19 uint32_t total_size;
20 };
21
22 /**
23 * Initialize struct spdk_iov_sgl with iov, iovcnt and iov_offset.
24 *
25 * \param s the spdk_iov_sgl to be filled.
26 * \param iov the io vector to fill the s
27 * \param iovcnt the size the iov
28 * \param iov_offset the current filled iov_offset for s.
29 */
30
31 static inline void
spdk_iov_sgl_init(struct spdk_iov_sgl * s,struct iovec * iov,int iovcnt,uint32_t iov_offset)32 spdk_iov_sgl_init(struct spdk_iov_sgl *s, struct iovec *iov, int iovcnt,
33 uint32_t iov_offset)
34 {
35 s->iov = iov;
36 s->iovcnt = iovcnt;
37 s->iov_offset = iov_offset;
38 s->total_size = 0;
39 }
40
41 /**
42 * Consume the iovs in spdk_iov_sgl with passed bytes
43 *
44 * \param s the spdk_iov_sgl which contains the iov
45 * \param step the bytes_size consumed.
46 */
47
48 static inline void
spdk_iov_sgl_advance(struct spdk_iov_sgl * s,uint32_t step)49 spdk_iov_sgl_advance(struct spdk_iov_sgl *s, uint32_t step)
50 {
51 s->iov_offset += step;
52 while (s->iovcnt > 0) {
53 assert(s->iov != NULL);
54 if (s->iov_offset < s->iov->iov_len) {
55 break;
56 }
57
58 s->iov_offset -= s->iov->iov_len;
59 s->iov++;
60 s->iovcnt--;
61 }
62 }
63
64 /**
65 * Append the data to the struct spdk_iov_sgl pointed by s
66 *
67 * \param s the address of the struct spdk_iov_sgl
68 * \param data the data buffer to be appended
69 * \param data_len the length of the data.
70 *
71 * \return true if all the data is appended.
72 */
73
74 static inline bool
spdk_iov_sgl_append(struct spdk_iov_sgl * s,uint8_t * data,uint32_t data_len)75 spdk_iov_sgl_append(struct spdk_iov_sgl *s, uint8_t *data, uint32_t data_len)
76 {
77 if (s->iov_offset >= data_len) {
78 s->iov_offset -= data_len;
79 } else {
80 assert(s->iovcnt > 0);
81 s->iov->iov_base = data + s->iov_offset;
82 s->iov->iov_len = data_len - s->iov_offset;
83 s->total_size += data_len - s->iov_offset;
84 s->iov_offset = 0;
85 s->iov++;
86 s->iovcnt--;
87 if (s->iovcnt == 0) {
88 return false;
89 }
90 }
91
92 return true;
93 }
94
95 #ifdef __cplusplus
96 }
97 #endif
98
99 #endif /* __SGL_INTERNAL_H__ */
100