xref: /spdk/test/unit/lib/nvmf/ctrlr_bdev.c/ctrlr_bdev_ut.c (revision 2e10c84c822790902c20cbe1ae21fdaeff91a220)
1488570ebSJim Harris /*   SPDX-License-Identifier: BSD-3-Clause
2a6dbe372Spaul luse  *   Copyright (C) 2017 Intel Corporation.
3f6e62d2cSBen Walker  *   All rights reserved.
4d03b31c6SEvgeniy Kochetov  *   Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
5f6e62d2cSBen Walker  */
6f6e62d2cSBen Walker 
7f6e62d2cSBen Walker #include "spdk/stdinc.h"
8f6e62d2cSBen Walker 
9ae431e31SKonrad Sztyber #include "spdk_internal/cunit.h"
10f6e62d2cSBen Walker 
11824bf663SShuhei Matsumoto #include "spdk_internal/mock.h"
125fc0475cSJiewei Ke #include "thread/thread_internal.h"
13824bf663SShuhei Matsumoto 
1429eb9567SJim Harris #include "nvmf/ctrlr_bdev.c"
15f6e62d2cSBen Walker 
16980a1396SMao Jiang #include "spdk/bdev_module.h"
17f6e62d2cSBen Walker 
182172c432STomasz Zawadzki SPDK_LOG_REGISTER_COMPONENT(nvmf)
19f6e62d2cSBen Walker 
20824bf663SShuhei Matsumoto DEFINE_STUB(spdk_nvmf_request_complete, int, (struct spdk_nvmf_request *req), -1);
21f6e62d2cSBen Walker 
22824bf663SShuhei Matsumoto DEFINE_STUB(spdk_bdev_get_name, const char *, (const struct spdk_bdev *bdev), "test");
23f6e62d2cSBen Walker 
246cebe9d0SSwapnil Ingle DEFINE_STUB(spdk_bdev_get_physical_block_size, uint32_t,
256cebe9d0SSwapnil Ingle 	    (const struct spdk_bdev *bdev), 4096);
266cebe9d0SSwapnil Ingle 
273b461269SNick Connolly DEFINE_STUB(nvmf_ctrlr_process_admin_cmd, int, (struct spdk_nvmf_request *req), 0);
283b461269SNick Connolly 
293b461269SNick Connolly DEFINE_STUB(spdk_bdev_comparev_blocks, int, (struct spdk_bdev_desc *desc,
303b461269SNick Connolly 		struct spdk_io_channel *ch, struct iovec *iov, int iovcnt,
313b461269SNick Connolly 		uint64_t offset_blocks, uint64_t num_blocks,
323b461269SNick Connolly 		spdk_bdev_io_completion_cb cb, void *cb_arg), 0);
333b461269SNick Connolly 
346f3b59beSJacek Kalwas DEFINE_STUB(spdk_bdev_readv_blocks_ext, int, (struct spdk_bdev_desc *desc,
356f3b59beSJacek Kalwas 		struct spdk_io_channel *ch, struct iovec *iov, int iovcnt, uint64_t offset_blocks,
366f3b59beSJacek Kalwas 		uint64_t num_blocks, spdk_bdev_io_completion_cb cb, void *cb_arg,
376f3b59beSJacek Kalwas 		struct spdk_bdev_ext_io_opts *opts), 0);
386f3b59beSJacek Kalwas 
396f3b59beSJacek Kalwas DEFINE_STUB(spdk_bdev_writev_blocks_ext, int, (struct spdk_bdev_desc *desc,
406f3b59beSJacek Kalwas 		struct spdk_io_channel *ch, struct iovec *iov, int iovcnt, uint64_t offset_blocks,
416f3b59beSJacek Kalwas 		uint64_t num_blocks, spdk_bdev_io_completion_cb cb, void *cb_arg,
426f3b59beSJacek Kalwas 		struct spdk_bdev_ext_io_opts *opts), 0);
436f3b59beSJacek Kalwas 
443b461269SNick Connolly DEFINE_STUB(spdk_bdev_nvme_admin_passthru, int,
453b461269SNick Connolly 	    (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
463b461269SNick Connolly 	     const struct spdk_nvme_cmd *cmd, void *buf, size_t nbytes,
473b461269SNick Connolly 	     spdk_bdev_io_completion_cb cb, void *cb_arg), 0);
483b461269SNick Connolly 
493b461269SNick Connolly DEFINE_STUB(spdk_bdev_abort, int,
503b461269SNick Connolly 	    (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
513b461269SNick Connolly 	     void *bio_cb_arg, spdk_bdev_io_completion_cb cb, void *cb_arg), 0);
523b461269SNick Connolly 
535818b42fSmatthewb DEFINE_STUB_V(spdk_bdev_io_get_iovec,
545818b42fSmatthewb 	      (struct spdk_bdev_io *bdev_io, struct iovec **iovp, int *iovcntp));
55fed1f52bSArtur Paszkiewicz DEFINE_STUB(spdk_bdev_get_write_unit_size, uint32_t, (const struct spdk_bdev *bdev), 1);
565818b42fSmatthewb 
57b09de013SShuhei Matsumoto struct spdk_bdev_desc {
58b09de013SShuhei Matsumoto 	struct spdk_bdev *bdev;
59b09de013SShuhei Matsumoto };
60b09de013SShuhei Matsumoto 
61980a1396SMao Jiang uint32_t
62980a1396SMao Jiang spdk_bdev_get_optimal_io_boundary(const struct spdk_bdev *bdev)
63980a1396SMao Jiang {
64980a1396SMao Jiang 	return bdev->optimal_io_boundary;
65980a1396SMao Jiang }
66980a1396SMao Jiang 
67980a1396SMao Jiang uint32_t
68980a1396SMao Jiang spdk_bdev_get_md_size(const struct spdk_bdev *bdev)
69980a1396SMao Jiang {
70980a1396SMao Jiang 	return bdev->md_len;
71980a1396SMao Jiang }
72980a1396SMao Jiang 
73980a1396SMao Jiang bool
74980a1396SMao Jiang spdk_bdev_is_md_interleaved(const struct spdk_bdev *bdev)
75980a1396SMao Jiang {
76980a1396SMao Jiang 	return (bdev->md_len != 0) && bdev->md_interleave;
77980a1396SMao Jiang }
78980a1396SMao Jiang 
798dd1cd21SBen Walker /* We have to use the typedef in the function declaration to appease astyle. */
808dd1cd21SBen Walker typedef enum spdk_dif_type spdk_dif_type_t;
818dd1cd21SBen Walker 
828dd1cd21SBen Walker spdk_dif_type_t
838dd1cd21SBen Walker spdk_bdev_get_dif_type(const struct spdk_bdev *bdev)
84980a1396SMao Jiang {
85980a1396SMao Jiang 	if (bdev->md_len != 0) {
86980a1396SMao Jiang 		return bdev->dif_type;
87980a1396SMao Jiang 	} else {
88980a1396SMao Jiang 		return SPDK_DIF_DISABLE;
89980a1396SMao Jiang 	}
90980a1396SMao Jiang }
91980a1396SMao Jiang 
92980a1396SMao Jiang bool
93980a1396SMao Jiang spdk_bdev_is_dif_head_of_md(const struct spdk_bdev *bdev)
94980a1396SMao Jiang {
95980a1396SMao Jiang 	if (spdk_bdev_get_dif_type(bdev) != SPDK_DIF_DISABLE) {
96980a1396SMao Jiang 		return bdev->dif_is_head_of_md;
97980a1396SMao Jiang 	} else {
98980a1396SMao Jiang 		return false;
99980a1396SMao Jiang 	}
100980a1396SMao Jiang }
101980a1396SMao Jiang 
102980a1396SMao Jiang uint32_t
103980a1396SMao Jiang spdk_bdev_get_data_block_size(const struct spdk_bdev *bdev)
104980a1396SMao Jiang {
105980a1396SMao Jiang 	if (spdk_bdev_is_md_interleaved(bdev)) {
106980a1396SMao Jiang 		return bdev->blocklen - bdev->md_len;
107980a1396SMao Jiang 	} else {
108980a1396SMao Jiang 		return bdev->blocklen;
109980a1396SMao Jiang 	}
110980a1396SMao Jiang }
111980a1396SMao Jiang 
112980a1396SMao Jiang uint16_t
113980a1396SMao Jiang spdk_bdev_get_acwu(const struct spdk_bdev *bdev)
114980a1396SMao Jiang {
115980a1396SMao Jiang 	return bdev->acwu;
116980a1396SMao Jiang }
1179b04e291SShuhei Matsumoto 
118f6e62d2cSBen Walker uint32_t
119f6e62d2cSBen Walker spdk_bdev_get_block_size(const struct spdk_bdev *bdev)
120f6e62d2cSBen Walker {
1219b04e291SShuhei Matsumoto 	return bdev->blocklen;
122f6e62d2cSBen Walker }
123f6e62d2cSBen Walker 
124f6e62d2cSBen Walker uint64_t
125f6e62d2cSBen Walker spdk_bdev_get_num_blocks(const struct spdk_bdev *bdev)
126f6e62d2cSBen Walker {
127980a1396SMao Jiang 	return bdev->blockcnt;
1289b04e291SShuhei Matsumoto }
1299b04e291SShuhei Matsumoto 
1305e4d957eSShuhei Matsumoto /* We have to use the typedef in the function declaration to appease astyle. */
1315e4d957eSShuhei Matsumoto typedef enum spdk_dif_pi_format spdk_dif_pi_format_t;
1325e4d957eSShuhei Matsumoto 
1335e4d957eSShuhei Matsumoto spdk_dif_pi_format_t
1345e4d957eSShuhei Matsumoto spdk_bdev_get_dif_pi_format(const struct spdk_bdev *bdev)
1355e4d957eSShuhei Matsumoto {
1365e4d957eSShuhei Matsumoto 	return bdev->dif_pi_format;
1375e4d957eSShuhei Matsumoto }
1385e4d957eSShuhei Matsumoto 
139b09de013SShuhei Matsumoto uint32_t
140b09de013SShuhei Matsumoto spdk_bdev_desc_get_md_size(struct spdk_bdev_desc *desc)
141b09de013SShuhei Matsumoto {
142b09de013SShuhei Matsumoto 	return spdk_bdev_get_md_size(desc->bdev);
143b09de013SShuhei Matsumoto }
144b09de013SShuhei Matsumoto 
145b09de013SShuhei Matsumoto bool
146b09de013SShuhei Matsumoto spdk_bdev_desc_is_md_interleaved(struct spdk_bdev_desc *desc)
147b09de013SShuhei Matsumoto {
148b09de013SShuhei Matsumoto 	return spdk_bdev_is_md_interleaved(desc->bdev);
149b09de013SShuhei Matsumoto }
150b09de013SShuhei Matsumoto 
151b09de013SShuhei Matsumoto /* We have to use the typedef in the function declaration to appease astyle. */
152b09de013SShuhei Matsumoto typedef enum spdk_dif_type spdk_dif_type_t;
153b09de013SShuhei Matsumoto 
154b09de013SShuhei Matsumoto spdk_dif_type_t
155b09de013SShuhei Matsumoto spdk_bdev_desc_get_dif_type(struct spdk_bdev_desc *desc)
156b09de013SShuhei Matsumoto {
157b09de013SShuhei Matsumoto 	return spdk_bdev_get_dif_type(desc->bdev);
158b09de013SShuhei Matsumoto }
159b09de013SShuhei Matsumoto 
160b09de013SShuhei Matsumoto bool
161b09de013SShuhei Matsumoto spdk_bdev_desc_is_dif_head_of_md(struct spdk_bdev_desc *desc)
162b09de013SShuhei Matsumoto {
163b09de013SShuhei Matsumoto 	return spdk_bdev_is_dif_head_of_md(desc->bdev);
164b09de013SShuhei Matsumoto }
165b09de013SShuhei Matsumoto 
166b09de013SShuhei Matsumoto uint32_t
167b09de013SShuhei Matsumoto spdk_bdev_desc_get_block_size(struct spdk_bdev_desc *desc)
168b09de013SShuhei Matsumoto {
169b09de013SShuhei Matsumoto 	return spdk_bdev_get_block_size(desc->bdev);
170b09de013SShuhei Matsumoto }
171b09de013SShuhei Matsumoto 
172b09de013SShuhei Matsumoto spdk_dif_pi_format_t
173b09de013SShuhei Matsumoto spdk_bdev_desc_get_dif_pi_format(struct spdk_bdev_desc *desc)
174b09de013SShuhei Matsumoto {
175b09de013SShuhei Matsumoto 	return spdk_bdev_get_dif_pi_format(desc->bdev);
176b09de013SShuhei Matsumoto }
177b09de013SShuhei Matsumoto 
178b27f6f9dSTomasz Kulasek DEFINE_STUB(spdk_bdev_comparev_and_writev_blocks, int,
179b27f6f9dSTomasz Kulasek 	    (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
180b27f6f9dSTomasz Kulasek 	     struct iovec *compare_iov, int compare_iovcnt,
181b27f6f9dSTomasz Kulasek 	     struct iovec *write_iov, int write_iovcnt,
182b27f6f9dSTomasz Kulasek 	     uint64_t offset_blocks, uint64_t num_blocks,
183b27f6f9dSTomasz Kulasek 	     spdk_bdev_io_completion_cb cb, void *cb_arg),
184b27f6f9dSTomasz Kulasek 	    0);
185b27f6f9dSTomasz Kulasek 
1869cb21ad6SSeth Howell DEFINE_STUB(nvmf_ctrlr_process_io_cmd, int, (struct spdk_nvmf_request *req), 0);
187b27f6f9dSTomasz Kulasek 
188b27f6f9dSTomasz Kulasek DEFINE_STUB_V(spdk_bdev_io_get_nvme_fused_status, (const struct spdk_bdev_io *bdev_io,
189b27f6f9dSTomasz Kulasek 		uint32_t *cdw0, int *cmp_sct, int *cmp_sc, int *wr_sct, int *wr_sc));
190b27f6f9dSTomasz Kulasek 
191b09de013SShuhei Matsumoto DEFINE_STUB(spdk_bdev_desc_is_dif_check_enabled, bool,
192b09de013SShuhei Matsumoto 	    (struct spdk_bdev_desc *desc, enum spdk_dif_check_type check_type), false);
1939b04e291SShuhei Matsumoto 
194824bf663SShuhei Matsumoto DEFINE_STUB(spdk_bdev_get_io_channel, struct spdk_io_channel *,
195824bf663SShuhei Matsumoto 	    (struct spdk_bdev_desc *desc), NULL);
196f6e62d2cSBen Walker 
197824bf663SShuhei Matsumoto DEFINE_STUB(spdk_bdev_flush_blocks, int,
198824bf663SShuhei Matsumoto 	    (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
1991578b5b5SDaniel Verkamp 	     uint64_t offset_blocks, uint64_t num_blocks,
200824bf663SShuhei Matsumoto 	     spdk_bdev_io_completion_cb cb, void *cb_arg),
201824bf663SShuhei Matsumoto 	    0);
202f6e62d2cSBen Walker 
203824bf663SShuhei Matsumoto DEFINE_STUB(spdk_bdev_unmap_blocks, int,
204824bf663SShuhei Matsumoto 	    (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
2051578b5b5SDaniel Verkamp 	     uint64_t offset_blocks, uint64_t num_blocks,
206824bf663SShuhei Matsumoto 	     spdk_bdev_io_completion_cb cb, void *cb_arg),
207824bf663SShuhei Matsumoto 	    0);
208f6e62d2cSBen Walker 
209824bf663SShuhei Matsumoto DEFINE_STUB(spdk_bdev_io_type_supported, bool,
210824bf663SShuhei Matsumoto 	    (struct spdk_bdev *bdev, enum spdk_bdev_io_type io_type), false);
211f6e62d2cSBen Walker 
212824bf663SShuhei Matsumoto DEFINE_STUB(spdk_bdev_queue_io_wait, int,
213824bf663SShuhei Matsumoto 	    (struct spdk_bdev *bdev, struct spdk_io_channel *ch,
214824bf663SShuhei Matsumoto 	     struct spdk_bdev_io_wait_entry *entry),
215824bf663SShuhei Matsumoto 	    0);
216d9b3149eSTomasz Zawadzki 
217824bf663SShuhei Matsumoto DEFINE_STUB(spdk_bdev_write_blocks, int,
218824bf663SShuhei Matsumoto 	    (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, void *buf,
2191578b5b5SDaniel Verkamp 	     uint64_t offset_blocks, uint64_t num_blocks,
220824bf663SShuhei Matsumoto 	     spdk_bdev_io_completion_cb cb, void *cb_arg),
221824bf663SShuhei Matsumoto 	    0);
222f6e62d2cSBen Walker 
223824bf663SShuhei Matsumoto DEFINE_STUB(spdk_bdev_writev_blocks, int,
224824bf663SShuhei Matsumoto 	    (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
225824bf663SShuhei Matsumoto 	     struct iovec *iov, int iovcnt, uint64_t offset_blocks, uint64_t num_blocks,
226824bf663SShuhei Matsumoto 	     spdk_bdev_io_completion_cb cb, void *cb_arg),
227824bf663SShuhei Matsumoto 	    0);
228824bf663SShuhei Matsumoto 
229824bf663SShuhei Matsumoto DEFINE_STUB(spdk_bdev_read_blocks, int,
230824bf663SShuhei Matsumoto 	    (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, void *buf,
2318580daa1SSrikanth kaligotla 	     uint64_t offset_blocks, uint64_t num_blocks,
232824bf663SShuhei Matsumoto 	     spdk_bdev_io_completion_cb cb, void *cb_arg),
233824bf663SShuhei Matsumoto 	    0);
2348580daa1SSrikanth kaligotla 
235824bf663SShuhei Matsumoto DEFINE_STUB(spdk_bdev_readv_blocks, int,
236824bf663SShuhei Matsumoto 	    (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
237824bf663SShuhei Matsumoto 	     struct iovec *iov, int iovcnt, uint64_t offset_blocks, uint64_t num_blocks,
238824bf663SShuhei Matsumoto 	     spdk_bdev_io_completion_cb cb, void *cb_arg),
239824bf663SShuhei Matsumoto 	    0);
240824bf663SShuhei Matsumoto 
241824bf663SShuhei Matsumoto DEFINE_STUB(spdk_bdev_write_zeroes_blocks, int,
242824bf663SShuhei Matsumoto 	    (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
2431578b5b5SDaniel Verkamp 	     uint64_t offset_blocks, uint64_t num_blocks,
244824bf663SShuhei Matsumoto 	     spdk_bdev_io_completion_cb cb, void *cb_arg),
245824bf663SShuhei Matsumoto 	    0);
246f6e62d2cSBen Walker 
24704a428f5SKarl Bonde Torp DEFINE_STUB(spdk_bdev_nvme_iov_passthru_md, int, (
24804a428f5SKarl Bonde Torp 		    struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
24904a428f5SKarl Bonde Torp 		    const struct spdk_nvme_cmd *cmd, struct iovec *iov, int iovcnt,
25004a428f5SKarl Bonde Torp 		    size_t nbytes, void *md_buf, size_t md_len,
251824bf663SShuhei Matsumoto 		    spdk_bdev_io_completion_cb cb, void *cb_arg),
252824bf663SShuhei Matsumoto 	    0);
2538580daa1SSrikanth kaligotla 
254824bf663SShuhei Matsumoto DEFINE_STUB_V(spdk_bdev_free_io, (struct spdk_bdev_io *bdev_io));
2550caab4e1SDaniel Verkamp 
256824bf663SShuhei Matsumoto DEFINE_STUB(spdk_nvmf_subsystem_get_nqn, const char *,
257fb712988SJacek Kalwas 	    (const struct spdk_nvmf_subsystem *subsystem), NULL);
258f6e62d2cSBen Walker 
2595818b42fSmatthewb DEFINE_STUB(spdk_bdev_zcopy_start, int,
2605818b42fSmatthewb 	    (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
2615818b42fSmatthewb 	     struct iovec *iov, int iovcnt,
2625818b42fSmatthewb 	     uint64_t offset_blocks, uint64_t num_blocks,
2635818b42fSmatthewb 	     bool populate,
2645818b42fSmatthewb 	     spdk_bdev_io_completion_cb cb, void *cb_arg),
2655818b42fSmatthewb 	    0);
2665818b42fSmatthewb 
2675818b42fSmatthewb DEFINE_STUB(spdk_bdev_zcopy_end, int,
2685818b42fSmatthewb 	    (struct spdk_bdev_io *bdev_io, bool commit,
2695818b42fSmatthewb 	     spdk_bdev_io_completion_cb cb, void *cb_arg),
2705818b42fSmatthewb 	    0);
2715818b42fSmatthewb 
2728305e49bSEvgeniy Kochetov DEFINE_STUB(spdk_bdev_copy_blocks, int,
2738305e49bSEvgeniy Kochetov 	    (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
2748305e49bSEvgeniy Kochetov 	     uint64_t dst_offset_blocks, uint64_t src_offset_blocks, uint64_t num_blocks,
2758305e49bSEvgeniy Kochetov 	     spdk_bdev_io_completion_cb cb, void *cb_arg),
2768305e49bSEvgeniy Kochetov 	    0);
2778305e49bSEvgeniy Kochetov 
2788305e49bSEvgeniy Kochetov DEFINE_STUB(spdk_bdev_get_max_copy, uint32_t, (const struct spdk_bdev *bdev), 0);
2798305e49bSEvgeniy Kochetov 
28014451d76SDaniel Verkamp struct spdk_nvmf_ns *
28114451d76SDaniel Verkamp spdk_nvmf_subsystem_get_ns(struct spdk_nvmf_subsystem *subsystem, uint32_t nsid)
28214451d76SDaniel Verkamp {
28314451d76SDaniel Verkamp 	abort();
28414451d76SDaniel Verkamp 	return NULL;
28514451d76SDaniel Verkamp }
28614451d76SDaniel Verkamp 
28714451d76SDaniel Verkamp struct spdk_nvmf_ns *
28814451d76SDaniel Verkamp spdk_nvmf_subsystem_get_first_ns(struct spdk_nvmf_subsystem *subsystem)
28914451d76SDaniel Verkamp {
29014451d76SDaniel Verkamp 	abort();
29114451d76SDaniel Verkamp 	return NULL;
29214451d76SDaniel Verkamp }
29314451d76SDaniel Verkamp 
29414451d76SDaniel Verkamp struct spdk_nvmf_ns *
29514451d76SDaniel Verkamp spdk_nvmf_subsystem_get_next_ns(struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_ns *prev_ns)
29614451d76SDaniel Verkamp {
29714451d76SDaniel Verkamp 	abort();
29814451d76SDaniel Verkamp 	return NULL;
29914451d76SDaniel Verkamp }
30014451d76SDaniel Verkamp 
3019b04e291SShuhei Matsumoto int
3029b04e291SShuhei Matsumoto spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_size,
3039b04e291SShuhei Matsumoto 		  bool md_interleave, bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags,
3049b04e291SShuhei Matsumoto 		  uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag,
3055256f0efSSlawomir Ptak 		  uint32_t data_offset, uint64_t guard_seed, struct spdk_dif_ctx_init_ext_opts *opts)
3069b04e291SShuhei Matsumoto {
307a711d629SSlawomir Ptak 	ctx->dif_pi_format = opts->dif_pi_format;
3089b04e291SShuhei Matsumoto 	ctx->block_size = block_size;
3099b04e291SShuhei Matsumoto 	ctx->md_size = md_size;
3109b04e291SShuhei Matsumoto 	ctx->init_ref_tag = init_ref_tag;
3119b04e291SShuhei Matsumoto 
3129b04e291SShuhei Matsumoto 	return 0;
3139b04e291SShuhei Matsumoto }
3149b04e291SShuhei Matsumoto 
315d03b31c6SEvgeniy Kochetov static uint32_t g_bdev_nvme_status_cdw0;
316d03b31c6SEvgeniy Kochetov static uint32_t g_bdev_nvme_status_sct = SPDK_NVME_SCT_GENERIC;
317d03b31c6SEvgeniy Kochetov static uint32_t g_bdev_nvme_status_sc = SPDK_NVME_SC_SUCCESS;
318d03b31c6SEvgeniy Kochetov 
3198dd1cd21SBen Walker static void
3208dd1cd21SBen Walker reset_bdev_nvme_status(void)
321d03b31c6SEvgeniy Kochetov {
322d03b31c6SEvgeniy Kochetov 	g_bdev_nvme_status_cdw0 = 0;
323d03b31c6SEvgeniy Kochetov 	g_bdev_nvme_status_sct = SPDK_NVME_SCT_GENERIC;
324d03b31c6SEvgeniy Kochetov 	g_bdev_nvme_status_sc = SPDK_NVME_SC_SUCCESS;
325d03b31c6SEvgeniy Kochetov }
326d03b31c6SEvgeniy Kochetov 
3278dd1cd21SBen Walker void
3288dd1cd21SBen Walker spdk_bdev_io_get_nvme_status(const struct spdk_bdev_io *bdev_io, uint32_t *cdw0, int *sct,
329d03b31c6SEvgeniy Kochetov 			     int *sc)
330d03b31c6SEvgeniy Kochetov {
331d03b31c6SEvgeniy Kochetov 	*cdw0 = g_bdev_nvme_status_cdw0;
332d03b31c6SEvgeniy Kochetov 	*sct = g_bdev_nvme_status_sct;
333d03b31c6SEvgeniy Kochetov 	*sc = g_bdev_nvme_status_sc;
334d03b31c6SEvgeniy Kochetov }
335d03b31c6SEvgeniy Kochetov 
33609e8e884SArtur Paszkiewicz bool
33709e8e884SArtur Paszkiewicz nvmf_ns_is_ptpl_capable(const struct spdk_nvmf_ns *ns)
33809e8e884SArtur Paszkiewicz {
33909e8e884SArtur Paszkiewicz 	return ns->ptpl_file != NULL;
34009e8e884SArtur Paszkiewicz }
34109e8e884SArtur Paszkiewicz 
342f6e62d2cSBen Walker static void
3435eb12964SDaniel Verkamp test_get_rw_params(void)
344f6e62d2cSBen Walker {
3455eb12964SDaniel Verkamp 	struct spdk_nvme_cmd cmd = {0};
3465eb12964SDaniel Verkamp 	uint64_t lba;
3475eb12964SDaniel Verkamp 	uint64_t count;
3485eb12964SDaniel Verkamp 
3495eb12964SDaniel Verkamp 	lba = 0;
3505eb12964SDaniel Verkamp 	count = 0;
3515eb12964SDaniel Verkamp 	to_le64(&cmd.cdw10, 0x1234567890ABCDEF);
3525eb12964SDaniel Verkamp 	to_le32(&cmd.cdw12, 0x9875 | SPDK_NVME_IO_FLAGS_FORCE_UNIT_ACCESS);
3535eb12964SDaniel Verkamp 	nvmf_bdev_ctrlr_get_rw_params(&cmd, &lba, &count);
3545eb12964SDaniel Verkamp 	CU_ASSERT(lba == 0x1234567890ABCDEF);
3555eb12964SDaniel Verkamp 	CU_ASSERT(count == 0x9875 + 1); /* NOTE: this field is 0's based, hence the +1 */
3565eb12964SDaniel Verkamp }
3575eb12964SDaniel Verkamp 
3585eb12964SDaniel Verkamp static void
3593dbaa93cSAnkit Kumar test_get_rw_ext_params(void)
3603dbaa93cSAnkit Kumar {
3613dbaa93cSAnkit Kumar 	struct spdk_nvme_cmd cmd = {0};
3623dbaa93cSAnkit Kumar 	struct spdk_bdev_ext_io_opts opts = {0};
3633dbaa93cSAnkit Kumar 
36438b931b2SShuhei Matsumoto 	to_le32(&cmd.cdw12, 0x9875 | SPDK_NVME_IO_FLAGS_DATA_PLACEMENT_DIRECTIVE |
36538b931b2SShuhei Matsumoto 		SPDK_NVME_IO_FLAGS_PRCHK_GUARD);
3663dbaa93cSAnkit Kumar 	to_le32(&cmd.cdw13, 0x2 << 16);
3673dbaa93cSAnkit Kumar 	nvmf_bdev_ctrlr_get_rw_ext_params(&cmd, &opts);
36838b931b2SShuhei Matsumoto 	CU_ASSERT(opts.nvme_cdw12.raw == 0x10209875);
3693dbaa93cSAnkit Kumar 	CU_ASSERT(opts.nvme_cdw13.raw == 0x20000);
37038b931b2SShuhei Matsumoto 	CU_ASSERT((opts.dif_check_flags_exclude_mask ^ SPDK_NVME_IO_FLAGS_PRCHK_MASK)
37138b931b2SShuhei Matsumoto 		  == SPDK_NVME_IO_FLAGS_PRCHK_GUARD);
3723dbaa93cSAnkit Kumar }
3733dbaa93cSAnkit Kumar 
3743dbaa93cSAnkit Kumar static void
3755eb12964SDaniel Verkamp test_lba_in_range(void)
3765eb12964SDaniel Verkamp {
3775eb12964SDaniel Verkamp 	/* Trivial cases (no overflow) */
3785eb12964SDaniel Verkamp 	CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(1000, 0, 1) == true);
3795eb12964SDaniel Verkamp 	CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(1000, 0, 1000) == true);
3805eb12964SDaniel Verkamp 	CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(1000, 0, 1001) == false);
3815eb12964SDaniel Verkamp 	CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(1000, 1, 999) == true);
3825eb12964SDaniel Verkamp 	CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(1000, 1, 1000) == false);
3835eb12964SDaniel Verkamp 	CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(1000, 999, 1) == true);
3845eb12964SDaniel Verkamp 	CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(1000, 1000, 1) == false);
3855eb12964SDaniel Verkamp 	CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(1000, 1001, 1) == false);
3865eb12964SDaniel Verkamp 
3875eb12964SDaniel Verkamp 	/* Overflow edge cases */
3885eb12964SDaniel Verkamp 	CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(UINT64_MAX, 0, UINT64_MAX) == true);
38999b25f1cSTomasz Zawadzki 	CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(UINT64_MAX, 1, UINT64_MAX) == false);
3905eb12964SDaniel Verkamp 	CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(UINT64_MAX, UINT64_MAX - 1, 1) == true);
3915eb12964SDaniel Verkamp 	CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(UINT64_MAX, UINT64_MAX, 1) == false);
392f6e62d2cSBen Walker }
393f6e62d2cSBen Walker 
3949b04e291SShuhei Matsumoto static void
3959b04e291SShuhei Matsumoto test_get_dif_ctx(void)
3969b04e291SShuhei Matsumoto {
3979b04e291SShuhei Matsumoto 	struct spdk_bdev bdev = {};
398b09de013SShuhei Matsumoto 	struct spdk_bdev_desc desc = { .bdev = &bdev, };
3999b04e291SShuhei Matsumoto 	struct spdk_nvme_cmd cmd = {};
4009b04e291SShuhei Matsumoto 	struct spdk_dif_ctx dif_ctx = {};
4019b04e291SShuhei Matsumoto 	bool ret;
4029b04e291SShuhei Matsumoto 
4039b04e291SShuhei Matsumoto 	bdev.md_len = 0;
4049b04e291SShuhei Matsumoto 
405b09de013SShuhei Matsumoto 	ret = nvmf_bdev_ctrlr_get_dif_ctx(&desc, &cmd, &dif_ctx);
4069b04e291SShuhei Matsumoto 	CU_ASSERT(ret == false);
4079b04e291SShuhei Matsumoto 
4089b04e291SShuhei Matsumoto 	to_le64(&cmd.cdw10, 0x1234567890ABCDEF);
4099b04e291SShuhei Matsumoto 	bdev.blocklen = 520;
4109b04e291SShuhei Matsumoto 	bdev.md_len = 8;
4119b04e291SShuhei Matsumoto 
412b09de013SShuhei Matsumoto 	ret = nvmf_bdev_ctrlr_get_dif_ctx(&desc, &cmd, &dif_ctx);
4139b04e291SShuhei Matsumoto 	CU_ASSERT(ret == true);
41475a12cbfSSlawomir Ptak 	CU_ASSERT(dif_ctx.block_size == 520);
4159b04e291SShuhei Matsumoto 	CU_ASSERT(dif_ctx.md_size == 8);
4169b04e291SShuhei Matsumoto 	CU_ASSERT(dif_ctx.init_ref_tag == 0x90ABCDEF);
4179b04e291SShuhei Matsumoto }
4189b04e291SShuhei Matsumoto 
419b27f6f9dSTomasz Kulasek static void
420b27f6f9dSTomasz Kulasek test_spdk_nvmf_bdev_ctrlr_compare_and_write_cmd(void)
421b27f6f9dSTomasz Kulasek {
422b27f6f9dSTomasz Kulasek 	int rc;
423b27f6f9dSTomasz Kulasek 	struct spdk_bdev bdev = {};
424b09de013SShuhei Matsumoto 	struct spdk_bdev_desc desc = { .bdev = &bdev, };
425b27f6f9dSTomasz Kulasek 	struct spdk_io_channel ch = {};
426b27f6f9dSTomasz Kulasek 
4275e1b30bdSRichael Zhuang 	struct spdk_nvmf_request cmp_req = {};
4285e1b30bdSRichael Zhuang 	union nvmf_c2h_msg cmp_rsp = {};
429b27f6f9dSTomasz Kulasek 
4305e1b30bdSRichael Zhuang 	struct spdk_nvmf_request write_req = {};
4315e1b30bdSRichael Zhuang 	union nvmf_c2h_msg write_rsp = {};
432b27f6f9dSTomasz Kulasek 
4335e1b30bdSRichael Zhuang 	struct spdk_nvmf_qpair qpair = {};
434b27f6f9dSTomasz Kulasek 
4355e1b30bdSRichael Zhuang 	struct spdk_nvme_cmd cmp_cmd = {};
4365e1b30bdSRichael Zhuang 	struct spdk_nvme_cmd write_cmd = {};
437b27f6f9dSTomasz Kulasek 
4385e1b30bdSRichael Zhuang 	struct spdk_nvmf_ctrlr ctrlr = {};
4395e1b30bdSRichael Zhuang 	struct spdk_nvmf_subsystem subsystem = {};
4405e1b30bdSRichael Zhuang 	struct spdk_nvmf_ns ns = {};
4415e1b30bdSRichael Zhuang 	struct spdk_nvmf_ns *subsys_ns[1] = {};
442b27f6f9dSTomasz Kulasek 
4435e1b30bdSRichael Zhuang 	struct spdk_nvmf_poll_group group = {};
4445e1b30bdSRichael Zhuang 	struct spdk_nvmf_subsystem_poll_group sgroups = {};
4455e1b30bdSRichael Zhuang 	struct spdk_nvmf_subsystem_pg_ns_info ns_info = {};
446b27f6f9dSTomasz Kulasek 
447b27f6f9dSTomasz Kulasek 	bdev.blocklen = 512;
448980a1396SMao Jiang 	bdev.blockcnt = 10;
449b27f6f9dSTomasz Kulasek 	ns.bdev = &bdev;
450b27f6f9dSTomasz Kulasek 
451b27f6f9dSTomasz Kulasek 	subsystem.id = 0;
452b27f6f9dSTomasz Kulasek 	subsystem.max_nsid = 1;
453b27f6f9dSTomasz Kulasek 	subsys_ns[0] = &ns;
454b27f6f9dSTomasz Kulasek 	subsystem.ns = (struct spdk_nvmf_ns **)&subsys_ns;
455b27f6f9dSTomasz Kulasek 
456b27f6f9dSTomasz Kulasek 	/* Enable controller */
457b27f6f9dSTomasz Kulasek 	ctrlr.vcprop.cc.bits.en = 1;
458b27f6f9dSTomasz Kulasek 	ctrlr.subsys = &subsystem;
459b27f6f9dSTomasz Kulasek 
460b27f6f9dSTomasz Kulasek 	group.num_sgroups = 1;
461b27f6f9dSTomasz Kulasek 	sgroups.num_ns = 1;
462b27f6f9dSTomasz Kulasek 	sgroups.ns_info = &ns_info;
463b27f6f9dSTomasz Kulasek 	group.sgroups = &sgroups;
464b27f6f9dSTomasz Kulasek 
465b27f6f9dSTomasz Kulasek 	qpair.ctrlr = &ctrlr;
466b27f6f9dSTomasz Kulasek 	qpair.group = &group;
467b27f6f9dSTomasz Kulasek 
468b27f6f9dSTomasz Kulasek 	cmp_req.qpair = &qpair;
469b27f6f9dSTomasz Kulasek 	cmp_req.cmd = (union nvmf_h2c_msg *)&cmp_cmd;
470b27f6f9dSTomasz Kulasek 	cmp_req.rsp = &cmp_rsp;
471b27f6f9dSTomasz Kulasek 
472b27f6f9dSTomasz Kulasek 	cmp_cmd.nsid = 1;
473b27f6f9dSTomasz Kulasek 	cmp_cmd.fuse = SPDK_NVME_CMD_FUSE_FIRST;
474b27f6f9dSTomasz Kulasek 	cmp_cmd.opc = SPDK_NVME_OPC_COMPARE;
475b27f6f9dSTomasz Kulasek 
476b27f6f9dSTomasz Kulasek 	write_req.qpair = &qpair;
477b27f6f9dSTomasz Kulasek 	write_req.cmd = (union nvmf_h2c_msg *)&write_cmd;
478b27f6f9dSTomasz Kulasek 	write_req.rsp = &write_rsp;
479b27f6f9dSTomasz Kulasek 
480b27f6f9dSTomasz Kulasek 	write_cmd.nsid = 1;
481b27f6f9dSTomasz Kulasek 	write_cmd.fuse = SPDK_NVME_CMD_FUSE_SECOND;
482b27f6f9dSTomasz Kulasek 	write_cmd.opc = SPDK_NVME_OPC_WRITE;
483b27f6f9dSTomasz Kulasek 
484b27f6f9dSTomasz Kulasek 	/* 1. SUCCESS */
485b27f6f9dSTomasz Kulasek 	cmp_cmd.cdw10 = 1;	/* SLBA: CDW10 and CDW11 */
486b27f6f9dSTomasz Kulasek 	cmp_cmd.cdw12 = 1;	/* NLB: CDW12 bits 15:00, 0's based */
487b27f6f9dSTomasz Kulasek 
488b27f6f9dSTomasz Kulasek 	write_cmd.cdw10 = 1;	/* SLBA: CDW10 and CDW11 */
489b27f6f9dSTomasz Kulasek 	write_cmd.cdw12 = 1;	/* NLB: CDW12 bits 15:00, 0's based */
490b27f6f9dSTomasz Kulasek 	write_req.length = (write_cmd.cdw12 + 1) * bdev.blocklen;
491b27f6f9dSTomasz Kulasek 
492b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_compare_and_write_cmd(&bdev, &desc, &ch, &cmp_req, &write_req);
493b27f6f9dSTomasz Kulasek 
494b27f6f9dSTomasz Kulasek 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS);
495b27f6f9dSTomasz Kulasek 	CU_ASSERT(cmp_rsp.nvme_cpl.status.sct == 0);
496b27f6f9dSTomasz Kulasek 	CU_ASSERT(cmp_rsp.nvme_cpl.status.sc == 0);
497b27f6f9dSTomasz Kulasek 	CU_ASSERT(write_rsp.nvme_cpl.status.sct == 0);
498b27f6f9dSTomasz Kulasek 	CU_ASSERT(write_rsp.nvme_cpl.status.sc == 0);
499b27f6f9dSTomasz Kulasek 
500b27f6f9dSTomasz Kulasek 	/* 2. Fused command start lba / num blocks mismatch */
501b27f6f9dSTomasz Kulasek 	cmp_cmd.cdw10 = 1;	/* SLBA: CDW10 and CDW11 */
502b27f6f9dSTomasz Kulasek 	cmp_cmd.cdw12 = 2;	/* NLB: CDW12 bits 15:00, 0's based */
503b27f6f9dSTomasz Kulasek 
504b27f6f9dSTomasz Kulasek 	write_cmd.cdw10 = 1;	/* SLBA: CDW10 and CDW11 */
505b27f6f9dSTomasz Kulasek 	write_cmd.cdw12 = 1;	/* NLB: CDW12 bits 15:00, 0's based */
506b27f6f9dSTomasz Kulasek 	write_req.length = (write_cmd.cdw12 + 1) * bdev.blocklen;
507b27f6f9dSTomasz Kulasek 
508b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_compare_and_write_cmd(&bdev, &desc, &ch, &cmp_req, &write_req);
509b27f6f9dSTomasz Kulasek 
510b27f6f9dSTomasz Kulasek 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
511b27f6f9dSTomasz Kulasek 	CU_ASSERT(cmp_rsp.nvme_cpl.status.sct == 0);
512b27f6f9dSTomasz Kulasek 	CU_ASSERT(cmp_rsp.nvme_cpl.status.sc == 0);
513b27f6f9dSTomasz Kulasek 	CU_ASSERT(write_rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
514b27f6f9dSTomasz Kulasek 	CU_ASSERT(write_rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD);
515b27f6f9dSTomasz Kulasek 
516b27f6f9dSTomasz Kulasek 	/* 3. SPDK_NVME_SC_LBA_OUT_OF_RANGE */
517b27f6f9dSTomasz Kulasek 	cmp_cmd.cdw10 = 1;	/* SLBA: CDW10 and CDW11 */
518b27f6f9dSTomasz Kulasek 	cmp_cmd.cdw12 = 100;	/* NLB: CDW12 bits 15:00, 0's based */
519b27f6f9dSTomasz Kulasek 
520b27f6f9dSTomasz Kulasek 	write_cmd.cdw10 = 1;	/* SLBA: CDW10 and CDW11 */
521b27f6f9dSTomasz Kulasek 	write_cmd.cdw12 = 100;	/* NLB: CDW12 bits 15:00, 0's based */
522b27f6f9dSTomasz Kulasek 	write_req.length = (write_cmd.cdw12 + 1) * bdev.blocklen;
523b27f6f9dSTomasz Kulasek 
524b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_compare_and_write_cmd(&bdev, &desc, &ch, &cmp_req, &write_req);
525b27f6f9dSTomasz Kulasek 
526b27f6f9dSTomasz Kulasek 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
527b27f6f9dSTomasz Kulasek 	CU_ASSERT(cmp_rsp.nvme_cpl.status.sct == 0);
528b27f6f9dSTomasz Kulasek 	CU_ASSERT(cmp_rsp.nvme_cpl.status.sc == 0);
529b27f6f9dSTomasz Kulasek 	CU_ASSERT(write_rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
530b27f6f9dSTomasz Kulasek 	CU_ASSERT(write_rsp.nvme_cpl.status.sc == SPDK_NVME_SC_LBA_OUT_OF_RANGE);
531b27f6f9dSTomasz Kulasek 
532b27f6f9dSTomasz Kulasek 	/* 4. SPDK_NVME_SC_DATA_SGL_LENGTH_INVALID */
533b27f6f9dSTomasz Kulasek 	cmp_cmd.cdw10 = 1;	/* SLBA: CDW10 and CDW11 */
534b27f6f9dSTomasz Kulasek 	cmp_cmd.cdw12 = 1;	/* NLB: CDW12 bits 15:00, 0's based */
535b27f6f9dSTomasz Kulasek 
536b27f6f9dSTomasz Kulasek 	write_cmd.cdw10 = 1;	/* SLBA: CDW10 and CDW11 */
537b27f6f9dSTomasz Kulasek 	write_cmd.cdw12 = 1;	/* NLB: CDW12 bits 15:00, 0's based */
538b27f6f9dSTomasz Kulasek 	write_req.length = (write_cmd.cdw12 + 1) * bdev.blocklen - 1;
539b27f6f9dSTomasz Kulasek 
540b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_compare_and_write_cmd(&bdev, &desc, &ch, &cmp_req, &write_req);
541b27f6f9dSTomasz Kulasek 
542b27f6f9dSTomasz Kulasek 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
543b27f6f9dSTomasz Kulasek 	CU_ASSERT(cmp_rsp.nvme_cpl.status.sct == 0);
544b27f6f9dSTomasz Kulasek 	CU_ASSERT(cmp_rsp.nvme_cpl.status.sc == 0);
545b27f6f9dSTomasz Kulasek 	CU_ASSERT(write_rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
546b27f6f9dSTomasz Kulasek 	CU_ASSERT(write_rsp.nvme_cpl.status.sc == SPDK_NVME_SC_DATA_SGL_LENGTH_INVALID);
547b27f6f9dSTomasz Kulasek }
548b27f6f9dSTomasz Kulasek 
549980a1396SMao Jiang static void
550980a1396SMao Jiang test_nvmf_bdev_ctrlr_identify_ns(void)
551980a1396SMao Jiang {
552980a1396SMao Jiang 	struct spdk_nvmf_ns ns = {};
553980a1396SMao Jiang 	struct spdk_nvme_ns_data nsdata = {};
554980a1396SMao Jiang 	struct spdk_bdev bdev = {};
555b09de013SShuhei Matsumoto 	struct spdk_bdev_desc desc = {};
556980a1396SMao Jiang 	uint8_t ns_g_id[16] = "abcdefgh";
557980a1396SMao Jiang 	uint8_t eui64[8] = "12345678";
558980a1396SMao Jiang 
559b09de013SShuhei Matsumoto 	desc.bdev = &bdev;
560b09de013SShuhei Matsumoto 	ns.desc = &desc;
561980a1396SMao Jiang 	ns.bdev = &bdev;
562980a1396SMao Jiang 	ns.ptpl_file = (void *)0xDEADBEEF;
563980a1396SMao Jiang 	memcpy(ns.opts.nguid, ns_g_id, 16);
564980a1396SMao Jiang 	memcpy(ns.opts.eui64, eui64, 8);
565980a1396SMao Jiang 
566980a1396SMao Jiang 	bdev.blockcnt = 10;
56781a3b8a5SJim Harris 	bdev.acwu = 1;
568980a1396SMao Jiang 	bdev.md_len = 512;
569980a1396SMao Jiang 	bdev.dif_type = SPDK_DIF_TYPE1;
570980a1396SMao Jiang 	bdev.blocklen = 4096;
571980a1396SMao Jiang 	bdev.md_interleave = 0;
572b45556e2SChangpeng Liu 	bdev.optimal_io_boundary = SPDK_BDEV_IO_NUM_CHILD_IOV;
573980a1396SMao Jiang 	bdev.dif_is_head_of_md = true;
574980a1396SMao Jiang 
575980a1396SMao Jiang 	nvmf_bdev_ctrlr_identify_ns(&ns, &nsdata, false);
576980a1396SMao Jiang 	CU_ASSERT(nsdata.nsze == 10);
577980a1396SMao Jiang 	CU_ASSERT(nsdata.ncap == 10);
578980a1396SMao Jiang 	CU_ASSERT(nsdata.nuse == 10);
579980a1396SMao Jiang 	CU_ASSERT(nsdata.nlbaf == 0);
580980a1396SMao Jiang 	CU_ASSERT(nsdata.flbas.format == 0);
5817bbeb80aSAnkit Kumar 	CU_ASSERT(nsdata.flbas.msb_format == 0);
582980a1396SMao Jiang 	CU_ASSERT(nsdata.nacwu == 0);
583980a1396SMao Jiang 	CU_ASSERT(nsdata.lbaf[0].lbads == spdk_u32log2(4096));
584980a1396SMao Jiang 	CU_ASSERT(nsdata.lbaf[0].ms == 512);
585*2e10c84cSShuhei Matsumoto 	CU_ASSERT(nsdata.dpc.pit1 == 1);
586*2e10c84cSShuhei Matsumoto 	CU_ASSERT(nsdata.dps.pit == SPDK_NVME_FMT_NVM_PROTECTION_TYPE1);
587b45556e2SChangpeng Liu 	CU_ASSERT(nsdata.noiob == SPDK_BDEV_IO_NUM_CHILD_IOV);
588980a1396SMao Jiang 	CU_ASSERT(nsdata.nmic.can_share == 1);
589980a1396SMao Jiang 	CU_ASSERT(nsdata.nsrescap.rescap.persist == 1);
590980a1396SMao Jiang 	CU_ASSERT(nsdata.nsrescap.rescap.write_exclusive == 1);
591980a1396SMao Jiang 	CU_ASSERT(nsdata.nsrescap.rescap.exclusive_access == 1);
592980a1396SMao Jiang 	CU_ASSERT(nsdata.nsrescap.rescap.write_exclusive_reg_only == 1);
593980a1396SMao Jiang 	CU_ASSERT(nsdata.nsrescap.rescap.exclusive_access_reg_only == 1);
594980a1396SMao Jiang 	CU_ASSERT(nsdata.nsrescap.rescap.write_exclusive_all_reg == 1);
595980a1396SMao Jiang 	CU_ASSERT(nsdata.nsrescap.rescap.exclusive_access_all_reg == 1);
596980a1396SMao Jiang 	CU_ASSERT(nsdata.nsrescap.rescap.ignore_existing_key == 1);
597980a1396SMao Jiang 	CU_ASSERT(nsdata.flbas.extended == 1);
598980a1396SMao Jiang 	CU_ASSERT(nsdata.mc.extended == 1);
599980a1396SMao Jiang 	CU_ASSERT(nsdata.mc.pointer == 0);
600980a1396SMao Jiang 	CU_ASSERT(nsdata.dps.md_start == true);
601980a1396SMao Jiang 	CU_ASSERT(!strncmp(nsdata.nguid, ns_g_id, 16));
602980a1396SMao Jiang 	CU_ASSERT(!strncmp((uint8_t *)&nsdata.eui64, eui64, 8));
603980a1396SMao Jiang 
604980a1396SMao Jiang 	memset(&nsdata, 0, sizeof(nsdata));
605980a1396SMao Jiang 	nvmf_bdev_ctrlr_identify_ns(&ns, &nsdata, true);
606980a1396SMao Jiang 	CU_ASSERT(nsdata.nsze == 10);
607980a1396SMao Jiang 	CU_ASSERT(nsdata.ncap == 10);
608980a1396SMao Jiang 	CU_ASSERT(nsdata.nuse == 10);
609980a1396SMao Jiang 	CU_ASSERT(nsdata.nlbaf == 0);
610980a1396SMao Jiang 	CU_ASSERT(nsdata.flbas.format == 0);
6117bbeb80aSAnkit Kumar 	CU_ASSERT(nsdata.flbas.msb_format == 0);
612980a1396SMao Jiang 	CU_ASSERT(nsdata.nacwu == 0);
613980a1396SMao Jiang 	CU_ASSERT(nsdata.lbaf[0].lbads == spdk_u32log2(4096));
614b45556e2SChangpeng Liu 	CU_ASSERT(nsdata.noiob == SPDK_BDEV_IO_NUM_CHILD_IOV);
615980a1396SMao Jiang 	CU_ASSERT(nsdata.nmic.can_share == 1);
616980a1396SMao Jiang 	CU_ASSERT(nsdata.lbaf[0].ms == 0);
617980a1396SMao Jiang 	CU_ASSERT(nsdata.nsrescap.rescap.persist == 1);
618980a1396SMao Jiang 	CU_ASSERT(nsdata.nsrescap.rescap.write_exclusive == 1);
619980a1396SMao Jiang 	CU_ASSERT(nsdata.nsrescap.rescap.exclusive_access == 1);
620980a1396SMao Jiang 	CU_ASSERT(nsdata.nsrescap.rescap.write_exclusive_reg_only == 1);
621980a1396SMao Jiang 	CU_ASSERT(nsdata.nsrescap.rescap.exclusive_access_reg_only == 1);
622980a1396SMao Jiang 	CU_ASSERT(nsdata.nsrescap.rescap.write_exclusive_all_reg == 1);
623980a1396SMao Jiang 	CU_ASSERT(nsdata.nsrescap.rescap.exclusive_access_all_reg == 1);
624980a1396SMao Jiang 	CU_ASSERT(nsdata.nsrescap.rescap.ignore_existing_key == 1);
625980a1396SMao Jiang 	CU_ASSERT(!strncmp(nsdata.nguid, ns_g_id, 16));
626980a1396SMao Jiang 	CU_ASSERT(!strncmp((uint8_t *)&nsdata.eui64, eui64, 8));
627980a1396SMao Jiang }
628980a1396SMao Jiang 
6295818b42fSmatthewb static void
6300e09df57SKonrad Sztyber test_nvmf_bdev_ctrlr_zcopy_start(void)
6315818b42fSmatthewb {
6325818b42fSmatthewb 	int rc;
6335818b42fSmatthewb 	struct spdk_bdev bdev = {};
634b09de013SShuhei Matsumoto 	struct spdk_bdev_desc desc = { .bdev = &bdev, };
6355818b42fSmatthewb 	struct spdk_io_channel ch = {};
6365818b42fSmatthewb 
6375818b42fSmatthewb 	struct spdk_nvmf_request write_req = {};
6385818b42fSmatthewb 	union nvmf_c2h_msg write_rsp = {};
6395818b42fSmatthewb 
6405818b42fSmatthewb 	struct spdk_nvmf_qpair qpair = {};
6415818b42fSmatthewb 
6425818b42fSmatthewb 	struct spdk_nvme_cmd write_cmd = {};
6435818b42fSmatthewb 
6445818b42fSmatthewb 	struct spdk_nvmf_ctrlr ctrlr = {};
6455818b42fSmatthewb 	struct spdk_nvmf_subsystem subsystem = {};
6465818b42fSmatthewb 	struct spdk_nvmf_ns ns = {};
6475818b42fSmatthewb 	struct spdk_nvmf_ns *subsys_ns[1] = {};
6485818b42fSmatthewb 
6495818b42fSmatthewb 	struct spdk_nvmf_poll_group group = {};
6505818b42fSmatthewb 	struct spdk_nvmf_subsystem_poll_group sgroups = {};
6515818b42fSmatthewb 	struct spdk_nvmf_subsystem_pg_ns_info ns_info = {};
6525818b42fSmatthewb 
6535818b42fSmatthewb 	bdev.blocklen = 512;
6545818b42fSmatthewb 	bdev.blockcnt = 10;
6555818b42fSmatthewb 	ns.bdev = &bdev;
6565818b42fSmatthewb 
6575818b42fSmatthewb 	subsystem.id = 0;
6585818b42fSmatthewb 	subsystem.max_nsid = 1;
6595818b42fSmatthewb 	subsys_ns[0] = &ns;
6605818b42fSmatthewb 	subsystem.ns = (struct spdk_nvmf_ns **)&subsys_ns;
6615818b42fSmatthewb 
6625818b42fSmatthewb 	/* Enable controller */
6635818b42fSmatthewb 	ctrlr.vcprop.cc.bits.en = 1;
6645818b42fSmatthewb 	ctrlr.subsys = &subsystem;
6655818b42fSmatthewb 
6665818b42fSmatthewb 	group.num_sgroups = 1;
6675818b42fSmatthewb 	sgroups.num_ns = 1;
6685818b42fSmatthewb 	sgroups.ns_info = &ns_info;
6695818b42fSmatthewb 	group.sgroups = &sgroups;
6705818b42fSmatthewb 
6715818b42fSmatthewb 	qpair.ctrlr = &ctrlr;
6725818b42fSmatthewb 	qpair.group = &group;
6735818b42fSmatthewb 
6745818b42fSmatthewb 	write_req.qpair = &qpair;
6755818b42fSmatthewb 	write_req.cmd = (union nvmf_h2c_msg *)&write_cmd;
6765818b42fSmatthewb 	write_req.rsp = &write_rsp;
6775818b42fSmatthewb 
6785818b42fSmatthewb 	write_cmd.nsid = 1;
6795818b42fSmatthewb 	write_cmd.opc = SPDK_NVME_OPC_WRITE;
6805818b42fSmatthewb 
6815818b42fSmatthewb 	/* 1. SUCCESS */
6825818b42fSmatthewb 	write_cmd.cdw10 = 1;	/* SLBA: CDW10 and CDW11 */
6835818b42fSmatthewb 	write_cmd.cdw12 = 1;	/* NLB: CDW12 bits 15:00, 0's based */
6845818b42fSmatthewb 	write_req.length = (write_cmd.cdw12 + 1) * bdev.blocklen;
6855818b42fSmatthewb 
686b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_zcopy_start(&bdev, &desc, &ch, &write_req);
6875818b42fSmatthewb 
688686b9984SKonrad Sztyber 	CU_ASSERT_EQUAL(rc, SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS);
689686b9984SKonrad Sztyber 	CU_ASSERT_EQUAL(write_rsp.nvme_cpl.status.sct, SPDK_NVME_SCT_GENERIC);
690686b9984SKonrad Sztyber 	CU_ASSERT_EQUAL(write_rsp.nvme_cpl.status.sc, SPDK_NVME_SC_SUCCESS);
6915818b42fSmatthewb 
6925818b42fSmatthewb 	/* 2. SPDK_NVME_SC_LBA_OUT_OF_RANGE */
6935818b42fSmatthewb 	write_cmd.cdw10 = 1;	/* SLBA: CDW10 and CDW11 */
6945818b42fSmatthewb 	write_cmd.cdw12 = 100;	/* NLB: CDW12 bits 15:00, 0's based */
6955818b42fSmatthewb 	write_req.length = (write_cmd.cdw12 + 1) * bdev.blocklen;
6965818b42fSmatthewb 
697b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_zcopy_start(&bdev, &desc, &ch, &write_req);
6985818b42fSmatthewb 
699686b9984SKonrad Sztyber 	CU_ASSERT_EQUAL(rc, SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
700686b9984SKonrad Sztyber 	CU_ASSERT_EQUAL(write_rsp.nvme_cpl.status.sct, SPDK_NVME_SCT_GENERIC);
701686b9984SKonrad Sztyber 	CU_ASSERT_EQUAL(write_rsp.nvme_cpl.status.sc, SPDK_NVME_SC_LBA_OUT_OF_RANGE);
7025818b42fSmatthewb 
7035818b42fSmatthewb 	/* 3. SPDK_NVME_SC_DATA_SGL_LENGTH_INVALID */
7045818b42fSmatthewb 	write_cmd.cdw10 = 1;	/* SLBA: CDW10 and CDW11 */
7055818b42fSmatthewb 	write_cmd.cdw12 = 1;	/* NLB: CDW12 bits 15:00, 0's based */
7065818b42fSmatthewb 	write_req.length = (write_cmd.cdw12 + 1) * bdev.blocklen - 1;
7075818b42fSmatthewb 
708b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_zcopy_start(&bdev, &desc, &ch, &write_req);
7095818b42fSmatthewb 
710686b9984SKonrad Sztyber 	CU_ASSERT_EQUAL(rc, SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
711686b9984SKonrad Sztyber 	CU_ASSERT_EQUAL(write_rsp.nvme_cpl.status.sct, SPDK_NVME_SCT_GENERIC);
712686b9984SKonrad Sztyber 	CU_ASSERT_EQUAL(write_rsp.nvme_cpl.status.sc, SPDK_NVME_SC_DATA_SGL_LENGTH_INVALID);
7135818b42fSmatthewb }
7145818b42fSmatthewb 
715d6e0bbeeSMao Jiang static void
716d6e0bbeeSMao Jiang test_nvmf_bdev_ctrlr_cmd(void)
717d6e0bbeeSMao Jiang {
718d6e0bbeeSMao Jiang 	int rc;
719d6e0bbeeSMao Jiang 	struct spdk_bdev bdev = {};
720b09de013SShuhei Matsumoto 	struct spdk_bdev_desc desc = { .bdev = &bdev, };
721d6e0bbeeSMao Jiang 	struct spdk_io_channel ch = {};
722d6e0bbeeSMao Jiang 	struct spdk_nvmf_request req = {};
723d6e0bbeeSMao Jiang 	struct spdk_nvmf_qpair qpair = {};
724d6e0bbeeSMao Jiang 	union nvmf_h2c_msg cmd = {};
725d6e0bbeeSMao Jiang 	union nvmf_c2h_msg rsp = {};
7268305e49bSEvgeniy Kochetov 	struct spdk_nvme_scc_source_range range = {};
727d6e0bbeeSMao Jiang 
728d6e0bbeeSMao Jiang 	req.cmd = &cmd;
729d6e0bbeeSMao Jiang 	req.rsp = &rsp;
730d6e0bbeeSMao Jiang 	req.qpair = &qpair;
731d6e0bbeeSMao Jiang 	req.length = 4096;
732d6e0bbeeSMao Jiang 	bdev.blocklen = 512;
733d6e0bbeeSMao Jiang 	bdev.blockcnt = 3;
734d6e0bbeeSMao Jiang 	cmd.nvme_cmd.cdw10 = 0;
735d6e0bbeeSMao Jiang 	cmd.nvme_cmd.cdw12 = 2;
736d6e0bbeeSMao Jiang 
737d6e0bbeeSMao Jiang 	/* Compare status asynchronous */
738b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_compare_cmd(&bdev, &desc, &ch, &req);
739d6e0bbeeSMao Jiang 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS);
740d6e0bbeeSMao Jiang 
741d6e0bbeeSMao Jiang 	/* SLBA out of range */
742d6e0bbeeSMao Jiang 	cmd.nvme_cmd.cdw10 = 3;
743d6e0bbeeSMao Jiang 
744b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_compare_cmd(&bdev, &desc, &ch, &req);
745d6e0bbeeSMao Jiang 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
746d6e0bbeeSMao Jiang 	CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
747d6e0bbeeSMao Jiang 	CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_LBA_OUT_OF_RANGE);
748d6e0bbeeSMao Jiang 
749d6e0bbeeSMao Jiang 	/* SGL length invalid */
750d6e0bbeeSMao Jiang 	cmd.nvme_cmd.cdw10 = 0;
751d6e0bbeeSMao Jiang 	req.length = 512;
752d6e0bbeeSMao Jiang 	memset(&rsp, 0, sizeof(rsp));
753d6e0bbeeSMao Jiang 
754b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_compare_cmd(&bdev, &desc, &ch, &req);
755d6e0bbeeSMao Jiang 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
756d6e0bbeeSMao Jiang 	CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
757d6e0bbeeSMao Jiang 	CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_DATA_SGL_LENGTH_INVALID);
758d6e0bbeeSMao Jiang 
759d6e0bbeeSMao Jiang 	/* Device error */
760d6e0bbeeSMao Jiang 	req.length = 4096;
761d6e0bbeeSMao Jiang 	memset(&rsp, 0, sizeof(rsp));
762d6e0bbeeSMao Jiang 	MOCK_SET(spdk_bdev_comparev_blocks, -1);
763d6e0bbeeSMao Jiang 
764b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_compare_cmd(&bdev, &desc, &ch, &req);
765d6e0bbeeSMao Jiang 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
766d6e0bbeeSMao Jiang 	CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
767d6e0bbeeSMao Jiang 	CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INTERNAL_DEVICE_ERROR);
768d6e0bbeeSMao Jiang 
769d6e0bbeeSMao Jiang 	/* bdev not support flush */
770d6e0bbeeSMao Jiang 	MOCK_SET(spdk_bdev_io_type_supported, false);
771d6e0bbeeSMao Jiang 	memset(&rsp, 0, sizeof(rsp));
772d6e0bbeeSMao Jiang 
773b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_flush_cmd(&bdev, &desc, &ch, &req);
774d6e0bbeeSMao Jiang 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
775d6e0bbeeSMao Jiang 	CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
776d6e0bbeeSMao Jiang 	CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS);
777d6e0bbeeSMao Jiang 
778d6e0bbeeSMao Jiang 	/*  Flush error */
779d6e0bbeeSMao Jiang 	MOCK_SET(spdk_bdev_io_type_supported, true);
780d6e0bbeeSMao Jiang 	MOCK_SET(spdk_bdev_flush_blocks, -1);
781d6e0bbeeSMao Jiang 	memset(&rsp, 0, sizeof(rsp));
782d6e0bbeeSMao Jiang 
783b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_flush_cmd(&bdev, &desc, &ch, &req);
784d6e0bbeeSMao Jiang 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
785d6e0bbeeSMao Jiang 	CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
786d6e0bbeeSMao Jiang 	CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INTERNAL_DEVICE_ERROR);
787d6e0bbeeSMao Jiang 
788d6e0bbeeSMao Jiang 	/* Flush blocks status asynchronous */
789d6e0bbeeSMao Jiang 	MOCK_SET(spdk_bdev_flush_blocks, 0);
790d6e0bbeeSMao Jiang 
791b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_flush_cmd(&bdev, &desc, &ch, &req);
792d6e0bbeeSMao Jiang 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS);
793d6e0bbeeSMao Jiang 	MOCK_CLEAR(spdk_bdev_io_type_supported);
794d6e0bbeeSMao Jiang 	MOCK_CLEAR(spdk_bdev_flush_blocks);
795d6e0bbeeSMao Jiang 
796d6e0bbeeSMao Jiang 	/* Write zeroes blocks status asynchronous */
797c7feb85dSHaoqian He 	struct spdk_nvmf_subsystem subsystem = { };
798c7feb85dSHaoqian He 	struct spdk_nvmf_ctrlr ctrlr = { .subsys = &subsystem };
799c7feb85dSHaoqian He 	qpair.ctrlr = &ctrlr;
800c7feb85dSHaoqian He 
801b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_write_zeroes_cmd(&bdev, &desc, &ch, &req);
802d6e0bbeeSMao Jiang 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS);
803d6e0bbeeSMao Jiang 
804c7feb85dSHaoqian He 	cmd.nvme_cmd.cdw12 = 3;
805c7feb85dSHaoqian He 	subsystem.max_write_zeroes_size_kib = 1;
806b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_write_zeroes_cmd(&bdev, &desc, &ch, &req);
807c7feb85dSHaoqian He 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
808c7feb85dSHaoqian He 
809d6e0bbeeSMao Jiang 	/* SLBA out of range */
810c7feb85dSHaoqian He 	subsystem.max_write_zeroes_size_kib = 0;
811c7feb85dSHaoqian He 	cmd.nvme_cmd.cdw12 = 2;
812d6e0bbeeSMao Jiang 	cmd.nvme_cmd.cdw10 = 3;
813d6e0bbeeSMao Jiang 	memset(&rsp, 0, sizeof(rsp));
814d6e0bbeeSMao Jiang 
815b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_write_zeroes_cmd(&bdev, &desc, &ch, &req);
816d6e0bbeeSMao Jiang 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
817d6e0bbeeSMao Jiang 	CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
818d6e0bbeeSMao Jiang 	CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_LBA_OUT_OF_RANGE);
819d6e0bbeeSMao Jiang 
820d6e0bbeeSMao Jiang 	/* Write block error */
821d6e0bbeeSMao Jiang 	MOCK_SET(spdk_bdev_write_zeroes_blocks, -1);
822d6e0bbeeSMao Jiang 	cmd.nvme_cmd.cdw10 = 0;
823d6e0bbeeSMao Jiang 	memset(&rsp, 0, sizeof(rsp));
824d6e0bbeeSMao Jiang 
825b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_write_zeroes_cmd(&bdev, &desc, &ch, &req);
826d6e0bbeeSMao Jiang 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
827d6e0bbeeSMao Jiang 	CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
828d6e0bbeeSMao Jiang 	CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INTERNAL_DEVICE_ERROR);
8298305e49bSEvgeniy Kochetov 
8308305e49bSEvgeniy Kochetov 	/* Copy blocks status asynchronous */
8318305e49bSEvgeniy Kochetov 	MOCK_SET(spdk_bdev_io_type_supported, true);
8328305e49bSEvgeniy Kochetov 	cmd.nvme_cmd.cdw10 = 1024;
8338305e49bSEvgeniy Kochetov 	cmd.nvme_cmd.cdw11 = 0;
8348305e49bSEvgeniy Kochetov 	cmd.nvme_cmd.cdw12 = 0;
8358305e49bSEvgeniy Kochetov 	cmd.nvme_cmd.cdw12_bits.copy.nr = 0;
8368305e49bSEvgeniy Kochetov 	range.slba = 512;
8378305e49bSEvgeniy Kochetov 	range.nlb = 511;
8389fa25237SJohn Levon 	req.length = 32;
839f029b824SJacek Kalwas 	SPDK_IOV_ONE(req.iov, &req.iovcnt, &range, req.length);
8408305e49bSEvgeniy Kochetov 	rc = nvmf_bdev_ctrlr_copy_cmd(&bdev, NULL, &ch, &req);
8418305e49bSEvgeniy Kochetov 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS);
8428305e49bSEvgeniy Kochetov 
8438305e49bSEvgeniy Kochetov 	/* Copy command not supported */
8448305e49bSEvgeniy Kochetov 	MOCK_SET(spdk_bdev_io_type_supported, false);
8458305e49bSEvgeniy Kochetov 	memset(&rsp, 0, sizeof(rsp));
8468305e49bSEvgeniy Kochetov 
847b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_copy_cmd(&bdev, &desc, &ch, &req);
84886136540SRui Chang 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS);
8498305e49bSEvgeniy Kochetov 
8508305e49bSEvgeniy Kochetov 	MOCK_SET(spdk_bdev_io_type_supported, true);
8518305e49bSEvgeniy Kochetov 
8528305e49bSEvgeniy Kochetov 	/* Unsupported number of source ranges */
8538305e49bSEvgeniy Kochetov 	cmd.nvme_cmd.cdw12_bits.copy.nr = 1;
8548305e49bSEvgeniy Kochetov 	req.length = 64;
8558305e49bSEvgeniy Kochetov 	memset(&rsp, 0, sizeof(rsp));
8568305e49bSEvgeniy Kochetov 
857b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_copy_cmd(&bdev, &desc, &ch, &req);
8588305e49bSEvgeniy Kochetov 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
8598305e49bSEvgeniy Kochetov 	CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC);
8608305e49bSEvgeniy Kochetov 	CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_CMD_SIZE_LIMIT_SIZE_EXCEEDED);
8618305e49bSEvgeniy Kochetov 
8628305e49bSEvgeniy Kochetov 	cmd.nvme_cmd.cdw12_bits.copy.nr = 0;
8638305e49bSEvgeniy Kochetov 	req.length = 32;
8648305e49bSEvgeniy Kochetov 
8658305e49bSEvgeniy Kochetov 	/* Unsupported source range descriptor format */
8668305e49bSEvgeniy Kochetov 	cmd.nvme_cmd.cdw12_bits.copy.df = 1;
8678305e49bSEvgeniy Kochetov 	memset(&rsp, 0, sizeof(rsp));
8688305e49bSEvgeniy Kochetov 
869b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_copy_cmd(&bdev, &desc, &ch, &req);
8708305e49bSEvgeniy Kochetov 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
8718305e49bSEvgeniy Kochetov 	CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
8728305e49bSEvgeniy Kochetov 	CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD);
8738305e49bSEvgeniy Kochetov 
8748305e49bSEvgeniy Kochetov 	cmd.nvme_cmd.cdw12_bits.copy.df = 0;
8758305e49bSEvgeniy Kochetov 
8768305e49bSEvgeniy Kochetov 	/* Bdev copy command failed */
8778305e49bSEvgeniy Kochetov 	MOCK_SET(spdk_bdev_copy_blocks, -1);
8788305e49bSEvgeniy Kochetov 	memset(&rsp, 0, sizeof(rsp));
8798305e49bSEvgeniy Kochetov 
880b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_copy_cmd(&bdev, &desc, &ch, &req);
8818305e49bSEvgeniy Kochetov 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
8828305e49bSEvgeniy Kochetov 	CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
8838305e49bSEvgeniy Kochetov 	CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INTERNAL_DEVICE_ERROR);
8848305e49bSEvgeniy Kochetov 
8858305e49bSEvgeniy Kochetov 	MOCK_CLEAR(spdk_bdev_copy_blocks);
8868305e49bSEvgeniy Kochetov 	MOCK_CLEAR(spdk_bdev_io_type_supported);
887d6e0bbeeSMao Jiang }
888d6e0bbeeSMao Jiang 
88925e1099bSMao Jiang static void
89025e1099bSMao Jiang test_nvmf_bdev_ctrlr_read_write_cmd(void)
89125e1099bSMao Jiang {
89225e1099bSMao Jiang 	struct spdk_bdev bdev = {};
893b09de013SShuhei Matsumoto 	struct spdk_bdev_desc desc = { .bdev = &bdev, };
89425e1099bSMao Jiang 	struct spdk_nvmf_request req = {};
89525e1099bSMao Jiang 	union nvmf_c2h_msg rsp = {};
89625e1099bSMao Jiang 	union nvmf_h2c_msg cmd = {};
89725e1099bSMao Jiang 	int rc;
89825e1099bSMao Jiang 
89925e1099bSMao Jiang 	req.cmd = &cmd;
90025e1099bSMao Jiang 	req.rsp = &rsp;
90125e1099bSMao Jiang 
90225e1099bSMao Jiang 	/* Read two blocks, block size 4096 */
90325e1099bSMao Jiang 	cmd.nvme_cmd.cdw12 = 1;
90425e1099bSMao Jiang 	bdev.blockcnt = 100;
90525e1099bSMao Jiang 	bdev.blocklen = 4096;
90625e1099bSMao Jiang 	req.length = 8192;
90725e1099bSMao Jiang 	req.zcopy_phase = NVMF_ZCOPY_PHASE_NONE;
90825e1099bSMao Jiang 
909b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_read_cmd(&bdev, &desc, NULL, &req);
91025e1099bSMao Jiang 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS);
91125e1099bSMao Jiang 
91225e1099bSMao Jiang 	/* Write two blocks, block size 4096 */
91325e1099bSMao Jiang 	cmd.nvme_cmd.cdw12 = 1;
91425e1099bSMao Jiang 	bdev.blockcnt = 100;
91525e1099bSMao Jiang 	bdev.blocklen = 4096;
91625e1099bSMao Jiang 	req.length = 8192;
91725e1099bSMao Jiang 	req.zcopy_phase = NVMF_ZCOPY_PHASE_NONE;
91825e1099bSMao Jiang 
919b09de013SShuhei Matsumoto 	rc = nvmf_bdev_ctrlr_write_cmd(&bdev, &desc, NULL, &req);
92025e1099bSMao Jiang 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS);
92125e1099bSMao Jiang }
92225e1099bSMao Jiang 
923d03b31c6SEvgeniy Kochetov static void
924d03b31c6SEvgeniy Kochetov test_nvmf_bdev_ctrlr_nvme_passthru(void)
925d03b31c6SEvgeniy Kochetov {
926d03b31c6SEvgeniy Kochetov 	int rc;
927d03b31c6SEvgeniy Kochetov 	struct spdk_bdev bdev = {};
928d03b31c6SEvgeniy Kochetov 	struct spdk_bdev_desc *desc = NULL;
929d03b31c6SEvgeniy Kochetov 	struct spdk_io_channel ch = {};
930d03b31c6SEvgeniy Kochetov 	struct spdk_nvmf_qpair qpair = {};
931d03b31c6SEvgeniy Kochetov 	struct spdk_nvmf_poll_group group = {};
932d03b31c6SEvgeniy Kochetov 
933d03b31c6SEvgeniy Kochetov 	struct spdk_nvmf_request req = {};
934d03b31c6SEvgeniy Kochetov 	union nvmf_c2h_msg rsp = {};
935d03b31c6SEvgeniy Kochetov 	struct spdk_nvme_cmd cmd = {};
936d03b31c6SEvgeniy Kochetov 	struct spdk_bdev_io bdev_io;
937d03b31c6SEvgeniy Kochetov 
938d03b31c6SEvgeniy Kochetov 	bdev.blocklen = 512;
939d03b31c6SEvgeniy Kochetov 	bdev.blockcnt = 10;
940d03b31c6SEvgeniy Kochetov 
941d03b31c6SEvgeniy Kochetov 	qpair.group = &group;
942d03b31c6SEvgeniy Kochetov 
943d03b31c6SEvgeniy Kochetov 	req.qpair = &qpair;
944d03b31c6SEvgeniy Kochetov 	req.cmd = (union nvmf_h2c_msg *)&cmd;
945d03b31c6SEvgeniy Kochetov 	req.rsp = &rsp;
946f029b824SJacek Kalwas 	SPDK_IOV_ONE(req.iov, &req.iovcnt, NULL, 0);
947d03b31c6SEvgeniy Kochetov 
948d03b31c6SEvgeniy Kochetov 	cmd.nsid = 1;
949d03b31c6SEvgeniy Kochetov 	cmd.opc = 0xFF;
950d03b31c6SEvgeniy Kochetov 
951d03b31c6SEvgeniy Kochetov 	cmd.cdw10 = 1;	/* SLBA: CDW10 and CDW11 */
952d03b31c6SEvgeniy Kochetov 	cmd.cdw12 = 1;	/* NLB: CDW12 bits 15:00, 0's based */
953d03b31c6SEvgeniy Kochetov 
954d03b31c6SEvgeniy Kochetov 	/* NVME_IO success */
955d03b31c6SEvgeniy Kochetov 	memset(&rsp, 0, sizeof(rsp));
956d03b31c6SEvgeniy Kochetov 	rc = nvmf_bdev_ctrlr_nvme_passthru_io(&bdev, desc, &ch, &req);
957d03b31c6SEvgeniy Kochetov 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS);
958d03b31c6SEvgeniy Kochetov 	nvmf_bdev_ctrlr_complete_cmd(&bdev_io, true, &req);
959d03b31c6SEvgeniy Kochetov 	CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
960d03b31c6SEvgeniy Kochetov 	CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS);
961d03b31c6SEvgeniy Kochetov 
962d03b31c6SEvgeniy Kochetov 	/* NVME_IO fail */
963d03b31c6SEvgeniy Kochetov 	memset(&rsp, 0, sizeof(rsp));
964d03b31c6SEvgeniy Kochetov 	rc = nvmf_bdev_ctrlr_nvme_passthru_io(&bdev, desc, &ch, &req);
965d03b31c6SEvgeniy Kochetov 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS);
966d03b31c6SEvgeniy Kochetov 	g_bdev_nvme_status_sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR;
967d03b31c6SEvgeniy Kochetov 	nvmf_bdev_ctrlr_complete_cmd(&bdev_io, false, &req);
968d03b31c6SEvgeniy Kochetov 	CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
969d03b31c6SEvgeniy Kochetov 	CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INTERNAL_DEVICE_ERROR);
970d03b31c6SEvgeniy Kochetov 	reset_bdev_nvme_status();
971d03b31c6SEvgeniy Kochetov 
972d03b31c6SEvgeniy Kochetov 	/* NVME_IO not supported */
973d03b31c6SEvgeniy Kochetov 	memset(&rsp, 0, sizeof(rsp));
97404a428f5SKarl Bonde Torp 	MOCK_SET(spdk_bdev_nvme_iov_passthru_md, -ENOTSUP);
975d03b31c6SEvgeniy Kochetov 	rc = nvmf_bdev_ctrlr_nvme_passthru_io(&bdev, desc, &ch, &req);
976d03b31c6SEvgeniy Kochetov 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
977d03b31c6SEvgeniy Kochetov 	CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
978d03b31c6SEvgeniy Kochetov 	CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_OPCODE);
9791fd2af01SEvgeniy Kochetov 	CU_ASSERT(rsp.nvme_cpl.status.dnr == 1);
980d03b31c6SEvgeniy Kochetov 
981d03b31c6SEvgeniy Kochetov 	/* NVME_IO no channel - queue IO */
982d03b31c6SEvgeniy Kochetov 	memset(&rsp, 0, sizeof(rsp));
98304a428f5SKarl Bonde Torp 	MOCK_SET(spdk_bdev_nvme_iov_passthru_md, -ENOMEM);
984d03b31c6SEvgeniy Kochetov 	rc = nvmf_bdev_ctrlr_nvme_passthru_io(&bdev, desc, &ch, &req);
985d03b31c6SEvgeniy Kochetov 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS);
986d03b31c6SEvgeniy Kochetov 	CU_ASSERT(group.stat.pending_bdev_io == 1);
987d03b31c6SEvgeniy Kochetov 
98804a428f5SKarl Bonde Torp 	MOCK_SET(spdk_bdev_nvme_iov_passthru_md, 0);
989d03b31c6SEvgeniy Kochetov 
990d03b31c6SEvgeniy Kochetov 	/* NVME_ADMIN success */
991d03b31c6SEvgeniy Kochetov 	memset(&rsp, 0, sizeof(rsp));
992d03b31c6SEvgeniy Kochetov 	rc = spdk_nvmf_bdev_ctrlr_nvme_passthru_admin(&bdev, desc, &ch, &req, NULL);
993d03b31c6SEvgeniy Kochetov 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS);
994d03b31c6SEvgeniy Kochetov 	nvmf_bdev_ctrlr_complete_admin_cmd(&bdev_io, true, &req);
995d03b31c6SEvgeniy Kochetov 	CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
996d03b31c6SEvgeniy Kochetov 	CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_SUCCESS);
997d03b31c6SEvgeniy Kochetov 
998d03b31c6SEvgeniy Kochetov 	/* NVME_ADMIN fail */
999d03b31c6SEvgeniy Kochetov 	memset(&rsp, 0, sizeof(rsp));
1000d03b31c6SEvgeniy Kochetov 	rc = spdk_nvmf_bdev_ctrlr_nvme_passthru_admin(&bdev, desc, &ch, &req, NULL);
1001d03b31c6SEvgeniy Kochetov 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS);
1002d03b31c6SEvgeniy Kochetov 	g_bdev_nvme_status_sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR;
1003d03b31c6SEvgeniy Kochetov 	nvmf_bdev_ctrlr_complete_admin_cmd(&bdev_io, true, &req);
1004d03b31c6SEvgeniy Kochetov 	CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
1005d03b31c6SEvgeniy Kochetov 	CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INTERNAL_DEVICE_ERROR);
1006d03b31c6SEvgeniy Kochetov 	reset_bdev_nvme_status();
1007d03b31c6SEvgeniy Kochetov 
1008d03b31c6SEvgeniy Kochetov 	/* NVME_ADMIN not supported */
1009d03b31c6SEvgeniy Kochetov 	memset(&rsp, 0, sizeof(rsp));
1010d03b31c6SEvgeniy Kochetov 	MOCK_SET(spdk_bdev_nvme_admin_passthru, -ENOTSUP);
1011d03b31c6SEvgeniy Kochetov 	rc = spdk_nvmf_bdev_ctrlr_nvme_passthru_admin(&bdev, desc, &ch, &req, NULL);
1012d03b31c6SEvgeniy Kochetov 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
1013d03b31c6SEvgeniy Kochetov 	CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
1014d03b31c6SEvgeniy Kochetov 	CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_OPCODE);
10151fd2af01SEvgeniy Kochetov 	CU_ASSERT(rsp.nvme_cpl.status.dnr == 1);
1016d03b31c6SEvgeniy Kochetov 
1017d03b31c6SEvgeniy Kochetov 	/* NVME_ADMIN no channel - queue IO */
1018d03b31c6SEvgeniy Kochetov 	memset(&rsp, 0, sizeof(rsp));
1019d03b31c6SEvgeniy Kochetov 	MOCK_SET(spdk_bdev_nvme_admin_passthru, -ENOMEM);
1020d03b31c6SEvgeniy Kochetov 	rc = spdk_nvmf_bdev_ctrlr_nvme_passthru_admin(&bdev, desc, &ch, &req, NULL);
1021d03b31c6SEvgeniy Kochetov 	CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS);
1022d03b31c6SEvgeniy Kochetov 	CU_ASSERT(group.stat.pending_bdev_io == 2);
1023d03b31c6SEvgeniy Kochetov 
1024d03b31c6SEvgeniy Kochetov 	MOCK_SET(spdk_bdev_nvme_admin_passthru, 0);
1025d03b31c6SEvgeniy Kochetov }
1026d03b31c6SEvgeniy Kochetov 
10278dd1cd21SBen Walker int
10288dd1cd21SBen Walker main(int argc, char **argv)
1029f6e62d2cSBen Walker {
1030f6e62d2cSBen Walker 	CU_pSuite	suite = NULL;
1031f6e62d2cSBen Walker 	unsigned int	num_failures;
1032f6e62d2cSBen Walker 
103378b696bcSVitaliy Mysak 	CU_initialize_registry();
1034f6e62d2cSBen Walker 
1035f6e62d2cSBen Walker 	suite = CU_add_suite("nvmf", NULL, NULL);
1036f6e62d2cSBen Walker 
1037dcf0ca15SVitaliy Mysak 	CU_ADD_TEST(suite, test_get_rw_params);
10383dbaa93cSAnkit Kumar 	CU_ADD_TEST(suite, test_get_rw_ext_params);
1039dcf0ca15SVitaliy Mysak 	CU_ADD_TEST(suite, test_lba_in_range);
1040dcf0ca15SVitaliy Mysak 	CU_ADD_TEST(suite, test_get_dif_ctx);
1041980a1396SMao Jiang 	CU_ADD_TEST(suite, test_nvmf_bdev_ctrlr_identify_ns);
1042dcf0ca15SVitaliy Mysak 	CU_ADD_TEST(suite, test_spdk_nvmf_bdev_ctrlr_compare_and_write_cmd);
10430e09df57SKonrad Sztyber 	CU_ADD_TEST(suite, test_nvmf_bdev_ctrlr_zcopy_start);
1044d6e0bbeeSMao Jiang 	CU_ADD_TEST(suite, test_nvmf_bdev_ctrlr_cmd);
104525e1099bSMao Jiang 	CU_ADD_TEST(suite, test_nvmf_bdev_ctrlr_read_write_cmd);
1046d03b31c6SEvgeniy Kochetov 	CU_ADD_TEST(suite, test_nvmf_bdev_ctrlr_nvme_passthru);
1047f6e62d2cSBen Walker 
1048ea941caeSKonrad Sztyber 	num_failures = spdk_ut_run_tests(argc, argv, NULL);
1049f6e62d2cSBen Walker 	CU_cleanup_registry();
1050f6e62d2cSBen Walker 	return num_failures;
1051f6e62d2cSBen Walker }
1052