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