4 * Copyright (c) Intel Corporation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "spdk/nvme_ocssd.h"
35 #include "nvme_internal.h"
38 spdk_nvme_ocssd_ns_cmd_vector_reset(struct spdk_nvme_ns
*ns
,
39 struct spdk_nvme_qpair
*qpair
,
40 uint64_t *lba_list
, uint32_t num_lbas
,
41 struct spdk_ocssd_chunk_information_entry
*chunk_info
,
42 spdk_nvme_cmd_cb cb_fn
, void *cb_arg
)
44 struct nvme_request
*req
;
45 struct spdk_nvme_cmd
*cmd
;
47 if (!lba_list
|| (num_lbas
== 0) ||
48 (num_lbas
> SPDK_NVME_OCSSD_MAX_LBAL_ENTRIES
)) {
52 req
= nvme_allocate_request_null(qpair
, cb_fn
, cb_arg
);
58 cmd
->opc
= SPDK_OCSSD_OPC_VECTOR_RESET
;
61 if (chunk_info
!= NULL
) {
62 cmd
->mptr
= spdk_vtophys(chunk_info
);
66 * Dword 10 and 11 store a pointer to the list of logical block addresses.
67 * If there is a single entry in the LBA list, the logical block
68 * address should be stored instead.
71 *(uint64_t *)&cmd
->cdw10
= *lba_list
;
73 *(uint64_t *)&cmd
->cdw10
= spdk_vtophys(lba_list
);
76 cmd
->cdw12
= num_lbas
- 1;
78 return nvme_qpair_submit_request(qpair
, req
);
82 _nvme_ocssd_ns_cmd_vector_rw_with_md(struct spdk_nvme_ns
*ns
,
83 struct spdk_nvme_qpair
*qpair
,
84 void *buffer
, void *metadata
,
85 uint64_t *lba_list
, uint32_t num_lbas
,
86 spdk_nvme_cmd_cb cb_fn
, void *cb_arg
,
87 enum spdk_ocssd_io_opcode opc
,
90 struct nvme_request
*req
;
91 struct spdk_nvme_cmd
*cmd
;
92 struct nvme_payload payload
;
93 uint32_t valid_flags
= SPDK_OCSSD_IO_FLAGS_LIMITED_RETRY
;
95 if (io_flags
& ~valid_flags
) {
99 if (!buffer
|| !lba_list
|| (num_lbas
== 0) ||
100 (num_lbas
> SPDK_NVME_OCSSD_MAX_LBAL_ENTRIES
)) {
104 payload
= NVME_PAYLOAD_CONTIG(buffer
, metadata
);
106 req
= nvme_allocate_request(qpair
, &payload
, num_lbas
* ns
->sector_size
, cb_fn
, cb_arg
);
116 * Dword 10 and 11 store a pointer to the list of logical block addresses.
117 * If there is a single entry in the LBA list, the logical block
118 * address should be stored instead.
121 *(uint64_t *)&cmd
->cdw10
= *lba_list
;
123 *(uint64_t *)&cmd
->cdw10
= spdk_vtophys(lba_list
);
126 cmd
->cdw12
= num_lbas
- 1;
127 cmd
->cdw12
|= io_flags
;
129 return nvme_qpair_submit_request(qpair
, req
);
133 spdk_nvme_ocssd_ns_cmd_vector_write_with_md(struct spdk_nvme_ns
*ns
,
134 struct spdk_nvme_qpair
*qpair
,
135 void *buffer
, void *metadata
,
136 uint64_t *lba_list
, uint32_t num_lbas
,
137 spdk_nvme_cmd_cb cb_fn
, void *cb_arg
,
140 return _nvme_ocssd_ns_cmd_vector_rw_with_md(ns
, qpair
, buffer
, metadata
, lba_list
,
141 num_lbas
, cb_fn
, cb_arg
, SPDK_OCSSD_OPC_VECTOR_WRITE
, io_flags
);
145 spdk_nvme_ocssd_ns_cmd_vector_write(struct spdk_nvme_ns
*ns
,
146 struct spdk_nvme_qpair
*qpair
,
148 uint64_t *lba_list
, uint32_t num_lbas
,
149 spdk_nvme_cmd_cb cb_fn
, void *cb_arg
,
152 return _nvme_ocssd_ns_cmd_vector_rw_with_md(ns
, qpair
, buffer
, NULL
, lba_list
,
153 num_lbas
, cb_fn
, cb_arg
, SPDK_OCSSD_OPC_VECTOR_WRITE
, io_flags
);
157 spdk_nvme_ocssd_ns_cmd_vector_read_with_md(struct spdk_nvme_ns
*ns
,
158 struct spdk_nvme_qpair
*qpair
,
159 void *buffer
, void *metadata
,
160 uint64_t *lba_list
, uint32_t num_lbas
,
161 spdk_nvme_cmd_cb cb_fn
, void *cb_arg
,
164 return _nvme_ocssd_ns_cmd_vector_rw_with_md(ns
, qpair
, buffer
, metadata
, lba_list
,
165 num_lbas
, cb_fn
, cb_arg
, SPDK_OCSSD_OPC_VECTOR_READ
, io_flags
);
169 spdk_nvme_ocssd_ns_cmd_vector_read(struct spdk_nvme_ns
*ns
,
170 struct spdk_nvme_qpair
*qpair
,
172 uint64_t *lba_list
, uint32_t num_lbas
,
173 spdk_nvme_cmd_cb cb_fn
, void *cb_arg
,
176 return _nvme_ocssd_ns_cmd_vector_rw_with_md(ns
, qpair
, buffer
, NULL
, lba_list
,
177 num_lbas
, cb_fn
, cb_arg
, SPDK_OCSSD_OPC_VECTOR_READ
, io_flags
);
181 spdk_nvme_ocssd_ns_cmd_vector_copy(struct spdk_nvme_ns
*ns
,
182 struct spdk_nvme_qpair
*qpair
,
183 uint64_t *dst_lba_list
,
184 uint64_t *src_lba_list
,
186 spdk_nvme_cmd_cb cb_fn
, void *cb_arg
,
189 struct nvme_request
*req
;
190 struct spdk_nvme_cmd
*cmd
;
192 uint32_t valid_flags
= SPDK_OCSSD_IO_FLAGS_LIMITED_RETRY
;
194 if (io_flags
& ~valid_flags
) {
198 if (!dst_lba_list
|| !src_lba_list
|| (num_lbas
== 0) ||
199 (num_lbas
> SPDK_NVME_OCSSD_MAX_LBAL_ENTRIES
)) {
203 req
= nvme_allocate_request_null(qpair
, cb_fn
, cb_arg
);
209 cmd
->opc
= SPDK_OCSSD_OPC_VECTOR_COPY
;
213 * Dword 10 and 11 store a pointer to the list of source logical
215 * Dword 14 and 15 store a pointer to the list of destination logical
217 * If there is a single entry in the LBA list, the logical block
218 * address should be stored instead.
221 *(uint64_t *)&cmd
->cdw10
= *src_lba_list
;
222 *(uint64_t *)&cmd
->cdw14
= *dst_lba_list
;
224 *(uint64_t *)&cmd
->cdw10
= spdk_vtophys(src_lba_list
);
225 *(uint64_t *)&cmd
->cdw14
= spdk_vtophys(dst_lba_list
);
228 cmd
->cdw12
= num_lbas
- 1;
229 cmd
->cdw12
|= io_flags
;
231 return nvme_qpair_submit_request(qpair
, req
);